From 74264a0486236c1b71f6e15130d1a1979d7d130d Mon Sep 17 00:00:00 2001 From: alexander-yevsyukov Date: Wed, 26 Mar 2025 20:57:19 +0000 Subject: [PATCH 01/15] Update `config` --- .github/workflows/build-on-ubuntu.yml | 14 +- .github/workflows/build-on-windows.yml | 15 +- .github/workflows/ensure-reports-updated.yml | 25 + .github/workflows/publish.yml | 6 +- ...move-obsolete-artifacts-from-packages.yaml | 73 ++ .gitignore | 33 +- .idea/copyright/TeamDev_Open_Source.xml | 2 +- .lift.toml | 1 - build.gradle.kts | 137 ++-- buildSrc/build.gradle.kts | 176 +++-- buildSrc/src/main/kotlin/BuildExtensions.kt | 295 +++++++ buildSrc/src/main/kotlin/BuildSettings.kt | 41 + buildSrc/src/main/kotlin/Dependencies.kt | 76 -- .../gradle => }/DependencyResolution.kt | 159 ++-- buildSrc/src/main/kotlin/DokkaExts.kt | 224 ++++++ buildSrc/src/main/kotlin/PluginsAccessors.kt | 66 -- buildSrc/src/main/kotlin/Strings.kt | 50 ++ buildSrc/src/main/kotlin/TaskDependencies.kt | 71 -- .../main/kotlin/compile-protobuf.gradle.kts | 53 ++ .../src/main/kotlin/config-tester.gradle.kts | 10 +- .../kotlin/detekt-code-analysis.gradle.kts | 7 +- .../src/main/kotlin/dokka-for-java.gradle.kts | 82 +- ...Service.kt => dokka-for-kotlin.gradle.kts} | 25 +- .../build}/AnimalSniffer.kt | 9 +- .../build/CheckStyle.kt} | 34 +- .../build}/CheckerFramework.kt | 21 +- .../dependency => dependency/build}/Dokka.kt | 28 +- .../build}/ErrorProne.kt | 33 +- .../build}/FindBugs.kt | 20 +- .../build}/GradleDoctor.kt | 9 +- .../kotlin/io/spine/dependency/build/Ksp.kt | 44 ++ .../spine/dependency/build/LicenseReport.kt | 40 + .../build}/OsDetector.kt | 11 +- .../kotlin/io/spine/dependency/build/Pmd.kt | 42 + .../JavaJwt.kt => dependency/lib/Aedile.kt} | 16 +- .../lib}/ApacheHttp.kt | 8 +- .../lib}/AppEngine.kt | 12 +- .../kotlin/io/spine/dependency/lib/Asm.kt | 43 + .../kotlin/io/spine/dependency/lib/Auto.kt | 55 ++ .../lib}/BouncyCastle.kt | 8 +- .../io/spine/dependency/lib/Caffeine.kt | 41 + .../CheckStyle.kt => dependency/lib/Clikt.kt} | 14 +- .../lib}/CommonsCli.kt | 11 +- .../lib}/CommonsCodec.kt | 10 +- .../lib}/CommonsLogging.kt | 11 +- .../io/spine/dependency/lib/Coroutines.kt | 45 ++ .../dependency => dependency/lib}/Firebase.kt | 10 +- .../dependency => dependency/lib}/Flogger.kt | 19 +- .../lib}/GoogleApis.kt | 12 +- .../lib}/GoogleCloud.kt | 8 +- .../dependency => dependency/lib}/Grpc.kt | 38 +- .../io/spine/dependency/lib/GrpcKotlin.kt | 43 + .../dependency => dependency/lib}/Gson.kt | 13 +- .../dependency => dependency/lib}/Guava.kt | 17 +- .../lib}/HttpClient.kt | 18 +- .../io/spine/dependency/lib/IntelliJ.kt | 89 +++ .../dependency => dependency/lib}/J2ObjC.kt | 28 +- .../dependency => dependency/lib}/Jackson.kt | 34 +- .../lib/JavaDiffUtils.kt} | 27 +- .../kotlin/io/spine/dependency/lib/JavaJwt.kt | 46 ++ .../dependency => dependency/lib}/JavaPoet.kt | 13 +- .../dependency => dependency/lib}/JavaX.kt | 13 +- .../dependency => dependency/lib}/Klaxon.kt | 11 +- .../kotlin/io/spine/dependency/lib/Kotlin.kt | 90 +++ .../lib/KotlinPoet.kt} | 16 +- .../lib}/KotlinSemver.kt | 10 +- .../kotlin/io/spine/dependency/lib/KotlinX.kt | 48 ++ .../kotlin/io/spine/dependency/lib/Log4j2.kt | 42 + .../dependency => dependency/lib}/Netty.kt | 22 +- .../kotlin/io/spine/dependency/lib/Okio.kt | 38 + .../ProtoJar.kt => dependency/lib/Plexus.kt} | 35 +- .../dependency => dependency/lib}/Protobuf.kt | 44 +- .../dependency => dependency/lib}/Roaster.kt | 23 +- .../dependency => dependency/lib}/Slf4J.kt | 24 +- .../spine/dependency/local/ArtifactVersion.kt | 137 ++++ .../kotlin/io/spine/dependency/local/Base.kt | 42 + .../io/spine/dependency/local/BaseTypes.kt | 40 + .../io/spine/dependency/local/Change.kt | 40 + .../io/spine/dependency/local/CoreJava.kt | 48 ++ .../io/spine/dependency/local/Logging.kt | 57 ++ .../io/spine/dependency/local/McJava.kt | 79 ++ .../spine/dependency/local/ModelCompiler.kt | 40 + .../io/spine/dependency/local/ProtoData.kt | 179 +++++ .../io/spine/dependency/local/ProtoTap.kt | 46 ++ .../Plexus.kt => dependency/local/Reflect.kt} | 20 +- .../kotlin/io/spine/dependency/local/Spine.kt | 117 +++ .../io/spine/dependency/local/TestLib.kt | 40 + .../kotlin/io/spine/dependency/local/Text.kt | 40 + .../kotlin/io/spine/dependency/local/Time.kt | 42 + .../io/spine/dependency/local/ToolBase.kt | 46 ++ .../local/Validation.kt} | 45 +- .../dependency => dependency/test}/AssertK.kt | 13 +- .../io/spine/dependency/test/Hamcrest.kt | 40 + .../dependency => dependency/test}/JUnit.kt | 47 +- .../test/Jacoco.kt} | 18 +- .../kotlin/io/spine/dependency/test/Kotest.kt | 60 ++ .../dependency/test/KotlinCompileTesting.kt | 40 + .../kotlin/io/spine/dependency/test/Kover.kt | 35 + .../Okio.kt => dependency/test/OpenTest4J.kt} | 19 +- .../test/SystemLambda.kt} | 15 +- .../test}/TestKitTruth.kt | 19 +- .../dependency => dependency/test}/Truth.kt | 15 +- .../markup => docs}/MarkdownDocument.kt | 6 +- .../io/spine/{internal => }/gradle/Build.kt | 6 +- .../io/spine/{internal => }/gradle/Clean.kt | 6 +- .../{internal => }/gradle/ConfigTester.kt | 6 +- .../gradle/ProjectExtensions.kt | 18 +- .../spine/{internal => }/gradle/RepoSlug.kt | 6 +- .../{internal => }/gradle/Repositories.kt | 104 ++- .../spine/{internal => }/gradle/RunBuild.kt | 8 +- .../spine/{internal => }/gradle/RunGradle.kt | 9 +- .../io/spine/{internal => }/gradle/Runtime.kt | 45 +- .../{internal => }/gradle/StringExtensions.kt | 6 +- .../spine/{internal => }/gradle/TaskName.kt | 6 +- .../{internal => }/gradle/VersionWriter.kt | 6 +- .../spine/{internal => }/gradle/base/Tasks.kt | 10 +- .../gradle/checkstyle/CheckStyleConfig.kt | 19 +- .../{internal => }/gradle/dart/DartContext.kt | 6 +- .../gradle/dart/DartEnvironment.kt | 6 +- .../gradle/dart/DartExtension.kt | 10 +- .../gradle/dart/plugin/DartPlugins.kt | 14 +- .../gradle/dart/plugin/Protobuf.kt | 19 +- .../{internal => }/gradle/dart/task/Build.kt | 22 +- .../gradle/dart/task/DartTasks.kt | 22 +- .../gradle/dart/task/IntegrationTest.kt | 19 +- .../gradle/dart/task/Publish.kt | 26 +- .../gradle/dokka/DokkaExtensions.kt | 7 +- .../gradle/dokka/TaskContainerExtensions.kt | 7 +- .../{internal => }/gradle/fs/LazyTempPath.kt | 6 +- .../spine/{internal => }/gradle/git/Branch.kt | 6 +- .../{internal => }/gradle/git/Repository.kt | 48 +- .../{internal => }/gradle/git/UserInfo.kt | 6 +- .../gradle/github/pages/AuthorEmail.kt | 6 +- .../github/pages/RepositoryExtensions.kt | 14 +- .../gradle/github/pages/SshKey.kt | 8 +- .../gradle/github/pages/TaskName.kt | 6 +- .../gradle/github/pages/Update.kt | 30 +- .../gradle/github/pages/UpdateGitHubPages.kt | 26 +- .../pages/UpdateGitHubPagesExtension.kt | 8 +- .../spine/{internal => }/gradle/java/Tasks.kt | 6 +- .../{internal => }/gradle/javac/ErrorProne.kt | 7 +- .../{internal => }/gradle/javac/Javac.kt | 6 +- .../{internal => }/gradle/javadoc/Encoding.kt | 6 +- .../gradle/javadoc/ExcludeInternalDoclet.kt | 20 +- .../gradle/javadoc/JavadocConfig.kt | 10 +- .../gradle/javadoc/JavadocTag.kt | 6 +- .../gradle/javadoc/TaskContainerExtensions.kt | 6 +- .../gradle/javascript/JsContext.kt | 11 +- .../gradle/javascript/JsEnvironment.kt | 6 +- .../gradle/javascript/JsExtension.kt | 10 +- .../gradle/javascript/plugin/Idea.kt | 6 +- .../gradle/javascript/plugin/JsPlugins.kt | 14 +- .../gradle/javascript/plugin/McJs.kt | 6 +- .../gradle/javascript/plugin/Protobuf.kt | 18 +- .../gradle/javascript/task/Assemble.kt | 26 +- .../gradle/javascript/task/Check.kt | 24 +- .../gradle/javascript/task/Clean.kt | 20 +- .../gradle/javascript/task/IntegrationTest.kt | 19 +- .../gradle/javascript/task/JsTasks.kt | 22 +- .../gradle/javascript/task/LicenseReport.kt | 19 +- .../gradle/javascript/task/Publish.kt | 26 +- .../gradle/javascript/task/Webpack.kt | 22 +- .../gradle/kotlin/KotlinConfig.kt | 18 +- .../gradle/protobuf/ProtoTaskExtensions.kt | 418 ++++++++++ .../gradle/publish/CheckVersionIncrement.kt | 30 +- .../gradle/publish/CloudArtifactRegistry.kt | 10 +- .../gradle/publish/CloudRepo.kt | 10 +- .../gradle/publish/GitHubPackages.kt | 13 +- .../gradle/publish/IncrementGuard.kt | 23 +- .../kotlin/io/spine/gradle/publish/JarDsl.kt | 167 ++++ .../publish/ProtoExts.kt} | 58 +- .../io/spine/gradle/publish/Publications.kt | 234 ++++++ .../io/spine/gradle/publish/PublishingExts.kt | 278 +++++++ .../spine/gradle/publish/PublishingRepos.kt | 42 + .../gradle/publish/SpinePublishing.kt | 180 +++-- .../gradle/report/coverage/CodebaseFilter.kt | 8 +- .../gradle/report/coverage/FileExtension.kt | 6 +- .../gradle/report/coverage/FileExtensions.kt | 22 +- .../gradle/report/coverage/FileFilter.kt | 6 +- .../gradle/report/coverage/JacocoConfig.kt | 65 +- .../gradle/report/coverage/PathMarker.kt | 6 +- .../gradle/report/coverage/TaskName.kt | 8 +- .../gradle/report/license/Configuration.kt | 6 +- .../gradle/report/license/LicenseReporter.kt | 23 +- .../report/license/MarkdownReportRenderer.kt | 13 +- .../report/license/ModuleDataExtensions.kt | 12 +- .../gradle/report/license/Paths.kt | 8 +- .../report/license/ProjectDependencies.kt | 8 +- .../gradle/report/license/Tasks.kt | 6 +- .../gradle/report/license/Template.kt | 10 +- .../gradle/report/pom/DependencyScope.kt | 6 +- .../gradle/report/pom/DependencyWriter.kt | 36 +- .../gradle/report/pom/InceptionYear.kt | 6 +- .../gradle/report/pom/MarkupExtensions.kt | 6 +- .../gradle/report/pom/ModuleDependency.kt | 29 +- .../gradle/report/pom/PomFormatting.kt | 6 +- .../gradle/report/pom/PomGenerator.kt | 28 +- .../gradle/report/pom/PomXmlWriter.kt | 10 +- .../gradle/report/pom/ProjectMetadata.kt | 6 +- .../gradle/report/pom/ScopedDependency.kt | 16 +- .../gradle/report/pom/SpineLicense.kt | 6 +- .../{internal => }/gradle/testing/Logging.kt | 6 +- .../gradle/testing/Multiproject.kt | 10 +- .../{internal => }/gradle/testing/Tasks.kt | 16 +- .../io/spine/internal/dependency/Kotlin.kt | 41 - .../io/spine/internal/dependency/Spine.kt | 284 ------- .../gradle/protobuf/ProtoTaskExtensions.kt | 194 ----- .../internal/gradle/publish/Artifacts.kt | 135 ---- .../internal/gradle/publish/Publications.kt | 201 ----- .../gradle/publish/PublishingConfig.kt | 171 ---- .../io/spine/internal/gradle/publish/Tasks.kt | 110 --- .../main/kotlin/jacoco-kotlin-jvm.gradle.kts | 67 ++ .../src/main/kotlin/jvm-module.gradle.kts | 204 +++++ .../src/main/kotlin/pmd-settings.gradle.kts | 6 +- .../src/main/kotlin/write-manifest.gradle.kts | 13 +- .../resources/dokka/styles/custom-styles.css | 4 +- change/build.gradle.kts | 67 +- config | 2 +- license-report.md | 736 ------------------ version.gradle.kts | 6 +- 220 files changed, 5868 insertions(+), 3563 deletions(-) create mode 100644 .github/workflows/ensure-reports-updated.yml create mode 100644 .github/workflows/remove-obsolete-artifacts-from-packages.yaml delete mode 100644 .lift.toml create mode 100644 buildSrc/src/main/kotlin/BuildExtensions.kt create mode 100644 buildSrc/src/main/kotlin/BuildSettings.kt delete mode 100644 buildSrc/src/main/kotlin/Dependencies.kt rename buildSrc/src/main/kotlin/{io/spine/internal/gradle => }/DependencyResolution.kt (54%) create mode 100644 buildSrc/src/main/kotlin/DokkaExts.kt delete mode 100644 buildSrc/src/main/kotlin/PluginsAccessors.kt create mode 100644 buildSrc/src/main/kotlin/Strings.kt delete mode 100644 buildSrc/src/main/kotlin/TaskDependencies.kt create mode 100644 buildSrc/src/main/kotlin/compile-protobuf.gradle.kts rename buildSrc/src/main/kotlin/{io/spine/internal/dependency/AutoService.kt => dokka-for-kotlin.gradle.kts} (71%) rename buildSrc/src/main/kotlin/io/spine/{internal/dependency => dependency/build}/AnimalSniffer.kt (88%) rename buildSrc/src/main/kotlin/io/spine/{internal/gradle/publish/TestJar.kt => dependency/build/CheckStyle.kt} (63%) rename buildSrc/src/main/kotlin/io/spine/{internal/dependency => dependency/build}/CheckerFramework.kt (70%) rename buildSrc/src/main/kotlin/io/spine/{internal/dependency => dependency/build}/Dokka.kt (73%) rename buildSrc/src/main/kotlin/io/spine/{internal/dependency => dependency/build}/ErrorProne.kt (66%) rename buildSrc/src/main/kotlin/io/spine/{internal/dependency => dependency/build}/FindBugs.kt (63%) rename buildSrc/src/main/kotlin/io/spine/{internal/dependency => dependency/build}/GradleDoctor.kt (87%) create mode 100644 buildSrc/src/main/kotlin/io/spine/dependency/build/Ksp.kt create mode 100644 buildSrc/src/main/kotlin/io/spine/dependency/build/LicenseReport.kt rename buildSrc/src/main/kotlin/io/spine/{internal/dependency => dependency/build}/OsDetector.kt (86%) create mode 100644 buildSrc/src/main/kotlin/io/spine/dependency/build/Pmd.kt rename buildSrc/src/main/kotlin/io/spine/{internal/dependency/JavaJwt.kt => dependency/lib/Aedile.kt} (76%) rename buildSrc/src/main/kotlin/io/spine/{internal/dependency => dependency/lib}/ApacheHttp.kt (88%) rename buildSrc/src/main/kotlin/io/spine/{internal/dependency => dependency/lib}/AppEngine.kt (84%) create mode 100644 buildSrc/src/main/kotlin/io/spine/dependency/lib/Asm.kt create mode 100644 buildSrc/src/main/kotlin/io/spine/dependency/lib/Auto.kt rename buildSrc/src/main/kotlin/io/spine/{internal/dependency => dependency/lib}/BouncyCastle.kt (88%) create mode 100644 buildSrc/src/main/kotlin/io/spine/dependency/lib/Caffeine.kt rename buildSrc/src/main/kotlin/io/spine/{internal/dependency/CheckStyle.kt => dependency/lib/Clikt.kt} (80%) rename buildSrc/src/main/kotlin/io/spine/{internal/dependency => dependency/lib}/CommonsCli.kt (83%) rename buildSrc/src/main/kotlin/io/spine/{internal/dependency => dependency/lib}/CommonsCodec.kt (86%) rename buildSrc/src/main/kotlin/io/spine/{internal/dependency => dependency/lib}/CommonsLogging.kt (80%) create mode 100644 buildSrc/src/main/kotlin/io/spine/dependency/lib/Coroutines.kt rename buildSrc/src/main/kotlin/io/spine/{internal/dependency => dependency/lib}/Firebase.kt (83%) rename buildSrc/src/main/kotlin/io/spine/{internal/dependency => dependency/lib}/Flogger.kt (70%) rename buildSrc/src/main/kotlin/io/spine/{internal/dependency => dependency/lib}/GoogleApis.kt (91%) rename buildSrc/src/main/kotlin/io/spine/{internal/dependency => dependency/lib}/GoogleCloud.kt (90%) rename buildSrc/src/main/kotlin/io/spine/{internal/dependency => dependency/lib}/Grpc.kt (54%) create mode 100644 buildSrc/src/main/kotlin/io/spine/dependency/lib/GrpcKotlin.kt rename buildSrc/src/main/kotlin/io/spine/{internal/dependency => dependency/lib}/Gson.kt (79%) rename buildSrc/src/main/kotlin/io/spine/{internal/dependency => dependency/lib}/Guava.kt (77%) rename buildSrc/src/main/kotlin/io/spine/{internal/dependency => dependency/lib}/HttpClient.kt (85%) create mode 100644 buildSrc/src/main/kotlin/io/spine/dependency/lib/IntelliJ.kt rename buildSrc/src/main/kotlin/io/spine/{internal/dependency => dependency/lib}/J2ObjC.kt (66%) rename buildSrc/src/main/kotlin/io/spine/{internal/dependency => dependency/lib}/Jackson.kt (69%) rename buildSrc/src/main/kotlin/io/spine/{internal/gradle/publish/DokkaJar.kt => dependency/lib/JavaDiffUtils.kt} (66%) create mode 100644 buildSrc/src/main/kotlin/io/spine/dependency/lib/JavaJwt.kt rename buildSrc/src/main/kotlin/io/spine/{internal/dependency => dependency/lib}/JavaPoet.kt (79%) rename buildSrc/src/main/kotlin/io/spine/{internal/dependency => dependency/lib}/JavaX.kt (77%) rename buildSrc/src/main/kotlin/io/spine/{internal/dependency => dependency/lib}/Klaxon.kt (83%) create mode 100644 buildSrc/src/main/kotlin/io/spine/dependency/lib/Kotlin.kt rename buildSrc/src/main/kotlin/io/spine/{internal/dependency/AutoValue.kt => dependency/lib/KotlinPoet.kt} (75%) rename buildSrc/src/main/kotlin/io/spine/{internal/dependency => dependency/lib}/KotlinSemver.kt (85%) create mode 100644 buildSrc/src/main/kotlin/io/spine/dependency/lib/KotlinX.kt create mode 100644 buildSrc/src/main/kotlin/io/spine/dependency/lib/Log4j2.kt rename buildSrc/src/main/kotlin/io/spine/{internal/dependency => dependency/lib}/Netty.kt (67%) create mode 100644 buildSrc/src/main/kotlin/io/spine/dependency/lib/Okio.kt rename buildSrc/src/main/kotlin/io/spine/{internal/gradle/publish/ProtoJar.kt => dependency/lib/Plexus.kt} (62%) rename buildSrc/src/main/kotlin/io/spine/{internal/dependency => dependency/lib}/Protobuf.kt (61%) rename buildSrc/src/main/kotlin/io/spine/{internal/dependency => dependency/lib}/Roaster.kt (65%) rename buildSrc/src/main/kotlin/io/spine/{internal/dependency => dependency/lib}/Slf4J.kt (66%) create mode 100644 buildSrc/src/main/kotlin/io/spine/dependency/local/ArtifactVersion.kt create mode 100644 buildSrc/src/main/kotlin/io/spine/dependency/local/Base.kt create mode 100644 buildSrc/src/main/kotlin/io/spine/dependency/local/BaseTypes.kt create mode 100644 buildSrc/src/main/kotlin/io/spine/dependency/local/Change.kt create mode 100644 buildSrc/src/main/kotlin/io/spine/dependency/local/CoreJava.kt create mode 100644 buildSrc/src/main/kotlin/io/spine/dependency/local/Logging.kt create mode 100644 buildSrc/src/main/kotlin/io/spine/dependency/local/McJava.kt create mode 100644 buildSrc/src/main/kotlin/io/spine/dependency/local/ModelCompiler.kt create mode 100644 buildSrc/src/main/kotlin/io/spine/dependency/local/ProtoData.kt create mode 100644 buildSrc/src/main/kotlin/io/spine/dependency/local/ProtoTap.kt rename buildSrc/src/main/kotlin/io/spine/{internal/dependency/Plexus.kt => dependency/local/Reflect.kt} (71%) create mode 100644 buildSrc/src/main/kotlin/io/spine/dependency/local/Spine.kt create mode 100644 buildSrc/src/main/kotlin/io/spine/dependency/local/TestLib.kt create mode 100644 buildSrc/src/main/kotlin/io/spine/dependency/local/Text.kt create mode 100644 buildSrc/src/main/kotlin/io/spine/dependency/local/Time.kt create mode 100644 buildSrc/src/main/kotlin/io/spine/dependency/local/ToolBase.kt rename buildSrc/src/main/kotlin/io/spine/{internal/gradle/publish/PublishingRepos.kt => dependency/local/Validation.kt} (52%) rename buildSrc/src/main/kotlin/io/spine/{internal/dependency => dependency/test}/AssertK.kt (83%) create mode 100644 buildSrc/src/main/kotlin/io/spine/dependency/test/Hamcrest.kt rename buildSrc/src/main/kotlin/io/spine/{internal/dependency => dependency/test}/JUnit.kt (55%) rename buildSrc/src/main/kotlin/io/spine/{internal/dependency/AutoCommon.kt => dependency/test/Jacoco.kt} (78%) create mode 100644 buildSrc/src/main/kotlin/io/spine/dependency/test/Kotest.kt create mode 100644 buildSrc/src/main/kotlin/io/spine/dependency/test/KotlinCompileTesting.kt create mode 100644 buildSrc/src/main/kotlin/io/spine/dependency/test/Kover.kt rename buildSrc/src/main/kotlin/io/spine/{internal/dependency/Okio.kt => dependency/test/OpenTest4J.kt} (73%) rename buildSrc/src/main/kotlin/io/spine/{internal/dependency/Pmd.kt => dependency/test/SystemLambda.kt} (75%) rename buildSrc/src/main/kotlin/io/spine/{internal/dependency => dependency/test}/TestKitTruth.kt (70%) rename buildSrc/src/main/kotlin/io/spine/{internal/dependency => dependency/test}/Truth.kt (75%) rename buildSrc/src/main/kotlin/io/spine/{internal/markup => docs}/MarkdownDocument.kt (96%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/Build.kt (90%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/Clean.kt (92%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/ConfigTester.kt (98%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/ProjectExtensions.kt (87%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/RepoSlug.kt (94%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/Repositories.kt (74%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/RunBuild.kt (89%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/RunGradle.kt (97%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/Runtime.kt (73%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/StringExtensions.kt (91%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/TaskName.kt (93%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/VersionWriter.kt (97%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/base/Tasks.kt (91%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/checkstyle/CheckStyleConfig.kt (82%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/dart/DartContext.kt (92%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/dart/DartEnvironment.kt (97%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/dart/DartExtension.kt (96%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/dart/plugin/DartPlugins.kt (89%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/dart/plugin/Protobuf.kt (78%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/dart/task/Build.kt (89%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/dart/task/DartTasks.kt (85%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/dart/task/IntegrationTest.kt (86%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/dart/task/Publish.kt (89%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/dokka/DokkaExtensions.kt (92%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/dokka/TaskContainerExtensions.kt (90%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/fs/LazyTempPath.kt (96%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/git/Branch.kt (91%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/git/Repository.kt (85%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/git/UserInfo.kt (92%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/github/pages/AuthorEmail.kt (93%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/github/pages/RepositoryExtensions.kt (87%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/github/pages/SshKey.kt (95%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/github/pages/TaskName.kt (92%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/github/pages/Update.kt (83%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/github/pages/UpdateGitHubPages.kt (92%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/github/pages/UpdateGitHubPagesExtension.kt (94%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/java/Tasks.kt (92%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/javac/ErrorProne.kt (94%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/javac/Javac.kt (94%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/javadoc/Encoding.kt (90%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/javadoc/ExcludeInternalDoclet.kt (86%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/javadoc/JavadocConfig.kt (94%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/javadoc/JavadocTag.kt (90%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/javadoc/TaskContainerExtensions.kt (91%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/javascript/JsContext.kt (86%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/javascript/JsEnvironment.kt (98%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/javascript/JsExtension.kt (95%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/javascript/plugin/Idea.kt (93%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/javascript/plugin/JsPlugins.kt (88%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/javascript/plugin/McJs.kt (93%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/javascript/plugin/Protobuf.kt (85%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/javascript/task/Assemble.kt (88%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/javascript/task/Check.kt (89%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/javascript/task/Clean.kt (86%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/javascript/task/IntegrationTest.kt (89%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/javascript/task/JsTasks.kt (85%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/javascript/task/LicenseReport.kt (84%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/javascript/task/Publish.kt (87%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/javascript/task/Webpack.kt (85%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/kotlin/KotlinConfig.kt (87%) create mode 100644 buildSrc/src/main/kotlin/io/spine/gradle/protobuf/ProtoTaskExtensions.kt rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/publish/CheckVersionIncrement.kt (80%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/publish/CloudArtifactRegistry.kt (93%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/publish/CloudRepo.kt (89%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/publish/GitHubPackages.kt (92%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/publish/IncrementGuard.kt (84%) create mode 100644 buildSrc/src/main/kotlin/io/spine/gradle/publish/JarDsl.kt rename buildSrc/src/main/kotlin/io/spine/{internal/gradle/publish/ProtoLocators.kt => gradle/publish/ProtoExts.kt} (50%) create mode 100644 buildSrc/src/main/kotlin/io/spine/gradle/publish/Publications.kt create mode 100644 buildSrc/src/main/kotlin/io/spine/gradle/publish/PublishingExts.kt create mode 100644 buildSrc/src/main/kotlin/io/spine/gradle/publish/PublishingRepos.kt rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/publish/SpinePublishing.kt (72%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/report/coverage/CodebaseFilter.kt (94%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/report/coverage/FileExtension.kt (91%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/report/coverage/FileExtensions.kt (85%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/report/coverage/FileFilter.kt (92%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/report/coverage/JacocoConfig.kt (82%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/report/coverage/PathMarker.kt (93%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/report/coverage/TaskName.kt (86%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/report/license/Configuration.kt (92%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/report/license/LicenseReporter.kt (88%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/report/license/MarkdownReportRenderer.kt (84%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/report/license/ModuleDataExtensions.kt (93%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/report/license/Paths.kt (89%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/report/license/ProjectDependencies.kt (93%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/report/license/Tasks.kt (91%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/report/license/Template.kt (91%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/report/pom/DependencyScope.kt (91%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/report/pom/DependencyWriter.kt (84%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/report/pom/InceptionYear.kt (92%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/report/pom/MarkupExtensions.kt (91%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/report/pom/ModuleDependency.kt (79%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/report/pom/PomFormatting.kt (96%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/report/pom/PomGenerator.kt (82%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/report/pom/PomXmlWriter.kt (91%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/report/pom/ProjectMetadata.kt (96%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/report/pom/ScopedDependency.kt (93%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/report/pom/SpineLicense.kt (93%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/testing/Logging.kt (95%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/testing/Multiproject.kt (90%) rename buildSrc/src/main/kotlin/io/spine/{internal => }/gradle/testing/Tasks.kt (84%) delete mode 100644 buildSrc/src/main/kotlin/io/spine/internal/dependency/Kotlin.kt delete mode 100644 buildSrc/src/main/kotlin/io/spine/internal/dependency/Spine.kt delete mode 100644 buildSrc/src/main/kotlin/io/spine/internal/gradle/protobuf/ProtoTaskExtensions.kt delete mode 100644 buildSrc/src/main/kotlin/io/spine/internal/gradle/publish/Artifacts.kt delete mode 100644 buildSrc/src/main/kotlin/io/spine/internal/gradle/publish/Publications.kt delete mode 100644 buildSrc/src/main/kotlin/io/spine/internal/gradle/publish/PublishingConfig.kt delete mode 100644 buildSrc/src/main/kotlin/io/spine/internal/gradle/publish/Tasks.kt create mode 100644 buildSrc/src/main/kotlin/jacoco-kotlin-jvm.gradle.kts create mode 100644 buildSrc/src/main/kotlin/jvm-module.gradle.kts delete mode 100644 license-report.md diff --git a/.github/workflows/build-on-ubuntu.yml b/.github/workflows/build-on-ubuntu.yml index 4029252..f8c2493 100644 --- a/.github/workflows/build-on-ubuntu.yml +++ b/.github/workflows/build-on-ubuntu.yml @@ -4,16 +4,17 @@ on: push jobs: build: + name: Build under Ubuntu runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: submodules: 'true' - - uses: actions/setup-java@v3 + - uses: actions/setup-java@v4 with: - java-version: 11 + java-version: 17 distribution: zulu cache: gradle @@ -23,14 +24,15 @@ jobs: # See: https://github.com/marketplace/actions/junit-report-action - name: Publish Test Report - uses: mikepenz/action-junit-report@v3.5.2 + uses: mikepenz/action-junit-report@v4.0.3 if: always() # always run even if the previous step fails with: - report_paths: '**/build/test-results/test/TEST-*.xml' + report_paths: '**/build/test-results/**/TEST-*.xml' require_tests: true # will fail workflow if test reports not found - name: Upload code coverage report - uses: codecov/codecov-action@v3 + uses: codecov/codecov-action@v4 with: + token: ${{ secrets.CODECOV_TOKEN }} fail_ci_if_error: false verbose: true diff --git a/.github/workflows/build-on-windows.yml b/.github/workflows/build-on-windows.yml index 01b0f35..4e6b57f 100644 --- a/.github/workflows/build-on-windows.yml +++ b/.github/workflows/build-on-windows.yml @@ -4,19 +4,24 @@ on: pull_request jobs: build: + name: Build under Windows runs-on: windows-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: submodules: 'true' - - uses: actions/setup-java@v3 + - uses: actions/setup-java@v4 with: - java-version: 11 + java-version: 17 distribution: zulu cache: gradle + # See: https://github.com/al-cheb/configure-pagefile-action + - name: Configure Pagefile + uses: al-cheb/configure-pagefile-action@v1.3 + - name: Build project and run tests shell: cmd # For the reason on `--no-daemon` see https://github.com/actions/cache/issues/454 @@ -24,8 +29,8 @@ jobs: # See: https://github.com/marketplace/actions/junit-report-action - name: Publish Test Report - uses: mikepenz/action-junit-report@v3.5.2 + uses: mikepenz/action-junit-report@v4.0.3 if: always() # always run even if the previous step fails with: - report_paths: '**/build/test-results/test/TEST-*.xml' + report_paths: '**/build/test-results/**/TEST-*.xml' require_tests: true # will fail workflow if test reports not found diff --git a/.github/workflows/ensure-reports-updated.yml b/.github/workflows/ensure-reports-updated.yml new file mode 100644 index 0000000..fdd8b8e --- /dev/null +++ b/.github/workflows/ensure-reports-updated.yml @@ -0,0 +1,25 @@ +# Ensures that the license report files were modified in this PR. + +name: Ensure license reports updated + +on: + pull_request: + branches: + - '**' + +jobs: + build: + name: Ensure license reports updated + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + with: + # Configure the checkout of all branches, so that it is possible to run the comparison. + fetch-depth: 0 + # Check out the `config` submodule to fetch the required script file. + submodules: true + + - name: Check that both `pom.xml` and license report files are modified + shell: bash + run: chmod +x ./config/scripts/ensure-reports-updated.sh && ./config/scripts/ensure-reports-updated.sh diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index cadc62c..8b5b4d5 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -8,13 +8,13 @@ jobs: publish: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: submodules: 'true' - - uses: actions/setup-java@v3 + - uses: actions/setup-java@v4 with: - java-version: 11 + java-version: 17 distribution: zulu cache: gradle diff --git a/.github/workflows/remove-obsolete-artifacts-from-packages.yaml b/.github/workflows/remove-obsolete-artifacts-from-packages.yaml new file mode 100644 index 0000000..fe8ad84 --- /dev/null +++ b/.github/workflows/remove-obsolete-artifacts-from-packages.yaml @@ -0,0 +1,73 @@ +# +# Periodically removes obsolete artifacts from GitHub Packages. +# +# Only non-release artifacts—those containing "SNAPSHOT" in their version name—are eligible +# for removal. The latest non-release artifacts will be retained, with the exact number determined +# by the `VERSION_COUNT_TO_KEEP` environment variable. +# +# Please note the following details: +# +# 1. An artifact cannot be deleted if it is public and has been downloaded more than 5,000 times. +# In this scenario, contact GitHub support for further assistance. +# +# 2. This workflow only applies to artifacts published from this repository. +# +# 3. A maximum of 100 artifacts can be removed per run from each package; +# if there are more than 100 obsolete artifacts, either manually restart the workflow +# or wait for the next scheduled removal. +# +# 4. When artifacts with version `x.x.x-SNAPSHOT` are published, GitHub automatically appends +# the current timestamp, resulting in versions like `x.x.x-SNAPSHOT.20241024.173759`. +# All such artifacts are grouped into one package and treated as a single package +# in GitHub Packages with the version `x.x.x-SNAPSHOT`. Consequently, it is not possible +# to remove obsolete versions within a package; only the entire package can be deleted. +# + +name: Remove obsolete Maven artifacts from GitHub Packages + +on: + schedule: + - cron: '0 0 * * *' # Run every day at midnight. + +env: + VERSION_COUNT_TO_KEEP: 5 # Number of most recent SNAPSHOT versions to retain. + +jobs: + retrieve-package-names: + name: Retrieve the package names published from this repository + runs-on: ubuntu-latest + outputs: + package-names: ${{ steps.request-package-names.outputs.package-names }} + steps: + - uses: actions/checkout@v4 + with: + submodules: 'true' + + - name: Retrieve the names of packages + id: request-package-names + shell: bash + run: | + repoName=$(echo ${{ github.repository }} | cut -d '/' -f2) + chmod +x ./config/scripts/request-package-names.sh + ./config/scripts/request-package-names.sh ${{ github.token }} \ + $repoName ${{ github.repository_owner }} ./package-names.json + echo "package-names=$(<./package-names.json)" >> $GITHUB_OUTPUT + + delete-obsolete-artifacts: + name: Remove obsolete artifacts published from this repository to GitHub Packages + needs: retrieve-package-names + runs-on: ubuntu-latest + strategy: + matrix: + package-name: ${{ fromJson(needs.retrieve-package-names.outputs.package-names) }} + steps: + - name: Remove obsolete artifacts from '${{ matrix.package-name }}' package + uses: actions/delete-package-versions@v5 + with: + owner: ${{ github.repository_owner }} + package-name: ${{ matrix.package-name }} + package-type: 'maven' + token: ${{ github.token }} + min-versions-to-keep: ${{ env.VERSION_COUNT_TO_KEEP }} + # Ignores artifacts that do not contain the word "SNAPSHOT". + ignore-versions: '^(?!.+SNAPSHOT).*$' diff --git a/.gitignore b/.gitignore index 29f034a..419020f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,12 +1,6 @@ # # Copyright 2022, TeamDev. All rights reserved. # -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# # Redistribution and use in source and/or binary forms, with or without # modification, must retain the above copyright notice and the following # disclaimer. @@ -31,6 +25,15 @@ # # Therefore, instructions below are superset of instructions required for all the projects. +# `jenv` local configuration. +.java-version + +# Internal tool directories. +.fleet/ + +# Kotlin temp directories. +**/.kotlin/** + # IntelliJ IDEA modules and interim config files. *.iml .idea/*.xml @@ -42,7 +45,6 @@ # Do not ignore the following IDEA settings !.idea/misc.xml -!.idea/kotlinc.xml !.idea/codeStyleSettings.xml !.idea/codeStyles/ !.idea/copyright/ @@ -55,6 +57,7 @@ # Gradle build files **/build/** +!**/src/**/build/** # Build files produced by the IDE **/out/** @@ -101,5 +104,17 @@ hs_err_pid* .packages pubspec.lock -# Ignore the `tmp` directory used for building dependant repositories. -/tmp + +# +# The gradle.properties file should contain settings specific to a developer's workstation. +# +# See sample file for a Mac OS X workstation below. +# ------- +# # Set Java home to point to JDK8. This is need to generate classes working with Java8 API. +# # Otherwise the following warning appears during the build: +# # warning: [options] bootstrap class path not set in conjunction with -source 1.8 +# # +# # suppress inspection "UnusedProperty" +# org.gradle.java.home=/Library/Java/JavaVirtualMachines/jdk1.8.0_51.jdk/Contents/Home/ +# ------- +gradle.properties diff --git a/.idea/copyright/TeamDev_Open_Source.xml b/.idea/copyright/TeamDev_Open_Source.xml index 14d7385..cea7fed 100644 --- a/.idea/copyright/TeamDev_Open_Source.xml +++ b/.idea/copyright/TeamDev_Open_Source.xml @@ -1,6 +1,6 @@ - diff --git a/.lift.toml b/.lift.toml deleted file mode 100644 index 178be58..0000000 --- a/.lift.toml +++ /dev/null @@ -1 +0,0 @@ -ignoreRules=["SpreadOperator"] diff --git a/build.gradle.kts b/build.gradle.kts index e2413f1..97c73e2 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -26,53 +26,68 @@ @file:Suppress("RemoveRedundantQualifierName") -import com.google.protobuf.gradle.builtins -import com.google.protobuf.gradle.generateProtoTasks import com.google.protobuf.gradle.id import com.google.protobuf.gradle.protobuf -import com.google.protobuf.gradle.protoc -import io.spine.internal.dependency.Dokka -import io.spine.internal.dependency.ErrorProne -import io.spine.internal.dependency.JUnit -import io.spine.internal.dependency.Jackson -import io.spine.internal.dependency.Spine -import io.spine.internal.gradle.applyGitHubPackages -import io.spine.internal.gradle.applyStandard -import io.spine.internal.gradle.checkstyle.CheckStyleConfig -import io.spine.internal.gradle.forceVersions -import io.spine.internal.gradle.github.pages.updateGitHubPages -import io.spine.internal.gradle.javac.configureErrorProne -import io.spine.internal.gradle.javac.configureJavac -import io.spine.internal.gradle.javadoc.JavadocConfig -import io.spine.internal.gradle.kotlin.setFreeCompilerArgs -import io.spine.internal.gradle.publish.PublishingRepos -import io.spine.internal.gradle.publish.spinePublishing -import io.spine.internal.gradle.report.coverage.JacocoConfig -import io.spine.internal.gradle.report.license.LicenseReporter -import io.spine.internal.gradle.report.pom.PomGenerator -import io.spine.internal.gradle.testing.configureLogging -import io.spine.internal.gradle.testing.registerTestTasks +import io.spine.dependency.build.Dokka +import io.spine.dependency.build.ErrorProne +import io.spine.dependency.test.JUnit +import io.spine.dependency.lib.KotlinPoet +import io.spine.dependency.lib.Jackson +import io.spine.dependency.lib.Coroutines +import io.spine.dependency.local.ArtifactVersion +import io.spine.dependency.local.Base +import io.spine.dependency.local.Spine +import io.spine.dependency.local.Logging +import io.spine.dependency.local.TestLib +import io.spine.dependency.local.ToolBase +import io.spine.dependency.local.ProtoData +import io.spine.dependency.local.Validation +import io.spine.gradle.applyGitHubPackages +import io.spine.gradle.applyStandard +import io.spine.gradle.standardToSpineSdk +import io.spine.gradle.checkstyle.CheckStyleConfig +import io.spine.gradle.github.pages.updateGitHubPages +import io.spine.gradle.javac.configureErrorProne +import io.spine.gradle.javac.configureJavac +import io.spine.gradle.javadoc.JavadocConfig +import io.spine.gradle.kotlin.setFreeCompilerArgs +import io.spine.gradle.publish.PublishingRepos +import io.spine.gradle.publish.spinePublishing +import io.spine.gradle.report.coverage.JacocoConfig +import io.spine.gradle.report.license.LicenseReporter +import io.spine.gradle.report.pom.PomGenerator +import io.spine.gradle.testing.configureLogging +import io.spine.gradle.testing.registerTestTasks import org.jetbrains.kotlin.gradle.tasks.KotlinCompile buildscript { - io.spine.internal.gradle.doApplyStandard(repositories) - io.spine.internal.gradle.doForceVersions(configurations) + standardSpineSdkRepositories() + doForceVersions(configurations) dependencies { - classpath(io.spine.internal.dependency.Spine.McJava.pluginLib) + classpath(io.spine.dependency.local.McJava.pluginLib) } - val spine = io.spine.internal.dependency.Spine(project) - val jackson = io.spine.internal.dependency.Jackson + val jackson = io.spine.dependency.lib.Jackson + val coroutiners = io.spine.dependency.lib.Coroutines + val validation = io.spine.dependency.local.Validation + val logging = io.spine.dependency.local.Logging + val base = io.spine.dependency.local.Base configurations { all { resolutionStrategy { force( - spine.base, jackson.annotations, jackson.bom, jackson.databind, - jackson.moduleKotlin + jackson.moduleKotlin, + base.lib, + validation.runtime, + logging.lib, + coroutiners.bom, + coroutiners.core, + coroutiners.coreJvm, + coroutiners.jdk8, ) } } @@ -81,7 +96,7 @@ buildscript { repositories { // Required to grab the dependencies for `JacocoConfig`. - applyStandard() + standardToSpineSdk() } plugins { @@ -101,13 +116,13 @@ spinePublishing { destinations = with(PublishingRepos) { setOf( gitHub("change"), - cloudRepo, cloudArtifactRegistry ) } dokkaJar { - enabled = true + kotlin = true + java = true } } @@ -123,15 +138,22 @@ allprojects { group = "io.spine" version = extra["versionToPublish"]!! - val spine = Spine(project) configurations { forceVersions() all { exclude("io.spine:spine-validate") resolutionStrategy { force( - spine.base, - spine.validation.runtime, + KotlinPoet.lib, + ToolBase.lib, + Coroutines.bom, + Coroutines.core, + Coroutines.coreJvm, + Coroutines.jdk8, + Base.lib, + ProtoData.api, + Validation.runtime, + Logging.lib, Dokka.BasePlugin.lib, Jackson.databind, protocArtifact @@ -158,19 +180,17 @@ subprojects { repositories { applyGitHubPackages("base", project) - applyStandard() + standardToSpineSdk() } - val spine = Spine(project) dependencies { errorprone(ErrorProne.core) - api(kotlin("stdlib-jdk8")) - testImplementation(spine.testlib) + testImplementation(TestLib.lib) testImplementation(JUnit.runner) } - val javaVersion = JavaVersion.VERSION_11 + val javaVersion = JavaVersion.VERSION_17 java { sourceCompatibility = javaVersion @@ -189,12 +209,9 @@ subprojects { kotlin { explicitApi() - - tasks { - withType().configureEach { - kotlinOptions.jvmTarget = javaVersion.toString() - setFreeCompilerArgs() - } + compilerOptions { + jvmTarget.set(BuildSettings.jvmTarget) + setFreeCompilerArgs() } } @@ -232,29 +249,11 @@ subprojects { } } - updateGitHubPages(Spine.DefaultVersion.javadocTools) { + updateGitHubPages(ArtifactVersion.javadocTools) { allowInternalJavadoc.set(true) rootFolder.set(rootDir) } - // Apply the same IDEA module configuration for each of subprojects. - idea { - module { - with(generatedSourceDirs) { - add(file("$generatedDir/main/js")) - add(file("$generatedDir/main/java")) - add(file("$generatedDir/main/kotlin")) - add(file("$generatedDir/main/spine")) - } - testSources.from( - file("$generatedDir/test/java"), - file("$generatedDir/test/kotlin") - ) - isDownloadJavadoc = true - isDownloadSources = true - } - } - project.configureTaskDependencies() } diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index fa1c5fc..050edc5 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,6 +24,8 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +import org.jetbrains.kotlin.gradle.dsl.JvmTarget + /** * This script uses two declarations of the constant [licenseReportVersion] because * currently there is no way to define a constant _before_ a build script of `buildSrc`. @@ -34,8 +36,9 @@ plugins { java groovy `kotlin-dsl` - val licenseReportVersion = "2.1" - id("com.github.jk1.dependency-license-report").version(licenseReportVersion) + + // https://github.com/jk1/Gradle-License-Report/releases + id("com.github.jk1.dependency-license-report").version("2.7") } repositories { @@ -47,113 +50,190 @@ repositories { /** * The version of Jackson used by `buildSrc`. * - * Please keep this value in sync. with `io.spine.internal.dependency.Jackson.version`. - * It's not a requirement, but would be good in terms of consistency. + * Please keep this value in sync with [io.spine.dependency.lib.Jackson.version]. + * It is not a requirement but would be good in terms of consistency. + */ +val jacksonVersion = "2.15.3" + +/** + * The version of Google Artifact Registry used by `buildSrc`. + * + * The version `2.1.5` is the latest before `2.2.0`, which introduces breaking changes. + * + * @see + * Google Artifact Registry at Maven */ -val jacksonVersion = "2.13.4" +val googleAuthToolVersion = "2.1.5" + +val licenseReportVersion = "2.7" -val googleAuthToolVersion = "2.1.2" -val licenseReportVersion = "2.1" -val grGitVersion = "3.1.1" +val grGitVersion = "4.1.1" /** - * The version of the Kotlin Gradle plugin. + * The version of the Kotlin Gradle plugin used by the build process. * - * Please check that this value matches one defined in - * [io.spine.internal.dependency.Kotlin.version]. + * This version may change from the [version of Kotlin][io.spine.dependency.lib.Kotlin.version] + * used by the project. */ -val kotlinVersion = "1.7.20" +val kotlinVersion = "2.1.20" /** * The version of Guava used in `buildSrc`. * - * Always use the same version as the one specified in [io.spine.internal.dependency.Guava]. + * Always use the same version as the one specified in [io.spine.dependency.lib.Guava]. * Otherwise, when testing Gradle plugins, clashes may occur. */ -val guavaVersion = "31.1-jre" +val guavaVersion = "32.1.3-jre" /** * The version of ErrorProne Gradle plugin. * - * Please keep in sync. with [io.spine.internal.dependency.ErrorProne.GradlePlugin.version]. + * Please keep in sync. with [io.spine.dependency.build.ErrorProne.GradlePlugin.version]. * * @see * Error Prone Gradle Plugin Releases */ -val errorProneVersion = "3.0.1" +val errorPronePluginVersion = "4.1.0" /** * The version of Protobuf Gradle Plugin. * - * Please keep in sync. with [io.spine.internal.dependency.Protobuf.GradlePlugin.version]. + * Please keep in sync. with [io.spine.dependency.lib.Protobuf.GradlePlugin.version]. * * @see * Protobuf Gradle Plugins Releases */ -val protobufPluginVersion = "0.8.19" +val protobufPluginVersion = "0.9.4" /** * The version of Dokka Gradle Plugins. * - * Please keep in sync with [io.spine.internal.dependency.Dokka.version]. + * Please keep in sync with [io.spine.dependency.build.Dokka.version]. * * @see * Dokka Releases */ -val dokkaVersion = "1.7.20" +val dokkaVersion = "1.9.20" /** * The version of Detekt Gradle Plugin. * * @see Detekt Releases */ -val detektVersion = "1.21.0" +val detektVersion = "1.23.8" + +/** + * @see [io.spine.dependency.test.Kotest] + */ +val kotestJvmPluginVersion = "0.4.10" + +/** + * @see [io.spine.dependency.test.Kover] + */ +val koverVersion = "0.7.2" + +/** + * The version of the Shadow Plugin. + * + * `7.1.2` is the last version compatible with Gradle 7.x. Newer versions require Gradle v8.x. + * + * @see Shadow Plugin releases + */ +val shadowVersion = "7.1.2" configurations.all { resolutionStrategy { force( + "com.google.guava:guava:${guavaVersion}", + "com.google.protobuf:protobuf-gradle-plugin:$protobufPluginVersion", + // Force Kotlin lib versions avoiding using those bundled with Gradle. "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion", "org.jetbrains.kotlin:kotlin-stdlib-common:$kotlinVersion", - "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlinVersion", - "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlinVersion", "org.jetbrains.kotlin:kotlin-reflect:$kotlinVersion" ) } } -val jvmVersion = JavaLanguageVersion.of(11) - java { - toolchain.languageVersion.set(jvmVersion) + toolchain.languageVersion.set(JavaLanguageVersion.of(17)) } -tasks.withType { - kotlinOptions { - jvmTarget = jvmVersion.toString() +kotlin { + compilerOptions { + jvmTarget.set(JvmTarget.JVM_17) } } dependencies { - implementation("com.fasterxml.jackson.core:jackson-databind:$jacksonVersion") - implementation("com.fasterxml.jackson.dataformat:jackson-dataformat-xml:$jacksonVersion") - implementation("com.google.cloud.artifactregistry:artifactregistry-auth-common:$googleAuthToolVersion") { - exclude(group = "com.google.guava") - } - implementation("com.google.guava:guava:$guavaVersion") api("com.github.jk1:gradle-license-report:$licenseReportVersion") - implementation("org.ajoberstar.grgit:grgit-core:${grGitVersion}") - implementation("net.ltgt.gradle:gradle-errorprone-plugin:${errorProneVersion}") + dependOnAuthCommon() + + listOf( + "com.fasterxml.jackson.core:jackson-databind:$jacksonVersion", + "com.fasterxml.jackson.dataformat:jackson-dataformat-xml:$jacksonVersion", + "com.github.jk1:gradle-license-report:$licenseReportVersion", + "com.google.guava:guava:$guavaVersion", + "com.google.protobuf:protobuf-gradle-plugin:$protobufPluginVersion", + "gradle.plugin.com.github.johnrengelman:shadow:${shadowVersion}", + "io.gitlab.arturbosch.detekt:detekt-gradle-plugin:$detektVersion", + "io.kotest:kotest-gradle-plugin:$kotestJvmPluginVersion", + // https://github.com/srikanth-lingala/zip4j + "net.lingala.zip4j:zip4j:2.10.0", + "net.ltgt.gradle:gradle-errorprone-plugin:${errorPronePluginVersion}", + "org.ajoberstar.grgit:grgit-core:${grGitVersion}", + "org.jetbrains.dokka:dokka-base:${dokkaVersion}", + "org.jetbrains.dokka:dokka-gradle-plugin:${dokkaVersion}", + "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion", + "org.jetbrains.kotlin:kotlin-reflect:$kotlinVersion", + "org.jetbrains.kotlinx:kover-gradle-plugin:$koverVersion" + ).forEach { + implementation(it) + } +} - // Add explicit dependency to avoid warning on different Kotlin runtime versions. - implementation("org.jetbrains.kotlin:kotlin-reflect:$kotlinVersion") - implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion") +dependOnBuildSrcJar() - implementation("io.gitlab.arturbosch.detekt:detekt-gradle-plugin:$detektVersion") - implementation("com.google.protobuf:protobuf-gradle-plugin:$protobufPluginVersion") - implementation("org.jetbrains.dokka:dokka-gradle-plugin:${dokkaVersion}") - implementation("org.jetbrains.dokka:dokka-base:${dokkaVersion}") +/** + * Adds a dependency on a `buildSrc.jar`, iff: + * 1) the `src` folder is missing, and + * 2) `buildSrc.jar` is present in `buildSrc/` folder instead. + * + * This approach is used in the scope of integration testing. + */ +fun Project.dependOnBuildSrcJar() { + val srcFolder = this.rootDir.resolve("src") + val buildSrcJar = rootDir.resolve("buildSrc.jar") + if (!srcFolder.exists() && buildSrcJar.exists()) { + logger.info("Adding the pre-compiled 'buildSrc.jar' to 'implementation' dependencies.") + dependencies { + implementation(files("buildSrc.jar")) + } + } +} - // https://github.com/srikanth-lingala/zip4j - implementation("net.lingala.zip4j:zip4j:2.10.0") +/** + * Includes the `implementation` dependency on `artifactregistry-auth-common`, + * with the version defined in [googleAuthToolVersion]. + * + * `artifactregistry-auth-common` has transitive dependency on Gson and Apache `commons-codec`. + * Gson from version `2.8.6` until `2.8.9` is vulnerable to Deserialization of Untrusted Data + * (https://devhub.checkmarx.com/cve-details/CVE-2022-25647/). + * + * Apache `commons-codec` before 1.13 is vulnerable to information exposure + * (https://devhub.checkmarx.com/cve-details/Cxeb68d52e-5509/). + * + * We use Gson `2.10.1` and we force it in `forceProductionDependencies()`. + * We use `commons-code` with version `1.16.0`, forcing it in `forceProductionDependencies()`. + * + * So, we should be safe with the current version `artifactregistry-auth-common` until + * we migrate to a later version. + */ +fun DependencyHandlerScope.dependOnAuthCommon() { + @Suppress("VulnerableLibrariesLocal", "RedundantSuppression") + implementation( + "com.google.cloud.artifactregistry:artifactregistry-auth-common:$googleAuthToolVersion" + ) { + exclude(group = "com.google.guava") + } } diff --git a/buildSrc/src/main/kotlin/BuildExtensions.kt b/buildSrc/src/main/kotlin/BuildExtensions.kt new file mode 100644 index 0000000..e5b4650 --- /dev/null +++ b/buildSrc/src/main/kotlin/BuildExtensions.kt @@ -0,0 +1,295 @@ +/* + * Copyright 2025, TeamDev. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +@file:Suppress("UnusedReceiverParameter", "unused", "TopLevelPropertyNaming", "ObjectPropertyName") + +import io.spine.dependency.build.ErrorProne +import io.spine.dependency.build.GradleDoctor +import io.spine.dependency.build.Ksp +import io.spine.dependency.lib.Protobuf +import io.spine.dependency.local.McJava +import io.spine.dependency.local.ProtoData +import io.spine.dependency.local.ProtoTap +import io.spine.dependency.test.Kotest +import io.spine.dependency.test.Kover +import io.spine.gradle.standardToSpineSdk +import org.gradle.api.Project +import org.gradle.api.Task +import org.gradle.api.tasks.JavaExec +import org.gradle.kotlin.dsl.ScriptHandlerScope +import org.gradle.plugin.use.PluginDependenciesSpec +import org.gradle.plugin.use.PluginDependencySpec + +/** + * Provides shortcuts to reference our dependency objects. + * + * Dependency objects cannot be used under `plugins` section because `io` is a value + * declared in auto-generated `org.gradle.kotlin.dsl.PluginAccessors.kt` file. + * It conflicts with our own declarations. + * + * In such cases, a shortcut to apply a plugin can be created: + * + * ``` + * val PluginDependenciesSpec.`gradle-doctor`: PluginDependencySpec + * get() = id(GradleDoctor.pluginId).version(GradleDoctor.version) + * ``` + * + * But for some plugins, it is impossible to apply them directly to a project. + * For example, when a plugin is not published to Gradle Portal, it can only be + * applied with the buildscript's classpath. Thus, it is necessary to leave some freedom + * upon how to apply them. In such cases, just a shortcut to a dependency object + * can be declared without applying the plugin in-place. + */ +private const val ABOUT_DEPENDENCY_EXTENSIONS = "" + +/** + * Applies [standard][standardToSpineSdk] repositories to this `buildscript`. + */ +fun ScriptHandlerScope.standardSpineSdkRepositories() { + repositories.standardToSpineSdk() +} + +/** + * Shortcut to [McJava] dependency object for using under `buildScript`. + */ +val ScriptHandlerScope.mcJava: McJava + get() = McJava + +/** + * Shortcut to [McJava] dependency object. + * + * This plugin is not published to Gradle Portal and cannot be applied directly to a project. + * Firstly, it should be put to buildscript's classpath and then applied by ID only. + */ +val PluginDependenciesSpec.mcJava: McJava + get() = McJava + +/** + * Shortcut to [ProtoData] dependency object for using under `buildscript`. + */ +val ScriptHandlerScope.protoData: ProtoData + get() = ProtoData + +/** + * Shortcut to [ProtoData] dependency object. + * + * This plugin is published at Gradle Plugin Portal. + * But when used in a pair with [mcJava], it cannot be applied directly to a project. + * It is so, because [mcJava] uses [protoData] as its dependency. + * And the buildscript's classpath ends up with both of them. + */ +val PluginDependenciesSpec.protoData: ProtoData + get() = ProtoData + +/** + * Provides shortcuts for applying plugins from our dependency objects. + * + * Dependency objects cannot be used under `plugins` section because `io` is a value + * declared in auto-generated `org.gradle.kotlin.dsl.PluginAccessors.kt` file. + * It conflicts with our own declarations. + * + * Declaring of top-level shortcuts eliminates the need to apply plugins + * using a fully qualified name of dependency objects. + * + * It is still possible to apply a plugin with a custom version, if needed. + * Just declare a version again on the returned [PluginDependencySpec]. + * + * For example: + * + * ``` + * plugins { + * protobuf version("0.8.19-custom") + * } + * ``` + */ +private const val ABOUT_PLUGIN_ACCESSORS = "" + +val PluginDependenciesSpec.errorprone: PluginDependencySpec + get() = id(ErrorProne.GradlePlugin.id) + +val PluginDependenciesSpec.protobuf: PluginDependencySpec + get() = id(Protobuf.GradlePlugin.id) + +val PluginDependenciesSpec.prototap: PluginDependencySpec + get() = id(ProtoTap.gradlePluginId).version(ProtoTap.version) + +val PluginDependenciesSpec.`gradle-doctor`: PluginDependencySpec + get() = id(GradleDoctor.pluginId).version(GradleDoctor.version) + +val PluginDependenciesSpec.kotest: PluginDependencySpec + get() = Kotest.MultiplatformGradlePlugin.let { + return id(it.id).version(it.version) + } + +val PluginDependenciesSpec.kover: PluginDependencySpec + get() = id(Kover.id).version(Kover.version) + +val PluginDependenciesSpec.ksp: PluginDependencySpec + get() = id(Ksp.id).version(Ksp.version) + +/** + * Configures the dependencies between third-party Gradle tasks + * and those defined via ProtoData and Spine Model Compiler. + * + * It is required to avoid warnings in build logs, detecting the undeclared + * usage of Spine-specific task output by other tasks, + * e.g., the output of `launchProtoData` is used by `compileKotlin`. + */ +@Suppress("unused") +fun Project.configureTaskDependencies() { + + /** + * Creates a dependency between the Gradle task of *this* name + * onto the task with `taskName`. + * + * If either of tasks does not exist in the enclosing `Project`, + * this method does nothing. + * + * This extension is kept local to `configureTaskDependencies` extension + * to prevent its direct usage from outside. + */ + fun String.dependOn(taskName: String) { + val whoDepends = this + val dependOntoTask: Task? = tasks.findByName(taskName) + dependOntoTask?.let { + tasks.findByName(whoDepends)?.dependsOn(it) + } + } + + afterEvaluate { + val launchProtoData = "launchProtoData" + val launchTestProtoData = "launchTestProtoData" + val generateProto = "generateProto" + val createVersionFile = "createVersionFile" + val compileKotlin = "compileKotlin" + compileKotlin.run { + dependOn(generateProto) + dependOn(launchProtoData) + } + val compileTestKotlin = "compileTestKotlin" + compileTestKotlin.dependOn(launchTestProtoData) + val sourcesJar = "sourcesJar" + val kspKotlin = "kspKotlin" + sourcesJar.run { + dependOn(generateProto) + dependOn(launchProtoData) + dependOn(kspKotlin) + dependOn(createVersionFile) + dependOn("prepareProtocConfigVersions") + } + val dokkaHtml = "dokkaHtml" + dokkaHtml.run { + dependOn(generateProto) + dependOn(launchProtoData) + dependOn(kspKotlin) + } + val dokkaJavadoc = "dokkaJavadoc" + dokkaJavadoc.run { + dependOn(launchProtoData) + dependOn(kspKotlin) + } + "publishPluginJar".dependOn(createVersionFile) + compileKotlin.dependOn(kspKotlin) + compileTestKotlin.dependOn("kspTestKotlin") + "compileTestFixturesKotlin".dependOn("kspTestFixturesKotlin") + "javadocJar".dependOn(dokkaHtml) + "dokkaKotlinJar".dependOn(dokkaJavadoc) + } +} + +/** + * Obtains all modules names of which do not have `"-tests"` as the suffix. + * + * By convention, such modules are for integration tests and should be treated differently. + */ +val Project.productionModules: Iterable + get() = rootProject.subprojects.filter { !it.name.contains("-tests") } + +/** + * Sets the remote debug option for this [JavaExec] task. + * + * The port number is [5566][BuildSettings.REMOTE_DEBUG_PORT]. + * + * @param enabled If `true` the task will be suspended. + */ +fun JavaExec.remoteDebug(enabled: Boolean = true) { + debugOptions { + this@debugOptions.enabled.set(enabled) + port.set(BuildSettings.REMOTE_DEBUG_PORT) + server.set(true) + suspend.set(true) + } +} + +/** + * Sets the remote debug option for the task of [JavaExec] type with the given name. + * + * The port number is [5566][BuildSettings.REMOTE_DEBUG_PORT]. + * + * @param enabled If `true` the task will be suspended. + * @throws IllegalStateException if the task with the given name is not found, or, + * if the taks is not of [JavaExec] type. + */ +fun Project.setRemoteDebug(taskName: String, enabled: Boolean = true) { + val task = tasks.findByName(taskName) + check(task != null) { + "Could not find a task named `$taskName` in the project `$name`." + } + check(task is JavaExec) { + "The task `$taskName` is not of type `JavaExec`." + } + task.remoteDebug(enabled) +} + +/** + * Sets remote debug options for the `launchProtoData` task. + * + * @param enabled if `true` the task will be suspended. + * + * @see remoteDebug + */ +fun Project.protoDataRemoteDebug(enabled: Boolean = true) = + setRemoteDebug("launchProtoData", enabled) + +/** + * Sets remote debug options for the `launchTestProtoData` task. + * + * @param enabled if `true` the task will be suspended. + * + * @see remoteDebug + */ +fun Project.testProtoDataRemoteDebug(enabled: Boolean = true) = + setRemoteDebug("launchTestProtoData", enabled) + +/** + * Sets remote debug options for the `launchTestFixturesProtoData` task. + * + * @param enabled if `true` the task will be suspended. + * + * @see remoteDebug + */ +fun Project.testFixturesProtoDataRemoteDebug(enabled: Boolean = true) = + setRemoteDebug("launchTestFixturesProtoData", enabled) diff --git a/buildSrc/src/main/kotlin/BuildSettings.kt b/buildSrc/src/main/kotlin/BuildSettings.kt new file mode 100644 index 0000000..562eb83 --- /dev/null +++ b/buildSrc/src/main/kotlin/BuildSettings.kt @@ -0,0 +1,41 @@ +/* + * Copyright 2025, TeamDev. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +import org.gradle.api.JavaVersion +import org.gradle.jvm.toolchain.JavaLanguageVersion +import org.jetbrains.kotlin.gradle.dsl.JvmTarget + +/** + * This object provides high-level constants, like the version of JVM, to be used + * throughout the project. + */ +object BuildSettings { + private const val JVM_VERSION = 17 + val javaVersion: JavaLanguageVersion = JavaLanguageVersion.of(JVM_VERSION) + val javaVersionCompat = JavaVersion.toVersion(JVM_VERSION) + val jvmTarget = JvmTarget.JVM_17 + const val REMOTE_DEBUG_PORT = 5566 +} diff --git a/buildSrc/src/main/kotlin/Dependencies.kt b/buildSrc/src/main/kotlin/Dependencies.kt deleted file mode 100644 index 2edb709..0000000 --- a/buildSrc/src/main/kotlin/Dependencies.kt +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright 2022, TeamDev. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Redistribution and use in source and/or binary forms, with or without - * modification, must retain the above copyright notice and the following - * disclaimer. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -@file:Suppress("UnusedReceiverParameter", "unused") - -import io.spine.internal.dependency.ErrorProne -import io.spine.internal.dependency.GradleDoctor -import io.spine.internal.dependency.Protobuf -import io.spine.internal.dependency.Spine -import io.spine.internal.dependency.Spine.ProtoData -import org.gradle.plugin.use.PluginDependenciesSpec -import org.gradle.plugin.use.PluginDependencySpec - -/** - * Provides shortucts to reference our dependnecy objects. - * - * Dependency objects cannot be used under `plugins` section because `io` is a value - * declared in auto-generatated `org.gradle.kotlin.dsl.PluginAccessors.kt` file. - * It conflicts with our own declarations. - * - * In such cases, a shortctut to apply a plugin can be created: - * - * ``` - * val PluginDependenciesSpec.`gradle-doctor`: PluginDependencySpec - * get() = id(GradleDoctor.pluginId).version(GradleDoctor.version) - * ``` - * - * But for some plugins, it's impossible to apply them directly to a project. - * For example, when a plugin is not published to Gradle Portal, it can only be - * applied with buildscript's classpath. Thus, it's needed to leave some freedom - * upon how to apply them. In such cases, just a shortcut to a dependency object - * can be declared, without applyin of the plugin in-place. - */ -private const val ABOUT = "" - -/** - * Shortcut to [Spine.McJava] dependency object. - * - * This plugin is not published to Gradle Portal and cannot be applied directly to a project. - * Firstly, it should be put to buildscript's classpath and then applied by ID only. - */ -val PluginDependenciesSpec.mcJava: Spine.McJava - get() = Spine.McJava - -/** - * Shortcut to [Spine.ProtoData] dependency object. - * - * This plugin is in Gradle Portal. But when used in pair with [mcJava], it cannot be applied - * directly to a project. It it so, because [mcJava] uses [protoData] as its dependency. - * And buildscript's classpath ends up with both of them. - */ -val PluginDependenciesSpec.protoData: ProtoData - get() = ProtoData diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/DependencyResolution.kt b/buildSrc/src/main/kotlin/DependencyResolution.kt similarity index 54% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/DependencyResolution.kt rename to buildSrc/src/main/kotlin/DependencyResolution.kt index ad768c5..adf5eae 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/DependencyResolution.kt +++ b/buildSrc/src/main/kotlin/DependencyResolution.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,36 +24,45 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle - -import io.spine.internal.dependency.AnimalSniffer -import io.spine.internal.dependency.AutoCommon -import io.spine.internal.dependency.AutoService -import io.spine.internal.dependency.AutoValue -import io.spine.internal.dependency.CheckerFramework -import io.spine.internal.dependency.CommonsCli -import io.spine.internal.dependency.CommonsLogging -import io.spine.internal.dependency.ErrorProne -import io.spine.internal.dependency.FindBugs -import io.spine.internal.dependency.Flogger -import io.spine.internal.dependency.Gson -import io.spine.internal.dependency.Guava -import io.spine.internal.dependency.J2ObjC -import io.spine.internal.dependency.JUnit -import io.spine.internal.dependency.Jackson -import io.spine.internal.dependency.Kotlin -import io.spine.internal.dependency.Okio -import io.spine.internal.dependency.Plexus -import io.spine.internal.dependency.Protobuf -import io.spine.internal.dependency.Truth +import io.spine.dependency.build.AnimalSniffer +import io.spine.dependency.build.CheckerFramework +import io.spine.dependency.build.Dokka +import io.spine.dependency.build.ErrorProne +import io.spine.dependency.build.FindBugs +import io.spine.dependency.lib.Asm +import io.spine.dependency.lib.AutoCommon +import io.spine.dependency.lib.AutoService +import io.spine.dependency.lib.AutoValue +import io.spine.dependency.lib.CommonsCli +import io.spine.dependency.lib.CommonsCodec +import io.spine.dependency.lib.CommonsLogging +import io.spine.dependency.lib.Gson +import io.spine.dependency.lib.Guava +import io.spine.dependency.lib.J2ObjC +import io.spine.dependency.lib.Jackson +import io.spine.dependency.lib.JavaDiffUtils +import io.spine.dependency.lib.Kotlin +import io.spine.dependency.lib.Okio +import io.spine.dependency.lib.Plexus +import io.spine.dependency.lib.Protobuf +import io.spine.dependency.lib.Slf4J +import io.spine.dependency.local.Base +import io.spine.dependency.local.Spine +import io.spine.dependency.test.Hamcrest +import io.spine.dependency.test.JUnit +import io.spine.dependency.test.Kotest +import io.spine.dependency.test.OpenTest4J +import io.spine.dependency.test.Truth import org.gradle.api.NamedDomainObjectContainer +import org.gradle.api.Project import org.gradle.api.artifacts.Configuration import org.gradle.api.artifacts.ConfigurationContainer +import org.gradle.api.artifacts.ModuleDependency import org.gradle.api.artifacts.ResolutionStrategy -import org.gradle.api.artifacts.dsl.RepositoryHandler +import org.gradle.kotlin.dsl.exclude /** - * The function to be used in `buildscript` when a fully-qualified call must be made. + * The function to be used in `buildscript` when a fully qualified call must be made. */ @Suppress("unused") fun doForceVersions(configurations: ConfigurationContainer) { @@ -76,25 +85,26 @@ fun NamedDomainObjectContainer.forceVersions() { } private fun ResolutionStrategy.forceProductionDependencies() { - @Suppress("DEPRECATION") // Force SLF4J version. + @Suppress("DEPRECATION") // Force versions of SLF4J and Kotlin libs. force( AnimalSniffer.lib, AutoCommon.lib, AutoService.annotations, CheckerFramework.annotations, + Dokka.BasePlugin.lib, ErrorProne.annotations, ErrorProne.core, - Guava.lib, FindBugs.annotations, - Flogger.lib, - Flogger.Runtime.systemBackend, + Gson.lib, + Guava.lib, Kotlin.reflect, Kotlin.stdLib, Kotlin.stdLibCommon, + Kotlin.stdLibJdk7, Kotlin.stdLibJdk8, - Protobuf.libs, Protobuf.GradlePlugin.lib, - io.spine.internal.dependency.Slf4J.lib + Protobuf.libs, + Slf4J.lib ) } @@ -102,10 +112,12 @@ private fun ResolutionStrategy.forceTestDependencies() { force( Guava.testLib, JUnit.api, - JUnit.platformCommons, - JUnit.platformLauncher, + JUnit.bom, + JUnit.Platform.commons, + JUnit.Platform.launcher, JUnit.legacy, - Truth.libs + Truth.libs, + Kotest.assertions, ) } @@ -114,24 +126,37 @@ private fun ResolutionStrategy.forceTestDependencies() { */ private fun ResolutionStrategy.forceTransitiveDependencies() { force( + Asm.lib, + Asm.tree, + Asm.analysis, + Asm.util, + Asm.commons, AutoValue.annotations, - Gson.lib, - J2ObjC.annotations, - Plexus.utils, - Okio.lib, CommonsCli.lib, - CheckerFramework.compatQual, + CommonsCodec.lib, CommonsLogging.lib, - Jackson.databind, + Gson.lib, + Hamcrest.core, + J2ObjC.annotations, + JUnit.Platform.engine, + JUnit.Platform.suiteApi, + JUnit.runner, + Jackson.annotations, + Jackson.bom, Jackson.core, + Jackson.databind, Jackson.dataformatXml, Jackson.dataformatYaml, Jackson.moduleKotlin, - Jackson.bom, - Jackson.annotations + JavaDiffUtils.lib, + Kotlin.jetbrainsAnnotations, + Okio.lib, + OpenTest4J.lib, + Plexus.utils, ) } +@Suppress("unused") fun NamedDomainObjectContainer.excludeProtobufLite() { fun excludeProtoLite(configurationName: String) { @@ -147,29 +172,37 @@ fun NamedDomainObjectContainer.excludeProtobufLite() { excludeProtoLite("testRuntimeOnly") } +/** + * Excludes `spine-base` from the dependencies. + */ @Suppress("unused") -object DependencyResolution { - @Deprecated( - "Please use `configurations.forceVersions()`.", - ReplaceWith("configurations.forceVersions()") - ) - fun forceConfiguration(configurations: ConfigurationContainer) { - configurations.forceVersions() - } +fun ModuleDependency.excludeSpineBase() { + exclude(group = Spine.group, module = "spine-base") +} - @Deprecated( - "Please use `configurations.excludeProtobufLite()`.", - ReplaceWith("configurations.excludeProtobufLite()") - ) - fun excludeProtobufLite(configurations: ConfigurationContainer) { - configurations.excludeProtobufLite() +/** + * Forces the version of [Spine.base] in the given project. + */ +@Suppress("unused") +fun Project.forceSpineBase() { + configurations.all { + resolutionStrategy { + force(Base.lib) + } } +} - @Deprecated( - "Please use `applyStandard(repositories)` instead.", - replaceWith = ReplaceWith("applyStandard(repositories)") - ) - fun defaultRepositories(repositories: RepositoryHandler) { - repositories.applyStandard() +/** + * Forces configurations containing `"proto"` in their names (disregarding the case) to + * use [Spine.baseForBuildScript]. + */ +@Suppress("unused") +fun Project.forceBaseInProtoTasks() { + configurations.configureEach { + if (name.lowercase().contains("proto")) { + resolutionStrategy { + force(Base.libForBuildScript) + } + } } } diff --git a/buildSrc/src/main/kotlin/DokkaExts.kt b/buildSrc/src/main/kotlin/DokkaExts.kt new file mode 100644 index 0000000..ff5de3f --- /dev/null +++ b/buildSrc/src/main/kotlin/DokkaExts.kt @@ -0,0 +1,224 @@ +/* + * Copyright 2025, TeamDev. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +import io.spine.dependency.build.Dokka +import io.spine.gradle.publish.getOrCreate +import java.io.File +import java.time.LocalDate +import org.gradle.api.Project +import org.gradle.api.artifacts.Dependency +import org.gradle.api.artifacts.dsl.DependencyHandler +import org.gradle.api.file.FileCollection +import org.gradle.api.tasks.TaskContainer +import org.gradle.api.tasks.TaskProvider +import org.gradle.api.tasks.bundling.Jar +import org.gradle.kotlin.dsl.DependencyHandlerScope +import org.jetbrains.dokka.DokkaConfiguration +import org.jetbrains.dokka.base.DokkaBase +import org.jetbrains.dokka.base.DokkaBaseConfiguration +import org.jetbrains.dokka.gradle.AbstractDokkaLeafTask +import org.jetbrains.dokka.gradle.AbstractDokkaTask +import org.jetbrains.dokka.gradle.DokkaTask +import org.jetbrains.dokka.gradle.GradleDokkaSourceSetBuilder + +/** + * To generate the documentation as seen from Java perspective, the `kotlin-as-java` + * plugin was added to the Dokka classpath. + * + * @see + * Dokka output formats + */ +fun DependencyHandlerScope.useDokkaForKotlinAsJava() { + dokkaPlugin(Dokka.KotlinAsJavaPlugin.lib) +} + +/** + * To exclude pieces of code annotated with `@Internal` from the documentation + * a custom plugin is added to the Dokka classpath. + * + * @see + * Custom Dokka Plugins + */ +fun DependencyHandlerScope.useDokkaWithSpineExtensions() { + dokkaPlugin(Dokka.SpineExtensions.lib) +} + +private fun DependencyHandler.dokkaPlugin(dependencyNotation: Any): Dependency? = + add("dokkaPlugin", dependencyNotation) + +private fun Project.dokkaOutput(language: String): File { + val lng = language.titleCaseFirstChar() + return layout.buildDirectory.dir("docs/dokka$lng").get().asFile +} + +fun Project.dokkaConfigFile(file: String): File { + val dokkaConfDir = project.rootDir.resolve("buildSrc/src/main/resources/dokka") + return dokkaConfDir.resolve(file) +} + +/** + * Configures the presentation style, logo, and footer message. + * + * Dokka Base plugin allows setting a few properties to customize the output: + * - `customStyleSheets` property to which CSS files are passed overriding + * styles generated by Dokka; + * - `customAssets` property to provide resources. The image with the name + * "logo-icon.svg" is passed to override the default logo used by Dokka; + * - `separateInheritedMembers` when set to `true`, creates a separate tab in + * type-documentation for inherited members. + * + * @see + * Dokka modifying frontend assets + */ +fun AbstractDokkaTask.configureStyle() { + pluginConfiguration { + customStyleSheets = listOf(project.dokkaConfigFile("styles/custom-styles.css")) + customAssets = listOf(project.dokkaConfigFile("assets/logo-icon.svg")) + separateInheritedMembers = true + footerMessage = "Copyright ${LocalDate.now().year}, TeamDev" + } +} + +private fun AbstractDokkaLeafTask.configureFor(language: String) { + dokkaSourceSets.configureEach { + /** + * Configures links to the external Java documentation. + */ + jdkVersion.set(BuildSettings.javaVersion.asInt()) + + skipEmptyPackages.set(true) + + includeNonPublic.set(true) + + documentedVisibilities.set( + setOf( + DokkaConfiguration.Visibility.PUBLIC, + DokkaConfiguration.Visibility.PROTECTED + ) + ) + } + + outputDirectory.set(project.dokkaOutput(language)) + + configureStyle() +} + +/** + * Configures this [DokkaTask] to accept only Kotlin files. + */ +fun AbstractDokkaLeafTask.configureForKotlin() { + configureFor("kotlin") +} + +/** + * Configures this [DokkaTask] to accept only Java files. + */ +fun AbstractDokkaLeafTask.configureForJava() { + configureFor("java") +} + +/** + * Finds the `dokkaHtml` Gradle task. + */ +fun TaskContainer.dokkaHtmlTask(): DokkaTask? = this.findByName("dokkaHtml") as DokkaTask? + +/** + * Returns only Java source roots out of all present in the source set. + * + * It is a helper method for generating documentation by Dokka only for Java code. + * It is helpful when both Java and Kotlin source files are present in a source set. + * Dokka can properly generate documentation for either Kotlin or Java depending on + * the configuration, but not both. + */ +@Suppress("unused") +internal fun GradleDokkaSourceSetBuilder.onlyJavaSources(): FileCollection { + return sourceRoots.filter(File::isJavaSourceDirectory) +} + +private fun File.isJavaSourceDirectory(): Boolean { + return isDirectory && name == "java" +} + +/** + * Locates or creates `dokkaKotlinJar` task in this [Project]. + * + * The output of this task is a `jar` archive. The archive contains the Dokka output, generated upon + * Kotlin sources from `main` source set. Requires Dokka to be configured in the target project by + * applying `dokka-for-kotlin` plugin. + */ +fun Project.dokkaKotlinJar(): TaskProvider = tasks.getOrCreate("dokkaKotlinJar") { + archiveClassifier.set("dokka") + from(files(dokkaOutput("kotlin"))) + + tasks.dokkaHtmlTask()?.let{ dokkaTask -> + this@getOrCreate.dependsOn(dokkaTask) + } +} + +/** + * Tells if this task belongs to the execution graph which contains publishing tasks. + * + * The task `"publishToMavenLocal"` is excluded from the check because it is a part of + * the local testing workflow. + */ +fun AbstractDokkaTask.isInPublishingGraph(): Boolean = + project.gradle.taskGraph.allTasks.any { + it.name == "publish" + } + +/** + * Locates or creates `dokkaJavaJar` task in this [Project]. + * + * The output of this task is a `jar` archive. The archive contains the Dokka output, generated upon + * Kotlin sources from `main` source set. Requires Dokka to be configured in the target project by + * applying `dokka-for-java` and/or `dokka-for-kotlin` script plugin. + */ +fun Project.dokkaJavaJar(): TaskProvider = tasks.getOrCreate("dokkaJavaJar") { + archiveClassifier.set("dokka-java") + from(files(dokkaOutput("java"))) + + tasks.dokkaHtmlTask()?.let{ dokkaTask -> + this@getOrCreate.dependsOn(dokkaTask) + } +} + +/** + * Disables Dokka and Javadoc tasks in this `Project`. + * + * This function could be useful to improve build speed when building subprojects containing + * test environments or integration test projects. + */ +@Suppress("unused") +fun Project.disableDocumentationTasks() { + gradle.taskGraph.whenReady { + tasks.forEach { task -> + val lowercaseName = task.name.lowercase() + if (lowercaseName.contains("dokka") || lowercaseName.contains("javadoc")) { + task.enabled = false + } + } + } +} diff --git a/buildSrc/src/main/kotlin/PluginsAccessors.kt b/buildSrc/src/main/kotlin/PluginsAccessors.kt deleted file mode 100644 index f20c550..0000000 --- a/buildSrc/src/main/kotlin/PluginsAccessors.kt +++ /dev/null @@ -1,66 +0,0 @@ -/* -* Copyright 2022, TeamDev. All rights reserved. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Redistribution and use in source and/or binary forms, with or without -* modification, must retain the above copyright notice and the following -* disclaimer. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -// Those accessors should match Gradle's naming conventions. -@file:Suppress("TopLevelPropertyNaming", "unused") - -import io.spine.internal.dependency.ErrorProne -import io.spine.internal.dependency.GradleDoctor -import io.spine.internal.dependency.Protobuf -import org.gradle.plugin.use.PluginDependenciesSpec -import org.gradle.plugin.use.PluginDependencySpec - -/** - * Provides shortucts for applying plugins from our dependnecy objects. - * - * Dependency objects cannot be used under `plugins` section because `io` is a value - * declared in auto-generatated `org.gradle.kotlin.dsl.PluginAccessors.kt` file. - * It conflicts with our own declarations. - * - * Declaring of top-level shortucts eliminates need in applying plugins - * using fully-qualified name of dependency objects. - * - * It is still possible to apply a plugin with a custom version, if needed. - * Just delcate a version again on the returned [PluginDependencySpec]. - * - * For example: - * - * ``` - * plugins { - * protobuf version("0.8.19-custom") - * } - * ``` - */ -private const val ABOUT = "" - -val PluginDependenciesSpec.errorprone: PluginDependencySpec - get() = id(ErrorProne.GradlePlugin.id) - -val PluginDependenciesSpec.protobuf: PluginDependencySpec - get() = id(Protobuf.GradlePlugin.id) - -val PluginDependenciesSpec.`gradle-doctor`: PluginDependencySpec - get() = id(GradleDoctor.pluginId).version(GradleDoctor.version) diff --git a/buildSrc/src/main/kotlin/Strings.kt b/buildSrc/src/main/kotlin/Strings.kt new file mode 100644 index 0000000..19e0c21 --- /dev/null +++ b/buildSrc/src/main/kotlin/Strings.kt @@ -0,0 +1,50 @@ +/* + * Copyright 2025, TeamDev. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * This file provides extensions to `String` and `CharSequence` that wrap + * analogues from standard Kotlin runtime. + * + * It helps in switching between versions of Gradle which have different versions of + * the Kotlin runtime. Please see the bodies of the extension functions for details on + * switching the implementations depending on the Kotlin version at hand. + * + * Once we migrate to newer Gradle, these wrappers should be inlined with + * the subsequent removal of this source file. + */ +@Suppress("unused") +private const val ABOUT = "" + +/** + * Makes the first character come in the title case. + */ +fun String.titleCaseFirstChar(): String = replaceFirstChar { it.titlecase() } + +/** + * Converts this string to lowercase. + */ +@Deprecated(message = "Please use `lowercase()` instead.", replaceWith = ReplaceWith("lowercase")) +fun String.lowercased(): String = lowercase() diff --git a/buildSrc/src/main/kotlin/TaskDependencies.kt b/buildSrc/src/main/kotlin/TaskDependencies.kt deleted file mode 100644 index cfabc4d..0000000 --- a/buildSrc/src/main/kotlin/TaskDependencies.kt +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2022, TeamDev. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Redistribution and use in source and/or binary forms, with or without - * modification, must retain the above copyright notice and the following - * disclaimer. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -import org.gradle.api.Project -import org.gradle.api.Task - -/** - * Configures the dependencies between third-party Gradle tasks - * and those defined via ProtoData and Spine Model Compiler. - * - * It is required in order to avoid warnings in build logs, detecting the undeclared - * usage of Spine-specific task output by other tasks, - * e.g. the output of `launchProtoDataMain` is used by `compileKotlin`. - */ -@Suppress("unused") -fun Project.configureTaskDependencies() { - - /** - * Creates a dependency between the Gradle task of *this* name - * onto the task with `taskName`. - * - * If either of tasks does not exist in the enclosing `Project`, - * this method does nothing. - * - * This extension is kept local to `configureTaskDependencies` extension - * to prevent its direct usage from outside. - */ - fun String.dependOn(taskName: String) { - val whoDepends = this - val dependOntoTask: Task? = tasks.findByName(taskName) - dependOntoTask?.let { - tasks.findByName(whoDepends)?.dependsOn(it) - } - } - - afterEvaluate { - "compileKotlin".dependOn("launchProtoDataMain") - "compileTestKotlin".dependOn("launchProtoDataTest") - "sourcesJar".dependOn("generateProto") - "sourcesJar".dependOn("launchProtoDataMain") - "sourcesJar".dependOn("createVersionFile") - "sourcesJar".dependOn("prepareProtocConfigVersions") - "dokkaHtml".dependOn("generateProto") - "dokkaHtml".dependOn("launchProtoDataMain") - "dokkaJavadoc".dependOn("launchProtoDataMain") - "publishPluginJar".dependOn("createVersionFile") - } -} diff --git a/buildSrc/src/main/kotlin/compile-protobuf.gradle.kts b/buildSrc/src/main/kotlin/compile-protobuf.gradle.kts new file mode 100644 index 0000000..4acbb86 --- /dev/null +++ b/buildSrc/src/main/kotlin/compile-protobuf.gradle.kts @@ -0,0 +1,53 @@ +/* + * Copyright 2025, TeamDev. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +import io.spine.dependency.lib.Protobuf +import io.spine.gradle.protobuf.setup + +plugins { + id("java-library") + id("com.google.protobuf") +} + +// For generating test fixtures. See `src/test/proto`. +protobuf { + configurations.excludeProtobufLite() + protoc { + artifact = Protobuf.compiler + } + + afterEvaluate { + // Walk the collection of tasks to force the execution + // of the `configureEach` operations earlier. + // This hack allows to avoid `ConcurrentModificationException` on + // creating `kspKotlin` task. + generateProtoTasks.all().size + } + + generateProtoTasks.all().configureEach { + setup() + } +} diff --git a/buildSrc/src/main/kotlin/config-tester.gradle.kts b/buildSrc/src/main/kotlin/config-tester.gradle.kts index 8095691..21d31e3 100644 --- a/buildSrc/src/main/kotlin/config-tester.gradle.kts +++ b/buildSrc/src/main/kotlin/config-tester.gradle.kts @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,9 +24,9 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -import io.spine.internal.gradle.ConfigTester -import io.spine.internal.gradle.SpineRepos -import io.spine.internal.gradle.cleanFolder +import io.spine.gradle.ConfigTester +import io.spine.gradle.SpineRepos +import io.spine.gradle.cleanFolder import java.nio.file.Path import java.nio.file.Paths diff --git a/buildSrc/src/main/kotlin/detekt-code-analysis.gradle.kts b/buildSrc/src/main/kotlin/detekt-code-analysis.gradle.kts index e38b8d6..7b0ffd1 100644 --- a/buildSrc/src/main/kotlin/detekt-code-analysis.gradle.kts +++ b/buildSrc/src/main/kotlin/detekt-code-analysis.gradle.kts @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -60,6 +60,7 @@ import io.gitlab.arturbosch.detekt.Detekt * } * ``` */ +@Suppress("unused") private val about = "" plugins { @@ -68,7 +69,7 @@ plugins { detekt { buildUponDefaultConfig = true - config = files("${rootDir}/config/quality/detekt-config.yml") + config.from(files("${rootDir}/config/quality/detekt-config.yml")) } tasks { diff --git a/buildSrc/src/main/kotlin/dokka-for-java.gradle.kts b/buildSrc/src/main/kotlin/dokka-for-java.gradle.kts index d8f970f..ee22622 100644 --- a/buildSrc/src/main/kotlin/dokka-for-java.gradle.kts +++ b/buildSrc/src/main/kotlin/dokka-for-java.gradle.kts @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,82 +24,20 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -import io.spine.internal.dependency.Dokka -import io.spine.internal.gradle.dokka.onlyJavaSources - -import java.time.LocalDate -import org.jetbrains.dokka.base.DokkaBase -import org.jetbrains.dokka.base.DokkaBaseConfiguration -import org.jetbrains.dokka.gradle.DokkaTask -import org.jetbrains.dokka.DokkaConfiguration.Visibility +import org.jetbrains.dokka.gradle.AbstractDokkaLeafTask plugins { - id("org.jetbrains.dokka") + id("org.jetbrains.dokka") // Cannot use `Dokka` dependency object here yet. } dependencies { - /** - * To generate the documentation as seen from Java perspective, the `kotlin-as-java` - * plugin was added to the Dokka's classpath. - * - * @see - * Dokka output formats - */ - dokkaPlugin(Dokka.KotlinAsJavaPlugin.lib) - - /** - * To exclude pieces of code annotated with `@Internal` from the documentation a - * custom plugin is added to the Dokka's classpath. - * - * @see - * Custom Dokka Plugins - */ - dokkaPlugin(Dokka.SpineExtensions.lib) + useDokkaForKotlinAsJava() + useDokkaWithSpineExtensions() } -tasks.withType().configureEach { - dokkaSourceSets.configureEach { - /** - * Configures links to the external Java documentation. By default links are - * pointing to the Java 8 documentation. - */ - jdkVersion.set(11) - - sourceRoots.setFrom( - onlyJavaSources() - ) - - skipEmptyPackages.set(true) - - documentedVisibilities.set( - setOf( - Visibility.PUBLIC, - Visibility.PROTECTED - ) - ) - } - - outputDirectory.set(buildDir.resolve("docs/dokka")) - - val dokkaConfDir = rootDir.resolve("buildSrc/src/main/resources/dokka") - - /** - * Dokka Base plugin allows to set a few properties to customize the output: - * - * - `customStyleSheets` property to which css files are passed overriding - * styles generated by Dokka; - * - `customAssets` property to provide resources. The image with the name - * "logo-icon.svg" is passed to override the default logo used by Dokka; - * - `separateInheritedMembers` when set to `true`, creates a separate tab in - * type-documentation for inherited members. - * - * @see - * Dokka modifying frontend assets - */ - pluginConfiguration { - customStyleSheets = listOf(file("${dokkaConfDir.resolve("styles/custom-styles.css")}")) - customAssets = listOf(file("${dokkaConfDir.resolve("assets/logo-icon.svg")}")) - separateInheritedMembers = true - footerMessage = "Copyright ${LocalDate.now().year}, TeamDev" +tasks.withType().configureEach { + configureForJava() + onlyIf { + (it as AbstractDokkaLeafTask).isInPublishingGraph() } } diff --git a/buildSrc/src/main/kotlin/io/spine/internal/dependency/AutoService.kt b/buildSrc/src/main/kotlin/dokka-for-kotlin.gradle.kts similarity index 71% rename from buildSrc/src/main/kotlin/io/spine/internal/dependency/AutoService.kt rename to buildSrc/src/main/kotlin/dokka-for-kotlin.gradle.kts index 80b7997..e50b10a 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/dependency/AutoService.kt +++ b/buildSrc/src/main/kotlin/dokka-for-kotlin.gradle.kts @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,12 +24,19 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.dependency +import org.jetbrains.dokka.gradle.AbstractDokkaLeafTask -// https://github.com/google/auto -object AutoService { - private const val version = "1.0.1" - const val annotations = "com.google.auto.service:auto-service-annotations:${version}" - @Suppress("unused") - const val processor = "com.google.auto.service:auto-service:${version}" +plugins { + id("org.jetbrains.dokka") // Cannot use `Dokka` dependency object here yet. +} + +dependencies { + useDokkaWithSpineExtensions() +} + +tasks.withType().configureEach { + configureForKotlin() + onlyIf { + (it as AbstractDokkaLeafTask).isInPublishingGraph() + } } diff --git a/buildSrc/src/main/kotlin/io/spine/internal/dependency/AnimalSniffer.kt b/buildSrc/src/main/kotlin/io/spine/dependency/build/AnimalSniffer.kt similarity index 88% rename from buildSrc/src/main/kotlin/io/spine/internal/dependency/AnimalSniffer.kt rename to buildSrc/src/main/kotlin/io/spine/dependency/build/AnimalSniffer.kt index 068ae59..8258896 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/dependency/AnimalSniffer.kt +++ b/buildSrc/src/main/kotlin/io/spine/dependency/build/AnimalSniffer.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,10 +24,11 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.dependency +package io.spine.dependency.build // https://www.mojohaus.org/animal-sniffer/animal-sniffer-maven-plugin/ +@Suppress("unused", "ConstPropertyName") object AnimalSniffer { private const val version = "1.21" - const val lib = "org.codehaus.mojo:animal-sniffer-annotations:${version}" + const val lib = "org.codehaus.mojo:animal-sniffer-annotations:$version" } diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/publish/TestJar.kt b/buildSrc/src/main/kotlin/io/spine/dependency/build/CheckStyle.kt similarity index 63% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/publish/TestJar.kt rename to buildSrc/src/main/kotlin/io/spine/dependency/build/CheckStyle.kt index 9723399..e1e3b28 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/publish/TestJar.kt +++ b/buildSrc/src/main/kotlin/io/spine/dependency/build/CheckStyle.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,27 +24,23 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.publish +package io.spine.dependency.build /** - * A DSL element of [SpinePublishing] extension which allows enabling publishing - * of [testJar] artifact. + * Dependencies on Checkstyle Java linter. * - * This artifact contains compilation output of `test` source set. By default, it is not published. - * - * Take a look on [SpinePublishing.testJar] for a usage example. - - * @see [registerArtifacts] + * @see Checkstyle + * @see [io.spine.gradle.checkstyle.CheckStyleConfig] */ -class TestJar { - - /** - * Set of modules, for which a test JAR will be published. - */ - var inclusions: Set = emptySet() - +@Suppress("unused", "ConstPropertyName") +object CheckStyle { /** - * Enables test JAR publishing for all published modules. + * The version to be used in the project. + * + * `10.12.1` is the last version in `10.12.0`, which does not introduce + * capability conflict over `google-collections` with Guava. + * + * @see Checkstyle */ - var enabled = false + const val version = "10.12.1" } diff --git a/buildSrc/src/main/kotlin/io/spine/internal/dependency/CheckerFramework.kt b/buildSrc/src/main/kotlin/io/spine/dependency/build/CheckerFramework.kt similarity index 70% rename from buildSrc/src/main/kotlin/io/spine/internal/dependency/CheckerFramework.kt rename to buildSrc/src/main/kotlin/io/spine/dependency/build/CheckerFramework.kt index 75cc67f..5d2140a 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/dependency/CheckerFramework.kt +++ b/buildSrc/src/main/kotlin/io/spine/dependency/build/CheckerFramework.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,21 +24,16 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.dependency +package io.spine.dependency.build // https://checkerframework.org/ +@Suppress("unused", "ConstPropertyName") object CheckerFramework { - private const val version = "3.21.3" - const val annotations = "org.checkerframework:checker-qual:${version}" + private const val version = "3.40.0" + const val annotations = "org.checkerframework:checker-qual:$version" @Suppress("unused") val dataflow = listOf( - "org.checkerframework:dataflow:${version}", - "org.checkerframework:javacutil:${version}" + "org.checkerframework:dataflow:$version", + "org.checkerframework:javacutil:$version" ) - /** - * This is discontinued artifact, which we do not use directly. - * This is a transitive dependency for us, which we force in - * [DependencyResolution.forceConfiguration] - */ - const val compatQual = "org.checkerframework:checker-compat-qual:2.5.5" } diff --git a/buildSrc/src/main/kotlin/io/spine/internal/dependency/Dokka.kt b/buildSrc/src/main/kotlin/io/spine/dependency/build/Dokka.kt similarity index 73% rename from buildSrc/src/main/kotlin/io/spine/internal/dependency/Dokka.kt rename to buildSrc/src/main/kotlin/io/spine/dependency/build/Dokka.kt index 063d0a8..41757db 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/dependency/Dokka.kt +++ b/buildSrc/src/main/kotlin/io/spine/dependency/build/Dokka.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,10 +24,10 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.dependency +package io.spine.dependency.build // https://github.com/Kotlin/dokka -@Suppress("unused") +@Suppress("unused", "ConstPropertyName") object Dokka { private const val group = "org.jetbrains.dokka" @@ -35,37 +35,37 @@ object Dokka { * When changing the version, also change the version used in the * `buildSrc/build.gradle.kts`. */ - const val version = "1.7.20" + const val version = "1.9.20" object GradlePlugin { const val id = "org.jetbrains.dokka" /** * The version of this plugin is already specified in `buildSrc/build.gradle.kts` - * file. Thus, when applying the plugin in project's build files, only the [id] + * file. Thus, when applying the plugin to project's build files, only the [id] * should be used. */ - const val lib = "${group}:dokka-gradle-plugin:${version}" + const val lib = "$group:dokka-gradle-plugin:$version" } object BasePlugin { - const val lib = "${group}:dokka-base:${version}" + const val lib = "$group:dokka-base:$version" } - const val analysis = "org.jetbrains.dokka:dokka-analysis:${version}" + const val analysis = "org.jetbrains.dokka:dokka-analysis:$version" object CorePlugin { - const val lib = "${group}:dokka-core:${version}" + const val lib = "$group:dokka-core:$version" } /** - * To generate the documentation as seen from Java perspective use this plugin. + * To generate the documentation as seen from the Java perspective, please use this plugin. * * @see * Dokka output formats */ object KotlinAsJavaPlugin { - const val lib = "${group}:kotlin-as-java-plugin:${version}" + const val lib = "$group:kotlin-as-java-plugin:$version" } /** @@ -78,7 +78,7 @@ object Dokka { object SpineExtensions { private const val group = "io.spine.tools" - const val version = "2.0.0-SNAPSHOT.4" - const val lib = "${group}:spine-dokka-extensions:${version}" + const val version = "2.0.0-SNAPSHOT.6" + const val lib = "$group:spine-dokka-extensions:$version" } } diff --git a/buildSrc/src/main/kotlin/io/spine/internal/dependency/ErrorProne.kt b/buildSrc/src/main/kotlin/io/spine/dependency/build/ErrorProne.kt similarity index 66% rename from buildSrc/src/main/kotlin/io/spine/internal/dependency/ErrorProne.kt rename to buildSrc/src/main/kotlin/io/spine/dependency/build/ErrorProne.kt index 5131c3e..5b47c1b 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/dependency/ErrorProne.kt +++ b/buildSrc/src/main/kotlin/io/spine/dependency/build/ErrorProne.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,36 +24,39 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.dependency +package io.spine.dependency.build // https://errorprone.info/ -@Suppress("unused") +@Suppress("unused", "ConstPropertyName") object ErrorProne { // https://github.com/google/error-prone - private const val version = "2.16" + private const val version = "2.36.0" + + const val group = "com.google.errorprone" + // https://github.com/tbroyer/gradle-errorprone-plugin/blob/v0.8/build.gradle.kts private const val javacPluginVersion = "9+181-r4173-1" val annotations = listOf( - "com.google.errorprone:error_prone_annotations:${version}", - "com.google.errorprone:error_prone_type_annotations:${version}" + "$group:error_prone_annotations:$version", + "$group:error_prone_type_annotations:$version" ) - const val core = "com.google.errorprone:error_prone_core:${version}" - const val checkApi = "com.google.errorprone:error_prone_check_api:${version}" - const val testHelpers = "com.google.errorprone:error_prone_test_helpers:${version}" - const val javacPlugin = "com.google.errorprone:javac:${javacPluginVersion}" + const val core = "$group:error_prone_core:$version" + const val checkApi = "$group:error_prone_check_api:$version" + const val testHelpers = "$group:error_prone_test_helpers:$version" + const val javacPlugin = "$group:javac:$javacPluginVersion" // https://github.com/tbroyer/gradle-errorprone-plugin/releases object GradlePlugin { const val id = "net.ltgt.errorprone" /** * The version of this plugin is already specified in `buildSrc/build.gradle.kts` file. - * Thus, when applying the plugin in projects build files, only the [id] should be used. + * Thus, when applying the plugin to project build files, only the [id] should be used. * - * When the plugin is used as a library (e.g. in tools), its version and the library + * When the plugin is used as a library (e.g., in tools), its version and the library * artifacts are of importance. */ - const val version = "3.0.1" - const val lib = "net.ltgt.gradle:gradle-errorprone-plugin:${version}" + const val version = "4.1.0" + const val lib = "net.ltgt.gradle:gradle-errorprone-plugin:$version" } } diff --git a/buildSrc/src/main/kotlin/io/spine/internal/dependency/FindBugs.kt b/buildSrc/src/main/kotlin/io/spine/dependency/build/FindBugs.kt similarity index 63% rename from buildSrc/src/main/kotlin/io/spine/internal/dependency/FindBugs.kt rename to buildSrc/src/main/kotlin/io/spine/dependency/build/FindBugs.kt index 52b05f7..98003b9 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/dependency/FindBugs.kt +++ b/buildSrc/src/main/kotlin/io/spine/dependency/build/FindBugs.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,16 +24,18 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.dependency +package io.spine.dependency.build /** - * The FindBugs project is dead since 2017. It has a successor called SpotBugs, but we don't use it. - * We use ErrorProne for static analysis instead. The only reason for having this dependency is - * the annotations for null-checking introduced by JSR-305. These annotations are troublesome, - * but no alternatives are known for some of them so far. Please see - * [this issue](https://github.com/SpineEventEngine/base/issues/108) for more details. + * The FindBugs project has been dead since 2017. It has a successor called SpotBugs, + * but we don't use it. We use ErrorProne for static analysis instead. + * The only reason for having this dependency is the annotations for null-checking + * introduced by JSR-305. These annotations are troublesome, + * but no alternatives are known for some of them so far. + * Please see [this issue](https://github.com/SpineEventEngine/base/issues/108) for more details. */ +@Suppress("unused", "ConstPropertyName") object FindBugs { private const val version = "3.0.2" - const val annotations = "com.google.code.findbugs:jsr305:${version}" + const val annotations = "com.google.code.findbugs:jsr305:$version" } diff --git a/buildSrc/src/main/kotlin/io/spine/internal/dependency/GradleDoctor.kt b/buildSrc/src/main/kotlin/io/spine/dependency/build/GradleDoctor.kt similarity index 87% rename from buildSrc/src/main/kotlin/io/spine/internal/dependency/GradleDoctor.kt rename to buildSrc/src/main/kotlin/io/spine/dependency/build/GradleDoctor.kt index ecd685c..89cfb34 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/dependency/GradleDoctor.kt +++ b/buildSrc/src/main/kotlin/io/spine/dependency/build/GradleDoctor.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,14 +24,15 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.dependency +package io.spine.dependency.build /** * Helps optimize Gradle Builds by ensuring recommendations at build time. * * See [plugin site](https://runningcode.github.io/gradle-doctor) for features and usage. */ +@Suppress("unused", "ConstPropertyName") object GradleDoctor { - const val version = "0.8.1" + const val version = "0.10.0" const val pluginId = "com.osacky.doctor" } diff --git a/buildSrc/src/main/kotlin/io/spine/dependency/build/Ksp.kt b/buildSrc/src/main/kotlin/io/spine/dependency/build/Ksp.kt new file mode 100644 index 0000000..991c6c3 --- /dev/null +++ b/buildSrc/src/main/kotlin/io/spine/dependency/build/Ksp.kt @@ -0,0 +1,44 @@ +/* + * Copyright 2025, TeamDev. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package io.spine.dependency.build + +/** + * Kotlin Symbol Processing API. + * + * @see KSP GitHub repository + */ +@Suppress("ConstPropertyName", "unused") +object Ksp { + const val version = "2.1.20-1.0.31" + const val id = "com.google.devtools.ksp" + const val group = "com.google.devtools.ksp" + const val symbolProcessingApi = "$group:symbol-processing-api:$version" + const val symbolProcessing = "$group:symbol-processing:$version" + const val symbolProcessingAaEmb = "$group:symbol-processing-aa-embeddable:$version" + const val symbolProcessingCommonDeps = "$group:symbol-processing-common-deps:$version" + const val gradlePlugin = "$group:symbol-processing-gradle-plugin:$version" +} diff --git a/buildSrc/src/main/kotlin/io/spine/dependency/build/LicenseReport.kt b/buildSrc/src/main/kotlin/io/spine/dependency/build/LicenseReport.kt new file mode 100644 index 0000000..a4eb754 --- /dev/null +++ b/buildSrc/src/main/kotlin/io/spine/dependency/build/LicenseReport.kt @@ -0,0 +1,40 @@ +/* + * Copyright 2025, TeamDev. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package io.spine.dependency.build + +// https://github.com/jk1/Gradle-License-Report +@Suppress("unused") +object LicenseReport { + private const val version = "1.16" + const val lib = "com.github.jk1:gradle-license-report:$version" + + object GradlePlugin { + const val version = LicenseReport.version + const val id = "com.github.jk1.dependency-license-report" + const val lib = LicenseReport.lib + } +} diff --git a/buildSrc/src/main/kotlin/io/spine/internal/dependency/OsDetector.kt b/buildSrc/src/main/kotlin/io/spine/dependency/build/OsDetector.kt similarity index 86% rename from buildSrc/src/main/kotlin/io/spine/internal/dependency/OsDetector.kt rename to buildSrc/src/main/kotlin/io/spine/dependency/build/OsDetector.kt index 7f4bb16..5b479bf 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/dependency/OsDetector.kt +++ b/buildSrc/src/main/kotlin/io/spine/dependency/build/OsDetector.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,12 +24,13 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.dependency +package io.spine.dependency.build +@Suppress("unused", "ConstPropertyName") object OsDetector { // https://github.com/google/osdetector-gradle-plugin - const val version = "1.7.0" + const val version = "1.7.3" const val id = "com.google.osdetector" - const val lib = "com.google.gradle:osdetector-gradle-plugin:${version}" + const val lib = "com.google.gradle:osdetector-gradle-plugin:$version" const val classpath = lib } diff --git a/buildSrc/src/main/kotlin/io/spine/dependency/build/Pmd.kt b/buildSrc/src/main/kotlin/io/spine/dependency/build/Pmd.kt new file mode 100644 index 0000000..e4f7fdd --- /dev/null +++ b/buildSrc/src/main/kotlin/io/spine/dependency/build/Pmd.kt @@ -0,0 +1,42 @@ +/* + * Copyright 2025, TeamDev. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +@file:Suppress("MaxLineLength") + +package io.spine.dependency.build + +// https://github.com/pmd/pmd/releases +@Suppress("unused", "ConstPropertyName") +object Pmd { + /** + * This is the last version in the 6.x series. + * + * There's a major update to 7.x series. + * + * @see Aedile at GitHub */ @Suppress("unused") -object JavaJwt { - private const val version = "3.19.1" - const val lib = "com.auth0:java-jwt:${version}" +object Aedile { + private const val version = "1.3.1" + const val lib = "com.sksamuel.aedile:aedile-core:$version" } diff --git a/buildSrc/src/main/kotlin/io/spine/internal/dependency/ApacheHttp.kt b/buildSrc/src/main/kotlin/io/spine/dependency/lib/ApacheHttp.kt similarity index 88% rename from buildSrc/src/main/kotlin/io/spine/internal/dependency/ApacheHttp.kt rename to buildSrc/src/main/kotlin/io/spine/dependency/lib/ApacheHttp.kt index dd518a0..f3eff5e 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/dependency/ApacheHttp.kt +++ b/buildSrc/src/main/kotlin/io/spine/dependency/lib/ApacheHttp.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,9 +24,9 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.dependency +package io.spine.dependency.lib -@Suppress("unused") +@Suppress("unused", "ConstPropertyName") object ApacheHttp { // https://hc.apache.org/downloads.cgi diff --git a/buildSrc/src/main/kotlin/io/spine/internal/dependency/AppEngine.kt b/buildSrc/src/main/kotlin/io/spine/dependency/lib/AppEngine.kt similarity index 84% rename from buildSrc/src/main/kotlin/io/spine/internal/dependency/AppEngine.kt rename to buildSrc/src/main/kotlin/io/spine/dependency/lib/AppEngine.kt index 0d7fee3..b4e7336 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/dependency/AppEngine.kt +++ b/buildSrc/src/main/kotlin/io/spine/dependency/lib/AppEngine.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,16 +24,16 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.dependency +package io.spine.dependency.lib // https://cloud.google.com/java/docs/reference -@Suppress("unused") +@Suppress("unused", "ConstPropertyName") object AppEngine { private const val version = "1.9.82" - const val sdk = "com.google.appengine:appengine-api-1.0-sdk:${version}" + const val sdk = "com.google.appengine:appengine-api-1.0-sdk:$version" object GradlePlugin { private const val version = "2.2.0" - const val lib = "com.google.cloud.tools:appengine-gradle-plugin:${version}" + const val lib = "com.google.cloud.tools:appengine-gradle-plugin:$version" } } diff --git a/buildSrc/src/main/kotlin/io/spine/dependency/lib/Asm.kt b/buildSrc/src/main/kotlin/io/spine/dependency/lib/Asm.kt new file mode 100644 index 0000000..0a388c9 --- /dev/null +++ b/buildSrc/src/main/kotlin/io/spine/dependency/lib/Asm.kt @@ -0,0 +1,43 @@ +/* + * Copyright 2025, TeamDev. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package io.spine.dependency.lib + +// https://asm.ow2.io/ +@Suppress("unused", "ConstPropertyName") +object Asm { + private const val version = "9.6" + const val group = "org.ow2.asm" + const val lib = "$group:asm:$version" + + // We use the following artifacts only to force the versions + // of the dependencies which are transitive for us. + // + const val tree = "$group:asm-tree:$version" + const val analysis = "$group:asm-analysis:$version" + const val util = "$group:asm-util:$version" + const val commons = "$group:asm-commons:$version" +} diff --git a/buildSrc/src/main/kotlin/io/spine/dependency/lib/Auto.kt b/buildSrc/src/main/kotlin/io/spine/dependency/lib/Auto.kt new file mode 100644 index 0000000..6c222b9 --- /dev/null +++ b/buildSrc/src/main/kotlin/io/spine/dependency/lib/Auto.kt @@ -0,0 +1,55 @@ +/* + * Copyright 2025, TeamDev. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +@file:Suppress("unused", "ConstPropertyName") + +package io.spine.dependency.lib + +// https://github.com/google/auto +object AutoCommon { + private const val version = "1.2.2" + const val lib = "com.google.auto:auto-common:$version" +} + +// https://github.com/google/auto +object AutoService { + private const val version = "1.1.1" + const val annotations = "com.google.auto.service:auto-service-annotations:$version" + @Suppress("unused") + const val processor = "com.google.auto.service:auto-service:$version" +} + +// https://github.com/google/auto +object AutoValue { + private const val version = "1.10.2" + const val annotations = "com.google.auto.value:auto-value-annotations:$version" +} + +// https://github.com/ZacSweers/auto-service-ksp +object AutoServiceKsp { + private const val version = "1.2.0" + const val processor = "dev.zacsweers.autoservice:auto-service-ksp:$version" +} diff --git a/buildSrc/src/main/kotlin/io/spine/internal/dependency/BouncyCastle.kt b/buildSrc/src/main/kotlin/io/spine/dependency/lib/BouncyCastle.kt similarity index 88% rename from buildSrc/src/main/kotlin/io/spine/internal/dependency/BouncyCastle.kt rename to buildSrc/src/main/kotlin/io/spine/dependency/lib/BouncyCastle.kt index c0567ed..5289d0c 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/dependency/BouncyCastle.kt +++ b/buildSrc/src/main/kotlin/io/spine/dependency/lib/BouncyCastle.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,10 +24,10 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.dependency +package io.spine.dependency.lib // https://www.bouncycastle.org/java.html -@Suppress("unused") +@Suppress("unused", "ConstPropertyName") object BouncyCastle { const val libPkcsJdk15 = "org.bouncycastle:bcpkix-jdk15on:1.68" } diff --git a/buildSrc/src/main/kotlin/io/spine/dependency/lib/Caffeine.kt b/buildSrc/src/main/kotlin/io/spine/dependency/lib/Caffeine.kt new file mode 100644 index 0000000..9b0c7c1 --- /dev/null +++ b/buildSrc/src/main/kotlin/io/spine/dependency/lib/Caffeine.kt @@ -0,0 +1,41 @@ +/* + * Copyright 2025, TeamDev. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package io.spine.dependency.lib + +/** + * A [high performance](https://github.com/ben-manes/caffeine/wiki/Benchmarks), + * [near optimal](https://github.com/ben-manes/caffeine/wiki/Efficiency) caching library. + * + * This library is a transitive dependency for us via ErrorProne. + * + * @see Caffeine at GitHub + */ +@Suppress("unused") +object Caffeine { + private const val version = "3.0.5" + const val lib = "com.github.ben-manes.caffeine:caffeine:$version" +} diff --git a/buildSrc/src/main/kotlin/io/spine/internal/dependency/CheckStyle.kt b/buildSrc/src/main/kotlin/io/spine/dependency/lib/Clikt.kt similarity index 80% rename from buildSrc/src/main/kotlin/io/spine/internal/dependency/CheckStyle.kt rename to buildSrc/src/main/kotlin/io/spine/dependency/lib/Clikt.kt index c05d2fb..3da42ce 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/dependency/CheckStyle.kt +++ b/buildSrc/src/main/kotlin/io/spine/dependency/lib/Clikt.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,11 +24,11 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.dependency +package io.spine.dependency.lib -// https://checkstyle.sourceforge.io/ -// See `io.spine.internal.gradle.checkstyle.CheckStyleConfig`. +// https://ajalt.github.io/clikt/ @Suppress("unused") -object CheckStyle { - const val version = "10.3.4" +object Clikt { + private const val version = "3.5.2" + const val lib = "com.github.ajalt.clikt:clikt:$version" } diff --git a/buildSrc/src/main/kotlin/io/spine/internal/dependency/CommonsCli.kt b/buildSrc/src/main/kotlin/io/spine/dependency/lib/CommonsCli.kt similarity index 83% rename from buildSrc/src/main/kotlin/io/spine/internal/dependency/CommonsCli.kt rename to buildSrc/src/main/kotlin/io/spine/dependency/lib/CommonsCli.kt index 79a4036..6063278 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/dependency/CommonsCli.kt +++ b/buildSrc/src/main/kotlin/io/spine/dependency/lib/CommonsCli.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,15 +24,16 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.dependency +package io.spine.dependency.lib /** * Commons CLI is a transitive dependency which we don't use directly. - * We `force` it in [DependencyResolution.forceConfiguration]. + * We `force` it in [forceVersions]. * * [Commons CLI](https://commons.apache.org/proper/commons-cli/) */ +@Suppress("unused", "ConstPropertyName") object CommonsCli { private const val version = "1.5.0" - const val lib = "commons-cli:commons-cli:${version}" + const val lib = "commons-cli:commons-cli:$version" } diff --git a/buildSrc/src/main/kotlin/io/spine/internal/dependency/CommonsCodec.kt b/buildSrc/src/main/kotlin/io/spine/dependency/lib/CommonsCodec.kt similarity index 86% rename from buildSrc/src/main/kotlin/io/spine/internal/dependency/CommonsCodec.kt rename to buildSrc/src/main/kotlin/io/spine/dependency/lib/CommonsCodec.kt index 97dbed8..270b704 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/dependency/CommonsCodec.kt +++ b/buildSrc/src/main/kotlin/io/spine/dependency/lib/CommonsCodec.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,11 +24,11 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.dependency +package io.spine.dependency.lib // https://commons.apache.org/proper/commons-codec/changes-report.html -@Suppress("unused") +@Suppress("unused", "ConstPropertyName") object CommonsCodec { - private const val version = "1.15" + private const val version = "1.16.0" const val lib = "commons-codec:commons-codec:$version" } diff --git a/buildSrc/src/main/kotlin/io/spine/internal/dependency/CommonsLogging.kt b/buildSrc/src/main/kotlin/io/spine/dependency/lib/CommonsLogging.kt similarity index 80% rename from buildSrc/src/main/kotlin/io/spine/internal/dependency/CommonsLogging.kt rename to buildSrc/src/main/kotlin/io/spine/dependency/lib/CommonsLogging.kt index e9d148f..9f1139c 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/dependency/CommonsLogging.kt +++ b/buildSrc/src/main/kotlin/io/spine/dependency/lib/CommonsLogging.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,14 +24,15 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.dependency +package io.spine.dependency.lib /** * [Commons Logging](https://commons.apache.org/proper/commons-logging/) is a transitive - * dependency which we don't use directly. This object is used for forcing the version. + * dependency, which we don't use directly. This object is used for forcing the version. */ +@Suppress("unused", "ConstPropertyName") object CommonsLogging { // https://commons.apache.org/proper/commons-logging/ private const val version = "1.2" - const val lib = "commons-logging:commons-logging:${version}" + const val lib = "commons-logging:commons-logging:$version" } diff --git a/buildSrc/src/main/kotlin/io/spine/dependency/lib/Coroutines.kt b/buildSrc/src/main/kotlin/io/spine/dependency/lib/Coroutines.kt new file mode 100644 index 0000000..07c43f0 --- /dev/null +++ b/buildSrc/src/main/kotlin/io/spine/dependency/lib/Coroutines.kt @@ -0,0 +1,45 @@ +/* + * Copyright 2025, TeamDev. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package io.spine.dependency.lib + +/** + * Kotlin Coroutines. + * + * @see GitHub projecet + */ +@Suppress("unused") +object Coroutines { + const val group = "org.jetbrains.kotlinx" + const val version = "1.10.1" + const val bom = "$group:kotlinx-coroutines-bom:$version" + const val core = "$group:kotlinx-coroutines-core:$version" + const val coreJvm = "$group:kotlinx-coroutines-core-jvm:$version" + const val jdk8 = "$group:kotlinx-coroutines-jdk8:$version" + const val debug = "$group:kotlinx-coroutines-debug:$version" + const val test = "$group:kotlinx-coroutines-test:$version" + const val testJvm = "$group:kotlinx-coroutines-test-jvm:$version" +} diff --git a/buildSrc/src/main/kotlin/io/spine/internal/dependency/Firebase.kt b/buildSrc/src/main/kotlin/io/spine/dependency/lib/Firebase.kt similarity index 83% rename from buildSrc/src/main/kotlin/io/spine/internal/dependency/Firebase.kt rename to buildSrc/src/main/kotlin/io/spine/dependency/lib/Firebase.kt index 5e471ca..1d798ee 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/dependency/Firebase.kt +++ b/buildSrc/src/main/kotlin/io/spine/dependency/lib/Firebase.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,11 +24,11 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.dependency +package io.spine.dependency.lib // https://firebase.google.com/docs/admin/setup#java -@Suppress("unused") +@Suppress("unused", "ConstPropertyName") object Firebase { private const val adminVersion = "8.1.0" - const val admin = "com.google.firebase:firebase-admin:${adminVersion}" + const val admin = "com.google.firebase:firebase-admin:$adminVersion" } diff --git a/buildSrc/src/main/kotlin/io/spine/internal/dependency/Flogger.kt b/buildSrc/src/main/kotlin/io/spine/dependency/lib/Flogger.kt similarity index 70% rename from buildSrc/src/main/kotlin/io/spine/internal/dependency/Flogger.kt rename to buildSrc/src/main/kotlin/io/spine/dependency/lib/Flogger.kt index 4332178..769c905 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/dependency/Flogger.kt +++ b/buildSrc/src/main/kotlin/io/spine/dependency/lib/Flogger.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,16 +24,19 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.dependency +package io.spine.dependency.lib // https://github.com/google/flogger +@Deprecated("Please use Spine Logging library instead.") +@Suppress("unused", "ConstPropertyName") object Flogger { internal const val version = "0.7.4" - const val lib = "com.google.flogger:flogger:${version}" - @Suppress("unused") + const val lib = "com.google.flogger:flogger:$version" + object Runtime { - const val systemBackend = "com.google.flogger:flogger-system-backend:${version}" - const val log4J = "com.google.flogger:flogger-log4j:${version}" - const val slf4J = "com.google.flogger:slf4j-backend-factory:${version}" + const val systemBackend = "com.google.flogger:flogger-system-backend:$version" + const val log4j2Backend = "com.google.flogger:flogger-log4j2-backend:$version" + const val slf4JBackend = "com.google.flogger:flogger-slf4j-backend:$version" + const val grpcContext = "com.google.flogger:flogger-grpc-context:$version" } } diff --git a/buildSrc/src/main/kotlin/io/spine/internal/dependency/GoogleApis.kt b/buildSrc/src/main/kotlin/io/spine/dependency/lib/GoogleApis.kt similarity index 91% rename from buildSrc/src/main/kotlin/io/spine/internal/dependency/GoogleApis.kt rename to buildSrc/src/main/kotlin/io/spine/dependency/lib/GoogleApis.kt index af663dc..7fd3340 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/dependency/GoogleApis.kt +++ b/buildSrc/src/main/kotlin/io/spine/dependency/lib/GoogleApis.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,12 +24,12 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.dependency +package io.spine.dependency.lib /** * Provides dependencies on [GoogleApis projects](https://github.com/googleapis/). */ -@Suppress("unused") +@Suppress("unused", "ConstPropertyName") object GoogleApis { // https://github.com/googleapis/google-api-java-client @@ -53,7 +53,7 @@ object GoogleApis { // https://github.com/googleapis/google-auth-library-java object AuthLibrary { const val version = "1.3.0" - const val credentials = "com.google.auth:google-auth-library-credentials:${version}" - const val oAuth2Http = "com.google.auth:google-auth-library-oauth2-http:${version}" + const val credentials = "com.google.auth:google-auth-library-credentials:$version" + const val oAuth2Http = "com.google.auth:google-auth-library-oauth2-http:$version" } } diff --git a/buildSrc/src/main/kotlin/io/spine/internal/dependency/GoogleCloud.kt b/buildSrc/src/main/kotlin/io/spine/dependency/lib/GoogleCloud.kt similarity index 90% rename from buildSrc/src/main/kotlin/io/spine/internal/dependency/GoogleCloud.kt rename to buildSrc/src/main/kotlin/io/spine/dependency/lib/GoogleCloud.kt index a764af2..b755168 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/dependency/GoogleCloud.kt +++ b/buildSrc/src/main/kotlin/io/spine/dependency/lib/GoogleCloud.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,9 +24,9 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.dependency +package io.spine.dependency.lib -@Suppress("unused") +@Suppress("unused", "ConstPropertyName") object GoogleCloud { // https://github.com/googleapis/java-core diff --git a/buildSrc/src/main/kotlin/io/spine/internal/dependency/Grpc.kt b/buildSrc/src/main/kotlin/io/spine/dependency/lib/Grpc.kt similarity index 54% rename from buildSrc/src/main/kotlin/io/spine/internal/dependency/Grpc.kt rename to buildSrc/src/main/kotlin/io/spine/dependency/lib/Grpc.kt index 9544d45..011b4d2 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/dependency/Grpc.kt +++ b/buildSrc/src/main/kotlin/io/spine/dependency/lib/Grpc.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,22 +24,28 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.dependency +package io.spine.dependency.lib // https://github.com/grpc/grpc-java -@Suppress("unused") +@Suppress("unused", "ConstPropertyName") object Grpc { @Suppress("MemberVisibilityCanBePrivate") - const val version = "1.46.0" - const val api = "io.grpc:grpc-api:${version}" - const val auth = "io.grpc:grpc-auth:${version}" - const val core = "io.grpc:grpc-core:${version}" - const val context = "io.grpc:grpc-context:${version}" - const val stub = "io.grpc:grpc-stub:${version}" - const val okHttp = "io.grpc:grpc-okhttp:${version}" - const val protobuf = "io.grpc:grpc-protobuf:${version}" - const val protobufLite = "io.grpc:grpc-protobuf-lite:${version}" - const val protobufPlugin = "io.grpc:protoc-gen-grpc-java:${version}" - const val netty = "io.grpc:grpc-netty:${version}" - const val nettyShaded = "io.grpc:grpc-netty-shaded:${version}" + const val version = "1.59.0" + const val group = "io.grpc" + const val api = "$group:grpc-api:$version" + const val auth = "$group:grpc-auth:$version" + const val core = "$group:grpc-core:$version" + const val context = "$group:grpc-context:$version" + const val inProcess = "$group:grpc-inprocess:$version" + const val stub = "$group:grpc-stub:$version" + const val okHttp = "$group:grpc-okhttp:$version" + const val protobuf = "$group:grpc-protobuf:$version" + const val protobufLite = "$group:grpc-protobuf-lite:$version" + const val netty = "$group:grpc-netty:$version" + const val nettyShaded = "$group:grpc-netty-shaded:$version" + + object ProtocPlugin { + const val id = "grpc" + const val artifact = "$group:protoc-gen-grpc-java:$version" + } } diff --git a/buildSrc/src/main/kotlin/io/spine/dependency/lib/GrpcKotlin.kt b/buildSrc/src/main/kotlin/io/spine/dependency/lib/GrpcKotlin.kt new file mode 100644 index 0000000..e695f6f --- /dev/null +++ b/buildSrc/src/main/kotlin/io/spine/dependency/lib/GrpcKotlin.kt @@ -0,0 +1,43 @@ +/* + * Copyright 2025, TeamDev. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package io.spine.dependency.lib + +/** + * gRPC-Kotlin/JVM. + * + * @see GitHub project + */ +@Suppress("unused") +object GrpcKotlin { + const val version = "1.3.0" + const val stub = "io.grpc:grpc-kotlin-stub:$version" + + object ProtocPlugin { + const val id = "grpckt" + const val artifact = "io.grpc:protoc-gen-grpc-kotlin:$version:jdk8@jar" + } +} diff --git a/buildSrc/src/main/kotlin/io/spine/internal/dependency/Gson.kt b/buildSrc/src/main/kotlin/io/spine/dependency/lib/Gson.kt similarity index 79% rename from buildSrc/src/main/kotlin/io/spine/internal/dependency/Gson.kt rename to buildSrc/src/main/kotlin/io/spine/dependency/lib/Gson.kt index e161ee1..229c434 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/dependency/Gson.kt +++ b/buildSrc/src/main/kotlin/io/spine/dependency/lib/Gson.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,15 +24,16 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.dependency +package io.spine.dependency.lib /** - * Gson is a transitive dependency which we don't use directly. + * Gson is a transitive dependency, which we don't use directly. * We `force` it in [DependencyResolution.forceConfiguration()]. * * [Gson](https://github.com/google/gson) */ +@Suppress("unused", "ConstPropertyName") object Gson { - private const val version = "2.9.0" - const val lib = "com.google.code.gson:gson:${version}" + private const val version = "2.10.1" + const val lib = "com.google.code.gson:gson:$version" } diff --git a/buildSrc/src/main/kotlin/io/spine/internal/dependency/Guava.kt b/buildSrc/src/main/kotlin/io/spine/dependency/lib/Guava.kt similarity index 77% rename from buildSrc/src/main/kotlin/io/spine/internal/dependency/Guava.kt rename to buildSrc/src/main/kotlin/io/spine/dependency/lib/Guava.kt index faaf3b8..5ea5fcc 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/dependency/Guava.kt +++ b/buildSrc/src/main/kotlin/io/spine/dependency/lib/Guava.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,7 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.dependency +package io.spine.dependency.lib /** * The dependencies for Guava. @@ -32,10 +32,13 @@ package io.spine.internal.dependency * When changing the version, also change the version used in the `build.gradle.kts`. We need * to synchronize the version used in `buildSrc` and in Spine modules. Otherwise, when testing * Gradle plugins, errors may occur due to version clashes. + * + * @see Guava at GitHub. */ -// https://github.com/google/guava +@Suppress("unused", "ConstPropertyName") object Guava { - private const val version = "31.1-jre" - const val lib = "com.google.guava:guava:${version}" - const val testLib = "com.google.guava:guava-testlib:${version}" + private const val version = "32.1.3-jre" + const val group = "com.google.guava" + const val lib = "$group:guava:$version" + const val testLib = "$group:guava-testlib:$version" } diff --git a/buildSrc/src/main/kotlin/io/spine/internal/dependency/HttpClient.kt b/buildSrc/src/main/kotlin/io/spine/dependency/lib/HttpClient.kt similarity index 85% rename from buildSrc/src/main/kotlin/io/spine/internal/dependency/HttpClient.kt rename to buildSrc/src/main/kotlin/io/spine/dependency/lib/HttpClient.kt index 849f1f4..526f05f 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/dependency/HttpClient.kt +++ b/buildSrc/src/main/kotlin/io/spine/dependency/lib/HttpClient.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,19 +24,19 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.dependency +package io.spine.dependency.lib /** * Google implementations of [HTTP client](https://github.com/googleapis/google-http-java-client). */ -@Suppress("unused") +@Suppress("unused", "ConstPropertyName") object HttpClient { // https://github.com/googleapis/google-http-java-client - const val version = "1.41.5" - const val google = "com.google.http-client:google-http-client:${version}" - const val jackson2 = "com.google.http-client:google-http-client-jackson2:${version}" - const val gson = "com.google.http-client:google-http-client-gson:${version}" - const val apache2 = "com.google.http-client:google-http-client-apache-v2:${version}" + const val version = "1.43.3" + const val google = "com.google.http-client:google-http-client:$version" + const val jackson2 = "com.google.http-client:google-http-client-jackson2:$version" + const val gson = "com.google.http-client:google-http-client-gson:$version" + const val apache2 = "com.google.http-client:google-http-client-apache-v2:$version" const val apache = "com.google.http-client:google-http-client-apache:2.1.2" } diff --git a/buildSrc/src/main/kotlin/io/spine/dependency/lib/IntelliJ.kt b/buildSrc/src/main/kotlin/io/spine/dependency/lib/IntelliJ.kt new file mode 100644 index 0000000..7f9232b --- /dev/null +++ b/buildSrc/src/main/kotlin/io/spine/dependency/lib/IntelliJ.kt @@ -0,0 +1,89 @@ +/* + * Copyright 2025, TeamDev. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +@file:Suppress("ConstPropertyName") + +package io.spine.dependency.lib + +/** + * The components of the IntelliJ Platform. + * + * Make sure to add the `intellijReleases` and `jetBrainsCacheRedirector` + * repositories to your project. See `kotlin/Repositories.kt` for details. + */ +@Suppress("unused") +object IntelliJ { + + /** + * The version of the IntelliJ platform. + * + * This is the version used by Kotlin compiler `1.9.21`. + * Advance this version with caution because it may break the setup of + * IntelliJ platform standalone execution. + */ + const val version = "213.7172.53" + + object Platform { + private const val group = "com.jetbrains.intellij.platform" + const val core = "$group:core:$version" + const val util = "$group:util:$version" + const val coreImpl = "$group:core-impl:$version" + const val codeStyle = "$group:code-style:$version" + const val codeStyleImpl = "$group:code-style-impl:$version" + const val projectModel = "$group:project-model:$version" + const val projectModelImpl = "$group:project-model-impl:$version" + const val lang = "$group:lang:$version" + const val langImpl = "$group:lang-impl:$version" + const val ideImpl = "$group:ide-impl:$version" + const val ideCoreImpl = "$group:ide-core-impl:$version" + const val analysisImpl = "$group:analysis-impl:$version" + const val indexingImpl = "$group:indexing-impl:$version" + } + + object Jsp { + private const val group = "com.jetbrains.intellij.jsp" + @Suppress("MemberNameEqualsClassName") + const val jsp = "$group:jsp:$version" + } + + object Xml { + private const val group = "com.jetbrains.intellij.xml" + const val xmlPsiImpl = "$group:xml-psi-impl:$version" + } + + object JavaPsi { + private const val group = "com.jetbrains.intellij.java" + const val api = "$group:java-psi:$version" + const val impl = "$group:java-psi-impl:$version" + } + + object Java { + private const val group = "com.jetbrains.intellij.java" + @Suppress("MemberNameEqualsClassName") + const val java = "$group:java:$version" + const val impl = "$group:java-impl:$version" + } +} diff --git a/buildSrc/src/main/kotlin/io/spine/internal/dependency/J2ObjC.kt b/buildSrc/src/main/kotlin/io/spine/dependency/lib/J2ObjC.kt similarity index 66% rename from buildSrc/src/main/kotlin/io/spine/internal/dependency/J2ObjC.kt rename to buildSrc/src/main/kotlin/io/spine/dependency/lib/J2ObjC.kt index 9ed18f2..3098466 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/dependency/J2ObjC.kt +++ b/buildSrc/src/main/kotlin/io/spine/dependency/lib/J2ObjC.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,18 +24,28 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.dependency +package io.spine.dependency.lib /** - * [J2ObjC](https://developers.google.com/j2objc) is a transitive dependency + * [J2ObjC](https://developers.google.com/j2objc) is a transitive dependency, * which we don't use directly. This object is used for forcing the version. */ +@Suppress("unused", "ConstPropertyName") object J2ObjC { - // https://github.com/google/j2objc/releases - // `1.3.` is the latest version available from Maven Central. - // https://search.maven.org/artifact/com.google.j2objc/j2objc-annotations - private const val version = "1.3" - const val annotations = "com.google.j2objc:j2objc-annotations:${version}" + /** + * See [J2ObjC releases](https://github.com/google/j2objc/releases). + * + * `1.3` was the latest version available from Maven Central. + * Now `2.8` is the latest version available. + * As [HttpClient] + * [migrated](https://github.com/googleapis/google-http-java-client/releases/tag/v1.43.3) to v2, + * we set the latest v2 version as well. + * + * @see + * J2ObjC on Maven Central + */ + private const val version = "2.8" + const val annotations = "com.google.j2objc:j2objc-annotations:$version" @Deprecated("Please use `annotations` instead.", ReplaceWith("annotations")) const val lib = annotations } diff --git a/buildSrc/src/main/kotlin/io/spine/internal/dependency/Jackson.kt b/buildSrc/src/main/kotlin/io/spine/dependency/lib/Jackson.kt similarity index 69% rename from buildSrc/src/main/kotlin/io/spine/internal/dependency/Jackson.kt rename to buildSrc/src/main/kotlin/io/spine/dependency/lib/Jackson.kt index 2ed3df8..4b78c8f 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/dependency/Jackson.kt +++ b/buildSrc/src/main/kotlin/io/spine/dependency/lib/Jackson.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,32 +24,40 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.dependency +package io.spine.dependency.lib -@Suppress("unused") +// https://github.com/FasterXML/jackson/wiki/Jackson-Releases +@Suppress("unused", "ConstPropertyName") object Jackson { - const val version = "2.13.4" - private const val databindVersion = "2.13.4.2" + const val version = "2.15.3" + private const val databindVersion = "2.15.3" private const val coreGroup = "com.fasterxml.jackson.core" private const val dataformatGroup = "com.fasterxml.jackson.dataformat" private const val moduleGroup = "com.fasterxml.jackson.module" // https://github.com/FasterXML/jackson-core - const val core = "$coreGroup:jackson-core:${version}" + const val core = "$coreGroup:jackson-core:$version" // https://github.com/FasterXML/jackson-databind - const val databind = "$coreGroup:jackson-databind:${databindVersion}" + const val databind = "$coreGroup:jackson-databind:$databindVersion" // https://github.com/FasterXML/jackson-annotations - const val annotations = "$coreGroup:jackson-annotations:${version}" + const val annotations = "$coreGroup:jackson-annotations:$version" // https://github.com/FasterXML/jackson-dataformat-xml/releases - const val dataformatXml = "$dataformatGroup:jackson-dataformat-xml:${version}" + const val dataformatXml = "$dataformatGroup:jackson-dataformat-xml:$version" // https://github.com/FasterXML/jackson-dataformats-text/releases - const val dataformatYaml = "$dataformatGroup:jackson-dataformat-yaml:${version}" + const val dataformatYaml = "$dataformatGroup:jackson-dataformat-yaml:$version" // https://github.com/FasterXML/jackson-module-kotlin/releases - const val moduleKotlin = "$moduleGroup:jackson-module-kotlin:${version}" + const val moduleKotlin = "$moduleGroup:jackson-module-kotlin:$version" // https://github.com/FasterXML/jackson-bom - const val bom = "com.fasterxml.jackson:jackson-bom:${version}" + const val bom = "com.fasterxml.jackson:jackson-bom:$version" + + // https://github.com/FasterXML/jackson-jr + object Junior { + const val version = Jackson.version + const val group = "com.fasterxml.jackson.jr" + const val objects = "$group:jackson-jr-objects:$version" + } } diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/publish/DokkaJar.kt b/buildSrc/src/main/kotlin/io/spine/dependency/lib/JavaDiffUtils.kt similarity index 66% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/publish/DokkaJar.kt rename to buildSrc/src/main/kotlin/io/spine/dependency/lib/JavaDiffUtils.kt index 1ddd1fb..7cc2e59 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/publish/DokkaJar.kt +++ b/buildSrc/src/main/kotlin/io/spine/dependency/lib/JavaDiffUtils.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,20 +24,19 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.publish +package io.spine.dependency.lib /** - * A DSL element of [SpinePublishing] extension which configures publishing of [dokkaJar] artifact. + * The dependency on the `java-diff-utils` library, which is transitive for us at the time + * of writing. * - * This artifact contains Dokka-generated documentation. By default, it is not published. - * - * Take a look at the [SpinePublishing.dokkaJar] for a usage example. - * - * @see [registerArtifacts] + * It might become our dependency as a part of + * the [Spine Text](https://github.com/SpineEventEngine/text) library. */ -class DokkaJar { - /** - * Enables publishing `JAR`s with Dokka-generated documentation for all published modules. - */ - var enabled = false +@Suppress("unused", "ConstPropertyName") +object JavaDiffUtils { + + // https://github.com/java-diff-utils/java-diff-utils/releases + private const val version = "4.12" + const val lib = "io.github.java-diff-utils:java-diff-utils:$version" } diff --git a/buildSrc/src/main/kotlin/io/spine/dependency/lib/JavaJwt.kt b/buildSrc/src/main/kotlin/io/spine/dependency/lib/JavaJwt.kt new file mode 100644 index 0000000..4d9b1df --- /dev/null +++ b/buildSrc/src/main/kotlin/io/spine/dependency/lib/JavaJwt.kt @@ -0,0 +1,46 @@ +/* + * Copyright 2025, TeamDev. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package io.spine.dependency.lib + +/** + * A Java implementation of JSON Web Token (JWT) - RFC 7519. + * + * [Java JWT](https://github.com/auth0/java-jwt) + */ +@Suppress("unused", "ConstPropertyName") +object JavaJwt { + + /** + * The last version in the v3.x.x series. + * + * There's a v4.x.x series (e.g., https://github.com/auth0/java-jwt/releases/tag/4.4.0), but + * it introduces breaking changes. Consider upgrading to it when we're ready to migrate. + */ + private const val version = "3.19.4" + + const val lib = "com.auth0:java-jwt:$version" +} diff --git a/buildSrc/src/main/kotlin/io/spine/internal/dependency/JavaPoet.kt b/buildSrc/src/main/kotlin/io/spine/dependency/lib/JavaPoet.kt similarity index 79% rename from buildSrc/src/main/kotlin/io/spine/internal/dependency/JavaPoet.kt rename to buildSrc/src/main/kotlin/io/spine/dependency/lib/JavaPoet.kt index e9bdb9b..b99e503 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/dependency/JavaPoet.kt +++ b/buildSrc/src/main/kotlin/io/spine/dependency/lib/JavaPoet.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,11 +24,14 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.dependency +package io.spine.dependency.lib // https://github.com/square/javapoet -@Suppress("unused") +@Suppress("unused", "ConstPropertyName") object JavaPoet { private const val version = "1.13.0" - const val lib = "com.squareup:javapoet:${version}" + const val group = "com.squareup" + const val artifact = "javapoet" + const val module = "$group:$artifact" + const val lib = "$module:$version" } diff --git a/buildSrc/src/main/kotlin/io/spine/internal/dependency/JavaX.kt b/buildSrc/src/main/kotlin/io/spine/dependency/lib/JavaX.kt similarity index 77% rename from buildSrc/src/main/kotlin/io/spine/internal/dependency/JavaX.kt rename to buildSrc/src/main/kotlin/io/spine/dependency/lib/JavaX.kt index 9fb7bd5..7ea8cdf 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/dependency/JavaX.kt +++ b/buildSrc/src/main/kotlin/io/spine/dependency/lib/JavaX.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,13 +24,14 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.dependency +package io.spine.dependency.lib -@Suppress("unused") +@Suppress("unused", "ConstPropertyName") object JavaX { - // This artifact which used to be a part of J2EE moved under Eclipse EE4J project. + // This artifact, which used to be a part of J2EE, moved under the Eclipse EE4J project. // https://github.com/eclipse-ee4j/common-annotations-api - const val annotations = "javax.annotation:javax.annotation-api:1.3.2" + const val annotationGroup = "javax.annotation" + const val annotations = "$annotationGroup:javax.annotation-api:1.3.2" const val servletApi = "javax.servlet:javax.servlet-api:3.1.0" } diff --git a/buildSrc/src/main/kotlin/io/spine/internal/dependency/Klaxon.kt b/buildSrc/src/main/kotlin/io/spine/dependency/lib/Klaxon.kt similarity index 83% rename from buildSrc/src/main/kotlin/io/spine/internal/dependency/Klaxon.kt rename to buildSrc/src/main/kotlin/io/spine/dependency/lib/Klaxon.kt index 160fdbf..69089c6 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/dependency/Klaxon.kt +++ b/buildSrc/src/main/kotlin/io/spine/dependency/lib/Klaxon.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,14 +24,15 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.dependency +package io.spine.dependency.lib /** - * A JSON parser in Kotlin + * A JSON parser in Kotlin. * * [Klaxon](https://github.com/cbeust/klaxon) */ +@Suppress("unused", "ConstPropertyName") object Klaxon { private const val version = "5.6" - const val lib = "com.beust:klaxon:${version}" + const val lib = "com.beust:klaxon:$version" } diff --git a/buildSrc/src/main/kotlin/io/spine/dependency/lib/Kotlin.kt b/buildSrc/src/main/kotlin/io/spine/dependency/lib/Kotlin.kt new file mode 100644 index 0000000..ba24aaa --- /dev/null +++ b/buildSrc/src/main/kotlin/io/spine/dependency/lib/Kotlin.kt @@ -0,0 +1,90 @@ +/* + * Copyright 2025, TeamDev. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package io.spine.dependency.lib + +// https://github.com/JetBrains/kotlin +// https://github.com/Kotlin +@Suppress("unused", "ConstPropertyName") +object Kotlin { + + /** + * This is the version of Kotlin we use for writing code which does not + * depend on Gradle and the version of embedded Kotlin. + */ + @Suppress("MemberVisibilityCanBePrivate") // used directly from the outside. + const val runtimeVersion = "2.1.20" + + /** + * This is the version of + * [Kotlin embedded into Gradle](https://docs.gradle.org/current/userguide/compatibility.html#kotlin). + */ + const val embeddedVersion = "2.0.21" + + /** + * The version of the JetBrains annotations library, which is a transitive + * dependency for us via Kotlin libraries. + * + * @see Java Annotations + */ + private const val annotationsVersion = "26.0.2" + + private const val group = "org.jetbrains.kotlin" + + const val scriptRuntime = "$group:kotlin-script-runtime:$runtimeVersion" + const val stdLib = "$group:kotlin-stdlib:$runtimeVersion" + const val stdLibCommon = "$group:kotlin-stdlib-common:$runtimeVersion" + + const val toolingCore = "$group:kotlin-tooling-core:$runtimeVersion" + + @Deprecated("Please use `stdLib` instead.") + const val stdLibJdk7 = "$group:kotlin-stdlib-jdk7:$runtimeVersion" + + @Deprecated("Please use `stdLib` instead.") + const val stdLibJdk8 = "$group:kotlin-stdlib-jdk8:$runtimeVersion" + + const val reflect = "$group:kotlin-reflect:$runtimeVersion" + const val testJUnit5 = "$group:kotlin-test-junit5:$runtimeVersion" + + @Deprecated(message = "Please use `GradlePlugin.api` instead.", ReplaceWith("GradlePlugin.api")) + const val gradlePluginApi = "$group:kotlin-gradle-plugin-api:$runtimeVersion" + + @Deprecated(message = "Please use `GradlePlugin.lib` instead.", ReplaceWith("GradlePlugin.lib")) + const val gradlePluginLib = "$group:kotlin-gradle-plugin:$runtimeVersion" + + const val jetbrainsAnnotations = "org.jetbrains:annotations:$annotationsVersion" + + object Compiler { + const val embeddable = "$group:kotlin-compiler-embeddable:$runtimeVersion" + } + + object GradlePlugin { + const val version = runtimeVersion + const val api = "$group:kotlin-gradle-plugin-api:$version" + const val lib = "$group:kotlin-gradle-plugin:$version" + const val model = "$group:kotlin-gradle-model:$version" + } +} diff --git a/buildSrc/src/main/kotlin/io/spine/internal/dependency/AutoValue.kt b/buildSrc/src/main/kotlin/io/spine/dependency/lib/KotlinPoet.kt similarity index 75% rename from buildSrc/src/main/kotlin/io/spine/internal/dependency/AutoValue.kt rename to buildSrc/src/main/kotlin/io/spine/dependency/lib/KotlinPoet.kt index 5b630bf..346c5d8 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/dependency/AutoValue.kt +++ b/buildSrc/src/main/kotlin/io/spine/dependency/lib/KotlinPoet.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,10 +24,12 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.dependency +package io.spine.dependency.lib -// https://github.com/google/auto -object AutoValue { - private const val version = "1.9" - const val annotations = "com.google.auto.value:auto-value-annotations:${version}" +// https://github.com/square/kotlinpoet +@Suppress("unused", "ConstPropertyName") +object KotlinPoet { + private const val version = "2.0.0" + const val lib = "com.squareup:kotlinpoet:$version" + const val ksp = "com.squareup:kotlinpoet-ksp:$version" } diff --git a/buildSrc/src/main/kotlin/io/spine/internal/dependency/KotlinSemver.kt b/buildSrc/src/main/kotlin/io/spine/dependency/lib/KotlinSemver.kt similarity index 85% rename from buildSrc/src/main/kotlin/io/spine/internal/dependency/KotlinSemver.kt rename to buildSrc/src/main/kotlin/io/spine/dependency/lib/KotlinSemver.kt index 47fd7de..1525360 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/dependency/KotlinSemver.kt +++ b/buildSrc/src/main/kotlin/io/spine/dependency/lib/KotlinSemver.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,11 +24,11 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.dependency +package io.spine.dependency.lib // https://github.com/z4kn4fein/kotlin-semver -@Suppress("unused") +@Suppress("unused", "ConstPropertyName") object KotlinSemver { - private const val version = "1.2.1" + private const val version = "1.4.2" const val lib = "io.github.z4kn4fein:semver:$version" } diff --git a/buildSrc/src/main/kotlin/io/spine/dependency/lib/KotlinX.kt b/buildSrc/src/main/kotlin/io/spine/dependency/lib/KotlinX.kt new file mode 100644 index 0000000..fc909af --- /dev/null +++ b/buildSrc/src/main/kotlin/io/spine/dependency/lib/KotlinX.kt @@ -0,0 +1,48 @@ +/* + * Copyright 2025, TeamDev. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package io.spine.dependency.lib + +@Suppress("unused", "ConstPropertyName") +object KotlinX { + + const val group = "org.jetbrains.kotlinx" + + @Deprecated( + message = "Pleaser use top level object `Coroutines` instead.", + ReplaceWith("Coroutines") + ) + object Coroutines { + + // https://github.com/Kotlin/kotlinx.coroutines + const val version = "1.10.1" + const val bom = "$group:kotlinx-coroutines-bom:$version" + const val core = "$group:kotlinx-coroutines-core:$version" + const val coreJvm = "$group:kotlinx-coroutines-core-jvm:$version" + const val jdk8 = "$group:kotlinx-coroutines-jdk8:$version" + const val test = "$group:kotlinx-coroutines-test:$version" + } +} diff --git a/buildSrc/src/main/kotlin/io/spine/dependency/lib/Log4j2.kt b/buildSrc/src/main/kotlin/io/spine/dependency/lib/Log4j2.kt new file mode 100644 index 0000000..d4f2bd2 --- /dev/null +++ b/buildSrc/src/main/kotlin/io/spine/dependency/lib/Log4j2.kt @@ -0,0 +1,42 @@ +/* + * Copyright 2025, TeamDev. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package io.spine.dependency.lib + +/** + * An open-source logging framework. + * + * Spine uses its own [logging library][io.spine.dependency.local.Logging], but also + * provides a backend implementation for [Log4j2]. This is why + * this dependency is needed. + * + * @see Log4j2 releases at GitHub + */ +@Suppress("unused", "ConstPropertyName") +object Log4j2 { + private const val version = "2.20.0" + const val core = "org.apache.logging.log4j:log4j-core:$version" +} diff --git a/buildSrc/src/main/kotlin/io/spine/internal/dependency/Netty.kt b/buildSrc/src/main/kotlin/io/spine/dependency/lib/Netty.kt similarity index 67% rename from buildSrc/src/main/kotlin/io/spine/internal/dependency/Netty.kt rename to buildSrc/src/main/kotlin/io/spine/dependency/lib/Netty.kt index dfcd80e..c317bb3 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/dependency/Netty.kt +++ b/buildSrc/src/main/kotlin/io/spine/dependency/lib/Netty.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,15 +24,15 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.dependency +package io.spine.dependency.lib -@Suppress("unused") +@Suppress("unused", "ConstPropertyName") object Netty { - // https://github.com/netty/netty/releases - private const val version = "4.1.72.Final" - const val common = "io.netty:netty-common:${version}" - const val buffer = "io.netty:netty-buffer:${version}" - const val transport = "io.netty:netty-transport:${version}" - const val handler = "io.netty:netty-handler:${version}" - const val codecHttp = "io.netty:netty-codec-http:${version}" + // https://github.com/netty/netty/tags + private const val version = "4.1.100.Final" + const val common = "io.netty:netty-common:$version" + const val buffer = "io.netty:netty-buffer:$version" + const val transport = "io.netty:netty-transport:$version" + const val handler = "io.netty:netty-handler:$version" + const val codecHttp = "io.netty:netty-codec-http:$version" } diff --git a/buildSrc/src/main/kotlin/io/spine/dependency/lib/Okio.kt b/buildSrc/src/main/kotlin/io/spine/dependency/lib/Okio.kt new file mode 100644 index 0000000..3107d76 --- /dev/null +++ b/buildSrc/src/main/kotlin/io/spine/dependency/lib/Okio.kt @@ -0,0 +1,38 @@ +/* + * Copyright 2025, TeamDev. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package io.spine.dependency.lib + +/** + * Okio is a transitive dependency, which we don't use directly. + * + * https://github.com/square/okio/tags + */ +@Suppress("unused", "ConstPropertyName") +object Okio { + private const val version = "3.6.0" + const val lib = "com.squareup.okio:okio:$version" +} diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/publish/ProtoJar.kt b/buildSrc/src/main/kotlin/io/spine/dependency/lib/Plexus.kt similarity index 62% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/publish/ProtoJar.kt rename to buildSrc/src/main/kotlin/io/spine/dependency/lib/Plexus.kt index b9ffb59..e393906 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/publish/ProtoJar.kt +++ b/buildSrc/src/main/kotlin/io/spine/dependency/lib/Plexus.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,28 +24,25 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.publish +@file:Suppress("MaxLineLength") + +package io.spine.dependency.lib /** - * A DSL element of [SpinePublishing] extension which allows disabling publishing - * of [protoJar] artifact. - * - * This artifact contains all the `.proto` definitions from `sourceSets.main.proto`. By default, - * it is published. - * - * Take a look on [SpinePublishing.protoJar] for a usage example. + * Plexus Utils is a transitive dependency, which we don't use directly. * - * @see [registerArtifacts] + * [Plexus Utils](https://github.com/codehaus-plexus/plexus-utils) */ -class ProtoJar { - - /** - * Set of modules, for which a proto JAR will not be published. - */ - var exclusions: Set = emptySet() +@Suppress("unused", "ConstPropertyName") +object Plexus { /** - * Disables proto JAR publishing for all published modules. + * This is the last version in the 3.x series. + * + * There's a major update to 4.x. + * + * @see plexus-utils-4.0.0 */ - var disabled = false + private const val version = "4.0.0" + const val utils = "org.codehaus.plexus:plexus-utils:$version" } diff --git a/buildSrc/src/main/kotlin/io/spine/internal/dependency/Protobuf.kt b/buildSrc/src/main/kotlin/io/spine/dependency/lib/Protobuf.kt similarity index 61% rename from buildSrc/src/main/kotlin/io/spine/internal/dependency/Protobuf.kt rename to buildSrc/src/main/kotlin/io/spine/dependency/lib/Protobuf.kt index bac3dc9..98ce188 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/dependency/Protobuf.kt +++ b/buildSrc/src/main/kotlin/io/spine/dependency/lib/Protobuf.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,30 +24,48 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.dependency +package io.spine.dependency.lib // https://github.com/protocolbuffers/protobuf -@Suppress("MemberVisibilityCanBePrivate") // used directly from outside +@Suppress( + "MemberVisibilityCanBePrivate" /* used directly from the outside */, + "ConstPropertyName" /* https://bit.ly/kotlin-prop-names */ +) object Protobuf { - private const val group = "com.google.protobuf" - const val version = "3.19.6" + const val group = "com.google.protobuf" + const val version = "3.25.1" + + /** + * The Java library with Protobuf data types. + */ + const val javaLib = "$group:protobuf-java:$version" + + /** + * The Java library containing proto definitions of Google Protobuf types. + */ + @Suppress("unused") + const val protoSrcLib = javaLib + + /** + * All Java and Kotlin libraries we depend on. + */ val libs = listOf( - "${group}:protobuf-java:${version}", - "${group}:protobuf-java-util:${version}", - "${group}:protobuf-kotlin:${version}" + javaLib, + "$group:protobuf-java-util:$version", + "$group:protobuf-kotlin:$version" ) - const val compiler = "${group}:protoc:${version}" + const val compiler = "$group:protoc:$version" // https://github.com/google/protobuf-gradle-plugin/releases object GradlePlugin { /** * The version of this plugin is already specified in `buildSrc/build.gradle.kts` file. - * Thus, when applying the plugin in projects build files, only the [id] should be used. + * Thus, when applying the plugin to projects build files, only the [id] should be used. * * When changing the version, also change the version used in the `build.gradle.kts`. */ - const val version = "0.8.19" + const val version = "0.9.4" const val id = "com.google.protobuf" - const val lib = "${group}:protobuf-gradle-plugin:${version}" + const val lib = "$group:protobuf-gradle-plugin:$version" } } diff --git a/buildSrc/src/main/kotlin/io/spine/internal/dependency/Roaster.kt b/buildSrc/src/main/kotlin/io/spine/dependency/lib/Roaster.kt similarity index 65% rename from buildSrc/src/main/kotlin/io/spine/internal/dependency/Roaster.kt rename to buildSrc/src/main/kotlin/io/spine/dependency/lib/Roaster.kt index 2d23706..e55420e 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/dependency/Roaster.kt +++ b/buildSrc/src/main/kotlin/io/spine/dependency/lib/Roaster.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,21 +24,22 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.dependency +package io.spine.dependency.lib // https://github.com/forge/roaster -@Suppress("unused") +@Suppress("unused", "ConstPropertyName") object Roaster { /** - * Do not advance this version further because it would break compatibility with Java 8 - * projects. Starting from the following version Roaster has a shaded version of Eclipse JFace - * built with Java 11. + * This is the last version build with Java 11. * - * Please see [this issue][https://github.com/SpineEventEngine/config/issues/220] for details. + * Starting from the version + * [2.29.0.Final](https://github.com/forge/roaster/releases/tag/2.29.0.Final), + * Roaster requires Java 17. */ - private const val version = "2.24.0.Final" + private const val version = "2.28.0.Final" - const val api = "org.jboss.forge.roaster:roaster-api:${version}" - const val jdt = "org.jboss.forge.roaster:roaster-jdt:${version}" + const val group = "org.jboss.forge.roaster" + const val api = "$group:roaster-api:$version" + const val jdt = "$group:roaster-jdt:$version" } diff --git a/buildSrc/src/main/kotlin/io/spine/internal/dependency/Slf4J.kt b/buildSrc/src/main/kotlin/io/spine/dependency/lib/Slf4J.kt similarity index 66% rename from buildSrc/src/main/kotlin/io/spine/internal/dependency/Slf4J.kt rename to buildSrc/src/main/kotlin/io/spine/dependency/lib/Slf4J.kt index 4cfa049..bd5b9df 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/dependency/Slf4J.kt +++ b/buildSrc/src/main/kotlin/io/spine/dependency/lib/Slf4J.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,18 +24,24 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.dependency +package io.spine.dependency.lib /** * Spine used to log with SLF4J. Now we use Flogger. Whenever a choice comes up, we recommend to * use the latter. * - * Some third-party libraries may clash with different versions of the library. Thus, we specify - * this version and force it via [forceConfiguration(..)][DependencyResolution.forceConfiguration]. + * The primary purpose of having this dependency object is working in combination with + * [Flogger.Runtime.slf4JBackend]. + * + * Some third-party libraries may clash with different versions of the library. + * Thus, we specify this version and force it via [forceVersions]. + * Please see `DependencyResolution.kt` for details. */ -@Deprecated("Use Flogger over SLF4J.", replaceWith = ReplaceWith("flogger")) +@Suppress("unused", "ConstPropertyName") object Slf4J { - private const val version = "1.7.30" - const val lib = "org.slf4j:slf4j-api:${version}" - const val jdk14 = "org.slf4j:slf4j-jdk14:${version}" + private const val version = "2.0.7" + const val lib = "org.slf4j:slf4j-api:$version" + const val jdk14 = "org.slf4j:slf4j-jdk14:$version" + const val reload4j = "org.slf4j:slf4j-reload4j:$version" + const val simple = "org.slf4j:slf4j-simple:$version" } diff --git a/buildSrc/src/main/kotlin/io/spine/dependency/local/ArtifactVersion.kt b/buildSrc/src/main/kotlin/io/spine/dependency/local/ArtifactVersion.kt new file mode 100644 index 0000000..77497b2 --- /dev/null +++ b/buildSrc/src/main/kotlin/io/spine/dependency/local/ArtifactVersion.kt @@ -0,0 +1,137 @@ +/* + * Copyright 2025, TeamDev. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package io.spine.dependency.local + +/** + * Versions for published Spine SDK artifacts. + */ +@Suppress("ConstPropertyName") +object ArtifactVersion { + + /** + * The version of [Spine.base]. + * + * @see spine-base + */ + @Deprecated(message = "Please use `Base.version`.", ReplaceWith("Base.version")) + const val base = Base.version + + @Suppress("unused") + @Deprecated( + message = "Please use `Base.versionForBuildScript`.", + ReplaceWith("Base.versionForBuildScript") + ) + const val baseForBuildScript = Base.versionForBuildScript + + /** + * The version of [Spine.reflect]. + * + * @see spine-reflect + */ + @Deprecated(message = "Please use `Reflect.version`.", ReplaceWith("Reflect.version")) + const val reflect = Reflect.version + + /** + * The version of [Logging]. + */ + @Deprecated(message = "Please use `Logging.version`.", ReplaceWith("Logging.version")) + const val logging = Logging.version + + /** + * The version of [Spine.testlib]. + * + * @see spine-testlib + */ + @Deprecated(message = "Please use `TestLib.version`.", ReplaceWith("TestLib.version")) + const val testlib = TestLib.version + + /** + * The version of `core-java`. + */ + @Deprecated(message = "Please use `CoreJava.version`.", ReplaceWith("CoreJava.version")) + const val core = CoreJava.version + + /** + * The version of [Spine.modelCompiler]. + * + * @see spine-model-compiler + */ + @Suppress("unused") + @Deprecated( + message = "Please use `ModelCompiler.version` instead.", + ReplaceWith("ModelCompiler.version") + ) + const val mc = ModelCompiler.version + + /** + * The version of [Spine.baseTypes]. + * + * @see spine-base-types + */ + @Deprecated(message = "Please use `BaseTypes.version`.", ReplaceWith("BaseTypes.version")) + const val baseTypes = BaseTypes.version + + /** + * The version of [Spine.time]. + * + * @see spine-time + */ + @Deprecated(message = "Please use `Time.version`.", ReplaceWith("Time.version")) + const val time = Time.version + + /** + * The version of [Spine.change]. + * + * @see spine-change + */ + @Deprecated(message = "Please use `Change.version`.", ReplaceWith("Change.version")) + const val change = Change.version + + /** + * The version of [Spine.text]. + * + * @see spine-text + */ + @Deprecated(message = "Please use `Text.version`.", ReplaceWith("Text.version")) + const val text = Text.version + + /** + * The version of [Spine.toolBase]. + * + * @see spine-tool-base + */ + @Suppress("unused") + @Deprecated(message = "Please use `ToolBase.version`.", ReplaceWith("ToolBase.version")) + const val toolBase = ToolBase.version + + /** + * The version of [Spine.javadocFilter]. + * + * @see spine-javadoc-tools + */ + const val javadocTools = "2.0.0-SNAPSHOT.75" +} diff --git a/buildSrc/src/main/kotlin/io/spine/dependency/local/Base.kt b/buildSrc/src/main/kotlin/io/spine/dependency/local/Base.kt new file mode 100644 index 0000000..8a8e0fb --- /dev/null +++ b/buildSrc/src/main/kotlin/io/spine/dependency/local/Base.kt @@ -0,0 +1,42 @@ +/* + * Copyright 2025, TeamDev. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package io.spine.dependency.local + +/** + * Spine Base module. + * + * @see spine-base + */ +@Suppress("ConstPropertyName") +object Base { + const val version = "2.0.0-SNAPSHOT.307" + const val versionForBuildScript = "2.0.0-SNAPSHOT.307" + const val group = Spine.group + const val artifact = "spine-base" + const val lib = "$group:$artifact:$version" + const val libForBuildScript = "$group:$artifact:$versionForBuildScript" +} diff --git a/buildSrc/src/main/kotlin/io/spine/dependency/local/BaseTypes.kt b/buildSrc/src/main/kotlin/io/spine/dependency/local/BaseTypes.kt new file mode 100644 index 0000000..988cab3 --- /dev/null +++ b/buildSrc/src/main/kotlin/io/spine/dependency/local/BaseTypes.kt @@ -0,0 +1,40 @@ +/* + * Copyright 2025, TeamDev. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package io.spine.dependency.local + +/** + * Spine Base module. + * + * @see spine-base-types + */ +@Suppress("ConstPropertyName") +object BaseTypes { + const val version = "2.0.0-SNAPSHOT.126" + const val group = Spine.group + const val artifact = "spine-base-types" + const val lib = "$group:$artifact:$version" +} diff --git a/buildSrc/src/main/kotlin/io/spine/dependency/local/Change.kt b/buildSrc/src/main/kotlin/io/spine/dependency/local/Change.kt new file mode 100644 index 0000000..a5728f7 --- /dev/null +++ b/buildSrc/src/main/kotlin/io/spine/dependency/local/Change.kt @@ -0,0 +1,40 @@ +/* + * Copyright 2025, TeamDev. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package io.spine.dependency.local + +/** + * Spine Reflect library. + * + * @see spine-change + */ +@Suppress("ConstPropertyName") +object Change { + const val version = "2.0.0-SNAPSHOT.118" + const val group = Spine.group + const val artifact = "spine-change" + const val lib = "$group:$artifact:$version" +} diff --git a/buildSrc/src/main/kotlin/io/spine/dependency/local/CoreJava.kt b/buildSrc/src/main/kotlin/io/spine/dependency/local/CoreJava.kt new file mode 100644 index 0000000..af124e6 --- /dev/null +++ b/buildSrc/src/main/kotlin/io/spine/dependency/local/CoreJava.kt @@ -0,0 +1,48 @@ +/* + * Copyright 2025, TeamDev. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package io.spine.dependency.local + +/** + * Dependencies on `core-java` modules. + * + * See [`SpineEventEngine/core-java`](https://github.com/SpineEventEngine/core-java/). + */ +@Suppress("ConstPropertyName", "unused") +object CoreJava { + const val group = Spine.group + const val version = "2.0.0-SNAPSHOT.206" + + const val coreArtifact = "spine-core" + const val clientArtifact = "spine-client" + const val serverArtifact = "spine-server" + + const val core = "$group:$coreArtifact:$version" + const val client = "$group:$clientArtifact:$version" + const val server = "$group:$serverArtifact:$version" + + const val testUtilServer = "${Spine.toolsGroup}:spine-testutil-server:$version" +} diff --git a/buildSrc/src/main/kotlin/io/spine/dependency/local/Logging.kt b/buildSrc/src/main/kotlin/io/spine/dependency/local/Logging.kt new file mode 100644 index 0000000..b1a00ab --- /dev/null +++ b/buildSrc/src/main/kotlin/io/spine/dependency/local/Logging.kt @@ -0,0 +1,57 @@ +/* + * Copyright 2025, TeamDev. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package io.spine.dependency.local + +/** + * Dependencies on the artifacts of the Spine Logging library. + * + * @see spine-logging + */ +@Suppress("ConstPropertyName", "unused") +object Logging { + const val version = "2.0.0-SNAPSHOT.242" + const val group = Spine.group + + const val loggingArtifact = "spine-logging" + + const val lib = "$group:$loggingArtifact:$version" + const val libJvm = "$group:spine-logging-jvm:$version" + + const val log4j2Backend = "$group:spine-logging-log4j2-backend:$version" + const val stdContext = "$group:spine-logging-std-context:$version" + const val grpcContext = "$group:spine-logging-grpc-context:$version" + const val smokeTest = "$group:spine-logging-smoke-test:$version" + + const val testLib = "${Spine.toolsGroup}:spine-logging-testlib:$version" + + // Transitive dependencies. + // Make `public` and use them to force a version in a particular repository, if needed. + internal const val julBackend = "$group:spine-logging-jul-backend:$version" + const val middleware = "$group:spine-logging-middleware:$version" + internal const val platformGenerator = "$group:spine-logging-platform-generator:$version" + internal const val jvmDefaultPlatform = "$group:spine-logging-jvm-default-platform:$version" +} diff --git a/buildSrc/src/main/kotlin/io/spine/dependency/local/McJava.kt b/buildSrc/src/main/kotlin/io/spine/dependency/local/McJava.kt new file mode 100644 index 0000000..30fabf8 --- /dev/null +++ b/buildSrc/src/main/kotlin/io/spine/dependency/local/McJava.kt @@ -0,0 +1,79 @@ +/* + * Copyright 2025, TeamDev. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package io.spine.dependency.local + +/** + * Dependencies on Spine Model Compiler for Java. + * + * See [mc-java](https://github.com/SpineEventEngine/mc-java). + */ +@Suppress( + "MemberVisibilityCanBePrivate" /* `pluginLib()` is used by subprojects. */, + "ConstPropertyName", + "unused" +) +object McJava { + const val group = Spine.toolsGroup + + /** + * The version used to in the build classpath. + */ + const val dogfoodingVersion = "2.0.0-SNAPSHOT.306" + + /** + * The version to be used for integration tests. + */ + const val version = "2.0.0-SNAPSHOT.306" + + /** + * The ID of the Gradle plugin. + */ + const val pluginId = "io.spine.mc-java" + + /** + * The library with the [dogfoodingVersion]. + */ + val pluginLib = pluginLib(dogfoodingVersion) + + /** + * The library with the given [version]. + */ + fun pluginLib(version: String): String = "$group:spine-mc-java-plugins:$version:all" + + /** The artifact reference for forcing in configurations. */ + const val pluginsArtifact: String = "$group:spine-mc-java-plugins:$version" + + /** + * The `mc-java-base` artifact with the [version]. + */ + val base = base(version) + + /** + * The `mc-java-base` artifact with the given [version]. + */ + fun base(version: String): String = "$group:spine-mc-java-base:$version" +} diff --git a/buildSrc/src/main/kotlin/io/spine/dependency/local/ModelCompiler.kt b/buildSrc/src/main/kotlin/io/spine/dependency/local/ModelCompiler.kt new file mode 100644 index 0000000..5f9e541 --- /dev/null +++ b/buildSrc/src/main/kotlin/io/spine/dependency/local/ModelCompiler.kt @@ -0,0 +1,40 @@ +/* + * Copyright 2025, TeamDev. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package io.spine.dependency.local + +/** + * Spine Model Compiler Gradle API. + * + * @see spine-model-compiler + */ +@Suppress("ConstPropertyName") +object ModelCompiler { + const val version = "2.0.0-SNAPSHOT.133" + const val group = Spine.toolsGroup + const val artifact = "spine-model-compiler" + const val lib = "$group:$artifact:$version" +} diff --git a/buildSrc/src/main/kotlin/io/spine/dependency/local/ProtoData.kt b/buildSrc/src/main/kotlin/io/spine/dependency/local/ProtoData.kt new file mode 100644 index 0000000..6d106f2 --- /dev/null +++ b/buildSrc/src/main/kotlin/io/spine/dependency/local/ProtoData.kt @@ -0,0 +1,179 @@ +/* + * Copyright 2025, TeamDev. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package io.spine.dependency.local + +/** + * Dependencies on ProtoData modules. + * + * To use a locally published ProtoData version instead of the version from a public plugin + * registry, set the `PROTODATA_VERSION` and/or the `PROTODATA_DF_VERSION` environment variables + * and stop the Gradle daemons so that Gradle observes the env change: + * ``` + * export PROTODATA_VERSION=0.43.0-local + * export PROTODATA_DF_VERSION=0.41.0 + * + * ./gradle --stop + * ./gradle build # Conduct the intended checks. + * ``` + * + * Then, to reset the console to run the usual versions again, remove the values of + * the environment variables and stop the daemon: + * ``` + * export PROTODATA_VERSION="" + * export PROTODATA_DF_VERSION="" + * + * ./gradle --stop + * ``` + * + * See [`SpineEventEngine/ProtoData`](https://github.com/SpineEventEngine/ProtoData/). + */ +@Suppress( + "unused" /* Some subprojects do not use ProtoData directly. */, + "ConstPropertyName" /* We use custom convention for artifact properties. */, + "MemberVisibilityCanBePrivate" /* The properties are used directly by other subprojects. */, + "KDocUnresolvedReference" /* Referencing private properties in constructor KDoc. */ +) +object ProtoData { + const val pluginGroup = Spine.group + const val group = "io.spine.protodata" + const val pluginId = "io.spine.protodata" + + /** + * Identifies ProtoData as a `classpath` dependency under `buildScript` block. + * + * The dependency is obtained from https://plugins.gradle.org/m2/. + */ + const val module = "io.spine:protodata" + + /** + * The version of ProtoData dependencies. + */ + val version: String + private const val fallbackVersion = "0.93.5" + + /** + * The distinct version of ProtoData used by other build tools. + * + * When ProtoData is used both for building the project and as a part of the Project's + * transitional dependencies, this is the version used to build the project itself. + */ + val dogfoodingVersion: String + private const val fallbackDfVersion = "0.93.5" + + /** + * The artifact for the ProtoData Gradle plugin. + */ + val pluginLib: String + + /** + * The artifact to be used during experiments when publishing locally. + * + * @see ProtoData + */ + private fun pluginLib(version: String): String = + "$group:gradle-plugin:$version" + + fun api(version: String): String = + "$group:protodata-api:$version" + + val api + get() = api(version) + + val backend + get() = "$group:protodata-backend:$version" + + val params + get() = "$group:protodata-params:$version" + + val protocPlugin + get() = "$group:protodata-protoc:$version" + + val gradleApi + get() = "$group:protodata-gradle-api:$version" + + val cliApi + get() = "$group:protodata-cli-api:$version" + + val javaModule = "$group:protodata-java" + + fun java(version: String): String = + "$javaModule:$version" + + val java + get() = java(version) + + val fatCli + get() = "$group:protodata-fat-cli:$version" + + val testlib + get() = "$group:protodata-testlib:$version" + + /** + * An env variable storing a custom [version]. + */ + private const val VERSION_ENV = "PROTODATA_VERSION" + + /** + * An env variable storing a custom [dogfoodingVersion]. + */ + private const val DF_VERSION_ENV = "PROTODATA_DF_VERSION" + + /** + * Sets up the versions and artifacts for the build to use. + * + * If either [VERSION_ENV] or [DF_VERSION_ENV] is set, those versions are used instead of + * the hardcoded ones. Also, in this mode, the [pluginLib] coordinates are changed so that + * it points at a locally published artifact. Otherwise, it points at an artifact that would be + * published to a public plugin registry. + */ + init { + val experimentVersion = System.getenv(VERSION_ENV) + val experimentDfVersion = System.getenv(DF_VERSION_ENV) + if (experimentVersion?.isNotBlank() == true || experimentDfVersion?.isNotBlank() == true) { + version = experimentVersion ?: fallbackVersion + dogfoodingVersion = experimentDfVersion ?: fallbackDfVersion + + pluginLib = pluginLib(version) + println(""" + + ❗ Running an experiment with ProtoData. ❗ + ----------------------------------------- + Regular version = v$version + Dogfooding version = v$dogfoodingVersion + + ProtoData Gradle plugin can now be loaded from Maven Local. + + To reset the versions, erase the `$$VERSION_ENV` and `$$DF_VERSION_ENV` environment variables. + + """.trimIndent()) + } else { + version = fallbackVersion + dogfoodingVersion = fallbackDfVersion + pluginLib = "$pluginGroup:protodata:$version" + } + } +} diff --git a/buildSrc/src/main/kotlin/io/spine/dependency/local/ProtoTap.kt b/buildSrc/src/main/kotlin/io/spine/dependency/local/ProtoTap.kt new file mode 100644 index 0000000..c811e58 --- /dev/null +++ b/buildSrc/src/main/kotlin/io/spine/dependency/local/ProtoTap.kt @@ -0,0 +1,46 @@ +/* + * Copyright 2025, TeamDev. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package io.spine.dependency.local + +/** + * Dependencies on ProtoTap plugins. + * + * See [`SpineEventEngine/ProtoTap`](https://github.com/SpineEventEngine/ProtoTap/). + */ +@Suppress( + "unused" /* Some subprojects do not use ProtoData directly. */, + "ConstPropertyName" /* We use custom convention for artifact properties. */, + "MemberVisibilityCanBePrivate" /* The properties are used directly by other subprojects. */, +) +object ProtoTap { + const val group = "io.spine.tools" + const val version = "0.9.1" + const val gradlePluginId = "io.spine.prototap" + const val api = "$group:prototap-api:$version" + const val gradlePlugin = "$group:prototap-gradle-plugin:$version" + const val protocPlugin = "$group:prototap-protoc-plugin:$version" +} diff --git a/buildSrc/src/main/kotlin/io/spine/internal/dependency/Plexus.kt b/buildSrc/src/main/kotlin/io/spine/dependency/local/Reflect.kt similarity index 71% rename from buildSrc/src/main/kotlin/io/spine/internal/dependency/Plexus.kt rename to buildSrc/src/main/kotlin/io/spine/dependency/local/Reflect.kt index 27d2720..fbf37f1 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/dependency/Plexus.kt +++ b/buildSrc/src/main/kotlin/io/spine/dependency/local/Reflect.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,15 +24,17 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.dependency +package io.spine.dependency.local /** - * Plexus Utils is a transitive dependency which we don't use directly. - * We `force` it in [DependencyResolution.forceConfiguration]. + * Spine Reflect library. * - * [Plexus Utils](https://codehaus-plexus.github.io/plexus-utils/) + * @see spine-reflect */ -object Plexus { - private const val version = "3.4.0" - const val utils = "org.codehaus.plexus:plexus-utils:${version}" +@Suppress("ConstPropertyName") +object Reflect { + const val version = "2.0.0-SNAPSHOT.191" + const val group = Spine.group + const val artifact = "spine-reflect" + const val lib = "$group:$artifact:$version" } diff --git a/buildSrc/src/main/kotlin/io/spine/dependency/local/Spine.kt b/buildSrc/src/main/kotlin/io/spine/dependency/local/Spine.kt new file mode 100644 index 0000000..d7b6d0c --- /dev/null +++ b/buildSrc/src/main/kotlin/io/spine/dependency/local/Spine.kt @@ -0,0 +1,117 @@ +/* + * Copyright 2025, TeamDev. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package io.spine.dependency.local + +/** + * Dependencies on smaller Spine modules. + */ +@Suppress("unused", "ConstPropertyName") +object Spine { + + const val group = "io.spine" + const val toolsGroup = "io.spine.tools" + + @Deprecated(message = "Please use `Base.lib`.", ReplaceWith("Base.lib")) + const val base = Base.lib + + @Deprecated( + message = "Please use `Base.libForBuildScript`.", + ReplaceWith("Base.libForBuildScript") + ) + const val baseForBuildScript = Base.libForBuildScript + + @Deprecated(message = "Please use `Reflect.lib`.", ReplaceWith("Reflect.lib")) + const val reflect = Reflect.lib + + @Deprecated(message = "Please use `BaseTypes.lib`.", ReplaceWith("BaseTypes.lib")) + const val baseTypes = BaseTypes.lib + + @Deprecated(message = "Please use `Time.lib`.", ReplaceWith("Time.lib")) + const val time = Time.lib + + @Deprecated(message = "Please use `Change.lib`.", ReplaceWith("Change.lib")) + const val change = Change.lib + + @Deprecated(message = "Please use `Text.lib`.", ReplaceWith("Text.lib")) + const val text = Text.lib + + @Deprecated(message = "Please use `TestLib.lib`.", ReplaceWith("TestLib.lib")) + const val testlib = TestLib.lib + + @Deprecated(message = "Please use `Time.testLib`.", ReplaceWith("Time.testLib")) + const val testUtilTime = Time.testLib + + @Deprecated(message = "Please use `ToolBase.psiJava` instead`.") + const val psiJava = "$toolsGroup:spine-psi-java:${ToolBase.version}" + + @Deprecated( + message = "Please use `ToolBase.psiJava` instead`.", + ReplaceWith("ToolBase.psiJava") + ) + const val psiJavaBundle = "$toolsGroup:spine-psi-java-bundle:${ToolBase.version}" + + @Deprecated(message = "Please use `ToolBase.lib` instead`.", ReplaceWith("ToolBase.lib")) + const val toolBase = "$toolsGroup:spine-tool-base:${ToolBase.version}" + + @Deprecated( + message = "Please use `ToolBase.pluginBase` instead`.", + ReplaceWith("ToolBase.pluginBase") + ) + const val pluginBase = "$toolsGroup:spine-plugin-base:${ToolBase.version}" + + @Deprecated( + message = "Please use `ToolBase.pluginTestlib` instead`.", + ReplaceWith("ToolBase.pluginTestlib") + ) + const val pluginTestlib = ToolBase.pluginTestlib + + @Deprecated( + message = "Please use `ModelCompiler.lib` instead.", + ReplaceWith("ModelCompiler.lib") + ) + const val modelCompiler = ModelCompiler.lib + + @Deprecated( + message = "Please use top level `McJava` object instead.", + ReplaceWith("McJava", "io.spine.dependency.local.McJava") + ) + val McJava = io.spine.dependency.local.McJava + + const val javadocFilter = "$toolsGroup:spine-javadoc-filter:${ArtifactVersion.javadocTools}" + + @Deprecated( + message = "Please use top level `CoreJava.client` object instead.", + ReplaceWith("CoreJava.client", "io.spine.dependency.local.CoreJava") + ) + const val client = CoreJava.client + + @Deprecated( + message = "Please use top level `CoreJava.server` object instead.", + ReplaceWith("CoreJava.server", "io.spine.dependency.local.CoreJava") + ) + const val server = CoreJava.server +} diff --git a/buildSrc/src/main/kotlin/io/spine/dependency/local/TestLib.kt b/buildSrc/src/main/kotlin/io/spine/dependency/local/TestLib.kt new file mode 100644 index 0000000..e7e6534 --- /dev/null +++ b/buildSrc/src/main/kotlin/io/spine/dependency/local/TestLib.kt @@ -0,0 +1,40 @@ +/* + * Copyright 2025, TeamDev. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package io.spine.dependency.local + +/** + * Spine TestLib library. + * + * @see spine-testlib + */ +@Suppress("ConstPropertyName") +object TestLib { + const val version = "2.0.0-SNAPSHOT.185" + const val group = Spine.toolsGroup + const val artifact = "spine-testlib" + const val lib = "$group:$artifact:$version" +} diff --git a/buildSrc/src/main/kotlin/io/spine/dependency/local/Text.kt b/buildSrc/src/main/kotlin/io/spine/dependency/local/Text.kt new file mode 100644 index 0000000..216ec13 --- /dev/null +++ b/buildSrc/src/main/kotlin/io/spine/dependency/local/Text.kt @@ -0,0 +1,40 @@ +/* + * Copyright 2025, TeamDev. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package io.spine.dependency.local + +/** + * Spine Reflect library. + * + * @see spine-text + */ +@Suppress("ConstPropertyName") +object Text { + const val version = "2.0.0-SNAPSHOT.6" + const val group = Spine.group + const val artifact = "spine-text" + const val lib = "$group:$artifact:$version" +} diff --git a/buildSrc/src/main/kotlin/io/spine/dependency/local/Time.kt b/buildSrc/src/main/kotlin/io/spine/dependency/local/Time.kt new file mode 100644 index 0000000..56518ec --- /dev/null +++ b/buildSrc/src/main/kotlin/io/spine/dependency/local/Time.kt @@ -0,0 +1,42 @@ +/* + * Copyright 2025, TeamDev. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package io.spine.dependency.local + +/** + * Spine Time library. + * + * @see spine-time + */ +@Suppress("ConstPropertyName") +object Time { + const val version = "2.0.0-SNAPSHOT.136" + const val group = Spine.group + const val artifact = "spine-time" + const val lib = "$group:$artifact:$version" + + const val testLib = "${Spine.toolsGroup}:spine-time-testlib:$version" +} diff --git a/buildSrc/src/main/kotlin/io/spine/dependency/local/ToolBase.kt b/buildSrc/src/main/kotlin/io/spine/dependency/local/ToolBase.kt new file mode 100644 index 0000000..b402a3d --- /dev/null +++ b/buildSrc/src/main/kotlin/io/spine/dependency/local/ToolBase.kt @@ -0,0 +1,46 @@ +/* + * Copyright 2025, TeamDev. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package io.spine.dependency.local + +/** + * Artifacts of the `tool-base` module. + * + * @see spine-tool-base + */ +@Suppress("ConstPropertyName", "unused") +object ToolBase { + const val group = Spine.toolsGroup + const val version = "2.0.0-SNAPSHOT.302" + + const val lib = "$group:spine-tool-base:$version" + const val pluginBase = "$group:spine-plugin-base:$version" + const val pluginTestlib = "$group:spine-plugin-testlib:$version" + + const val intellijPlatformJava = "$group:intellij-platform-java:$version" + + const val psiJava = "$group:spine-psi-java:$version" +} diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/publish/PublishingRepos.kt b/buildSrc/src/main/kotlin/io/spine/dependency/local/Validation.kt similarity index 52% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/publish/PublishingRepos.kt rename to buildSrc/src/main/kotlin/io/spine/dependency/local/Validation.kt index 5abdc10..4df0bcc 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/publish/PublishingRepos.kt +++ b/buildSrc/src/main/kotlin/io/spine/dependency/local/Validation.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,29 +24,34 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.publish - -import io.spine.internal.gradle.Repository +package io.spine.dependency.local /** - * Repositories to which we may publish. + * Dependencies on Spine Validation SDK. + * + * See [`SpineEventEngine/validation`](https://github.com/SpineEventEngine/validation/). */ -object PublishingRepos { +@Suppress("ConstPropertyName", "unused") +object Validation { + /** + * The version of the Validation library artifacts. + */ + const val version = "2.0.0-SNAPSHOT.305" - @Suppress("HttpUrlsUsage") // HTTPS is not supported by this repository. - val mavenTeamDev = Repository( - name = "maven.teamdev.com", - releases = "http://maven.teamdev.com/repository/spine", - snapshots = "http://maven.teamdev.com/repository/spine-snapshots", - credentialsFile = "credentials.properties" - ) + const val group = "io.spine.validation" + private const val prefix = "spine-validation" - val cloudRepo = CloudRepo.destination + const val runtimeModule = "$group:$prefix-java-runtime" + const val runtime = "$runtimeModule:$version" + const val java = "$group:$prefix-java:$version" - val cloudArtifactRegistry = CloudArtifactRegistry.repository + const val javaBundleModule = "$group:$prefix-java-bundle" - /** - * Obtains a GitHub repository by the given name. - */ - fun gitHub(repoName: String): Repository = GitHubPackages.repository(repoName) + /** Obtains the artifact for the `java-bundle` artifact of the given version. */ + fun javaBundle(version: String) = "$javaBundleModule:$version" + + val javaBundle = javaBundle(version) + + const val model = "$group:$prefix-model:$version" + const val config = "$group:$prefix-configuration:$version" } diff --git a/buildSrc/src/main/kotlin/io/spine/internal/dependency/AssertK.kt b/buildSrc/src/main/kotlin/io/spine/dependency/test/AssertK.kt similarity index 83% rename from buildSrc/src/main/kotlin/io/spine/internal/dependency/AssertK.kt rename to buildSrc/src/main/kotlin/io/spine/dependency/test/AssertK.kt index 8d42b61..b9a554b 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/dependency/AssertK.kt +++ b/buildSrc/src/main/kotlin/io/spine/dependency/test/AssertK.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,15 +24,16 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.dependency +package io.spine.dependency.test /** * Assertion library for tests in Kotlin * * [AssertK](https://github.com/willowtreeapps/assertk) */ -@Suppress("unused") +@Deprecated("Please use Kotest assertions instead.") +@Suppress("unused", "ConstPropertyName") object AssertK { - private const val version = "0.25" - const val libJvm = "com.willowtreeapps.assertk:assertk-jvm:${version}" + private const val version = "0.26.1" + const val libJvm = "com.willowtreeapps.assertk:assertk-jvm:$version" } diff --git a/buildSrc/src/main/kotlin/io/spine/dependency/test/Hamcrest.kt b/buildSrc/src/main/kotlin/io/spine/dependency/test/Hamcrest.kt new file mode 100644 index 0000000..c2dcfe2 --- /dev/null +++ b/buildSrc/src/main/kotlin/io/spine/dependency/test/Hamcrest.kt @@ -0,0 +1,40 @@ +/* + * Copyright 2025, TeamDev. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package io.spine.dependency.test + +/** + * The dependency on the Hamcrest, which is transitive for us. + * + * If you need assertions in Java, please use Google [Truth] instead. + * For Kotlin, please use [Kotest]. + */ +@Suppress("unused", "ConstPropertyName") +object Hamcrest { + // https://github.com/hamcrest/JavaHamcrest/releases + private const val version = "2.2" + const val core = "org.hamcrest:hamcrest-core:$version" +} diff --git a/buildSrc/src/main/kotlin/io/spine/internal/dependency/JUnit.kt b/buildSrc/src/main/kotlin/io/spine/dependency/test/JUnit.kt similarity index 55% rename from buildSrc/src/main/kotlin/io/spine/internal/dependency/JUnit.kt rename to buildSrc/src/main/kotlin/io/spine/dependency/test/JUnit.kt index 3402460..c410b42 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/dependency/JUnit.kt +++ b/buildSrc/src/main/kotlin/io/spine/dependency/test/JUnit.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,30 +24,41 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.dependency +package io.spine.dependency.test // https://junit.org/junit5/ -@Suppress("unused") +@Suppress("unused", "ConstPropertyName") object JUnit { - const val version = "5.9.1" - private const val platformVersion = "1.9.1" - private const val legacyVersion = "4.13.1" + const val version = "5.10.0" + private const val legacyVersion = "4.13.1" // https://github.com/apiguardian-team/apiguardian private const val apiGuardianVersion = "1.1.2" + // https://github.com/junit-pioneer/junit-pioneer - private const val pioneerVersion = "1.7.1" + private const val pioneerVersion = "2.0.1" + + const val legacy = "junit:junit:$legacyVersion" - const val legacy = "junit:junit:${legacyVersion}" val api = listOf( - "org.apiguardian:apiguardian-api:${apiGuardianVersion}", - "org.junit.jupiter:junit-jupiter-api:${version}", - "org.junit.jupiter:junit-jupiter-params:${version}" + "org.apiguardian:apiguardian-api:$apiGuardianVersion", + "org.junit.jupiter:junit-jupiter-api:$version", + "org.junit.jupiter:junit-jupiter-params:$version" ) - const val bom = "org.junit:junit-bom:${version}" - const val runner = "org.junit.jupiter:junit-jupiter-engine:${version}" - const val pioneer = "org.junit-pioneer:junit-pioneer:${pioneerVersion}" - const val platformCommons = "org.junit.platform:junit-platform-commons:${platformVersion}" - const val platformLauncher = "org.junit.platform:junit-platform-launcher:${platformVersion}" - const val params = "org.junit.jupiter:junit-jupiter-params:${version}" + const val bom = "org.junit:junit-bom:$version" + + const val runner = "org.junit.jupiter:junit-jupiter-engine:$version" + const val params = "org.junit.jupiter:junit-jupiter-params:$version" + + const val pioneer = "org.junit-pioneer:junit-pioneer:$pioneerVersion" + + object Platform { + // https://junit.org/junit5/ + const val version = "1.10.0" + internal const val group = "org.junit.platform" + const val commons = "$group:junit-platform-commons:$version" + const val launcher = "$group:junit-platform-launcher:$version" + const val engine = "$group:junit-platform-engine:$version" + const val suiteApi = "$group:junit-platform-suite-api:$version" + } } diff --git a/buildSrc/src/main/kotlin/io/spine/internal/dependency/AutoCommon.kt b/buildSrc/src/main/kotlin/io/spine/dependency/test/Jacoco.kt similarity index 78% rename from buildSrc/src/main/kotlin/io/spine/internal/dependency/AutoCommon.kt rename to buildSrc/src/main/kotlin/io/spine/dependency/test/Jacoco.kt index 4053ef5..b883928 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/dependency/AutoCommon.kt +++ b/buildSrc/src/main/kotlin/io/spine/dependency/test/Jacoco.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,10 +24,14 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.dependency +package io.spine.dependency.test -// https://github.com/google/auto -object AutoCommon { - private const val version = "1.2.1" - const val lib = "com.google.auto:auto-common:${version}" +/** + * Code coverage library for Java. + * + * @see Releases + */ +@Suppress("ConstPropertyName") +object Jacoco { + const val version = "0.8.12" } diff --git a/buildSrc/src/main/kotlin/io/spine/dependency/test/Kotest.kt b/buildSrc/src/main/kotlin/io/spine/dependency/test/Kotest.kt new file mode 100644 index 0000000..8de10ff --- /dev/null +++ b/buildSrc/src/main/kotlin/io/spine/dependency/test/Kotest.kt @@ -0,0 +1,60 @@ +/* + * Copyright 2025, TeamDev. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +@file:Suppress("unused") + +package io.spine.dependency.test + +/** + * Testing framework for Kotlin. + * + * @see Kotest site + */ +@Suppress("unused", "ConstPropertyName") +object Kotest { + const val version = "5.9.1" + const val group = "io.kotest" + const val assertions = "$group:kotest-assertions-core:$version" + const val runnerJUnit5 = "$group:kotest-runner-junit5:$version" + const val runnerJUnit5Jvm = "$group:kotest-runner-junit5-jvm:$version" + const val frameworkApi = "$group:kotest-framework-api:$version" + const val datatest = "$group:kotest-framework-datatest:$version" + const val frameworkEngine = "$group:kotest-framework-engine:$version" + + // https://plugins.gradle.org/plugin/io.kotest.multiplatform + object MultiplatformGradlePlugin { + const val version = Kotest.version + const val id = "io.kotest.multiplatform" + const val classpath = "$group:kotest-framework-multiplatform-plugin-gradle:$version" + } + + // https://github.com/kotest/kotest-gradle-plugin + object JvmGradlePlugin { + const val version = "0.4.10" + const val id = "io.kotest" + const val classpath = "$group:kotest-gradle-plugin:$version" + } +} diff --git a/buildSrc/src/main/kotlin/io/spine/dependency/test/KotlinCompileTesting.kt b/buildSrc/src/main/kotlin/io/spine/dependency/test/KotlinCompileTesting.kt new file mode 100644 index 0000000..0e9110b --- /dev/null +++ b/buildSrc/src/main/kotlin/io/spine/dependency/test/KotlinCompileTesting.kt @@ -0,0 +1,40 @@ +/* + * Copyright 2025, TeamDev. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package io.spine.dependency.test + +/** + * A library for in-process compilation of Kotlin and Java code compilation. + * + * @see GitHub repo + */ +@Suppress("unused", "ConstPropertyName") +object KotlinCompileTesting { + private const val version = "0.7.0" + private const val group = "dev.zacsweers.kctfork" + const val libCore = "$group:core:$version" + const val libKsp = "$group:ksp:$version" +} diff --git a/buildSrc/src/main/kotlin/io/spine/dependency/test/Kover.kt b/buildSrc/src/main/kotlin/io/spine/dependency/test/Kover.kt new file mode 100644 index 0000000..759e21a --- /dev/null +++ b/buildSrc/src/main/kotlin/io/spine/dependency/test/Kover.kt @@ -0,0 +1,35 @@ +/* + * Copyright 2025, TeamDev. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package io.spine.dependency.test + +// https://github.com/Kotlin/kotlinx-kover +@Suppress("unused", "ConstPropertyName") +object Kover { + const val version = "0.7.6" + const val id = "org.jetbrains.kotlinx.kover" + const val classpath = "org.jetbrains.kotlinx:kover-gradle-plugin:$version" +} diff --git a/buildSrc/src/main/kotlin/io/spine/internal/dependency/Okio.kt b/buildSrc/src/main/kotlin/io/spine/dependency/test/OpenTest4J.kt similarity index 73% rename from buildSrc/src/main/kotlin/io/spine/internal/dependency/Okio.kt rename to buildSrc/src/main/kotlin/io/spine/dependency/test/OpenTest4J.kt index 4ad91c6..1e22fb3 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/dependency/Okio.kt +++ b/buildSrc/src/main/kotlin/io/spine/dependency/test/OpenTest4J.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,14 +24,15 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.dependency +package io.spine.dependency.test /** - * Okio is a transitive dependency which we don't use directly. - * We `force` it in [DependencyResolution.forceConfiguration]. + * The dependency on the OpenTest4j library, which is transitive for us. */ -object Okio { - // This is the last version before next major. - private const val version = "1.17.5" - const val lib = "com.squareup.okio:okio:${version}" +@Suppress("unused", "ConstPropertyName") +object OpenTest4J { + + // https://github.com/ota4j-team/opentest4j/releases + private const val version = "1.3.0" + const val lib = "org.opentest4j:opentest4j:$version" } diff --git a/buildSrc/src/main/kotlin/io/spine/internal/dependency/Pmd.kt b/buildSrc/src/main/kotlin/io/spine/dependency/test/SystemLambda.kt similarity index 75% rename from buildSrc/src/main/kotlin/io/spine/internal/dependency/Pmd.kt rename to buildSrc/src/main/kotlin/io/spine/dependency/test/SystemLambda.kt index edb0790..5f0eef8 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/dependency/Pmd.kt +++ b/buildSrc/src/main/kotlin/io/spine/dependency/test/SystemLambda.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,9 +24,12 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.dependency +package io.spine.dependency.test -// https://pmd.github.io/ -object Pmd { - const val version = "6.50.0" +// https://github.com/stefanbirkner/system-lambda +@Suppress("unused", "ConstPropertyName") +object SystemLambda { + const val version = "1.2.1" + const val group = "com.github.stefanbirkner" + const val lib = "$group:system-lambda:$version" } diff --git a/buildSrc/src/main/kotlin/io/spine/internal/dependency/TestKitTruth.kt b/buildSrc/src/main/kotlin/io/spine/dependency/test/TestKitTruth.kt similarity index 70% rename from buildSrc/src/main/kotlin/io/spine/internal/dependency/TestKitTruth.kt rename to buildSrc/src/main/kotlin/io/spine/dependency/test/TestKitTruth.kt index 8d572d9..bfec211 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/dependency/TestKitTruth.kt +++ b/buildSrc/src/main/kotlin/io/spine/dependency/test/TestKitTruth.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,19 +24,18 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.dependency +@file:Suppress("MaxLineLength") + +package io.spine.dependency.test /** * Gradle TestKit extension for Google Truth. * - * Source code: - * https://github.com/autonomousapps/dependency-analysis-android-gradle-plugin/tree/main/testkit-truth - * - * Usage description: - * https://dev.to/autonomousapps/gradle-all-the-way-down-testing-your-gradle-plugin-with-gradle-testkit-2hmc + * @see TestKit source code + * @see Usage description */ -@Suppress("unused") +@Suppress("unused", "ConstPropertyName") object TestKitTruth { - private const val version = "1.1" + private const val version = "1.20.0" const val lib = "com.autonomousapps:testkit-truth:$version" } diff --git a/buildSrc/src/main/kotlin/io/spine/internal/dependency/Truth.kt b/buildSrc/src/main/kotlin/io/spine/dependency/test/Truth.kt similarity index 75% rename from buildSrc/src/main/kotlin/io/spine/internal/dependency/Truth.kt rename to buildSrc/src/main/kotlin/io/spine/dependency/test/Truth.kt index 48c1f2d..f9af032 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/dependency/Truth.kt +++ b/buildSrc/src/main/kotlin/io/spine/dependency/test/Truth.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,14 +24,15 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.dependency +package io.spine.dependency.test // https://github.com/google/truth +@Suppress("unused", "ConstPropertyName") object Truth { - private const val version = "1.1.3" + private const val version = "1.1.5" val libs = listOf( - "com.google.truth:truth:${version}", - "com.google.truth.extensions:truth-java8-extension:${version}", - "com.google.truth.extensions:truth-proto-extension:${version}" + "com.google.truth:truth:$version", + "com.google.truth.extensions:truth-java8-extension:$version", + "com.google.truth.extensions:truth-proto-extension:$version" ) } diff --git a/buildSrc/src/main/kotlin/io/spine/internal/markup/MarkdownDocument.kt b/buildSrc/src/main/kotlin/io/spine/docs/MarkdownDocument.kt similarity index 96% rename from buildSrc/src/main/kotlin/io/spine/internal/markup/MarkdownDocument.kt rename to buildSrc/src/main/kotlin/io/spine/docs/MarkdownDocument.kt index a73076b..23937bd 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/markup/MarkdownDocument.kt +++ b/buildSrc/src/main/kotlin/io/spine/docs/MarkdownDocument.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,7 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.markup +package io.spine.docs import java.io.File diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/Build.kt b/buildSrc/src/main/kotlin/io/spine/gradle/Build.kt similarity index 90% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/Build.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/Build.kt index c42a3c0..327031e 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/Build.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/Build.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,7 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle +package io.spine.gradle @Suppress("unused") object Build { diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/Clean.kt b/buildSrc/src/main/kotlin/io/spine/gradle/Clean.kt similarity index 92% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/Clean.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/Clean.kt index ad5c1c5..380e835 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/Clean.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/Clean.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,7 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle +package io.spine.gradle import java.io.File import java.nio.file.Files diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/ConfigTester.kt b/buildSrc/src/main/kotlin/io/spine/gradle/ConfigTester.kt similarity index 98% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/ConfigTester.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/ConfigTester.kt index 2178a23..3de99c4 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/ConfigTester.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/ConfigTester.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -26,7 +26,7 @@ @file:Suppress("unused") /* Some constants may be used throughout the Spine repos. */ -package io.spine.internal.gradle +package io.spine.gradle import java.io.File import java.net.URI diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/ProjectExtensions.kt b/buildSrc/src/main/kotlin/io/spine/gradle/ProjectExtensions.kt similarity index 87% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/ProjectExtensions.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/ProjectExtensions.kt index a2e34b3..3b43246 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/ProjectExtensions.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/ProjectExtensions.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,9 +24,10 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle +package io.spine.gradle -import io.spine.internal.gradle.publish.SpinePublishing +import io.spine.gradle.publish.SpinePublishing +import java.io.File import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.api.Task @@ -69,7 +70,8 @@ fun Project.applyPlugin(cls: Class>) { @Suppress("UNCHECKED_CAST") /* See the method docs. */ fun Project.findTask(name: String): T { val task = this.tasks.findByName(name) - return task!! as T + ?: error("Unable to find a task named `$name` in the project `${this.name}`.") + return task as T } /** @@ -90,3 +92,9 @@ val Project.artifactId: String val artifactId = spinePublishing?.artifactId(this) return artifactId ?: name } + +/** + * Returns project's build directory as [File]. + */ +val Project.buildDirectory: File + get() = layout.buildDirectory.get().asFile diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/RepoSlug.kt b/buildSrc/src/main/kotlin/io/spine/gradle/RepoSlug.kt similarity index 94% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/RepoSlug.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/RepoSlug.kt index 48a4938..71fbac3 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/RepoSlug.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/RepoSlug.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,7 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle +package io.spine.gradle import org.gradle.api.GradleException diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/Repositories.kt b/buildSrc/src/main/kotlin/io/spine/gradle/Repositories.kt similarity index 74% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/Repositories.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/Repositories.kt index 6a35ab1..8ec449e 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/Repositories.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/Repositories.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,11 +24,13 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle +@file:Suppress("TooManyFunctions") // Deprecated functions will be kept for a while. -import io.spine.internal.gradle.publish.CloudRepo -import io.spine.internal.gradle.publish.PublishingRepos -import io.spine.internal.gradle.publish.PublishingRepos.gitHub +package io.spine.gradle + +import io.spine.gradle.publish.CloudRepo +import io.spine.gradle.publish.PublishingRepos +import io.spine.gradle.publish.PublishingRepos.gitHub import java.io.File import java.net.URI import java.util.* @@ -36,6 +38,7 @@ import org.gradle.api.Project import org.gradle.api.artifacts.dsl.RepositoryHandler import org.gradle.api.artifacts.repositories.MavenArtifactRepository import org.gradle.kotlin.dsl.ScriptHandlerScope +import org.gradle.kotlin.dsl.maven /** * Applies [standard][doApplyStandard] repositories to this [ScriptHandlerScope] @@ -51,6 +54,10 @@ import org.gradle.kotlin.dsl.ScriptHandlerScope * [standard repositories][doApplyStandard] are required. */ @Suppress("unused") +@Deprecated( + message = "Please use `standardSpineSdkRepositories()`.", + replaceWith = ReplaceWith("standardSpineSdkRepositories()") +) fun applyWithStandard( buildscript: ScriptHandlerScope, rootProject: Project, @@ -60,7 +67,7 @@ fun applyWithStandard( gitHubRepo.iterator().forEachRemaining { repo -> repositories.applyGitHubPackages(repo, rootProject) } - repositories.applyStandard() + repositories.standardToSpineSdk() } /** @@ -77,6 +84,10 @@ fun applyWithStandard( * @see applyGitHubPackages */ @Suppress("unused") +@Deprecated( + message = "Please use `standardSpineSdkRepositories()`.", + replaceWith = ReplaceWith("standardSpineSdkRepositories()") +) fun doApplyGitHubPackages( repositories: RepositoryHandler, shortRepositoryName: String, @@ -89,7 +100,11 @@ fun doApplyGitHubPackages( * To be used in `buildscript` clauses when a fully-qualified call must be made. */ @Suppress("unused") -fun doApplyStandard(repositories: RepositoryHandler) = repositories.applyStandard() +@Deprecated( + message = "Please use `standardSpineSdkRepositories()`.", + replaceWith = ReplaceWith("standardSpineSdkRepositories()") +) +fun doApplyStandard(repositories: RepositoryHandler) = repositories.standardToSpineSdk() /** * Applies the repository hosted at GitHub Packages, to which Spine artifacts were published. @@ -142,21 +157,75 @@ fun RepositoryHandler.applyGitHubPackages(project: Project, vararg shortReposito * [standard repositories][applyStandard] are required. */ @Suppress("unused") +@Deprecated( + message = "Please use `standardToSpineSdk()`.", + replaceWith = ReplaceWith("standardToSpineSdk()") +) fun RepositoryHandler.applyStandardWithGitHub(project: Project, vararg gitHubRepo: String) { gitHubRepo.iterator().forEachRemaining { repo -> applyGitHubPackages(repo, project) } - applyStandard() + standardToSpineSdk() } /** - * Applies repositories commonly used by Spine Event Engine projects. + * A scrambled version of PAT generated with the only "read:packages" scope. * - * Does not include the repositories hosted at GitHub Packages. + * The scrambling around PAT is necessary because GitHub analyzes commits for the presence + * of tokens and invalidates them. * - * @see applyGitHubPackages + * @see + * How to make GitHub packages to the public */ -fun RepositoryHandler.applyStandard() { +object Pat { + private const val shade = "_phg->8YlN->MFRA->gxIk->HVkm->eO6g->FqHJ->z8MS->H4zC->ZEPq" + private const val separator = "->" + private val chunks: Int = shade.split(separator).size - 1 + + fun credentials(): Credentials { + val pass = shade.replace(separator, "").splitAndReverse(chunks, "") + return Credentials("public", pass) + } + + /** + * Splits this string to the chunks, reverses each chunk, and joins them + * back to a string using the [separator]. + */ + private fun String.splitAndReverse(numChunks: Int, separator: String): String { + check(length / numChunks >= 2) { + "The number of chunks is too big. Must be <= ${length / 2}." + } + val chunks = chunked(length / numChunks) + val reversedChunks = chunks.map { chunk -> chunk.reversed() } + return reversedChunks.joinToString(separator) + } +} + +/** + * Adds a read-only view to all artifacts of the SpineEventEngine + * GitHub organization. + */ +fun RepositoryHandler.spineArtifacts(): MavenArtifactRepository = maven { + url = URI("https://maven.pkg.github.com/SpineEventEngine/*") + includeSpineOnly() + val pat = Pat.credentials() + credentials { + username = pat.username + password = pat.password + } +} + +val RepositoryHandler.intellijReleases: MavenArtifactRepository + get() = maven("https://www.jetbrains.com/intellij-repository/releases") + +val RepositoryHandler.jetBrainsCacheRedirector: MavenArtifactRepository + get() = maven("https://cache-redirector.jetbrains.com/intellij-dependencies") + +/** + * Applies repositories commonly used by Spine Event Engine projects. + */ +fun RepositoryHandler.standardToSpineSdk() { + spineArtifacts() val spineRepos = listOf( Repos.spine, @@ -174,6 +243,9 @@ fun RepositoryHandler.applyStandard() { } } + intellijReleases + jetBrainsCacheRedirector + maven { url = URI(Repos.sonatypeSnapshots) } @@ -183,6 +255,12 @@ fun RepositoryHandler.applyStandard() { mavenLocal().includeSpineOnly() } +@Deprecated( + message = "Please use `standardToSpineSdk() instead.", + replaceWith = ReplaceWith("standardToSpineSdk()") +) +fun RepositoryHandler.applyStandard() = this.standardToSpineSdk() + /** * A Maven repository. */ diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/RunBuild.kt b/buildSrc/src/main/kotlin/io/spine/gradle/RunBuild.kt similarity index 89% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/RunBuild.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/RunBuild.kt index 03cef70..aa2759d 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/RunBuild.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/RunBuild.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,7 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle +package io.spine.gradle /** * Runs the `build` task via Gradle Wrapper. @@ -32,6 +32,6 @@ package io.spine.internal.gradle open class RunBuild : RunGradle() { init { - task("build") + task("clean", "build") } } diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/RunGradle.kt b/buildSrc/src/main/kotlin/io/spine/gradle/RunGradle.kt similarity index 97% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/RunGradle.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/RunGradle.kt index 857d170..8942630 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/RunGradle.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/RunGradle.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,7 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle +package io.spine.gradle import java.io.File import java.io.FileOutputStream @@ -55,7 +55,6 @@ open class RunGradle : DefaultTask() { private const val BUILD_TIMEOUT_MINUTES: Long = 10 } - /** * Path to the directory which contains a Gradle wrapper script. */ @@ -101,7 +100,7 @@ open class RunGradle : DefaultTask() { } @TaskAction - private fun execute() { + public fun execute() { // Ensure build error output log. // Since we're executing this task in another process, we redirect error output to // the file under the `_out` directory. Using the `build` directory for this purpose diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/Runtime.kt b/buildSrc/src/main/kotlin/io/spine/gradle/Runtime.kt similarity index 73% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/Runtime.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/Runtime.kt index eced40e..c5b5f54 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/Runtime.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/Runtime.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,19 +24,19 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle +package io.spine.gradle -import com.google.common.base.Joiner -import io.spine.internal.dependency.Flogger import java.io.File import java.io.InputStream import java.io.StringWriter +import java.lang.ProcessBuilder.Redirect.PIPE import java.util.* -object Runtime { - @Suppress("unused") - val flogger = Flogger.Runtime -} +/** + * Utilities for working with processes from Gradle code. + */ +@Suppress("unused") +private const val ABOUT = "" /** * Executor of CLI commands. @@ -60,23 +60,26 @@ class Cli(private val workingFolder: File) { val outWriter = StringWriter() val errWriter = StringWriter() - val process = ProcessBuilder(*command) - .directory(workingFolder) - .redirectOutput(ProcessBuilder.Redirect.PIPE) - .redirectError(ProcessBuilder.Redirect.PIPE) - .start() + val process = ProcessBuilder(*command).apply { + directory(workingFolder) + redirectOutput(PIPE) + redirectError(PIPE) + }.start() - process.inputStream!!.pourTo(outWriter) - process.errorStream!!.pourTo(errWriter) - val exitCode = process.waitFor() + val exitCode = process.run { + inputStream!!.pourTo(outWriter) + errorStream!!.pourTo(errWriter) + waitFor() + } if (exitCode == 0) { return outWriter.toString() } else { - val cmdAsString = Joiner.on(" ").join(command.iterator()) - val errorMsg = "Command `$cmdAsString` finished with exit code $exitCode:" + - " ${System.lineSeparator()}$errWriter" + - " ${System.lineSeparator()}$outWriter." + val commandLine = command.joinToString(" ") + val nl = System.lineSeparator() + val errorMsg = "Command `$commandLine` finished with exit code $exitCode:" + + "$nl$errWriter" + + "$nl$outWriter." throw IllegalStateException(errorMsg) } } diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/StringExtensions.kt b/buildSrc/src/main/kotlin/io/spine/gradle/StringExtensions.kt similarity index 91% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/StringExtensions.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/StringExtensions.kt index ae19007..a185892 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/StringExtensions.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/StringExtensions.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,7 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle +package io.spine.gradle /** * Returns `true` if the version of a project contains `snapshot` (in any case), diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/TaskName.kt b/buildSrc/src/main/kotlin/io/spine/gradle/TaskName.kt similarity index 93% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/TaskName.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/TaskName.kt index e6967b4..7c7abd1 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/TaskName.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/TaskName.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,7 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle +package io.spine.gradle import kotlin.reflect.KClass import org.gradle.api.Task diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/VersionWriter.kt b/buildSrc/src/main/kotlin/io/spine/gradle/VersionWriter.kt similarity index 97% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/VersionWriter.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/VersionWriter.kt index 79ae732..d3d4323 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/VersionWriter.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/VersionWriter.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,7 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle +package io.spine.gradle import java.util.* import org.gradle.api.DefaultTask diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/base/Tasks.kt b/buildSrc/src/main/kotlin/io/spine/gradle/base/Tasks.kt similarity index 91% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/base/Tasks.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/base/Tasks.kt index 1029071..c77b795 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/base/Tasks.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/base/Tasks.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,7 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.base +package io.spine.gradle.base import org.gradle.api.Task import org.gradle.api.tasks.Delete @@ -77,8 +77,8 @@ val TaskContainer.assemble: TaskProvider * * Intended to build everything, including running all tests, producing the production artifacts * and generating documentation. One will probably rarely attach concrete tasks directly - * to `build` as [assemble][io.spine.internal.gradle.base.assemble] and - * [check][io.spine.internal.gradle.base.check] are typically more appropriate. + * to `build` as [assemble][io.spine.gradle.base.assemble] and + * [check][io.spine.gradle.base.check] are typically more appropriate. * * @see * Tasks | The Base Plugin diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/checkstyle/CheckStyleConfig.kt b/buildSrc/src/main/kotlin/io/spine/gradle/checkstyle/CheckStyleConfig.kt similarity index 82% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/checkstyle/CheckStyleConfig.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/checkstyle/CheckStyleConfig.kt index e3a0ef2..122a604 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/checkstyle/CheckStyleConfig.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/checkstyle/CheckStyleConfig.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,11 +24,10 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.checkstyle +package io.spine.gradle.checkstyle -import io.spine.internal.dependency.CheckStyle +import io.spine.dependency.build.CheckStyle import org.gradle.api.Project -import org.gradle.api.plugins.quality.Checkstyle import org.gradle.api.plugins.quality.CheckstyleExtension import org.gradle.api.plugins.quality.CheckstylePlugin import org.gradle.kotlin.dsl.the @@ -65,9 +64,13 @@ object CheckStyleConfig { } project.afterEvaluate { - // Disables checking the test sources. - val checkstyleTest = project.tasks.findByName("checkstyleTest") as Checkstyle - checkstyleTest.enabled = false + // Disables checking the test sources and test fixtures. + arrayOf( + "checkstyleTest", + "checkstyleTestFixtures" + ).forEach { + task -> tasks.findByName(task)?.enabled = false + } } } } diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/dart/DartContext.kt b/buildSrc/src/main/kotlin/io/spine/gradle/dart/DartContext.kt similarity index 92% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/dart/DartContext.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/dart/DartContext.kt index 2f33b28..c32c10f 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/dart/DartContext.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/dart/DartContext.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,7 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.dart +package io.spine.gradle.dart import org.gradle.api.Project import org.gradle.api.tasks.Exec diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/dart/DartEnvironment.kt b/buildSrc/src/main/kotlin/io/spine/gradle/dart/DartEnvironment.kt similarity index 97% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/dart/DartEnvironment.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/dart/DartEnvironment.kt index 7b10f64..4e4ae83 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/dart/DartEnvironment.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/dart/DartEnvironment.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,7 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.dart +package io.spine.gradle.dart import java.io.File import org.apache.tools.ant.taskdefs.condition.Os diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/dart/DartExtension.kt b/buildSrc/src/main/kotlin/io/spine/gradle/dart/DartExtension.kt similarity index 96% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/dart/DartExtension.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/dart/DartExtension.kt index cf585a9..57a2bcf 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/dart/DartExtension.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/dart/DartExtension.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,10 +24,10 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.dart +package io.spine.gradle.dart -import io.spine.internal.gradle.dart.task.DartTasks -import io.spine.internal.gradle.dart.plugin.DartPlugins +import io.spine.gradle.dart.plugin.DartPlugins +import io.spine.gradle.dart.task.DartTasks import org.gradle.api.Project import org.gradle.kotlin.dsl.create import org.gradle.kotlin.dsl.findByType diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/dart/plugin/DartPlugins.kt b/buildSrc/src/main/kotlin/io/spine/gradle/dart/plugin/DartPlugins.kt similarity index 89% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/dart/plugin/DartPlugins.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/dart/plugin/DartPlugins.kt index 061e2ad..9d76a77 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/dart/plugin/DartPlugins.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/dart/plugin/DartPlugins.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,10 +24,10 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.dart.plugin +package io.spine.gradle.dart.plugin -import io.spine.internal.gradle.dart.DartContext -import io.spine.internal.gradle.dart.DartEnvironment +import io.spine.gradle.dart.DartContext +import io.spine.gradle.dart.DartEnvironment import org.gradle.api.Project import org.gradle.api.plugins.ExtensionContainer import org.gradle.api.plugins.PluginContainer @@ -63,8 +63,8 @@ import org.gradle.api.tasks.TaskContainer * And here's how to apply it in `build.gradle.kts`: * * ``` - * import io.spine.internal.gradle.dart.dart - * import io.spine.internal.gradle.dart.plugins.fooBar + * import io.spine.gradle.dart.dart + * import io.spine.gradle.dart.plugins.fooBar * * // ... * diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/dart/plugin/Protobuf.kt b/buildSrc/src/main/kotlin/io/spine/gradle/dart/plugin/Protobuf.kt similarity index 78% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/dart/plugin/Protobuf.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/dart/plugin/Protobuf.kt index 350f0fb..bfd503f 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/dart/plugin/Protobuf.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/dart/plugin/Protobuf.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,14 +24,12 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.dart.plugin +package io.spine.gradle.dart.plugin -import com.google.protobuf.gradle.builtins +import com.google.protobuf.gradle.ProtobufExtension import com.google.protobuf.gradle.id -import com.google.protobuf.gradle.plugins -import com.google.protobuf.gradle.protobuf import com.google.protobuf.gradle.remove -import io.spine.internal.dependency.Protobuf +import io.spine.dependency.lib.Protobuf /** * Applies `protobuf` plugin and configures `GenerateProtoTask` to work with a Dart module. @@ -42,9 +40,10 @@ fun DartPlugins.protobuf() { plugins.apply(Protobuf.GradlePlugin.id) - project.protobuf { - generateProtoTasks.all().forEach { task -> - task.apply { + val protobufExtension = project.extensions.getByType(ProtobufExtension::class.java) + protobufExtension.apply { + generateProtoTasks.all().configureEach { + apply { plugins { id("dart") } builtins { remove("java") } } diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/dart/task/Build.kt b/buildSrc/src/main/kotlin/io/spine/gradle/dart/task/Build.kt similarity index 89% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/dart/task/Build.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/dart/task/Build.kt index 79c387c..163747e 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/dart/task/Build.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/dart/task/Build.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,14 +24,14 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.dart.task +package io.spine.gradle.dart.task -import io.spine.internal.gradle.TaskName -import io.spine.internal.gradle.base.assemble -import io.spine.internal.gradle.base.check -import io.spine.internal.gradle.base.clean -import io.spine.internal.gradle.named -import io.spine.internal.gradle.register +import io.spine.gradle.TaskName +import io.spine.gradle.base.assemble +import io.spine.gradle.base.check +import io.spine.gradle.base.clean +import io.spine.gradle.named +import io.spine.gradle.register import org.gradle.api.tasks.Delete import org.gradle.api.tasks.Exec import org.gradle.api.tasks.TaskContainer @@ -49,8 +49,8 @@ import org.gradle.api.tasks.TaskProvider * An example of how to apply it in `build.gradle.kts`: * * ``` - * import io.spine.internal.gradle.dart.dart - * import io.spine.internal.gradle.dart.task.build + * import io.spine.gradle.dart.dart + * import io.spine.gradle.dart.task.build * * // ... * diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/dart/task/DartTasks.kt b/buildSrc/src/main/kotlin/io/spine/gradle/dart/task/DartTasks.kt similarity index 85% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/dart/task/DartTasks.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/dart/task/DartTasks.kt index 5ebe927..bc5e1e9 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/dart/task/DartTasks.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/dart/task/DartTasks.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,10 +24,10 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.dart.task +package io.spine.gradle.dart.task -import io.spine.internal.gradle.dart.DartContext -import io.spine.internal.gradle.dart.DartEnvironment +import io.spine.gradle.dart.DartContext +import io.spine.gradle.dart.DartEnvironment import org.gradle.api.Project import org.gradle.api.tasks.TaskContainer @@ -43,7 +43,7 @@ import org.gradle.api.tasks.TaskContainer * Supposing, one needs to create a new task that would participate in building. Let the task name * be `testDart`. To do that, several steps should be completed: * - * 1. Define the task name and type using [TaskName][io.spine.internal.gradle.TaskName]. + * 1. Define the task name and type using [TaskName][io.spine.gradle.TaskName]. * 2. Create a public typed reference for the task upon [TaskContainer]. It would facilitate * referencing to the new task, so that external tasks could depend on it. This reference * should be documented. @@ -53,9 +53,9 @@ import org.gradle.api.tasks.TaskContainer * Here's an example of `testDart()` extension: * * ``` - * import io.spine.internal.gradle.named - * import io.spine.internal.gradle.register - * import io.spine.internal.gradle.TaskName + * import io.spine.gradle.named + * import io.spine.gradle.register + * import io.spine.gradle.TaskName * import org.gradle.api.Task * import org.gradle.api.tasks.TaskContainer * import org.gradle.api.tasks.Exec @@ -85,8 +85,8 @@ import org.gradle.api.tasks.TaskContainer * And here's how to apply it in `build.gradle.kts`: * * ``` - * import io.spine.internal.gradle.dart.dart - * import io.spine.internal.gradle.dart.task.testDart + * import io.spine.gradle.dart.dart + * import io.spine.gradle.dart.task.testDart * * // ... * diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/dart/task/IntegrationTest.kt b/buildSrc/src/main/kotlin/io/spine/gradle/dart/task/IntegrationTest.kt similarity index 86% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/dart/task/IntegrationTest.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/dart/task/IntegrationTest.kt index f12b96f..19f1f14 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/dart/task/IntegrationTest.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/dart/task/IntegrationTest.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,11 +24,11 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.dart.task +package io.spine.gradle.dart.task -import io.spine.internal.gradle.TaskName -import io.spine.internal.gradle.named -import io.spine.internal.gradle.register +import io.spine.gradle.TaskName +import io.spine.gradle.named +import io.spine.gradle.register import org.gradle.api.tasks.Exec import org.gradle.api.tasks.TaskContainer import org.gradle.api.tasks.TaskProvider @@ -57,9 +57,9 @@ val TaskContainer.integrationTest: TaskProvider * Here's an example of how to apply it in `build.gradle.kts`: * * ``` - * import io.spine.internal.gradle.dart.dart - * import io.spine.internal.gradle.task.build - * import io.spine.internal.gradle.task.integrationTest + * import io.spine.gradle.dart.dart + * import io.spine.gradle.task.build + * import io.spine.gradle.task.integrationTest * * // ... * @@ -71,6 +71,7 @@ val TaskContainer.integrationTest: TaskProvider * } * ``` */ +@Suppress("unused") fun DartTasks.integrationTest() = register(integrationTestName) { diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/dart/task/Publish.kt b/buildSrc/src/main/kotlin/io/spine/gradle/dart/task/Publish.kt similarity index 89% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/dart/task/Publish.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/dart/task/Publish.kt index 92eb290..2f8df6b 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/dart/task/Publish.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/dart/task/Publish.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,13 +24,13 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.dart.task +package io.spine.gradle.dart.task -import io.spine.internal.gradle.TaskName -import io.spine.internal.gradle.base.assemble -import io.spine.internal.gradle.publish.publish -import io.spine.internal.gradle.named -import io.spine.internal.gradle.register +import io.spine.gradle.TaskName +import io.spine.gradle.base.assemble +import io.spine.gradle.named +import io.spine.gradle.publish.publish +import io.spine.gradle.register import org.gradle.api.tasks.Copy import org.gradle.api.tasks.Exec import org.gradle.api.tasks.TaskContainer @@ -51,9 +51,9 @@ import org.gradle.api.tasks.TaskProvider * Usage example: * * ``` - * import io.spine.internal.gradle.dart.dart - * import io.spine.internal.gradle.dart.task.build - * import io.spine.internal.gradle.dart.task.publish + * import io.spine.gradle.dart.dart + * import io.spine.gradle.dart.task.build + * import io.spine.gradle.dart.task.publish * * // ... * @@ -83,7 +83,7 @@ private val stagePubPublicationName = TaskName.of("stagePubPublication", Copy::c * Locates `stagePubPublication` in this [TaskContainer]. * * The task prepares the Dart package for Pub publication in the - * [publication directory][io.spine.internal.gradle.dart.DartEnvironment.publicationDir]. + * [publication directory][io.spine.gradle.dart.DartEnvironment.publicationDir]. */ val TaskContainer.stagePubPublication: TaskProvider get() = named(stagePubPublicationName) @@ -110,7 +110,7 @@ private fun DartTasks.stagePubPublication(): TaskProvider = into(publicationDir) doLast { - logger.debug("Pub publication is prepared in directory `$publicationDir`.") + logger.debug("Pub publication is prepared in directory `{}`.", publicationDir) } } diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/dokka/DokkaExtensions.kt b/buildSrc/src/main/kotlin/io/spine/gradle/dokka/DokkaExtensions.kt similarity index 92% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/dokka/DokkaExtensions.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/dokka/DokkaExtensions.kt index a912d50..727a079 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/dokka/DokkaExtensions.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/dokka/DokkaExtensions.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,7 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.dokka +package io.spine.gradle.dokka import java.io.File import org.gradle.api.file.FileCollection @@ -38,6 +38,7 @@ import org.jetbrains.dokka.gradle.GradleDokkaSourceSetBuilder * Dokka can properly generate documentation for either Kotlin or Java depending on * the configuration, but not both. */ +@Suppress("unused") internal fun GradleDokkaSourceSetBuilder.onlyJavaSources(): FileCollection { return sourceRoots.filter(File::isJavaSourceDirectory) } diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/dokka/TaskContainerExtensions.kt b/buildSrc/src/main/kotlin/io/spine/gradle/dokka/TaskContainerExtensions.kt similarity index 90% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/dokka/TaskContainerExtensions.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/dokka/TaskContainerExtensions.kt index 058eb99..02deead 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/dokka/TaskContainerExtensions.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/dokka/TaskContainerExtensions.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,7 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.dokka +package io.spine.gradle.dokka import org.gradle.api.tasks.TaskContainer import org.jetbrains.dokka.gradle.DokkaTask @@ -32,4 +32,5 @@ import org.jetbrains.dokka.gradle.DokkaTask /** * Finds the `dokkaHtml` Gradle task. */ +@Suppress("unused") fun TaskContainer.dokkaHtmlTask() = this.getByName("dokkaHtml") as DokkaTask diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/fs/LazyTempPath.kt b/buildSrc/src/main/kotlin/io/spine/gradle/fs/LazyTempPath.kt similarity index 96% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/fs/LazyTempPath.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/fs/LazyTempPath.kt index 9f48371..f6e1777 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/fs/LazyTempPath.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/fs/LazyTempPath.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,7 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.fs +package io.spine.gradle.fs import java.io.File import java.net.URI diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/git/Branch.kt b/buildSrc/src/main/kotlin/io/spine/gradle/git/Branch.kt similarity index 91% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/git/Branch.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/git/Branch.kt index 47ddd30..a10a65f 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/git/Branch.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/git/Branch.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,7 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.git +package io.spine.gradle.git /** * Branch names. diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/git/Repository.kt b/buildSrc/src/main/kotlin/io/spine/gradle/git/Repository.kt similarity index 85% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/git/Repository.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/git/Repository.kt index 824003c..55ce67f 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/git/Repository.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/git/Repository.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,10 +24,10 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.git +package io.spine.gradle.git -import io.spine.internal.gradle.Cli -import io.spine.internal.gradle.fs.LazyTempPath +import io.spine.gradle.Cli +import io.spine.gradle.fs.LazyTempPath /** * Interacts with a real Git repository. @@ -44,43 +44,31 @@ import io.spine.internal.gradle.fs.LazyTempPath * release of resources please use the provided functionality inside a `use` block or * call the `close` method manually. */ -class Repository : AutoCloseable { - /** - * The GitHub SSH URL to the underlying repository. - */ - val sshUrl: String +class Repository private constructor( /** - * Path to the temporal folder for a clone of the underlying repository. + * The GitHub SSH URL to the underlying repository. */ - val location = LazyTempPath("repoTemp") + private val sshUrl: String, /** * Current user configuration. * - * This configuration determines what ends up in author and commiter fields of a commit. + * This configuration determines what ends up in author and committer fields of a commit. */ - var user: UserInfo - get() = field - private set(value) { - field = value - } + private var user: UserInfo, /** * Currently checked out branch. */ - var currentBranch: String - get() = field - private set(value) { - field = value - } + private var currentBranch: String +) : AutoCloseable { - private constructor(sshUrl: String, user: UserInfo, branch: String) { - this.sshUrl = sshUrl - this.user = user - this.currentBranch = branch - } + /** + * Path to the temporal folder for a clone of the underlying repository. + */ + val location = LazyTempPath("repoTemp") /** * Clones the repository with [the SSH url][sshUrl] into the [temporal folder][location]. @@ -101,7 +89,7 @@ class Repository : AutoCloseable { fun checkout(branch: String) { repoExecute("git", "checkout", branch) - this.currentBranch = branch + currentBranch = branch } /** @@ -109,7 +97,7 @@ class Repository : AutoCloseable { * * Overwrites `user.name` and `user.email` settings locally in [location] with * values from [user]. These settings determine what ends up in author and - * commiter fields of a commit. + * committer fields of a commit. */ fun configureUser(user: UserInfo) { repoExecute("git", "config", "user.name", user.name) diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/git/UserInfo.kt b/buildSrc/src/main/kotlin/io/spine/gradle/git/UserInfo.kt similarity index 92% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/git/UserInfo.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/git/UserInfo.kt index 310e721..bc9f08d 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/git/UserInfo.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/git/UserInfo.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,7 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.git +package io.spine.gradle.git /** * Contains information about a Git user. diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/github/pages/AuthorEmail.kt b/buildSrc/src/main/kotlin/io/spine/gradle/github/pages/AuthorEmail.kt similarity index 93% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/github/pages/AuthorEmail.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/github/pages/AuthorEmail.kt index 7eb4f9c..f0d839f 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/github/pages/AuthorEmail.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/github/pages/AuthorEmail.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,7 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.github.pages +package io.spine.gradle.github.pages /** * An author of updates to GitHub pages. diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/github/pages/RepositoryExtensions.kt b/buildSrc/src/main/kotlin/io/spine/gradle/github/pages/RepositoryExtensions.kt similarity index 87% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/github/pages/RepositoryExtensions.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/github/pages/RepositoryExtensions.kt index 617ee94..94ab6ac 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/github/pages/RepositoryExtensions.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/github/pages/RepositoryExtensions.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,12 +24,12 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.github.pages +package io.spine.gradle.github.pages -import io.spine.internal.gradle.RepoSlug -import io.spine.internal.gradle.git.Branch -import io.spine.internal.gradle.git.Repository -import io.spine.internal.gradle.git.UserInfo +import io.spine.gradle.RepoSlug +import io.spine.gradle.git.Branch +import io.spine.gradle.git.Repository +import io.spine.gradle.git.UserInfo /** * Clones the current project repository with the branch dedicated to publishing diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/github/pages/SshKey.kt b/buildSrc/src/main/kotlin/io/spine/gradle/github/pages/SshKey.kt similarity index 95% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/github/pages/SshKey.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/github/pages/SshKey.kt index 4bda3f7..186c474 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/github/pages/SshKey.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/github/pages/SshKey.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,9 +24,9 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.github.pages +package io.spine.gradle.github.pages -import io.spine.internal.gradle.Cli +import io.spine.gradle.Cli import java.io.File import org.gradle.api.GradleException diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/github/pages/TaskName.kt b/buildSrc/src/main/kotlin/io/spine/gradle/github/pages/TaskName.kt similarity index 92% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/github/pages/TaskName.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/github/pages/TaskName.kt index 82f9a6e..f5e3bfc 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/github/pages/TaskName.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/github/pages/TaskName.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,7 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.github.pages +package io.spine.gradle.github.pages object TaskName { diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/github/pages/Update.kt b/buildSrc/src/main/kotlin/io/spine/gradle/github/pages/Update.kt similarity index 83% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/github/pages/Update.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/github/pages/Update.kt index f237156..0f9a0f5 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/github/pages/Update.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/github/pages/Update.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,8 +24,9 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.github.pages +package io.spine.gradle.github.pages +import io.spine.gradle.git.Repository import java.io.File import java.nio.file.Path import org.gradle.api.Project @@ -33,7 +34,6 @@ import org.gradle.api.Task import org.gradle.api.file.ConfigurableFileCollection import org.gradle.api.file.FileCollection import org.gradle.api.logging.Logger -import io.spine.internal.gradle.git.Repository /** * Performs the update of GitHub pages. @@ -90,25 +90,33 @@ private abstract class UpdateDocumentation( File("${repository.location}/${docsDestinationFolder}/${project.name}") } + private fun logDebug(message: () -> String) { + if (logger.isDebugEnabled) { + logger.debug(message()) + } + } + fun run() { val module = project.name - logger.debug("Update of the $toolName documentation for module `$module` started.") + logDebug {"Update of the $toolName documentation for module `$module` started." } val documentation = replaceMostRecentDocs() copyIntoVersionDir(documentation) val version = project.version - val updateMessage = "Update $toolName documentation for module `$module` as for " + - "version $version" + val updateMessage = + "Update `$toolName` documentation for module `$module` as for version $version" repository.commitAllChanges(updateMessage) - logger.debug("Update of the $toolName documentation for `$module` successfully finished.") + logDebug { "Update of the `$toolName` documentation for `$module` successfully finished." } } private fun replaceMostRecentDocs(): ConfigurableFileCollection { val generatedDocs = project.files(docsSourceFolder) - logger.debug("Replacing the most recent $toolName documentation in ${mostRecentFolder}.") + logDebug { + "Replacing the most recent `$toolName` documentation in `${mostRecentFolder}`." + } copyDocs(generatedDocs, mostRecentFolder) return generatedDocs @@ -125,7 +133,9 @@ private abstract class UpdateDocumentation( private fun copyIntoVersionDir(generatedDocs: ConfigurableFileCollection) { val versionedDocDir = File("$mostRecentFolder/v/${project.version}") - logger.debug("Storing the new version of $toolName documentation in `${versionedDocDir}.") + logDebug { + "Storing the new version of `$toolName` documentation in `${versionedDocDir}`." + } copyDocs(generatedDocs, versionedDocDir) } } diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/github/pages/UpdateGitHubPages.kt b/buildSrc/src/main/kotlin/io/spine/gradle/github/pages/UpdateGitHubPages.kt similarity index 92% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/github/pages/UpdateGitHubPages.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/github/pages/UpdateGitHubPages.kt index 87d160a..e46a565 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/github/pages/UpdateGitHubPages.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/github/pages/UpdateGitHubPages.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,16 +24,16 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.github.pages +package io.spine.gradle.github.pages -import io.spine.internal.gradle.dokka.dokkaHtmlTask -import io.spine.internal.gradle.fs.LazyTempPath -import io.spine.internal.gradle.github.pages.TaskName.copyDokka -import io.spine.internal.gradle.github.pages.TaskName.copyJavadoc -import io.spine.internal.gradle.github.pages.TaskName.updateGitHubPages -import io.spine.internal.gradle.isSnapshot -import io.spine.internal.gradle.javadoc.ExcludeInternalDoclet -import io.spine.internal.gradle.javadoc.javadocTask +import dokkaHtmlTask +import io.spine.gradle.fs.LazyTempPath +import io.spine.gradle.github.pages.TaskName.copyDokka +import io.spine.gradle.github.pages.TaskName.copyJavadoc +import io.spine.gradle.github.pages.TaskName.updateGitHubPages +import io.spine.gradle.isSnapshot +import io.spine.gradle.javadoc.ExcludeInternalDoclet +import io.spine.gradle.javadoc.javadocTask import java.io.File import org.gradle.api.Plugin import org.gradle.api.Project @@ -205,7 +205,9 @@ class UpdateGitHubPages : Plugin { private fun TaskContainer.composeDokkaInputs(): List { val inputs = mutableListOf() - inputs.add(dokkaHtmlTask()) + dokkaHtmlTask()?.let { + inputs.add(it) + } inputs.addAll(includedInputs) return inputs diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/github/pages/UpdateGitHubPagesExtension.kt b/buildSrc/src/main/kotlin/io/spine/gradle/github/pages/UpdateGitHubPagesExtension.kt similarity index 94% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/github/pages/UpdateGitHubPagesExtension.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/github/pages/UpdateGitHubPagesExtension.kt index 778d841..90eebc2 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/github/pages/UpdateGitHubPagesExtension.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/github/pages/UpdateGitHubPagesExtension.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,7 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.github.pages +package io.spine.gradle.github.pages import java.io.File import org.gradle.api.Project @@ -78,7 +78,7 @@ private constructor( /** * The version of the - * [ExcludeInternalDoclet][io.spine.internal.gradle.javadoc.ExcludeInternalDoclet] + * [ExcludeInternalDoclet][io.spine.gradle.javadoc.ExcludeInternalDoclet] * used when updating documentation at GitHub Pages. * * This value is used when adding dependency on the doclet when the plugin tasks diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/java/Tasks.kt b/buildSrc/src/main/kotlin/io/spine/gradle/java/Tasks.kt similarity index 92% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/java/Tasks.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/java/Tasks.kt index 8f2344f..12d4d56 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/java/Tasks.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/java/Tasks.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,7 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.java +package io.spine.gradle.java import org.gradle.api.tasks.TaskContainer import org.gradle.api.tasks.TaskProvider diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/javac/ErrorProne.kt b/buildSrc/src/main/kotlin/io/spine/gradle/javac/ErrorProne.kt similarity index 94% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/javac/ErrorProne.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/javac/ErrorProne.kt index 7a97cab..84c6bcb 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/javac/ErrorProne.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/javac/ErrorProne.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,7 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.javac +package io.spine.gradle.javac import net.ltgt.gradle.errorprone.errorprone import org.gradle.api.tasks.compile.JavaCompile @@ -51,6 +51,7 @@ import org.gradle.process.CommandLineArgumentProvider */ @Suppress("unused") fun JavaCompile.configureErrorProne() { + options.compilerArgs.add("--should-stop=ifError=FLOW") options.errorprone .errorproneArgumentProviders .add(ErrorProneConfig.ARGUMENTS) diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/javac/Javac.kt b/buildSrc/src/main/kotlin/io/spine/gradle/javac/Javac.kt similarity index 94% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/javac/Javac.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/javac/Javac.kt index 839252d..44223cb 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/javac/Javac.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/javac/Javac.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,7 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.javac +package io.spine.gradle.javac import org.gradle.api.tasks.compile.JavaCompile import org.gradle.process.CommandLineArgumentProvider diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/javadoc/Encoding.kt b/buildSrc/src/main/kotlin/io/spine/gradle/javadoc/Encoding.kt similarity index 90% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/javadoc/Encoding.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/javadoc/Encoding.kt index f712968..052a1aa 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/javadoc/Encoding.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/javadoc/Encoding.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,7 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.javadoc +package io.spine.gradle.javadoc /** * The encoding to use in Javadoc processing. diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/javadoc/ExcludeInternalDoclet.kt b/buildSrc/src/main/kotlin/io/spine/gradle/javadoc/ExcludeInternalDoclet.kt similarity index 86% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/javadoc/ExcludeInternalDoclet.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/javadoc/ExcludeInternalDoclet.kt index 72d7f6a..541504c 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/javadoc/ExcludeInternalDoclet.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/javadoc/ExcludeInternalDoclet.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,10 +24,12 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.javadoc +package io.spine.gradle.javadoc -import io.spine.internal.gradle.javadoc.ExcludeInternalDoclet.Companion.taskName -import io.spine.internal.gradle.sourceSets +import io.spine.dependency.local.ArtifactVersion +import io.spine.dependency.local.Spine +import io.spine.gradle.javadoc.ExcludeInternalDoclet.Companion.taskName +import io.spine.gradle.sourceSets import org.gradle.api.Project import org.gradle.api.artifacts.Configuration import org.gradle.api.tasks.javadoc.Javadoc @@ -36,9 +38,13 @@ import org.gradle.external.javadoc.StandardJavadocDocletOptions /** * The doclet which removes Javadoc for `@Internal` things in the Java code. */ -class ExcludeInternalDoclet(val version: String) { +@Suppress("ConstPropertyName") +class ExcludeInternalDoclet( + @Deprecated("`Spine.ArtifactVersion.javadocTools` is used instead.") + val version: String = ArtifactVersion.javadocTools +) { - private val dependency = "io.spine.tools:spine-javadoc-filter:${version}" + private val dependency = Spine.javadocFilter companion object { diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/javadoc/JavadocConfig.kt b/buildSrc/src/main/kotlin/io/spine/gradle/javadoc/JavadocConfig.kt similarity index 94% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/javadoc/JavadocConfig.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/javadoc/JavadocConfig.kt index f6002ca..d2e4c90 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/javadoc/JavadocConfig.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/javadoc/JavadocConfig.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,7 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.javadoc +package io.spine.gradle.javadoc import java.io.File import org.gradle.api.JavaVersion @@ -43,9 +43,9 @@ object JavadocConfig { /** * Link to the documentation for Java 11 Standard Library API. * - * OpenJDK SE 11 is used for the reference. + * Oracle JDK SE 11 is used for the reference. */ - private const val standardLibraryAPI = "https://cr.openjdk.java.net/~iris/se/11/latestSpec/api/" + private const val standardLibraryAPI = "https://docs.oracle.com/en/java/javase/11/docs/api/" @Suppress("MemberVisibilityCanBePrivate") // opened to be visible from docs. val tags = listOf( diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/javadoc/JavadocTag.kt b/buildSrc/src/main/kotlin/io/spine/gradle/javadoc/JavadocTag.kt similarity index 90% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/javadoc/JavadocTag.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/javadoc/JavadocTag.kt index 2a278bd..a6224a5 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/javadoc/JavadocTag.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/javadoc/JavadocTag.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,7 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.javadoc +package io.spine.gradle.javadoc /** * The Javadoc tag. diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/javadoc/TaskContainerExtensions.kt b/buildSrc/src/main/kotlin/io/spine/gradle/javadoc/TaskContainerExtensions.kt similarity index 91% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/javadoc/TaskContainerExtensions.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/javadoc/TaskContainerExtensions.kt index f80d53e..7e5b517 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/javadoc/TaskContainerExtensions.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/javadoc/TaskContainerExtensions.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,7 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.javadoc +package io.spine.gradle.javadoc import org.gradle.api.tasks.TaskContainer import org.gradle.api.tasks.javadoc.Javadoc diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/javascript/JsContext.kt b/buildSrc/src/main/kotlin/io/spine/gradle/javascript/JsContext.kt similarity index 86% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/javascript/JsContext.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/javascript/JsContext.kt index 8754173..ec5d872 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/javascript/JsContext.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/javascript/JsContext.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,10 +24,12 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.javascript +package io.spine.gradle.javascript import java.io.File import org.gradle.api.Project +import org.gradle.kotlin.dsl.support.serviceOf +import org.gradle.process.ExecOperations /** * Provides access to the current [JsEnvironment] and shortcuts for running `npm` tool. @@ -47,8 +49,7 @@ open class JsContext(jsEnv: JsEnvironment, internal val project: Project) * * This [File] is used as a working directory. */ - fun File.npm(vararg args: String) = project.exec { - + fun File.npm(vararg args: String) = project.serviceOf().exec { workingDir(this@npm) commandLine(npmExecutable) args(*args) diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/javascript/JsEnvironment.kt b/buildSrc/src/main/kotlin/io/spine/gradle/javascript/JsEnvironment.kt similarity index 98% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/javascript/JsEnvironment.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/javascript/JsEnvironment.kt index f2d10ac..c2dc68e 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/javascript/JsEnvironment.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/javascript/JsEnvironment.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,7 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.javascript +package io.spine.gradle.javascript import java.io.File import org.apache.tools.ant.taskdefs.condition.Os diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/javascript/JsExtension.kt b/buildSrc/src/main/kotlin/io/spine/gradle/javascript/JsExtension.kt similarity index 95% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/javascript/JsExtension.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/javascript/JsExtension.kt index 4fe1d3f..69c3e26 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/javascript/JsExtension.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/javascript/JsExtension.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,10 +24,10 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.javascript +package io.spine.gradle.javascript -import io.spine.internal.gradle.javascript.task.JsTasks -import io.spine.internal.gradle.javascript.plugin.JsPlugins +import io.spine.gradle.javascript.plugin.JsPlugins +import io.spine.gradle.javascript.task.JsTasks import org.gradle.api.Project import org.gradle.kotlin.dsl.create import org.gradle.kotlin.dsl.extra diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/javascript/plugin/Idea.kt b/buildSrc/src/main/kotlin/io/spine/gradle/javascript/plugin/Idea.kt similarity index 93% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/javascript/plugin/Idea.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/javascript/plugin/Idea.kt index f409016..087dd25 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/javascript/plugin/Idea.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/javascript/plugin/Idea.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,7 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.javascript.plugin +package io.spine.gradle.javascript.plugin import org.gradle.kotlin.dsl.configure import org.gradle.plugins.ide.idea.model.IdeaModel diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/javascript/plugin/JsPlugins.kt b/buildSrc/src/main/kotlin/io/spine/gradle/javascript/plugin/JsPlugins.kt similarity index 88% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/javascript/plugin/JsPlugins.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/javascript/plugin/JsPlugins.kt index 6a17820..b478f64 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/javascript/plugin/JsPlugins.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/javascript/plugin/JsPlugins.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,10 +24,10 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.javascript.plugin +package io.spine.gradle.javascript.plugin -import io.spine.internal.gradle.javascript.JsContext -import io.spine.internal.gradle.javascript.JsEnvironment +import io.spine.gradle.javascript.JsContext +import io.spine.gradle.javascript.JsEnvironment import org.gradle.api.Project import org.gradle.api.plugins.ExtensionContainer import org.gradle.api.plugins.PluginContainer @@ -63,8 +63,8 @@ import org.gradle.api.tasks.TaskContainer * And here's how to apply it in `build.gradle.kts`: * * ``` - * import io.spine.internal.gradle.javascript.javascript - * import io.spine.internal.gradle.javascript.plugins.fooBar + * import io.spine.gradle.javascript.javascript + * import io.spine.gradle.javascript.plugins.fooBar * * // ... * diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/javascript/plugin/McJs.kt b/buildSrc/src/main/kotlin/io/spine/gradle/javascript/plugin/McJs.kt similarity index 93% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/javascript/plugin/McJs.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/javascript/plugin/McJs.kt index 56b1263..2efa4a4 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/javascript/plugin/McJs.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/javascript/plugin/McJs.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,7 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.javascript.plugin +package io.spine.gradle.javascript.plugin import org.gradle.api.Task import org.gradle.api.tasks.TaskContainer diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/javascript/plugin/Protobuf.kt b/buildSrc/src/main/kotlin/io/spine/gradle/javascript/plugin/Protobuf.kt similarity index 85% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/javascript/plugin/Protobuf.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/javascript/plugin/Protobuf.kt index d99d2a2..c1c2d64 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/javascript/plugin/Protobuf.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/javascript/plugin/Protobuf.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,15 +24,12 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.javascript.plugin +package io.spine.gradle.javascript.plugin -import com.google.protobuf.gradle.builtins -import com.google.protobuf.gradle.generateProtoTasks +import com.google.protobuf.gradle.ProtobufExtension import com.google.protobuf.gradle.id -import com.google.protobuf.gradle.protobuf -import com.google.protobuf.gradle.protoc import com.google.protobuf.gradle.remove -import io.spine.internal.dependency.Protobuf +import io.spine.dependency.lib.Protobuf /** * Applies and configures `protobuf` plugin to work with a JavaScript module. @@ -50,9 +47,8 @@ fun JsPlugins.protobuf() { apply(Protobuf.GradlePlugin.id) } - project.protobuf { - - generatedFilesBaseDir = projectDir.path + val protobufExt = project.extensions.getByType(ProtobufExtension::class.java) + protobufExt.apply { protoc { artifact = Protobuf.compiler diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/javascript/task/Assemble.kt b/buildSrc/src/main/kotlin/io/spine/gradle/javascript/task/Assemble.kt similarity index 88% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/javascript/task/Assemble.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/javascript/task/Assemble.kt index dbc770d..4b57a4e 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/javascript/task/Assemble.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/javascript/task/Assemble.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,16 +24,16 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.javascript.task +package io.spine.gradle.javascript.task import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.databind.node.ObjectNode import com.google.protobuf.gradle.GenerateProtoTask -import io.spine.internal.gradle.base.assemble -import io.spine.internal.gradle.javascript.plugin.generateJsonParsers -import io.spine.internal.gradle.named -import io.spine.internal.gradle.register -import io.spine.internal.gradle.TaskName +import io.spine.gradle.TaskName +import io.spine.gradle.base.assemble +import io.spine.gradle.javascript.plugin.generateJsonParsers +import io.spine.gradle.named +import io.spine.gradle.register import org.gradle.api.Task import org.gradle.api.tasks.TaskContainer import org.gradle.api.tasks.TaskProvider @@ -42,8 +42,8 @@ import org.gradle.kotlin.dsl.withType /** * Registers tasks for assembling JavaScript artifacts. * - * Please note, this task group depends on [mc-js][io.spine.internal.gradle.javascript.plugin.mcJs] - * and [protobuf][io.spine.internal.gradle.javascript.plugin.protobuf]` plugins. Therefore, + * Please note, this task group depends on [mc-js][io.spine.gradle.javascript.plugin.mcJs] + * and [protobuf][io.spine.gradle.javascript.plugin.protobuf]` plugins. Therefore, * these plugins should be applied in the first place. * * List of tasks to be created: @@ -56,8 +56,8 @@ import org.gradle.kotlin.dsl.withType * Here's an example of how to apply it in `build.gradle.kts`: * * ``` - * import io.spine.internal.gradle.javascript.javascript - * import io.spine.internal.gradle.javascript.task.assemble + * import io.spine.gradle.javascript.javascript + * import io.spine.gradle.javascript.task.assemble * * // ... * @@ -175,7 +175,7 @@ private val updatePackageVersionName = TaskName.of("updatePackageVersion") * Locates `updatePackageVersion` task in this [TaskContainer]. * * The task sets the module's version in `package.json` to the value of - * [moduleVersion][io.spine.internal.gradle.javascript.JsEnvironment.moduleVersion] + * [moduleVersion][io.spine.gradle.javascript.JsEnvironment.moduleVersion] * specified in the current `JsEnvironment`. */ val TaskContainer.updatePackageVersion: TaskProvider diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/javascript/task/Check.kt b/buildSrc/src/main/kotlin/io/spine/gradle/javascript/task/Check.kt similarity index 89% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/javascript/task/Check.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/javascript/task/Check.kt index 4fdd69f..d25c3c2 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/javascript/task/Check.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/javascript/task/Check.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,14 +24,14 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.javascript.task +package io.spine.gradle.javascript.task -import io.spine.internal.gradle.base.check -import io.spine.internal.gradle.java.test -import io.spine.internal.gradle.javascript.isWindows -import io.spine.internal.gradle.named -import io.spine.internal.gradle.register -import io.spine.internal.gradle.TaskName +import io.spine.gradle.TaskName +import io.spine.gradle.base.check +import io.spine.gradle.java.test +import io.spine.gradle.javascript.isWindows +import io.spine.gradle.named +import io.spine.gradle.register import org.gradle.api.Task import org.gradle.api.tasks.TaskContainer import org.gradle.api.tasks.TaskProvider @@ -52,9 +52,9 @@ import org.gradle.api.tasks.TaskProvider * Here's an example of how to apply it in `build.gradle.kts`: * * ``` - * import io.spine.internal.gradle.javascript.javascript - * import io.spine.internal.gradle.javascript.task.assemble - * import io.spine.internal.gradle.javascript.task.check + * import io.spine.gradle.javascript.javascript + * import io.spine.gradle.javascript.task.assemble + * import io.spine.gradle.javascript.task.check * * // ... * diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/javascript/task/Clean.kt b/buildSrc/src/main/kotlin/io/spine/gradle/javascript/task/Clean.kt similarity index 86% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/javascript/task/Clean.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/javascript/task/Clean.kt index 6658b83..c5ff835 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/javascript/task/Clean.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/javascript/task/Clean.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,12 +24,12 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.javascript.task +package io.spine.gradle.javascript.task -import io.spine.internal.gradle.base.clean -import io.spine.internal.gradle.named -import io.spine.internal.gradle.register -import io.spine.internal.gradle.TaskName +import io.spine.gradle.TaskName +import io.spine.gradle.base.clean +import io.spine.gradle.named +import io.spine.gradle.register import org.gradle.api.tasks.Delete import org.gradle.api.tasks.TaskContainer import org.gradle.api.tasks.TaskProvider @@ -48,9 +48,9 @@ import org.gradle.api.tasks.TaskProvider * Here's an example of how to apply it in `build.gradle.kts`: * * ``` - * import io.spine.internal.gradle.javascript.javascript - * import io.spine.internal.gradle.javascript.task.assemble - * import io.spine.internal.gradle.javascript.task.clean + * import io.spine.gradle.javascript.javascript + * import io.spine.gradle.javascript.task.assemble + * import io.spine.gradle.javascript.task.clean * * // ... * diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/javascript/task/IntegrationTest.kt b/buildSrc/src/main/kotlin/io/spine/gradle/javascript/task/IntegrationTest.kt similarity index 89% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/javascript/task/IntegrationTest.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/javascript/task/IntegrationTest.kt index fadcc09..227e33e 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/javascript/task/IntegrationTest.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/javascript/task/IntegrationTest.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,12 +24,12 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.javascript.task +package io.spine.gradle.javascript.task -import io.spine.internal.gradle.base.build -import io.spine.internal.gradle.named -import io.spine.internal.gradle.register -import io.spine.internal.gradle.TaskName +import io.spine.gradle.TaskName +import io.spine.gradle.base.build +import io.spine.gradle.named +import io.spine.gradle.register import org.gradle.api.Task import org.gradle.api.tasks.TaskContainer import org.gradle.api.tasks.TaskProvider @@ -61,8 +61,8 @@ val TaskContainer.integrationTest: TaskProvider * Here's an example of how to apply it in `build.gradle.kts`: * * ``` - * import io.spine.internal.gradle.javascript.javascript - * import io.spine.internal.gradle.javascript.task.integrationTest + * import io.spine.gradle.javascript.javascript + * import io.spine.gradle.javascript.task.integrationTest * * // ... * @@ -74,6 +74,7 @@ val TaskContainer.integrationTest: TaskProvider * } * ``` */ +@Suppress("unused") fun JsTasks.integrationTest() { linkSpineWebModule() diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/javascript/task/JsTasks.kt b/buildSrc/src/main/kotlin/io/spine/gradle/javascript/task/JsTasks.kt similarity index 85% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/javascript/task/JsTasks.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/javascript/task/JsTasks.kt index b384fd3..3cf6335 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/javascript/task/JsTasks.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/javascript/task/JsTasks.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,10 +24,10 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.javascript.task +package io.spine.gradle.javascript.task -import io.spine.internal.gradle.javascript.JsEnvironment -import io.spine.internal.gradle.javascript.JsContext +import io.spine.gradle.javascript.JsContext +import io.spine.gradle.javascript.JsEnvironment import org.gradle.api.Project import org.gradle.api.tasks.TaskContainer @@ -43,7 +43,7 @@ import org.gradle.api.tasks.TaskContainer * Supposing, one needs to create a new task that would participate in building. Let the task name * be `bundleJs`. To do that, several steps should be completed: * - * 1. Define the task name and type using [TaskName][io.spine.internal.gradle.TaskName]. + * 1. Define the task name and type using [TaskName][io.spine.gradle.TaskName]. * 2. Create a public typed reference for the task upon [TaskContainer]. It would facilitate * referencing to the new task, so that external tasks could depend on it. This reference * should be documented. @@ -53,9 +53,9 @@ import org.gradle.api.tasks.TaskContainer * Here's an example of `bundleJs()` extension: * * ``` - * import io.spine.internal.gradle.named - * import io.spine.internal.gradle.register - * import io.spine.internal.gradle.TaskName + * import io.spine.gradle.named + * import io.spine.gradle.register + * import io.spine.gradle.TaskName * import org.gradle.api.Task * import org.gradle.api.tasks.TaskContainer * import org.gradle.api.tasks.Exec @@ -85,8 +85,8 @@ import org.gradle.api.tasks.TaskContainer * And here's how to apply it in `build.gradle.kts`: * * ``` - * import io.spine.internal.gradle.javascript.javascript - * import io.spine.internal.gradle.javascript.task.bundleJs + * import io.spine.gradle.javascript.javascript + * import io.spine.gradle.javascript.task.bundleJs * * // ... * diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/javascript/task/LicenseReport.kt b/buildSrc/src/main/kotlin/io/spine/gradle/javascript/task/LicenseReport.kt similarity index 84% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/javascript/task/LicenseReport.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/javascript/task/LicenseReport.kt index 99935ed..c3b3a6a 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/javascript/task/LicenseReport.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/javascript/task/LicenseReport.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,12 +24,12 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.javascript.task +package io.spine.gradle.javascript.task -import io.spine.internal.gradle.named -import io.spine.internal.gradle.register -import io.spine.internal.gradle.report.license.generateLicenseReport -import io.spine.internal.gradle.TaskName +import io.spine.gradle.TaskName +import io.spine.gradle.named +import io.spine.gradle.register +import io.spine.gradle.report.license.generateLicenseReport import org.gradle.api.Task import org.gradle.api.tasks.TaskContainer import org.gradle.api.tasks.TaskProvider @@ -42,8 +42,8 @@ import org.gradle.api.tasks.TaskProvider * Here's an example of how to apply it in `build.gradle.kts`: * * ``` - * import io.spine.internal.gradle.javascript.javascript - * import io.spine.internal.gradle.javascript.task.clean + * import io.spine.gradle.javascript.javascript + * import io.spine.gradle.javascript.task.clean * * // ... * @@ -54,6 +54,7 @@ import org.gradle.api.tasks.TaskProvider * } * ``` */ +@Suppress("unused") fun JsTasks.licenseReport() { npmLicenseReport().also { generateLicenseReport.configure { diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/javascript/task/Publish.kt b/buildSrc/src/main/kotlin/io/spine/gradle/javascript/task/Publish.kt similarity index 87% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/javascript/task/Publish.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/javascript/task/Publish.kt index 486d831..7d1baea 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/javascript/task/Publish.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/javascript/task/Publish.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,12 +24,12 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.javascript.task +package io.spine.gradle.javascript.task -import io.spine.internal.gradle.publish.publish -import io.spine.internal.gradle.named -import io.spine.internal.gradle.register -import io.spine.internal.gradle.TaskName +import io.spine.gradle.TaskName +import io.spine.gradle.named +import io.spine.gradle.publish.publish +import io.spine.gradle.register import org.gradle.api.Task import org.gradle.api.tasks.TaskContainer import org.gradle.api.tasks.TaskProvider @@ -49,9 +49,9 @@ import org.gradle.api.tasks.TaskProvider * Here's an example of how to apply it in `build.gradle.kts`: * * ``` - * import io.spine.internal.gradle.javascript.javascript - * import io.spine.internal.gradle.javascript.task.assemble - * import io.spine.internal.gradle.javascript.task.publish + * import io.spine.gradle.javascript.javascript + * import io.spine.gradle.javascript.task.assemble + * import io.spine.gradle.javascript.task.publish * * // ... * @@ -103,7 +103,7 @@ private val prepareJsPublicationName = TaskName.of("prepareJsPublication") * Locates `prepareJsPublication` task in this [TaskContainer]. * * This is a lifecycle task that prepares the NPM package in - * [publicationDirectory][io.spine.internal.gradle.javascript.JsEnvironment.publicationDir] + * [publicationDirectory][io.spine.gradle.javascript.JsEnvironment.publicationDir] * of the current `JsEnvironment`. */ val TaskContainer.prepareJsPublication: TaskProvider @@ -168,11 +168,11 @@ private val publishJsName = TaskName.of("publishJs") * Locates `publishJs` task in this [TaskContainer]. * * The task publishes the prepared NPM package from - * [publicationDirectory][io.spine.internal.gradle.javascript.JsEnvironment.publicationDir] + * [publicationDirectory][io.spine.gradle.javascript.JsEnvironment.publicationDir] * using `npm publish`. * * Please note, in order to publish an NMP package, a valid - * [npmAuthToken][io.spine.internal.gradle.javascript.JsEnvironment.npmAuthToken] should be + * [npmAuthToken][io.spine.gradle.javascript.JsEnvironment.npmAuthToken] should be * set. If no token is set, a default dummy value is quite enough for the local development. * * @see npm-publish | npm Docs diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/javascript/task/Webpack.kt b/buildSrc/src/main/kotlin/io/spine/gradle/javascript/task/Webpack.kt similarity index 85% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/javascript/task/Webpack.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/javascript/task/Webpack.kt index cbf3aae..7c82ad7 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/javascript/task/Webpack.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/javascript/task/Webpack.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,11 +24,11 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.javascript.task +package io.spine.gradle.javascript.task -import io.spine.internal.gradle.named -import io.spine.internal.gradle.register -import io.spine.internal.gradle.TaskName +import io.spine.gradle.TaskName +import io.spine.gradle.named +import io.spine.gradle.register import org.gradle.api.tasks.Copy import org.gradle.api.tasks.TaskContainer import org.gradle.api.tasks.TaskProvider @@ -47,10 +47,10 @@ import org.gradle.api.tasks.TaskProvider * Here's an example of how to apply it in `build.gradle.kts`: * * ``` - * import io.spine.internal.gradle.javascript.javascript - * import io.spine.internal.gradle.javascript.task.assemble - * import io.spine.internal.gradle.javascript.task.publish - * import io.spine.internal.gradle.javascript.task.webpack + * import io.spine.gradle.javascript.javascript + * import io.spine.gradle.javascript.task.assemble + * import io.spine.gradle.javascript.task.publish + * import io.spine.gradle.javascript.task.webpack * * // ... * @@ -63,6 +63,7 @@ import org.gradle.api.tasks.TaskProvider * } * ``` */ +@Suppress("unused") fun JsTasks.webpack() { assembleJs.configure { @@ -92,6 +93,7 @@ private val copyBundledJsName = TaskName.of("copyBundledJs", Copy::class) * * The task copies bundled JavaScript sources to the publication directory. */ +@Suppress("unused") val TaskContainer.copyBundledJs: TaskProvider get() = named(copyBundledJsName) diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/kotlin/KotlinConfig.kt b/buildSrc/src/main/kotlin/io/spine/gradle/kotlin/KotlinConfig.kt similarity index 87% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/kotlin/KotlinConfig.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/kotlin/KotlinConfig.kt index af31ca1..65cdebd 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/kotlin/KotlinConfig.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/kotlin/KotlinConfig.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,15 +24,15 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.kotlin +package io.spine.gradle.kotlin import org.gradle.jvm.toolchain.JavaLanguageVersion +import org.jetbrains.kotlin.gradle.dsl.KotlinJvmCompilerOptions import org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension -import org.jetbrains.kotlin.gradle.tasks.KotlinCompile /** * Sets [Java toolchain](https://kotlinlang.org/docs/gradle.html#gradle-java-toolchains-support) - * to the specified version (e.g. 11 or 8). + * to the specified version (e.g., 11 or 8). */ fun KotlinJvmProjectExtension.applyJvmToolchain(version: Int) { jvmToolchain { @@ -52,9 +52,9 @@ fun KotlinJvmProjectExtension.applyJvmToolchain(version: String) = * Opts-in to experimental features that we use in our codebase. */ @Suppress("unused") -fun KotlinCompile.setFreeCompilerArgs() { - kotlinOptions { - freeCompilerArgs = listOf( +fun KotlinJvmCompilerOptions.setFreeCompilerArgs() { + freeCompilerArgs.addAll( + listOf( "-Xskip-prerelease-check", "-Xjvm-default=all", "-Xinline-classes", @@ -65,5 +65,5 @@ fun KotlinCompile.setFreeCompilerArgs() { "kotlin.ExperimentalStdlibApi," + "kotlin.experimental.ExperimentalTypeInference", ) - } + ) } diff --git a/buildSrc/src/main/kotlin/io/spine/gradle/protobuf/ProtoTaskExtensions.kt b/buildSrc/src/main/kotlin/io/spine/gradle/protobuf/ProtoTaskExtensions.kt new file mode 100644 index 0000000..85ef9fc --- /dev/null +++ b/buildSrc/src/main/kotlin/io/spine/gradle/protobuf/ProtoTaskExtensions.kt @@ -0,0 +1,418 @@ +/* + * Copyright 2025, TeamDev. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package io.spine.gradle.protobuf + +import com.google.protobuf.gradle.GenerateProtoTask +import com.google.protobuf.gradle.ProtobufExtension +import io.spine.gradle.sourceSets +import java.io.File +import java.nio.file.Files +import java.nio.file.Path +import java.nio.file.Paths +import java.nio.file.StandardOpenOption.TRUNCATE_EXISTING +import org.gradle.api.Project +import org.gradle.api.file.SourceDirectorySet +import org.gradle.api.tasks.SourceSet +import org.gradle.kotlin.dsl.get +import org.gradle.kotlin.dsl.getByType +import org.gradle.plugins.ide.idea.GenerateIdeaModule +import org.gradle.plugins.ide.idea.model.IdeaModel +import org.gradle.plugins.ide.idea.model.IdeaModule +import org.jetbrains.kotlin.gradle.tasks.KotlinCompilationTask +import titleCaseFirstChar + +/** + * Obtains the path of the `generated` directory under the project root directory. + */ +private val Project.generatedDir: Path + get() = projectDir.resolve("generated").toPath() + +/** + * Obtains the `generated` directory for the source set of the task. + * + * If [language] is specified returns the subdirectory for this language. + */ +private fun GenerateProtoTask.generatedDir(language: String = ""): File { + val path = "${project.generatedDir}/${sourceSet.name}/$language" + return File(path) +} + +/** + * Configures a [GenerateProtoTask] for the code which cannot use Spine Model Compiler + * (e.g., Spine Base or Spine Validation modules). + * + * The task configuration consists of the following steps: + * + * 1. Adding `"kotlin"` to the list of involved `protoc` builtins. + * + * 2. Turning on the generation of a descriptor set file for each source set. + * These files are placed under the `build/descriptors` directory. + * + * 3. Removing source code generated for `com.google` package for both Java and Kotlin. + * This is done at the final steps of the code generation. + * + * 4. Making `processResource` tasks depend on corresponding `generateProto` tasks. + * If the source set of the configured task isn't `main`, appropriate infix for + * the task names is used. + * + * The usage of this extension in a module build file would be: + * ``` + * protobuf { + * generateProtoTasks.all().configureEach { + * setup() + * } + * } + * ``` + * Using the same code under `subprojects` in a root build file does not seem to work because + * test descriptor set files are not copied to resources. Performing this configuration from + * a module build script solves the issue. + * + * IMPORTANT: In addition to calling `setup`, a submodule must contain a descriptor set reference + * file (`desc.ref`) files placed under `resources`. The descriptor reference file must contain + * a reference to the descriptor set file generated by the corresponding `GenerateProtoTask`. + * + * For example, for the `test` source set, the reference would be `known_types_test.desc`, and + * for the `main` source set, the reference would be `known_types_main.desc`. + * + * See `io.spine.code.proto.DescriptorReference` and `io.spine.code.proto.FileDescriptors` classes + * under the `base` project for more details. + */ +@Suppress("unused") +fun GenerateProtoTask.setup() { + builtins.maybeCreate("kotlin") + setupDescriptorSetFileCreation() + + doLast { + copyGeneratedFiles() + } + + excludeProtocOutput() + + setupKotlinCompile() + dependOnProcessResourcesTask() + makeDirsForIdeaModule() +} + +/** + * Tell `protoc` to generate descriptor set files under the project build dir. + * + * The name of the descriptor set file to be generated + * is made to be unique via the project's Maven coordinates. + * + * As the last step of this task, writes a `desc.ref` file + * for the contextual source set, pointing to the generated descriptor set file. + * This is needed to allow other Spine libraries to locate and load the generated + * descriptor set files properly. + * + * Such a job is usually performed by Spine McJava plugin; + * however, it is not possible to use this plugin (or its code) + * in this repository due to cyclic dependencies. + */ +@Suppress( + "TooGenericExceptionCaught" /* Handling all file-writing failures in the same way.*/ +) +fun GenerateProtoTask.setupDescriptorSetFileCreation() { + // Tell `protoc` generate a descriptor set file. + // The name of the generated file reflects the Maven coordinates of the project. + val ssn = sourceSet.name + generateDescriptorSet = true + val buildDir = project.layout.buildDirectory.asFile.get().path + val descriptorsDir = "$buildDir/descriptors/${ssn}" + val descriptorName = project.descriptorSetName(sourceSet) + with(descriptorSetOptions) { + path = "$descriptorsDir/$descriptorName" + includeImports = true + includeSourceInfo = true + } + + // Add the descriptor set file into the resources. + project.sourceSets.named(ssn) { + resources.srcDirs(descriptorsDir) + } + + // Create a `desc.ref` in the same resource folder, + // with the name of the descriptor set file created above. + this.doLast { + val descRefFile = File(descriptorsDir, "desc.ref") + descRefFile.createNewFile() + try { + Files.write(descRefFile.toPath(), setOf(descriptorName), TRUNCATE_EXISTING) + } catch (e: Exception) { + project.logger.error("Error writing `${descRefFile.absolutePath}`.", e) + throw e + } + } +} + +/** + * Returns a name of the descriptor file for the given [sourceSet], + * reflecting the Maven coordinates of Gradle artifact, and the source set + * for which the descriptor set name is to be generated. + * + * The returned value is just a file name and does not contain a file path. + */ +private fun Project.descriptorSetName(sourceSet: SourceSet) = + arrayOf( + group.toString(), + name, + sourceSet.name, + version.toString() + ).joinToString(separator = "_", postfix = ".desc") + +/** + * Copies files from the [outputBaseDir][GenerateProtoTask.outputBaseDir] into + * a subdirectory of [generatedDir][Project.generatedDir] for + * the current [sourceSet][GenerateProtoTask.sourceSet]. + * + * Also removes sources belonging to the `com.google` package in the target directory. + */ +private fun GenerateProtoTask.copyGeneratedFiles() { + project.copy { + from(outputBaseDir) + into(generatedDir()) + } + deleteComGoogle("java") + deleteComGoogle("kotlin") +} + +/** + * Remove the code generated for Google Protobuf library types. + * + * Java code for the `com.google` package was generated because we wanted + * to have descriptors for all the types, including those from Google Protobuf library. + * We want all the descriptors so that they are included into the resources used by + * the `io.spine.type.KnownTypes` class. + * + * Now, as we have the descriptors _and_ excessive Java or Kotlin code, we delete it to avoid + * classes that duplicate those coming from Protobuf library JARs. + */ +private fun GenerateProtoTask.deleteComGoogle(language: String) { + val comDirectory = generatedDir(language).resolve("com") + val googlePackage = comDirectory.resolve("google") + + project.delete(googlePackage) + + // If the `com` directory becomes empty, delete it too. + if (comDirectory.exists() && comDirectory.isDirectory && comDirectory.list()!!.isEmpty()) { + project.delete(comDirectory) + } +} + +/** + * Exclude [GenerateProtoTask.outputBaseDir] from Java source set directories to avoid + * duplicated source code files. + */ +fun GenerateProtoTask.excludeProtocOutput() { + val protocOutputDir = File(outputBaseDir).parentFile + val java: SourceDirectorySet = sourceSet.java + + // Filter out directories belonging to `build/generated/source/proto`. + val newSourceDirectories = java.sourceDirectories + .filter { !it.residesIn(protocOutputDir) } + .toSet() + // Make sure we start from scratch. + // Not doing this failed the following, real, assignment sometimes. + java.setSrcDirs(listOf()) + java.srcDirs(newSourceDirectories) + + // Add copied files to the Java source set. + java.srcDir(generatedDir("java")) + java.srcDir(generatedDir("kotlin")) +} + +/** + * Make sure Kotlin compilation explicitly depends on this `GenerateProtoTask` to avoid racing. + */ +fun GenerateProtoTask.setupKotlinCompile() { + val kotlinCompile = project.kotlinCompilationTaskFor(sourceSet) + kotlinCompile?.dependsOn(this) +} + +/** + * Make the tasks `processResources` depend on `generateProto` tasks explicitly so that: + * 1) Descriptor set files get into resources, avoiding the racing conditions + * during the build. + * + * 2) We don't have the warning "Execution optimizations have been disabled..." issued + * by Gradle during the build because Protobuf Gradle Plugin does not set + * dependencies between `generateProto` and `processResources` tasks. + */ +fun GenerateProtoTask.dependOnProcessResourcesTask() { + val processResources = processResourceTaskName(sourceSet.name) + project.tasks[processResources].dependsOn(this) +} + +/** + * Obtains the name of the `processResource` task for the given source set name. + */ +private fun processResourceTaskName(sourceSetName: String): String { + val infix = + if (sourceSetName == "main") "" + else sourceSetName.titleCaseFirstChar() + return "process${infix}Resources" +} + +private fun Project.kotlinCompilationTaskFor(sourceSet: SourceSet): KotlinCompilationTask<*>? { + val taskName = sourceSet.getCompileTaskName("Kotlin") + return tasks.named(taskName, KotlinCompilationTask::class.java).orNull +} + +private fun File.residesIn(directory: File): Boolean = + canonicalFile.startsWith(directory.absolutePath) + +/** + * Ensures that generated directories for Java and Kotlin are created before [GenerateIdeaModule]. + * + * This works as advised by `Utils.groovy` from Protobuf Gradle plugin: + * ``` + * This is required because the IntelliJ IDEA plugin does not allow adding source directories + * that do not exist. The IntelliJ IDEA config files should be valid from the start even if + * a user runs './gradlew idea' before running './gradlew generateProto'. + * ``` + */ +fun GenerateProtoTask.makeDirsForIdeaModule() { + project.plugins.withId("idea") { + val javaDir = generatedDir("java") + val kotlinDir = generatedDir("kotlin") + project.tasks.withType(GenerateIdeaModule::class.java).forEach { + it.doFirst { + javaDir.mkdirs() + kotlinDir.mkdirs() + } + } + } +} + +/** + * Prints diagnostic output of `sourceDirs` and `generatedSourceDirs` of an [IdeaModule]. + * + * To get a handle on [IdeaModule] please use the following code: + * + * ```kotlin + * val module = project.extensions.findByType(IdeaModel::class.java)!!.module + * ``` + */ +@Suppress("unused") // To be used when debugging build scripts. +fun IdeaModule.printSourceDirectories() { + println("**** [IDEA] Source directories:") + sourceDirs.forEach { println(it) } + println() + println("**** [IDEA] Generated source directories:") + generatedSourceDirs.forEach { println(it) } + println() + println("**** [IDEA] Excluded directories:") + excludeDirs.forEach { println(it) } +} + +/** + * Obtains the directory where the Protobuf Gradle Plugin should place the generated code. + * + * The directory is fixed to be `$buildDir/generated/source/proto` and cannot be + * changed by the settings of the plugin. Even though [ProtobufExtension] has a property + * [generatedFilesBaseDir][ProtobufExtension.getGeneratedFilesBaseDir], which is supposed + * to be used for this purpose, it is declared with `@PackageScope` and thus cannot be + * accessed from outside the plugin. The Protobuf Gradle Plugin (at v0.9.2) does not + * modify the value of the property either. + */ +val Project.generatedSourceProtoDir: Path + get() = layout.buildDirectory.dir("generated/source/proto").get().asFile.toPath() + +/** + * Ensures that the sources generated by Protobuf Gradle Plugin + * are not included in the IDEA project. + * + * IDEA should only see the sources generated by ProtoData as + * we define in [GenerateProtoTask.excludeProtocOutput]. + */ +@Suppress("unused") +fun Project.configureIdea() { + + fun filterSources(sources: Set, excludeDir: File): Set = + sources.filter { !it.residesIn(excludeDir) }.toSet() + + pluginManager.withPlugin("idea") { + val idea = extensions.getByType() + with(idea.module) { + val protocOutput = file(generatedSourceProtoDir) + val protocTargets = protocTargets() + excludeWithNested(protocOutput.toPath(), protocTargets) + sourceDirs = filterSources(sourceDirs, protocOutput) + testSources.filter { !it.residesIn(protocOutput) } + generatedSourceDirs = generatedDir.resolve(protocTargets) + .map { it.toFile() } + .toSet() + } + } +} + +/** + * Lists target directories for Protobuf code generation. + * + * The directory names are in the following format: + * + * `/` + */ +private fun Project.protocTargets(): List { + val protobufTasks = tasks.withType(GenerateProtoTask::class.java) + val codegenTargets = sequence { + protobufTasks.forEach { task -> + val sourceSet = task.sourceSet.name + val builtins = task.builtins.map { builtin -> builtin.name } + val plugins = task.plugins.map { plugin -> plugin.name } + val combined = builtins + plugins + combined.forEach { subdir -> + yield(Paths.get(sourceSet, subdir)) + } + } + } + return codegenTargets.toList() +} + +private fun Path.resolve(subdirs: Iterable): List = + subdirs.map { + resolve(it) + } + +/** + * Excludes the given directory and its subdirectories from + * being seen as ones with the source code. + * + * The primary use of this extension is to exclude `build/generated/source/proto` and its + * subdirectories to avoid duplication of types in the generated code with those in + * produced by ProtoData under the `$projectDir/generated/` directory. + */ +private fun IdeaModule.excludeWithNested(directory: Path, subdirs: Iterable) { + excludeDirs.add(directory.toFile()) + directory.resolve(subdirs).forEach { + excludeDirs.add(it.toFile()) + } +} + +@Suppress("unused") // To be used when debugging build scripts. +private fun printExcluded(dir: Any) { + println(" [IDEA] Excluding directory: $dir") +} diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/publish/CheckVersionIncrement.kt b/buildSrc/src/main/kotlin/io/spine/gradle/publish/CheckVersionIncrement.kt similarity index 80% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/publish/CheckVersionIncrement.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/publish/CheckVersionIncrement.kt index e797527..9e38068 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/publish/CheckVersionIncrement.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/publish/CheckVersionIncrement.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,11 +24,11 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.publish +package io.spine.gradle.publish import com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES import com.fasterxml.jackson.dataformat.xml.XmlMapper -import io.spine.internal.gradle.Repository +import io.spine.gradle.Repository import java.io.FileNotFoundException import java.net.URL import org.gradle.api.DefaultTask @@ -70,8 +70,9 @@ open class CheckVersionIncrement : DefaultTask() { val versions = metadata?.versioning?.versions val versionExists = versions?.contains(version) ?: false if (versionExists) { - throw GradleException(""" - Version `$version` is already published to maven repository `$repoUrl`. + throw GradleException( + """ + The version `$version` is already published to the Maven repository `$repoUrl`. Try incrementing the library version. All available versions are: ${versions?.joinToString(separator = ", ")}. @@ -88,13 +89,28 @@ open class CheckVersionIncrement : DefaultTask() { private fun Project.artifactPath(): String { val group = this.group as String - val name = "spine-${this.name}" + val name = "${artifactPrefix()}${this.name}" val pathElements = ArrayList(group.split('.')) pathElements.add(name) val path = pathElements.joinToString(separator = "/") return path } + + /** + * Returns the artifact prefix used for the publishing of this project. + * + * All current Spine modules should be using `SpinePublishing`. + * Therefore, the corresponding extension should be present in the root project. + * However, just in case, we define the "standard" prefix here as well. + * + * This value MUST be the same as defined by the defaults in `SpinePublishing`. + */ + private fun Project.artifactPrefix(): String { + val ext = rootProject.extensions.findByType(SpinePublishing::class.java) + val result = ext?.artifactPrefix ?: SpinePublishing.DEFAULT_PREFIX + return result + } } private data class MavenMetadata(var versioning: Versioning = Versioning()) { diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/publish/CloudArtifactRegistry.kt b/buildSrc/src/main/kotlin/io/spine/gradle/publish/CloudArtifactRegistry.kt similarity index 93% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/publish/CloudArtifactRegistry.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/publish/CloudArtifactRegistry.kt index 143ea25..1cfa7c2 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/publish/CloudArtifactRegistry.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/publish/CloudArtifactRegistry.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,12 +24,12 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.publish +package io.spine.gradle.publish import com.google.auth.oauth2.GoogleCredentials import com.google.cloud.artifactregistry.auth.DefaultCredentialProvider -import io.spine.internal.gradle.Credentials -import io.spine.internal.gradle.Repository +import io.spine.gradle.Credentials +import io.spine.gradle.Repository import java.io.IOException import org.gradle.api.Project diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/publish/CloudRepo.kt b/buildSrc/src/main/kotlin/io/spine/gradle/publish/CloudRepo.kt similarity index 89% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/publish/CloudRepo.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/publish/CloudRepo.kt index 48cd858..7db15aa 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/publish/CloudRepo.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/publish/CloudRepo.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,16 +24,16 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.publish +package io.spine.gradle.publish -import io.spine.internal.gradle.Repository +import io.spine.gradle.Repository /** * CloudRepo Maven repository. * * There is a special treatment for this repository. Usually, fetching and publishing of artifacts * is performed via the same URL. But it is not true for CloudRepo. Fetching is performed via - * public repository, and publishing via private one. Their URLs differ in `/public` infix. + * the public repository, and publishing via the private one. Their URLs differ in `/public` infix. */ internal object CloudRepo { diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/publish/GitHubPackages.kt b/buildSrc/src/main/kotlin/io/spine/gradle/publish/GitHubPackages.kt similarity index 92% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/publish/GitHubPackages.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/publish/GitHubPackages.kt index e1867bf..1072139 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/publish/GitHubPackages.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/publish/GitHubPackages.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,10 +24,11 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.publish +package io.spine.gradle.publish -import io.spine.internal.gradle.Credentials -import io.spine.internal.gradle.Repository +import io.spine.gradle.Credentials +import io.spine.gradle.Repository +import io.spine.gradle.buildDirectory import net.lingala.zip4j.ZipFile import org.gradle.api.Project @@ -90,7 +91,7 @@ private fun Project.readGitHubToken(): String { * use such a workaround. */ private fun Project.readTokenFromArchive(): String { - val targetDir = "${buildDir}/token" + val targetDir = "$buildDirectory/token" file(targetDir).mkdirs() val fileToUnzip = "${rootDir}/buildSrc/aus.weis" diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/publish/IncrementGuard.kt b/buildSrc/src/main/kotlin/io/spine/gradle/publish/IncrementGuard.kt similarity index 84% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/publish/IncrementGuard.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/publish/IncrementGuard.kt index e69b624..b6683fa 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/publish/IncrementGuard.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/publish/IncrementGuard.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -26,7 +26,7 @@ @file:Suppress("unused") -package io.spine.internal.gradle.publish +package io.spine.gradle.publish import org.gradle.api.Plugin import org.gradle.api.Project @@ -45,19 +45,20 @@ class IncrementGuard : Plugin { /** * Adds the [CheckVersionIncrement] task to the project. * - * Only adds the check if the project is built on Travis CI and the job is a pull request. + * The task is created anyway, but it is enabled only if: + * 1. The project is built on GitHub CI, and + * 2. The job is a pull request. * - * The task only runs on non-master branches on GitHub Actions. This is done - * to prevent unexpected CI fails when re-building `master` multiple times, creating git - * tags, and in other cases that go outside of the "usual" development cycle. + * The task only runs on non-master branches on GitHub Actions. + * This is done to prevent unexpected CI fails when re-building `master` multiple times, + * creating git tags, and in other cases that go outside the "usual" development cycle. */ override fun apply(target: Project) { val tasks = target.tasks tasks.register(taskName, CheckVersionIncrement::class.java) { - repository = CloudRepo.published + repository = CloudArtifactRegistry.repository tasks.getByName("check").dependsOn(this) - shouldRunAfter("test") if (!shouldCheckVersion()) { logger.info( "The build does not represent a GitHub Actions feature branch job, " + @@ -72,10 +73,10 @@ class IncrementGuard : Plugin { * Returns `true` if the current build is a GitHub Actions build which represents a push * to a feature branch. * - * Returns `false` if the associated reference is not a branch (e.g. a tag) or if it has + * Returns `false` if the associated reference is not a branch (e.g., a tag) or if it has * the name which ends with `master` or `main`. * - * For example, on the following branhces the method would return `false`: + * For example, on the following branches the method would return `false`: * * 1. `master`. * 2. `main`. diff --git a/buildSrc/src/main/kotlin/io/spine/gradle/publish/JarDsl.kt b/buildSrc/src/main/kotlin/io/spine/gradle/publish/JarDsl.kt new file mode 100644 index 0000000..1371184 --- /dev/null +++ b/buildSrc/src/main/kotlin/io/spine/gradle/publish/JarDsl.kt @@ -0,0 +1,167 @@ +/* + * Copyright 2025, TeamDev. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package io.spine.gradle.publish + +/** + * A DSL element of [SpinePublishing] extension which configures publishing of + * [dokkaKotlinJar] artifact. + * + * This artifact contains Dokka-generated documentation. By default, it is not published. + * + * Take a look at the [SpinePublishing.dokkaJar] for a usage example. + * + * @see [artifacts] + */ +class DokkaJar { + /** + * Enables publishing `JAR`s with Dokka-generated documentation for all published modules. + */ + @Suppress("unused") + @Deprecated("Please use `kotlin` and `java` flags instead.") + var enabled = false + + /** + * Controls whether [dokkaKotlinJar] artifact should be published. + * The default value is `true`. + */ + var kotlin = true + + /** + * Controls whether [dokkaJavaJar] artifact should be published. + * The default value is `false`. + */ + var java = false +} + +/** + * A DSL element of [SpinePublishing] extension which allows enabling publishing + * of [testJar] artifact. + * + * This artifact contains compilation output of `test` source set. By default, it is not published. + * + * Take a look on [SpinePublishing.testJar] for a usage example. + + * @see [artifacts] + */ +class TestJar { + + /** + * Set of modules, for which a test JAR will be published. + */ + var inclusions: Set = emptySet() + + /** + * Enables test JAR publishing for all published modules. + */ + var enabled = false +} + +/** + * A DSL element of [SpinePublishing] extension which allows disabling publishing + * of [protoJar] artifact. + * + * This artifact contains all the `.proto` definitions from `sourceSets.main.proto`. By default, + * it is published. + * + * Take a look on [SpinePublishing.protoJar] for a usage example. + * + * @see [artifacts] + */ +class ProtoJar { + + /** + * Set of modules, for which a proto JAR will not be published. + */ + var exclusions: Set = emptySet() + + /** + * Disables proto JAR publishing for all published modules. + */ + var disabled = false +} + +/** + * Flags for turning optional JAR artifacts in a project. + */ +internal data class JarFlags( + + /** + * Tells whether [sourcesJar] artifact should be published. + * + * Default value is `true`. + */ + val sourcesJar: Boolean = true, + + /** + * Tells whether [javadocJar] artifact should be published. + * + * Default value is `true`. + */ + val javadocJar: Boolean = true, + + /** + * Tells whether [protoJar] artifact should be published. + */ + val publishProtoJar: Boolean, + + /** + * Tells whether [testJar] artifact should be published. + */ + val publishTestJar: Boolean, + + /** + * Tells whether [dokkaKotlinJar] artifact should be published. + */ + val publishDokkaKotlinJar: Boolean, + + /** + * Tells whether [dokkaJavaJar] artifact should be published. + */ + val publishDokkaJavaJar: Boolean +) { + internal companion object { + /** + * Creates an instance of [JarFlags] for the project with the given name, + * taking the setup parameters from JAR DSL elements. + */ + fun create( + projectName: String, + protoJar: ProtoJar, + testJar: TestJar, + dokkaJar: DokkaJar + ): JarFlags { + val addProtoJar = (protoJar.exclusions.contains(projectName) || protoJar.disabled).not() + val addTestJar = testJar.inclusions.contains(projectName) || testJar.enabled + return JarFlags( + sourcesJar = true, + javadocJar = true, + addProtoJar, addTestJar, + dokkaJar.kotlin, dokkaJar.java + ) + } + } +} diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/publish/ProtoLocators.kt b/buildSrc/src/main/kotlin/io/spine/gradle/publish/ProtoExts.kt similarity index 50% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/publish/ProtoLocators.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/publish/ProtoExts.kt index ef048f2..874b7f9 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/publish/ProtoLocators.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/publish/ProtoExts.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,14 +24,15 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.publish +package io.spine.gradle.publish -import io.spine.internal.gradle.sourceSets +import io.spine.gradle.sourceSets import java.io.File import org.gradle.api.Project +import org.gradle.api.Task +import org.gradle.api.file.FileTreeElement import org.gradle.api.file.SourceDirectorySet -import org.gradle.kotlin.dsl.get - +import org.gradle.api.tasks.bundling.Jar /** * Tells whether there are any Proto sources in "main" source set. @@ -43,13 +44,46 @@ internal fun Project.hasProto(): Boolean { } /** - * Locates Proto sources in "main" source set. + * Locates directories with proto sources under the "main" source sets. * - * "main" source set is added by `java` plugin. Special treatment for Proto sources is needed, - * because they are not Java-related, and, thus, not included in `sourceSets["main"].allSource`. + * Special treatment for Proto sources is needed, because they are not Java-related, and, + * thus, not included in `sourceSets["main"].allSource`. */ internal fun Project.protoSources(): Set { - val mainSourceSet = sourceSets["main"] - val protoSourceDirs = mainSourceSet.extensions.findByName("proto") as SourceDirectorySet? - return protoSourceDirs?.srcDirs ?: emptySet() + val mainSourceSets = sourceSets.filter { + ss -> ss.name.endsWith("main", ignoreCase = true) + } + + val protoExtensions = mainSourceSets.mapNotNull { + it.extensions.findByName("proto") as SourceDirectorySet? + } + + val protoDirs = mutableSetOf() + protoExtensions.forEach { + protoDirs.addAll(it.srcDirs) + } + + return protoDirs +} + +/** + * Checks if the given file belongs to the Google `.proto` sources. + */ +internal fun FileTreeElement.isGoogleProtoSource(): Boolean { + val pathSegments = relativePath.segments + return pathSegments.isNotEmpty() && pathSegments[0].equals("google") +} + +/** + * The reference to the `generateProto` task of a `main` source set. + */ +internal fun Project.generateProto(): Task? = tasks.findByName("generateProto") + +/** + * Makes this [Jar] task depend on the [generateProto] task, if it exists in the same project. + */ +internal fun Jar.dependOnGenerateProto() { + project.generateProto()?.let { + this.dependsOn(it) + } } diff --git a/buildSrc/src/main/kotlin/io/spine/gradle/publish/Publications.kt b/buildSrc/src/main/kotlin/io/spine/gradle/publish/Publications.kt new file mode 100644 index 0000000..c9acef8 --- /dev/null +++ b/buildSrc/src/main/kotlin/io/spine/gradle/publish/Publications.kt @@ -0,0 +1,234 @@ +/* + * Copyright 2025, TeamDev. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package io.spine.gradle.publish + +import io.spine.gradle.Repository +import io.spine.gradle.isSnapshot +import org.gradle.api.Project +import org.gradle.api.artifacts.dsl.RepositoryHandler +import org.gradle.api.publish.maven.MavenPublication +import org.gradle.api.tasks.TaskProvider +import org.gradle.api.tasks.bundling.Jar +import org.gradle.kotlin.dsl.apply +import org.gradle.kotlin.dsl.create + +/** + * The name of the Maven Publishing Gradle plugin. + */ +private const val MAVEN_PUBLISH = "maven-publish" + +/** + * Abstract base for handlers of publications in a project + * with [spinePublishing] settings declared. + */ +internal sealed class PublicationHandler( + protected val project: Project, + private val destinations: Set +) { + + fun apply() = with(project) { + if (!hasCustomPublishing) { + apply(plugin = MAVEN_PUBLISH) + } + + pluginManager.withPlugin(MAVEN_PUBLISH) { + handlePublications() + registerDestinations() + configurePublishTask(destinations) + } + } + + /** + * Either handles publications already declared in the given project, + * or creates new ones. + */ + abstract fun handlePublications() + + /** + * Goes through the [destinations] and registers each as a repository for publishing + * in the given Gradle project. + */ + private fun registerDestinations() { + val repositories = project.publishingExtension.repositories + destinations.forEach { destination -> + repositories.register(project, destination) + } + } + + /** + * Copies the attributes of Gradle [Project] to this [MavenPublication]. + * + * The following project attributes are copied: + * * [group][Project.getGroup]; + * * [version][Project.getVersion]; + * * [description][Project.getDescription]. + * + * Also, this function adds the [artifactPrefix][SpinePublishing.artifactPrefix] to + * the [artifactId][MavenPublication.setArtifactId] of this publication, + * if the prefix is not added yet. + * + * Finally, the Apache Software License 2.0 is set as the only license + * under which the published artifact is distributed. + */ + protected fun MavenPublication.copyProjectAttributes() { + groupId = project.group.toString() + val prefix = project.spinePublishing.artifactPrefix + if (!artifactId.startsWith(prefix)) { + artifactId = prefix + artifactId + } + version = project.version.toString() + pom.description.set(project.description) + + pom.licenses { + license { + name.set("The Apache Software License, Version 2.0") + url.set("https://www.apache.org/licenses/LICENSE-2.0.txt") + } + } + } +} + +/** + * Adds a Maven repository to the project specifying credentials, if they are + * [available][Repository.credentials] from the root project. + */ +private fun RepositoryHandler.register(project: Project, repository: Repository) { + val isSnapshot = project.version.toString().isSnapshot() + val target = if (isSnapshot) repository.snapshots else repository.releases + val credentials = repository.credentials(project.rootProject) + maven { + url = project.uri(target) + credentials { + username = credentials?.username + password = credentials?.password + } + } +} + +/** + * A publication for a typical Java project. + * + * In Gradle, to publish something, one should create a publication. + * A publication has a name and consists of one or more artifacts plus information about + * those artifacts – the metadata. + * + * An instance of this class represents [MavenPublication] named "mavenJava". It is generally + * accepted that a publication with this name contains a Java project published to one or + * more Maven repositories. + * + * By default, only a jar with the compilation output of `main` source set and its + * metadata files are published. Other artifacts are specified through the + * [constructor parameter][jarFlags]. Please, take a look on [specifyArtifacts] for additional info. + * + * @param jarFlags + * flags for additional JARs published along with the compilation output. + * @param destinations + * Maven repositories to which the produced artifacts will be sent. + * @see + * Maven Publish Plugin | Publications + */ +internal class StandardJavaPublicationHandler( + project: Project, + private val jarFlags: JarFlags, + destinations: Set, +) : PublicationHandler(project, destinations) { + + /** + * Creates a new "mavenJava" [MavenPublication] in the given project. + */ + override fun handlePublications() { + val jars = project.artifacts(jarFlags) + val publications = project.publications + publications.create("mavenJava") { + copyProjectAttributes() + specifyArtifacts(jars) + } + } + + /** + * Specifies which artifacts this [MavenPublication] will contain. + * + * A typical Maven publication contains: + * + * 1. Jar archives. For example, compilation output, sources, javadoc, etc. + * 2. Maven metadata file that has the ".pom" extension. + * 3. Gradle's metadata file that has the ".module" extension. + * + * Metadata files contain information about a publication itself, its artifacts, and their + * dependencies. Presence of ".pom" file is mandatory for publication to be consumed by + * `mvn` build tool itself or other build tools that understand Maven notation (Gradle, Ivy). + * The presence of ".module" is optional, but useful when a publication is consumed by Gradle. + * + * @see Maven – POM Reference + * @see + * Understanding Gradle Module Metadata + */ + private fun MavenPublication.specifyArtifacts(jars: Set>) { + + /* "java" component provides a jar with compilation output of "main" source set. + It is NOT defined as another `Jar` task intentionally. Doing that will leave the + publication without correct ".pom" and ".module" metadata files generated. + */ + val javaComponent = project.components.findByName("java") + javaComponent?.let { + from(it) + } + + /* Other artifacts are represented by `Jar` tasks. Those artifacts don't bring any other + metadata in comparison with `Component` (such as dependencies notation). + */ + jars.forEach { + artifact(it) + } + } +} + +/** + * A handler for custom publications, which are declared under the [publications] + * section of a module. + * + * Such publications should be treated differently than [StandardJavaPublicationHandler], + * which is created for a module. Instead, since the publications are already declared, + * this class only [assigns maven coordinates][copyProjectAttributes]. + * + * A module which declares custom publications must be specified in + * the [SpinePublishing.modulesWithCustomPublishing] property. + * + * If a module with [publications] declared locally is not specified as one with custom publishing, + * it may cause a name clash between an artifact produced by the [standard][MavenPublication] + * publication, and custom ones. To have both standard and custom publications, + * please specify custom artifact IDs or classifiers for each custom publication. + */ +internal class CustomPublicationHandler(project: Project, destinations: Set) : + PublicationHandler(project, destinations) { + + override fun handlePublications() { + project.publications.forEach { + (it as MavenPublication).copyProjectAttributes() + } + } +} diff --git a/buildSrc/src/main/kotlin/io/spine/gradle/publish/PublishingExts.kt b/buildSrc/src/main/kotlin/io/spine/gradle/publish/PublishingExts.kt new file mode 100644 index 0000000..62c639b --- /dev/null +++ b/buildSrc/src/main/kotlin/io/spine/gradle/publish/PublishingExts.kt @@ -0,0 +1,278 @@ +/* + * Copyright 2025, TeamDev. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package io.spine.gradle.publish + +import dokkaKotlinJar +import io.spine.gradle.Repository +import io.spine.gradle.sourceSets +import java.util.* +import org.gradle.api.InvalidUserDataException +import org.gradle.api.Project +import org.gradle.api.Task +import org.gradle.api.publish.PublicationContainer +import org.gradle.api.publish.PublishingExtension +import org.gradle.api.tasks.TaskContainer +import org.gradle.api.tasks.TaskProvider +import org.gradle.api.tasks.bundling.Jar +import org.gradle.kotlin.dsl.findByType +import org.gradle.kotlin.dsl.get +import org.gradle.kotlin.dsl.getByType +import org.gradle.kotlin.dsl.named +import org.gradle.kotlin.dsl.register +import org.gradle.kotlin.dsl.withType + +/** + * Obtains [PublishingExtension] of this project. + */ +internal val Project.publishingExtension: PublishingExtension + get() = extensions.getByType() + +/** + * Obtains [PublicationContainer] of this project. + */ +internal val Project.publications: PublicationContainer + get() = publishingExtension.publications + +/** + * Obtains [SpinePublishing] extension from this [Project]. + * + * If this [Project] doesn't have one, it returns [SpinePublishing] + * declared in the root project. + */ +internal val Project.spinePublishing: SpinePublishing + get() { + val local = this.extensions.findByType() + if (local != null) { + return local + } + val fromRoot = this.rootProject.extensions.findByType() + if (fromRoot != null) { + return fromRoot + } + error("`SpinePublishing` is not found in `${project.name}`.") + } + +/** + * Tells if this project has custom publishing. + */ +internal val Project.hasCustomPublishing: Boolean + get() = spinePublishing.modulesWithCustomPublishing.contains(name) + +private const val PUBLISH_TASK = "publish" + +/** + * Locates `publish` task in this [TaskContainer]. + * + * This task publishes all defined publications to all defined repositories. To achieve that, + * the task depends on all `publish`*PubName*`PublicationTo`*RepoName*`Repository` tasks. + * + * Please note, task execution would not copy publications to the local Maven cache. + * + * @see + * Tasks | Maven Publish Plugin + */ +internal val TaskContainer.publish: TaskProvider + get() = named(PUBLISH_TASK) + +/** + * Sets dependencies for `publish` task in this [Project]. + * + * This method performs the following: + * + * 1. When this [Project] is not a root, makes `publish` task in a root project + * depend on a local `publish`. + * 2. Makes local `publish` task verify that credentials are present for each + * of destination repositories. + */ +internal fun Project.configurePublishTask(destinations: Set) { + attachCredentialsVerification(destinations) + bindToRootPublish() +} + +private fun Project.attachCredentialsVerification(destinations: Set) { + val checkCredentials = tasks.registerCheckCredentialsTask(destinations) + val localPublish = tasks.publish + localPublish.configure { dependsOn(checkCredentials) } +} + +private fun Project.bindToRootPublish() { + if (project == rootProject) { + return + } + + val localPublish = tasks.publish + val rootPublish = rootProject.tasks.getOrCreatePublishTask() + rootPublish.configure { dependsOn(localPublish) } +} + +/** + * Use this task accessor when it is not guaranteed that the task is present + * in this [TaskContainer]. + */ +private fun TaskContainer.getOrCreatePublishTask(): TaskProvider = + if (names.contains(PUBLISH_TASK)) { + named(PUBLISH_TASK) + } else { + register(PUBLISH_TASK) + } + +private fun TaskContainer.registerCheckCredentialsTask( + destinations: Set +): TaskProvider = + register("checkCredentials") { + doLast { + destinations.forEach { it.ensureCredentials(project) } + } + } + +private fun Repository.ensureCredentials(project: Project) { + val credentials = credentials(project) + if (Objects.isNull(credentials)) { + throw InvalidUserDataException( + "No valid credentials for repository `${this}`. Please make sure " + + "to pass username/password or a valid `.properties` file." + ) + } +} + +/** + * Excludes Google `.proto` sources from all artifacts. + * + * Goes through all registered `Jar` tasks and filters out Google's files. + */ +@Suppress("unused") +fun TaskContainer.excludeGoogleProtoFromArtifacts() { + withType().configureEach { + exclude { it.isGoogleProtoSource() } + } +} + +/** + * Locates or creates `sourcesJar` task in this [Project]. + * + * The output of this task is a `jar` archive. The archive contains sources from `main` source set. + * The task makes sure that sources from the directories below will be included into + * a resulted archive: + * + * - Kotlin + * - Java + * - Proto + * + * Java and Kotlin sources are default to `main` source set since it is created by `java` plugin. + * For Proto sources to be included – [special treatment][protoSources] is needed. + */ +internal fun Project.sourcesJar(): TaskProvider = tasks.getOrCreate("sourcesJar") { + dependOnGenerateProto() + archiveClassifier.set("sources") + from(sourceSets["main"].allSource) // Puts Java and Kotlin sources. + from(protoSources()) // Puts Proto sources. + exclude("desc.ref", "*.desc") // Exclude descriptor files and the descriptor reference. +} + +/** + * Locates or creates `protoJar` task in this [Project]. + * + * The output of this task is a `jar` archive. The archive contains only + * [Proto sources][protoSources] from `main` source set. + */ +internal fun Project.protoJar(): TaskProvider = tasks.getOrCreate("protoJar") { + dependOnGenerateProto() + archiveClassifier.set("proto") + from(protoSources()) +} + +/** + * Locates or creates `testJar` task in this [Project]. + * + * The output of this task is a `jar` archive. The archive contains compilation output + * of `test` source set. + */ +internal fun Project.testJar(): TaskProvider = tasks.getOrCreate("testJar") { + archiveClassifier.set("test") + from(sourceSets["test"].output) +} + +/** + * Locates or creates `javadocJar` task in this [Project]. + * + * The output of this task is a `jar` archive. The archive contains Javadoc, + * generated upon Java sources from `main` source set. If javadoc for Kotlin is also needed, + * apply Dokka plugin. It tunes `javadoc` task to generate docs upon Kotlin sources as well. + */ +fun Project.javadocJar(): TaskProvider = tasks.getOrCreate("javadocJar") { + archiveClassifier.set("javadoc") + val javadocFiles = layout.buildDirectory.files("/docs/javadoc") + from(javadocFiles) + dependsOn("javadoc") +} + +internal fun TaskContainer.getOrCreate(name: String, init: Jar.() -> Unit): TaskProvider = + if (names.contains(name)) { + named(name) + } else { + register(name) { + init() + } + } + +/** + * Obtains as a set of [Jar] tasks, output of which is used as Maven artifacts. + * + * By default, only a jar with Java compilation output is included into publication. This method + * registers tasks which produce additional artifacts according to the values of [jarFlags]. + * + * @return the list of the registered tasks. + */ +internal fun Project.artifacts(jarFlags: JarFlags): Set> { + val tasks = mutableSetOf>() + + if (jarFlags.sourcesJar) { + tasks.add(sourcesJar()) + } + + if (jarFlags.javadocJar) { + tasks.add(javadocJar()) + } + + // We don't want to have an empty "proto.jar" when a project doesn't have any Proto files. + if (hasProto() && jarFlags.publishProtoJar) { + tasks.add(protoJar()) + } + + // Here, we don't have the corresponding `hasTests()` check, since this artifact is disabled + // by default. And turning it on means "We have tests and need them to be published." + if (jarFlags.publishTestJar) { + tasks.add(testJar()) + } + + if (jarFlags.publishDokkaKotlinJar) { + tasks.add(dokkaKotlinJar()) + } + + return tasks +} + diff --git a/buildSrc/src/main/kotlin/io/spine/gradle/publish/PublishingRepos.kt b/buildSrc/src/main/kotlin/io/spine/gradle/publish/PublishingRepos.kt new file mode 100644 index 0000000..f383e68 --- /dev/null +++ b/buildSrc/src/main/kotlin/io/spine/gradle/publish/PublishingRepos.kt @@ -0,0 +1,42 @@ +/* + * Copyright 2025, TeamDev. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package io.spine.gradle.publish + +import io.spine.gradle.Repository + +/** + * Repositories to which we may publish. + */ +object PublishingRepos { + + val cloudArtifactRegistry = CloudArtifactRegistry.repository + + /** + * Obtains a GitHub repository by the given name. + */ + fun gitHub(repoName: String): Repository = GitHubPackages.repository(repoName) +} diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/publish/SpinePublishing.kt b/buildSrc/src/main/kotlin/io/spine/gradle/publish/SpinePublishing.kt similarity index 72% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/publish/SpinePublishing.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/publish/SpinePublishing.kt index 9f63de1..2f74536 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/publish/SpinePublishing.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/publish/SpinePublishing.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,17 +24,18 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.publish +@file:Suppress("TooManyFunctions") -import io.spine.internal.gradle.Repository +package io.spine.gradle.publish + +import dokkaJavaJar +import dokkaKotlinJar +import io.spine.gradle.Repository import org.gradle.api.Project -import org.gradle.api.publish.PublicationContainer -import org.gradle.api.publish.PublishingExtension import org.gradle.api.publish.maven.plugins.MavenPublishPlugin import org.gradle.kotlin.dsl.apply import org.gradle.kotlin.dsl.create import org.gradle.kotlin.dsl.findByType -import org.gradle.kotlin.dsl.getByType /** * Configures [SpinePublishing] extension. @@ -76,7 +77,7 @@ import org.gradle.kotlin.dsl.getByType * `spinePublishing` extension within `subprojectA` itself would lead to an exception. * * In Gradle, in order to publish something somewhere one should create a publication. In each - * of published modules, the extension will create a [publication][MavenJavaPublication] + * of published modules, the extension will create a [publication][StandardJavaPublicationHandler] * named "mavenJava". All artifacts, published by this extension belong to this publication. * * By default, along with the compilation output of "main" source set, the extension publishes @@ -103,20 +104,24 @@ import org.gradle.kotlin.dsl.getByType * 3. [javadocJar] - javadoc, generated upon Java sources from "main" source set. * If javadoc for Kotlin is also needed, apply Dokka plugin. It tunes `javadoc` task to generate * docs upon Kotlin sources as well. + * 4. [dokkaKotlinJar] - documentation generated by Dokka for Kotlin and Java sources + * using the Kotlin API mode. + * 5. [dokkaJavaJar] - documentation generated by Dokka for Kotlin and Java sources + * * using the Java API mode. * * Additionally, [testJar] artifact can be published. This artifact contains compilation output * of "test" source set. Use [SpinePublishing.testJar] to enable its publishing. * - * @see [registerArtifacts] + * @see [artifacts] */ -fun Project.spinePublishing(configuration: SpinePublishing.() -> Unit) { +fun Project.spinePublishing(block: SpinePublishing.() -> Unit) { apply() val name = SpinePublishing::class.java.simpleName val extension = with(extensions) { findByType() ?: create(name, project) } extension.run { - configuration() + block() configured() } } @@ -132,6 +137,14 @@ fun Project.spinePublishing(configuration: SpinePublishing.() -> Unit) { */ open class SpinePublishing(private val project: Project) { + companion object { + + /** + * The default prefix added before a module name when publishing artifacts. + */ + const val DEFAULT_PREFIX = "spine-" + } + private val protoJar = ProtoJar() private val testJar = TestJar() private val dokkaJar = DokkaJar() @@ -139,7 +152,7 @@ open class SpinePublishing(private val project: Project) { /** * Set of modules to be published. * - * Both module's name or path can be used. + * Both the module's name or path can be used. * * Use this property if the extension is configured from a root project's build file. * @@ -149,6 +162,22 @@ open class SpinePublishing(private val project: Project) { */ var modules: Set = emptySet() + /** + * Controls whether the published module needs standard publications. + * + * If `true`, the module should configure publications on its own. + * Otherwise, the extension will configure standard [ones][StandardJavaPublicationHandler]. + * + * This property is analogue of [modulesWithCustomPublishing] for projects, + * for which [spinePublishing] is configured individually. + * + * Setting of this property and having a non-empty [modules] will lead + * to an exception. + * + * Default value is `false`. + */ + var customPublishing = false + /** * Set of modules that have custom publications and do not need standard ones. * @@ -176,16 +205,14 @@ open class SpinePublishing(private val project: Project) { /** * A prefix to be added before the name of each artifact. - * - * Default value is "spine-". */ - var artifactPrefix: String = "spine-" + var artifactPrefix: String = DEFAULT_PREFIX /** * Allows disabling publishing of [protoJar] artifact, containing all Proto sources * from `sourceSets.main.proto`. * - * Here's an example of how to disable it for some of published modules: + * Here's an example of how to disable it for some of the published modules: * * ``` * spinePublishing { @@ -211,20 +238,20 @@ open class SpinePublishing(private val project: Project) { * } * ``` * - * The resulting artifact is available under "proto" classifier. I.e., in Gradle 7+, one could - * depend on it like this: + * The resulting artifact is available under "proto" classifier. + * For example, in Gradle 7+, one could depend on it like this: * * ``` * implementation("io.spine:spine-client:$version@proto") * ``` */ - fun protoJar(configuration: ProtoJar.() -> Unit) = protoJar.run(configuration) + fun protoJar(block: ProtoJar.() -> Unit) = protoJar.run(block) /** * Allows enabling publishing of [testJar] artifact, containing compilation output * of "test" source set. * - * Here's an example of how to enable it for some of published modules: + * Here's an example of how to enable it for some of the published modules: * * ``` * spinePublishing { @@ -250,38 +277,42 @@ open class SpinePublishing(private val project: Project) { * } * ``` * - * The resulting artifact is available under "test" classifier. I.e., in Gradle 7+, one could - * depend on it like this: + * The resulting artifact is available under "test" classifier. For example, + * in Gradle 7+, one could depend on it like this: * * ``` * implementation("io.spine:spine-client:$version@test") * ``` */ - fun testJar(configuration: TestJar.() -> Unit) = testJar.run(configuration) - + fun testJar(block: TestJar.() -> Unit) = testJar.run(block) /** - * Configures publishing of [dokkaJar] artifact, containing Dokka-generated documentation. By - * default, publishing of the artifact is disabled. + * Configures publishing of [dokkaKotlinJar] and [dokkaJavaJar] artifacts, + * containing Dokka-generated documentation. + * + * By default, publishing of the [dokkaKotlinJar] artifact is enabled, and [dokkaJavaJar] + * is disabled. * * Remember that the Dokka Gradle plugin should be applied to publish this artifact as it is * produced by the `dokkaHtml` task. It can be done by using the - * [io.spine.internal.dependency.Dokka] dependency object or by applying the - * `buildSrc/src/main/kotlin/dokka-for-java` script plugin for Java projects. + * [io.spine.dependency.build.Dokka] dependency object or by applying the + * `buildSrc/src/main/kotlin/dokka-for-kotlin` or + * `buildSrc/src/main/kotlin/dokka-for-java` script plugins. * * Here's an example of how to use this option: * * ``` * spinePublishing { * dokkaJar { - * enabled = true + * kotlin = false + * java = true * } * } * ``` * * The resulting artifact is available under "dokka" classifier. */ - fun dokkaJar(configuration: DokkaJar.() -> Unit) = dokkaJar.run(configuration) + fun dokkaJar(block: DokkaJar.() -> Unit) = dokkaJar.run(block) /** * Called to notify the extension that its configuration is completed. @@ -292,17 +323,13 @@ open class SpinePublishing(private val project: Project) { internal fun configured() { ensureProtoJarExclusionsArePublished() ensureTestJarInclusionsArePublished() - ensuresModulesNotDuplicated() - - val protoJarExclusions = protoJar.exclusions - val testJarInclusions = testJar.inclusions - val publishedProjects = publishedProjects() + ensureModulesNotDuplicated() + ensureCustomPublishingNotMisused() - publishedProjects.forEach { project -> - val name = project.name - val includeProtoJar = (protoJarExclusions.contains(name) || protoJar.disabled).not() - val includeTestJar = (testJarInclusions.contains(name) || testJar.enabled) - setUpPublishing(project, includeProtoJar, includeTestJar, dokkaJar.enabled) + val projectsToPublish = projectsToPublish() + projectsToPublish.forEach { project -> + val jarFlags = JarFlags.create(project.name, protoJar, testJar, dokkaJar) + project.setUpPublishing(jarFlags) } } @@ -318,50 +345,46 @@ open class SpinePublishing(private val project: Project) { * * @see modules */ - private fun publishedProjects() = modules.union(modulesWithCustomPublishing) - .map { name -> project.project(name) } - .ifEmpty { setOf(project) } + private fun projectsToPublish(): Collection { + if (project.subprojects.isEmpty()) { + return setOf(project) + } + return modules.union(modulesWithCustomPublishing) + .map { name -> project.project(name) } + .ifEmpty { setOf(project) } + } /** * Sets up `maven-publish` plugin for the given project. * - * Firstly, an instance of [PublishingConfig] is assembled for the project. - * Then, this config is applied. + * Firstly, an instance of [PublicationHandler] is created for the project depending + * on the nature of the publication process configured. + * Then, this the handler is scheduled to apply on [Project.afterEvaluate]. * - * This method utilizes `project.afterEvaluate` closure. General rule of thumb is to avoid using - * of this closure, as it configures a project when its configuration is considered completed. + * General rule of thumb is to avoid using [Project.afterEvaluate] of this closure, + * as it configures a project when its configuration is considered completed. * Which is quite counter-intuitive. * - * The root cause why it is used here is a possibility to configure publishing of multiple - * modules from a root project. When this possibility is employed, in fact, we configure - * publishing for a module, build file of which has not been even evaluated by that time. - * That leads to an unexpected behavior. + * We selected to use [Project.afterEvaluate] so that we can configure publishing of multiple + * modules from a root project. When we do this, we configure publishing for a module, + * build file of which has not been even evaluated yet. * * The simplest example here is specifying of `version` and `group` for Maven coordinates. * Let's suppose, they are declared in a module's build file. It is a common practice. * But publishing of the module is configured from a root project's build file. By the time, * when we need to specify them, we just don't know them. As a result, we have to use - * `project.afterEvaluate` in order to guarantee that a module will be configured by the time + * [Project.afterEvaluate] in order to guarantee that a module will be configured by the time * we configure publishing for it. */ - private fun setUpPublishing( - project: Project, - includeProtoJar: Boolean, - includeTestJar: Boolean, - includeDokkaJar: Boolean - ) { - val artifactId = artifactId(project) - val customPublishing = modulesWithCustomPublishing.contains(project.name) - val publishingConfig = if (customPublishing) { - PublishingConfig(artifactId, destinations) + private fun Project.setUpPublishing(jarFlags: JarFlags) { + val customPublishing = modulesWithCustomPublishing.contains(name) || customPublishing + val handler = if (customPublishing) { + CustomPublicationHandler(project, destinations) } else { - PublishingConfig( - artifactId, destinations, - includeProtoJar, includeTestJar, includeDokkaJar - ) + StandardJavaPublicationHandler(project, jarFlags, destinations) } - project.afterEvaluate { - publishingConfig.apply(project) + afterEvaluate { + handler.apply() } } @@ -411,7 +434,7 @@ open class SpinePublishing(private val project: Project) { * We allow configuration of publishing from two places - a root project and module itself. * Here we verify that publishing of a module is not configured in both places simultaneously. */ - private fun ensuresModulesNotDuplicated() { + private fun ensureModulesNotDuplicated() { val rootProject = project.rootProject if (rootProject == project) { return @@ -427,16 +450,11 @@ open class SpinePublishing(private val project: Project) { } } } -} - -/** - * Obtains [PublishingExtension] of this project. - */ -internal val Project.publishingExtension: PublishingExtension - get() = extensions.getByType() -/** - * Obtains [PublicationContainer] of this project. - */ -internal val Project.publications: PublicationContainer - get() = publishingExtension.publications + private fun ensureCustomPublishingNotMisused() { + if (modules.isNotEmpty() && customPublishing) { + error("`customPublishing` property can be set only if `spinePublishing` extension " + + "is open in an individual module, so `modules` property should be empty.") + } + } +} diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/report/coverage/CodebaseFilter.kt b/buildSrc/src/main/kotlin/io/spine/gradle/report/coverage/CodebaseFilter.kt similarity index 94% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/report/coverage/CodebaseFilter.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/report/coverage/CodebaseFilter.kt index 89e2912..a5b9e72 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/report/coverage/CodebaseFilter.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/report/coverage/CodebaseFilter.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,10 +24,10 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.report.coverage +package io.spine.gradle.report.coverage import com.google.errorprone.annotations.CanIgnoreReturnValue -import io.spine.internal.gradle.report.coverage.FileFilter.generatedOnly +import io.spine.gradle.report.coverage.FileFilter.generatedOnly import java.io.File import kotlin.streams.toList import org.gradle.api.Project diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/report/coverage/FileExtension.kt b/buildSrc/src/main/kotlin/io/spine/gradle/report/coverage/FileExtension.kt similarity index 91% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/report/coverage/FileExtension.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/report/coverage/FileExtension.kt index 97ab594..ae4734c 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/report/coverage/FileExtension.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/report/coverage/FileExtension.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,7 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.report.coverage +package io.spine.gradle.report.coverage /** * File extensions. diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/report/coverage/FileExtensions.kt b/buildSrc/src/main/kotlin/io/spine/gradle/report/coverage/FileExtensions.kt similarity index 85% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/report/coverage/FileExtensions.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/report/coverage/FileExtensions.kt index 4a42797..89c8789 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/report/coverage/FileExtensions.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/report/coverage/FileExtensions.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,16 +24,16 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.report.coverage +package io.spine.gradle.report.coverage -import io.spine.internal.gradle.report.coverage.FileExtension.COMPILED_CLASS -import io.spine.internal.gradle.report.coverage.FileExtension.JAVA_SOURCE -import io.spine.internal.gradle.report.coverage.PathMarker.ANONYMOUS_CLASS -import io.spine.internal.gradle.report.coverage.PathMarker.GENERATED -import io.spine.internal.gradle.report.coverage.PathMarker.GRPC_SRC_FOLDER -import io.spine.internal.gradle.report.coverage.PathMarker.JAVA_OUTPUT_FOLDER -import io.spine.internal.gradle.report.coverage.PathMarker.JAVA_SRC_FOLDER -import io.spine.internal.gradle.report.coverage.PathMarker.SPINE_JAVA_SRC_FOLDER +import io.spine.gradle.report.coverage.FileExtension.COMPILED_CLASS +import io.spine.gradle.report.coverage.FileExtension.JAVA_SOURCE +import io.spine.gradle.report.coverage.PathMarker.ANONYMOUS_CLASS +import io.spine.gradle.report.coverage.PathMarker.GENERATED +import io.spine.gradle.report.coverage.PathMarker.GRPC_SRC_FOLDER +import io.spine.gradle.report.coverage.PathMarker.JAVA_OUTPUT_FOLDER +import io.spine.gradle.report.coverage.PathMarker.JAVA_SRC_FOLDER +import io.spine.gradle.report.coverage.PathMarker.SPINE_JAVA_SRC_FOLDER import java.io.File /** diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/report/coverage/FileFilter.kt b/buildSrc/src/main/kotlin/io/spine/gradle/report/coverage/FileFilter.kt similarity index 92% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/report/coverage/FileFilter.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/report/coverage/FileFilter.kt index 1f4b382..5b26cc7 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/report/coverage/FileFilter.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/report/coverage/FileFilter.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,7 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.report.coverage +package io.spine.gradle.report.coverage import java.io.File diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/report/coverage/JacocoConfig.kt b/buildSrc/src/main/kotlin/io/spine/gradle/report/coverage/JacocoConfig.kt similarity index 82% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/report/coverage/JacocoConfig.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/report/coverage/JacocoConfig.kt index 5e7fff4..de5d00b 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/report/coverage/JacocoConfig.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/report/coverage/JacocoConfig.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,19 +24,19 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.report.coverage +package io.spine.gradle.report.coverage -import io.spine.internal.gradle.applyPlugin -import io.spine.internal.gradle.findTask -import io.spine.internal.gradle.report.coverage.TaskName.check -import io.spine.internal.gradle.report.coverage.TaskName.copyReports -import io.spine.internal.gradle.report.coverage.TaskName.jacocoRootReport -import io.spine.internal.gradle.report.coverage.TaskName.jacocoTestReport -import io.spine.internal.gradle.sourceSets +import io.spine.dependency.test.Jacoco +import io.spine.gradle.applyPlugin +import io.spine.gradle.findTask +import io.spine.gradle.report.coverage.TaskName.check +import io.spine.gradle.report.coverage.TaskName.copyReports +import io.spine.gradle.report.coverage.TaskName.jacocoRootReport +import io.spine.gradle.report.coverage.TaskName.jacocoTestReport +import io.spine.gradle.sourceSets import java.io.File import java.util.* import org.gradle.api.Project -import org.gradle.api.Task import org.gradle.api.file.ConfigurableFileCollection import org.gradle.api.plugins.BasePlugin import org.gradle.api.tasks.Copy @@ -45,7 +45,9 @@ import org.gradle.api.tasks.SourceSetOutput import org.gradle.api.tasks.TaskContainer import org.gradle.api.tasks.TaskProvider import org.gradle.kotlin.dsl.get +import org.gradle.kotlin.dsl.the import org.gradle.testing.jacoco.plugins.JacocoPlugin +import org.gradle.testing.jacoco.plugins.JacocoPluginExtension import org.gradle.testing.jacoco.tasks.JacocoReport /** @@ -89,12 +91,14 @@ class JacocoConfig( */ fun applyTo(project: Project) { project.applyPlugin(BasePlugin::class.java) - project.afterEvaluate { - val javaProjects: Iterable = eligibleProjects(project) - val reportsDir = project.rootProject.buildDir.resolve(reportsDirSuffix) - JacocoConfig(project.rootProject, reportsDir, javaProjects) - .configure() - } + val javaProjects: Iterable = eligibleProjects(project) + val reportsDir = project.rootProject.layout + .buildDirectory.dir(reportsDirSuffix).get().asFile + JacocoConfig( + project.rootProject, + reportsDir, + javaProjects + ).configure() } /** @@ -120,12 +124,22 @@ class JacocoConfig( } private fun configure() { + configureVersion() + configureTask() + } + + private fun configureVersion() { + val jacoco = rootProject.the() + jacoco.toolVersion = Jacoco.version + } + + private fun configureTask() { val tasks = rootProject.tasks val copyReports = registerCopy(tasks) val rootReport = registerRootReport(tasks, copyReports) - rootProject - .findTask(check.name) - .dependsOn(rootReport) + tasks.named(check.name) { + dependsOn(rootReport) + } } private fun registerRootReport( @@ -134,9 +148,14 @@ class JacocoConfig( ): TaskProvider { val allSourceSets = Projects(projects).sourceSets() val mainJavaSrcDirs = allSourceSets.mainJavaSrcDirs() - val humanProducedSourceFolders = FileFilter.producedByHuman(mainJavaSrcDirs) - - val filter = CodebaseFilter(rootProject, mainJavaSrcDirs, allSourceSets.mainOutputs()) + val humanProducedSourceFolders = + FileFilter.producedByHuman(mainJavaSrcDirs) + + val filter = CodebaseFilter( + rootProject, + mainJavaSrcDirs, + allSourceSets.mainOutputs() + ) val humanProducedCompiledFiles = filter.humanProducedCompiledFiles() val rootReport = tasks.register(jacocoRootReport.name, JacocoReport::class.java) { diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/report/coverage/PathMarker.kt b/buildSrc/src/main/kotlin/io/spine/gradle/report/coverage/PathMarker.kt similarity index 93% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/report/coverage/PathMarker.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/report/coverage/PathMarker.kt index 00fdf24..26bb135 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/report/coverage/PathMarker.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/report/coverage/PathMarker.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,7 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.report.coverage +package io.spine.gradle.report.coverage /** * Fragments of file path which allow to detect the type of the file. diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/report/coverage/TaskName.kt b/buildSrc/src/main/kotlin/io/spine/gradle/report/coverage/TaskName.kt similarity index 86% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/report/coverage/TaskName.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/report/coverage/TaskName.kt index 76d3458..7c0e386 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/report/coverage/TaskName.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/report/coverage/TaskName.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,10 +24,10 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.report.coverage +package io.spine.gradle.report.coverage /** - * The names of Gradle tasks involved into the JaCoCo reporting. + * The names of Gradle tasks involved in the JaCoCo reporting. */ @Suppress("EnumEntryName", "EnumNaming") /* Dubbing the actual values in Gradle. */ internal enum class TaskName { diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/report/license/Configuration.kt b/buildSrc/src/main/kotlin/io/spine/gradle/report/license/Configuration.kt similarity index 92% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/report/license/Configuration.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/report/license/Configuration.kt index 65fd036..f6e06fd 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/report/license/Configuration.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/report/license/Configuration.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,7 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.report.license +package io.spine.gradle.report.license import com.github.jk1.license.ConfigurationData diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/report/license/LicenseReporter.kt b/buildSrc/src/main/kotlin/io/spine/gradle/report/license/LicenseReporter.kt similarity index 88% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/report/license/LicenseReporter.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/report/license/LicenseReporter.kt index be3e250..9b7a57f 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/report/license/LicenseReporter.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/report/license/LicenseReporter.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,13 +24,13 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.report.license +package io.spine.gradle.report.license import com.github.jk1.license.LicenseReportExtension import com.github.jk1.license.LicenseReportExtension.ALL import com.github.jk1.license.LicenseReportPlugin -import io.spine.internal.gradle.applyPlugin -import io.spine.internal.gradle.findTask +import io.spine.gradle.applyPlugin +import io.spine.gradle.findTask import java.io.File import org.gradle.api.Project import org.gradle.api.Task @@ -80,11 +80,17 @@ object LicenseReporter { */ fun generateReportIn(project: Project) { project.applyPlugin(LicenseReportPlugin::class.java) - val reportOutputDir = project.buildDir.resolve(Paths.relativePath) + val reportOutputDir = project.layout.buildDirectory.dir(Paths.relativePath).get().asFile with(project.the()) { outputDir = reportOutputDir.absolutePath - excludeGroups = arrayOf("io.spine", "io.spine.tools", "io.spine.gcloud") + excludeGroups = arrayOf( + "io.spine", + "io.spine.gcloud", + "io.spine.protodata", + "io.spine.tools", + "io.spine.validation" + ) configurations = ALL renderers = arrayOf(MarkdownReportRenderer(Paths.outputFilename)) @@ -146,7 +152,8 @@ object LicenseReporter { rootProject: Project ) { val paths = sourceProjects.map { - "${it.buildDir}/${Paths.relativePath}/${Paths.outputFilename}" + val buildDir = it.layout.buildDirectory.asFile.get() + "$buildDir/${Paths.relativePath}/${Paths.outputFilename}" } println("Merging the license reports from the all projects.") val mergedContent = paths.joinToString("\n\n\n") { (File(it)).readText() } diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/report/license/MarkdownReportRenderer.kt b/buildSrc/src/main/kotlin/io/spine/gradle/report/license/MarkdownReportRenderer.kt similarity index 84% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/report/license/MarkdownReportRenderer.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/report/license/MarkdownReportRenderer.kt index ebd62d5..b158210 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/report/license/MarkdownReportRenderer.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/report/license/MarkdownReportRenderer.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,12 +24,12 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.report.license +package io.spine.gradle.report.license import com.github.jk1.license.LicenseReportExtension import com.github.jk1.license.ProjectData import com.github.jk1.license.render.ReportRenderer -import io.spine.internal.markup.MarkdownDocument +import io.spine.docs.MarkdownDocument import java.io.File import org.gradle.api.Project @@ -54,9 +54,8 @@ internal class MarkdownReportRenderer( } private fun outputFile(project: Project): File { - val config = - project.extensions.findByName("licenseReport") as LicenseReportExtension - return File(config.outputDir).resolve(filename) + val ext = project.extensions.findByName("licenseReport") as LicenseReportExtension + return File(ext.outputDir).resolve(filename) } } diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/report/license/ModuleDataExtensions.kt b/buildSrc/src/main/kotlin/io/spine/gradle/report/license/ModuleDataExtensions.kt similarity index 93% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/report/license/ModuleDataExtensions.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/report/license/ModuleDataExtensions.kt index c219dec..0aca30f 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/report/license/ModuleDataExtensions.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/report/license/ModuleDataExtensions.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,10 +24,10 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.report.license +package io.spine.gradle.report.license import com.github.jk1.license.ModuleData -import io.spine.internal.markup.MarkdownDocument +import io.spine.docs.MarkdownDocument import kotlin.reflect.KCallable /** @@ -49,7 +49,7 @@ internal fun MarkdownDocument.printSection( } /** - * Prints the metadata of the module to the specified [Markdown document][out]. + * Prints the module metadata to this [MarkdownDocument]. */ private fun MarkdownDocument.printModule(module: ModuleData) { ol() @@ -105,7 +105,7 @@ private fun MarkdownDocument.printProjectUrl(projectUrl: String?, indent: Int) { } /** - * Prints the links to the the source code licenses. + * Prints the links to the source code licenses. */ @Suppress("SameParameterValue" /* Indentation is consistent across the list. */) private fun MarkdownDocument.printLicenses(licenses: Set, indent: Int) { diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/report/license/Paths.kt b/buildSrc/src/main/kotlin/io/spine/gradle/report/license/Paths.kt similarity index 89% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/report/license/Paths.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/report/license/Paths.kt index cf1f460..975a73b 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/report/license/Paths.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/report/license/Paths.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,7 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.report.license +package io.spine.gradle.report.license /** * Filesystem paths used by [LicenseReporter]. @@ -40,7 +40,7 @@ internal object Paths { * Its contents describe the licensing information for each of the Java dependencies * which are referenced by Gradle projects in the repository. */ - internal const val outputFilename = "license-report.md" + internal const val outputFilename = "dependencies.md" /** * The path to a directory, to which a per-project report is generated. diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/report/license/ProjectDependencies.kt b/buildSrc/src/main/kotlin/io/spine/gradle/report/license/ProjectDependencies.kt similarity index 93% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/report/license/ProjectDependencies.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/report/license/ProjectDependencies.kt index 164df07..d9e569c 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/report/license/ProjectDependencies.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/report/license/ProjectDependencies.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,11 +24,11 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.report.license +package io.spine.gradle.report.license import com.github.jk1.license.ModuleData import com.github.jk1.license.ProjectData -import io.spine.internal.markup.MarkdownDocument +import io.spine.docs.MarkdownDocument /** * Dependencies of some [Gradle project][ProjectData] classified by the Gradle configuration diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/report/license/Tasks.kt b/buildSrc/src/main/kotlin/io/spine/gradle/report/license/Tasks.kt similarity index 91% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/report/license/Tasks.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/report/license/Tasks.kt index 4206f3d..05df91a 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/report/license/Tasks.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/report/license/Tasks.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,7 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.report.license +package io.spine.gradle.report.license import org.gradle.api.Task import org.gradle.api.tasks.TaskContainer diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/report/license/Template.kt b/buildSrc/src/main/kotlin/io/spine/gradle/report/license/Template.kt similarity index 91% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/report/license/Template.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/report/license/Template.kt index f8f835e..adda37b 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/report/license/Template.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/report/license/Template.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,10 +24,10 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.report.license +package io.spine.gradle.report.license -import io.spine.internal.gradle.artifactId -import io.spine.internal.markup.MarkdownDocument +import io.spine.docs.MarkdownDocument +import io.spine.gradle.artifactId import java.util.* import org.gradle.api.Project diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/report/pom/DependencyScope.kt b/buildSrc/src/main/kotlin/io/spine/gradle/report/pom/DependencyScope.kt similarity index 91% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/report/pom/DependencyScope.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/report/pom/DependencyScope.kt index 6a11b7c..1b4f478 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/report/pom/DependencyScope.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/report/pom/DependencyScope.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,7 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.report.pom +package io.spine.gradle.report.pom /** * A Maven dependency scope. diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/report/pom/DependencyWriter.kt b/buildSrc/src/main/kotlin/io/spine/gradle/report/pom/DependencyWriter.kt similarity index 84% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/report/pom/DependencyWriter.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/report/pom/DependencyWriter.kt index 49326e9..eda2493 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/report/pom/DependencyWriter.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/report/pom/DependencyWriter.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,13 +24,14 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.report.pom +package io.spine.gradle.report.pom import groovy.xml.MarkupBuilder import java.io.Writer import java.util.* import kotlin.reflect.full.isSubclassOf import org.gradle.api.Project +import org.gradle.api.artifacts.Configuration import org.gradle.api.artifacts.Dependency import org.gradle.api.internal.artifacts.dependencies.AbstractExternalModuleDependency import org.gradle.kotlin.dsl.withGroovyBuilder @@ -126,13 +127,34 @@ private fun Project.depsFromAllConfigurations(): Set { } configuration.dependencies.filter { it.isExternal() } .forEach { dependency -> - val moduleDependency = ModuleDependency(project, configuration, dependency) + val forcedVersion = configuration.forcedVersionOf(dependency) + val moduleDependency = + if (forcedVersion != null) { + ModuleDependency(project, configuration, dependency, forcedVersion) + } else { + ModuleDependency(project, configuration, dependency) + } result.add(moduleDependency) } } return result } +/** + * Searches for a forced version of given [dependency] in this [Configuration]. + * + * Returns `null`, if it wasn't forced. + */ +private fun Configuration.forcedVersionOf(dependency: Dependency): String? { + val forcedModules = resolutionStrategy.forcedModules + val maybeForced = forcedModules.firstOrNull { + it.group == dependency.group + && it.name == dependency.name + && it.version != null + } + return maybeForced?.version +} + /** * Tells whether the dependency is an external module dependency. */ @@ -160,8 +182,8 @@ private fun Project.deduplicate(dependencies: Set): List - group.value.maxByOrNull { dep -> dep.version!! }!! - } + group.value.maxByOrNull { dep -> dep.version ?: "" } + }.filterNotNull() return filtered } @@ -177,7 +199,7 @@ private fun Project.logDuplicate(dependency: String, versions: List { companion object { - private val COMPARATOR = compareBy { it.module } + private val COMPARATOR = compareBy { it.project } .thenBy { it.configuration.name } .thenBy { it.group } .thenBy { it.name } - .thenBy { it.version } + .thenBy { it.factualVersion } } + override fun getVersion(): String? = factualVersion + /** * A project dependency with its [scope][DependencyScope]. * * Doesn't contain any info about an origin module and configuration. */ - val scoped = ScopedDependency.of(dependency, configuration) + val scoped = ScopedDependency.of(this, configuration) /** * GAV coordinates of this dependency. * * Gradle's [Dependency] is a mutable object. Its properties can change their - * values with time. In parcticular, the version can be changed as more + * values with time. In particular, the version can be changed as more * configurations are getting resolved. This is why this property is calculated. */ val gav: String - get() = "$group:$name:$version" + get() = "$group:$name:$factualVersion" override fun compareTo(other: ModuleDependency): Int = COMPARATOR.compare(this, other) @@ -76,17 +79,17 @@ internal class ModuleDependency( other as ModuleDependency - if (module != other.module) return false + if (project != other.project) return false if (configuration != other.configuration) return false - if (dependency != other.dependency) return false + if (gav != other.gav) return false return true } override fun hashCode(): Int { - var result = module.hashCode() + var result = project.hashCode() result = 31 * result + configuration.hashCode() - result = 31 * result + dependency.hashCode() + result = 31 * result + gav.hashCode() return result } } diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/report/pom/PomFormatting.kt b/buildSrc/src/main/kotlin/io/spine/gradle/report/pom/PomFormatting.kt similarity index 96% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/report/pom/PomFormatting.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/report/pom/PomFormatting.kt index 446b3cb..ba673bb 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/report/pom/PomFormatting.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/report/pom/PomFormatting.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,7 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.report.pom +package io.spine.gradle.report.pom import java.io.StringWriter import java.lang.System.lineSeparator diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/report/pom/PomGenerator.kt b/buildSrc/src/main/kotlin/io/spine/gradle/report/pom/PomGenerator.kt similarity index 82% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/report/pom/PomGenerator.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/report/pom/PomGenerator.kt index 8b9ab50..9144e2f 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/report/pom/PomGenerator.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/report/pom/PomGenerator.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,11 +24,10 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.report.pom +package io.spine.gradle.report.pom import org.gradle.api.Project import org.gradle.api.plugins.BasePlugin -import org.gradle.kotlin.dsl.extra /** * Generates a `pom.xml` file that contains dependencies of the root project as @@ -76,20 +75,21 @@ object PomGenerator { plugin(BasePlugin::class.java) } - val task = project.tasks.create("generatePom") - task.doLast { - val pomFile = project.projectDir.resolve("pom.xml") - project.delete(pomFile) + val task = project.tasks.register("generatePom") { + doLast { + val pomFile = project.projectDir.resolve("pom.xml") + project.delete(pomFile) - val projectData = project.metadata() - val writer = PomXmlWriter(projectData) - writer.writeTo(pomFile) + val projectData = project.metadata() + val writer = PomXmlWriter(projectData) + writer.writeTo(pomFile) + } + + val assembleTask = project.tasks.findByName("assemble")!! + dependsOn(assembleTask) } val buildTask = project.tasks.findByName("build")!! buildTask.finalizedBy(task) - - val assembleTask = project.tasks.findByName("assemble")!! - task.dependsOn(assembleTask) } } diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/report/pom/PomXmlWriter.kt b/buildSrc/src/main/kotlin/io/spine/gradle/report/pom/PomXmlWriter.kt similarity index 91% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/report/pom/PomXmlWriter.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/report/pom/PomXmlWriter.kt index 3df3403..5312219 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/report/pom/PomXmlWriter.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/report/pom/PomXmlWriter.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,10 +24,10 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.report.pom +package io.spine.gradle.report.pom -import io.spine.internal.gradle.report.pom.PomFormatting.writeBlocks -import io.spine.internal.gradle.report.pom.PomFormatting.writeStart +import io.spine.gradle.report.pom.PomFormatting.writeBlocks +import io.spine.gradle.report.pom.PomFormatting.writeStart import java.io.File import java.io.FileWriter import java.io.StringWriter diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/report/pom/ProjectMetadata.kt b/buildSrc/src/main/kotlin/io/spine/gradle/report/pom/ProjectMetadata.kt similarity index 96% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/report/pom/ProjectMetadata.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/report/pom/ProjectMetadata.kt index 40c84f2..ffb89a2 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/report/pom/ProjectMetadata.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/report/pom/ProjectMetadata.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,7 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.report.pom +package io.spine.gradle.report.pom import groovy.xml.MarkupBuilder import java.io.StringWriter diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/report/pom/ScopedDependency.kt b/buildSrc/src/main/kotlin/io/spine/gradle/report/pom/ScopedDependency.kt similarity index 93% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/report/pom/ScopedDependency.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/report/pom/ScopedDependency.kt index cb841dd..7c67a32 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/report/pom/ScopedDependency.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/report/pom/ScopedDependency.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,13 +24,13 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.report.pom +package io.spine.gradle.report.pom -import io.spine.internal.gradle.report.pom.DependencyScope.compile -import io.spine.internal.gradle.report.pom.DependencyScope.provided -import io.spine.internal.gradle.report.pom.DependencyScope.runtime -import io.spine.internal.gradle.report.pom.DependencyScope.test -import io.spine.internal.gradle.report.pom.DependencyScope.undefined +import io.spine.gradle.report.pom.DependencyScope.compile +import io.spine.gradle.report.pom.DependencyScope.provided +import io.spine.gradle.report.pom.DependencyScope.runtime +import io.spine.gradle.report.pom.DependencyScope.test +import io.spine.gradle.report.pom.DependencyScope.undefined import org.gradle.api.artifacts.Configuration import org.gradle.api.artifacts.Dependency diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/report/pom/SpineLicense.kt b/buildSrc/src/main/kotlin/io/spine/gradle/report/pom/SpineLicense.kt similarity index 93% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/report/pom/SpineLicense.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/report/pom/SpineLicense.kt index 7c95db2..114395e 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/report/pom/SpineLicense.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/report/pom/SpineLicense.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,7 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.report.pom +package io.spine.gradle.report.pom import groovy.xml.MarkupBuilder import java.io.StringWriter diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/testing/Logging.kt b/buildSrc/src/main/kotlin/io/spine/gradle/testing/Logging.kt similarity index 95% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/testing/Logging.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/testing/Logging.kt index 00143e6..6fb7eab 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/testing/Logging.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/testing/Logging.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,7 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.testing +package io.spine.gradle.testing import org.gradle.api.tasks.testing.Test import org.gradle.api.tasks.testing.TestDescriptor diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/testing/Multiproject.kt b/buildSrc/src/main/kotlin/io/spine/gradle/testing/Multiproject.kt similarity index 90% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/testing/Multiproject.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/testing/Multiproject.kt index b540923..1f5ed49 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/testing/Multiproject.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/testing/Multiproject.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,10 +24,10 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.testing +package io.spine.gradle.testing +import io.spine.gradle.publish.testJar import org.gradle.api.Project -import io.spine.internal.gradle.publish.testJar /** * Exposes the test classes of this project as a new "testArtifacts" configuration. @@ -57,7 +57,7 @@ import io.spine.internal.gradle.publish.testJar * * Don't forget that this exposure mechanism works only for projects that reside within the same * multi-project build. In order to share the test classes with external projects, publish a - * dedicated [testJar][io.spine.internal.gradle.publish.SpinePublishing.testJar] artifact. + * dedicated [testJar][io.spine.gradle.publish.SpinePublishing.testJar] artifact. */ @Suppress("unused") fun Project.exposeTestConfiguration() { diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/testing/Tasks.kt b/buildSrc/src/main/kotlin/io/spine/gradle/testing/Tasks.kt similarity index 84% rename from buildSrc/src/main/kotlin/io/spine/internal/gradle/testing/Tasks.kt rename to buildSrc/src/main/kotlin/io/spine/gradle/testing/Tasks.kt index cf5ba42..971c4b4 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/testing/Tasks.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/testing/Tasks.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,7 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package io.spine.internal.gradle.testing +package io.spine.gradle.testing import org.gradle.api.tasks.TaskContainer import org.gradle.api.tasks.testing.Test @@ -47,6 +47,9 @@ import org.gradle.kotlin.dsl.register fun TaskContainer.registerTestTasks() { withType(Test::class.java).configureEach { filter { + // There could be cases with no matching tests. E.g. tests could be based on Kotest, + // which has custom task types and names. + isFailOnNoMatchingTests = false includeTestsMatching("*Test") includeTestsMatching("*Spec") } @@ -72,7 +75,7 @@ private const val SLOW_TAG = "slow" /** * Executes JUnit tests filtering out the ones tagged as `slow`. */ -private open class FastTest : Test() { +private abstract class FastTest : Test() { init { description = "Executes all JUnit tests but the ones tagged as `slow`." group = "Verification" @@ -86,11 +89,12 @@ private open class FastTest : Test() { /** * Executes JUnit tests tagged as `slow`. */ -private open class SlowTest : Test() { +private abstract class SlowTest : Test() { init { description = "Executes JUnit tests tagged as `slow`." group = "Verification" - + // No slow tests -- no problem. + filter.isFailOnNoMatchingTests = false this.useJUnitPlatform { includeTags(SLOW_TAG) } diff --git a/buildSrc/src/main/kotlin/io/spine/internal/dependency/Kotlin.kt b/buildSrc/src/main/kotlin/io/spine/internal/dependency/Kotlin.kt deleted file mode 100644 index 501df00..0000000 --- a/buildSrc/src/main/kotlin/io/spine/internal/dependency/Kotlin.kt +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2022, TeamDev. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Redistribution and use in source and/or binary forms, with or without - * modification, must retain the above copyright notice and the following - * disclaimer. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package io.spine.internal.dependency - -// https://github.com/JetBrains/kotlin -// https://github.com/Kotlin -object Kotlin { - /** - * When changing the version, also change the version used in the `buildSrc/build.gradle.kts`. - */ - @Suppress("MemberVisibilityCanBePrivate") // used directly from outside - const val version = "1.7.20" - const val reflect = "org.jetbrains.kotlin:kotlin-reflect:${version}" - const val stdLib = "org.jetbrains.kotlin:kotlin-stdlib:${version}" - const val stdLibCommon = "org.jetbrains.kotlin:kotlin-stdlib-common:${version}" - const val stdLibJdk8 = "org.jetbrains.kotlin:kotlin-stdlib-jdk8:${version}" -} diff --git a/buildSrc/src/main/kotlin/io/spine/internal/dependency/Spine.kt b/buildSrc/src/main/kotlin/io/spine/internal/dependency/Spine.kt deleted file mode 100644 index 8f43433..0000000 --- a/buildSrc/src/main/kotlin/io/spine/internal/dependency/Spine.kt +++ /dev/null @@ -1,284 +0,0 @@ -/* - * Copyright 2022, TeamDev. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Redistribution and use in source and/or binary forms, with or without - * modification, must retain the above copyright notice and the following - * disclaimer. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package io.spine.internal.dependency - -import org.gradle.api.plugins.ExtensionAware -import org.gradle.kotlin.dsl.extra - -/** - * Dependencies on Spine modules. - * - * @constructor - * Creates a new instance of `Spine` taking the property values - * of versions from the given project's extra properties. - */ -@Suppress("unused") -class Spine(p: ExtensionAware) { - - /** - * Default versions for the modules of Spine, unless they are - * configured in `versions.gradle.kts`. - */ - object DefaultVersion { - - /** - * The version of ProtoData to be used in the project. - * - * We do it here instead of `versions.gradle.kts` because we later use - * it in a `plugins` section in a build script. - * - * This version cannot be re-defined via `version.gradle.kts` like versions - * of other subprojects like [base] or [core]. So, if you want to use another version, - * please update this value in your `buildSrc. - * - * Development of ProtoData uses custom convention for using custom version - * of ProtoData in its integration tests. Please see `ProtoData/version.gradle.kts` - * for details. - * - * @see [ProtoData] - */ - const val protoData = "0.3.0" - - /** - * The default version of `base` to use. - * @see [Spine.base] - */ - const val base = "2.0.0-SNAPSHOT.120" - - /** - * The default version of `core-java` to use. - * @see [Spine.CoreJava.client] - * @see [Spine.CoreJava.server] - */ - const val core = "2.0.0-SNAPSHOT.119" - - /** - * The version of `model-compiler` to use. - * @see [Spine.modelCompiler] - */ - const val mc = "2.0.0-SNAPSHOT.90" - - /** - * The version of `mc-java` to use. - */ - const val mcJava = "2.0.0-SNAPSHOT.105" - - /** - * The version of `base-types` to use. - * @see [Spine.baseTypes] - */ - const val baseTypes = "2.0.0-SNAPSHOT.112" - - /** - * The version of `time` to use. - * @see [Spine.time] - */ - const val time = "2.0.0-SNAPSHOT.120" - - /** - * The version of `change` to use. - * @see [Spine.change] - */ - const val change = "2.0.0-SNAPSHOT.117" - - /** - * The version of `text` to use. - * - * @see Spine.text - */ - const val text = "2.0.0-SNAPSHOT.1" - - /** - * The version of `tool-base` to use. - * @see [Spine.toolBase] - */ - const val toolBase = "2.0.0-SNAPSHOT.111" - - /** - * The version of `validation` to use. - * @see [Spine.validation] - */ - const val validation = "2.0.0-SNAPSHOT.61" - - /** - * The version of Javadoc Tools to use. - * @see [Spine.javadocTools] - */ - const val javadocTools = "2.0.0-SNAPSHOT.75" - } - - companion object { - const val group = "io.spine" - const val toolsGroup = "io.spine.tools" - - /** - * The version of ProtoData to be used in the project. - * - * We do it here instead of `versions.gradle.kts` because we later use - * it in a `plugins` section in a build script. - * - * @see [ProtoData] - */ - const val protoDataVersion = DefaultVersion.protoData - } - - val base = "$group:spine-base:${p.baseVersion}" - val baseTypes = "$group:spine-base-types:${p.baseTypesVersion}" - val time = "$group:spine-time:${p.timeVersion}" - val change = "$group:spine-change:${p.changeVersion}" - val text = "$group:spine-text:${p.textVersion}" - - val testlib = "$toolsGroup:spine-testlib:${p.baseVersion}" - val testUtilTime = "$toolsGroup:spine-testutil-time:${p.timeVersion}" - val toolBase = "$toolsGroup:spine-tool-base:${p.toolBaseVersion}" - val pluginBase = "$toolsGroup:spine-plugin-base:${p.toolBaseVersion}" - val pluginTestlib = "$toolsGroup:spine-plugin-testlib:${p.toolBaseVersion}" - val modelCompiler = "$toolsGroup:spine-model-compiler:${p.mcVersion}" - - /** - * Coordinates of the McJava plugin bundle which uses version of the bundle - * from [ExtensionAware.mcJavaVersion] property. - * - * This property and [ExtensionAware.mcJavaVersion] are deprecated because - * we discourage using versions of Spine components outside of this dependency - * object class. - */ - @Deprecated(message = "Please use `McJava.pluginLib` instead") - @Suppress("DEPRECATION") - val mcJavaPlugin = "$toolsGroup:spine-mc-java-plugins:${p.mcJavaVersion}:all" - - object McJava { - const val version = DefaultVersion.mcJava - const val pluginId = "io.spine.mc-java" - const val pluginLib = "$toolsGroup:spine-mc-java-plugins:${version}:all" - } - - /** - * Does not allow re-definition via a project property. - * Please change [DefaultVersion.javadocTools]. ˚ - */ - val javadocTools = "$toolsGroup::${DefaultVersion.javadocTools}" - - @Deprecated("Please use `validation.runtime`", replaceWith = ReplaceWith("validation.runtime")) - val validate = "$group:spine-validate:${p.baseVersion}" - - val validation = Validation(p) - - val coreJava = CoreJava(p) - val client = coreJava.client // Added for brevity. - val server = coreJava.server // Added for brevity. - - private val ExtensionAware.baseVersion: String - get() = "baseVersion".asExtra(this, DefaultVersion.base) - - private val ExtensionAware.baseTypesVersion: String - get() = "baseTypesVersion".asExtra(this, DefaultVersion.baseTypes) - - private val ExtensionAware.timeVersion: String - get() = "timeVersion".asExtra(this, DefaultVersion.time) - - private val ExtensionAware.changeVersion: String - get() = "changeVersion".asExtra(this, DefaultVersion.change) - - private val ExtensionAware.textVersion: String - get() = "textVersion".asExtra(this, DefaultVersion.text) - - private val ExtensionAware.mcVersion: String - get() = "mcVersion".asExtra(this, DefaultVersion.mc) - - @Deprecated(message = "Please use `Spine.McJava` dependency object instead.") - private val ExtensionAware.mcJavaVersion: String - get() = "mcJavaVersion".asExtra(this, DefaultVersion.mcJava) - - private val ExtensionAware.toolBaseVersion: String - get() = "toolBaseVersion".asExtra(this, DefaultVersion.toolBase) - - /** - * Dependencies on Spine validation modules. - * - * See [`SpineEventEngine/validation`](https://github.com/SpineEventEngine/validation/). - */ - class Validation(p: ExtensionAware) { - companion object { - const val group = "io.spine.validation" - } - val runtime = "$group:spine-validation-java-runtime:${p.validationVersion}" - val java = "$group:spine-validation-java:${p.validationVersion}" - val model = "$group:spine-validation-model:${p.validationVersion}" - val config = "$group:spine-validation-configuration:${p.validationVersion}" - - private val ExtensionAware.validationVersion: String - get() = "validationVersion".asExtra(this, DefaultVersion.validation) - } - - /** - * Dependencies on ProtoData modules. - * - * See [`SpineEventEngine/ProtoData`](https://github.com/SpineEventEngine/ProtoData/). - */ - object ProtoData { - const val group = "io.spine.protodata" - const val version = protoDataVersion - const val compiler = "$group:protodata-compiler:$version" - - const val codegenJava = "io.spine.protodata:protodata-codegen-java:$version" - - const val pluginId = "io.spine.protodata" - const val pluginLib = "${Spine.group}:protodata:$version" - } - - /** - * Dependencies on `core-java` modules. - * - * See [`SpineEventEngine/core-java`](https://github.com/SpineEventEngine/core-java/). - */ - class CoreJava(p: ExtensionAware) { - val core = "$group:spine-core:${p.coreVersion}" - val client = "$group:spine-client:${p.coreVersion}" - val server = "$group:spine-server:${p.coreVersion}" - val testUtilServer = "$toolsGroup:spine-testutil-server:${p.coreVersion}" - - private val ExtensionAware.coreVersion: String - get() = "coreVersion".asExtra(this, DefaultVersion.core) - } -} - -/** - * Obtains the value of the extension property named as this string from the given project. - * - * @param p the project declaring extension properties - * @param defaultValue - * the default value to return, if the project does not have such a property. - * If `null` then rely on the property declaration, even if this would cause an error. - */ -private fun String.asExtra(p: ExtensionAware, defaultValue: String? = null): String { - return if (p.extra.has(this) || defaultValue == null) { - p.extra[this] as String - } else { - defaultValue - } -} diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/protobuf/ProtoTaskExtensions.kt b/buildSrc/src/main/kotlin/io/spine/internal/gradle/protobuf/ProtoTaskExtensions.kt deleted file mode 100644 index ca32203..0000000 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/protobuf/ProtoTaskExtensions.kt +++ /dev/null @@ -1,194 +0,0 @@ -/* - * Copyright 2022, TeamDev. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Redistribution and use in source and/or binary forms, with or without - * modification, must retain the above copyright notice and the following - * disclaimer. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package io.spine.internal.gradle.protobuf - -import com.google.protobuf.gradle.GenerateProtoTask -import java.io.File -import java.lang.System.lineSeparator -import org.gradle.api.Task -import org.gradle.configurationcache.extensions.capitalized -import org.gradle.kotlin.dsl.get - -/** - * Configures protobuf code generation task for the code which cannot use Spine Model Compiler - * (e.g. the `base` project). - * - * The task configuration consists of the following steps: - * - * 1. Adding `"kotlin"` to the list of involved `protoc` plugins. - * - * 2. Generation of descriptor set file is turned on for each source set. - * These files are placed under the `build/descriptors` directory. - * - * 3. Removing source code generated for `com.google` package for both Java and Kotlin. - * This is done at the final steps of the code generation. - * - * 4. Adding suppression of deprecation warnings in the generated Kotlin code. - * - * 5. Making `processResource` tasks depend on corresponding `generateProto` tasks. - * If the source set of the configured task isn't `main`, appropriate infix for - * the task names is used. - * - * The usage of this extension in a module build file would be: - * ``` - * val generatedDir by extra("$projectDir/generated") - * protobuf { - * generateProtoTasks { - * for (task in all()) { - * task.setup(generatedDir) - * } - * } - * } - * ``` - * Using the same code under `subprojects` in a root build file does not seem to work because - * test descriptor set files are not copied to resources. Performing this configuration from - * subprojects solves the issue. - * - * IMPORTANT: In addition to calling `setup`, a submodule must contain a descriptor set reference - * file (`desc.ref`) files placed under `resources`. The descriptor reference file must contain - * a reference to the descriptor set file generated by the corresponding `GenerateProtoTask`. - * - * For example, for the `test` source set, the reference would be `known_types_test.desc`, and - * for the `main` source set, the reference would be `known_types_main.desc`. - * - * See `io.spine.code.proto.DescriptorReference` and `io.spine.code.proto.FileDescriptors` classes - * under the `base` project for more details. - */ -@Suppress("unused") -fun GenerateProtoTask.setup(generatedDir: String) { - - builtins.maybeCreate("kotlin") - - /** - * Generate descriptor set files. - */ - val ssn = sourceSet.name - generateDescriptorSet = true - with(descriptorSetOptions) { - path = "${project.buildDir}/descriptors/${ssn}/known_types_${ssn}.desc" - includeImports = true - includeSourceInfo = true - } - - doLast { - deleteComGoogle(generatedDir, ssn, "java") - deleteComGoogle(generatedDir, ssn, "kotlin") - suppressDeprecationsInKotlin(generatedDir, ssn) - } - - /** - * Make the tasks `processResources` depend on `generateProto` tasks explicitly so that: - * 1) descriptor set files get into resources, avoiding the racing conditions - * during the build. - * 2) we don't have the warning "Execution optimizations have been disabled..." issued - * by Gradle during the build because Protobuf Gradle Plugin does not set - * dependencies between `generateProto` and `processResources` tasks. - */ - val processResources = processResourceTaskName(ssn) - project.tasks[processResources].dependsOn(this) -} - -/** - * Remove the code generated for Google Protobuf library types. - * - * Java code for the `com.google` package was generated because we wanted - * to have descriptors for all the types, including those from Google Protobuf library. - * We want all the descriptors so that they are included into the resources used by - * the `io.spine.type.KnownTypes` class. - * - * Now, as we have the descriptors _and_ excessive Java or Kotlin code, we delete it to avoid - * classes that duplicate those coming from Protobuf library JARs. - */ -private fun Task.deleteComGoogle(generatedDir: String, ssn: String, language: String) { - val comDirectory = File("${generatedDir}/${ssn}/$language/com") - val googlePackage = comDirectory.resolve("google") - project.delete(googlePackage) - - // If the `com` directory becomes empty, delete it too. - if (comDirectory.exists() && comDirectory.isDirectory && comDirectory.list()!!.isEmpty()) { - project.delete(comDirectory) - } -} - -/** - * Obtains the name of the task `processResource` task for the given source set name. - */ -private fun processResourceTaskName(sourceSetName: String): String { - val infix = if (sourceSetName == "main") "" else sourceSetName.capitalized() - return "process${infix}Resources" -} - -/** - * Obtains the path to this source code file, starting from `buildSrc`. - */ -private object SourcePath { - - val value: String - get() { - val thisClass = SourcePath::class.java - val filePath = thisClass.`package`.name.replace('.', '/') + "/ProtoTaskExtensions.kt" - return "buildSrc/src/main/kotlin/$filePath" - } -} - -/** - * The comment added to the top of the Kotlin file generated by Protobuf. - */ -private val suppressionComment = "// Suppressed by `${SourcePath.value}`." - -/** - * The text of the suppression. - */ -private const val SUPPRESS_DEPRECATION = "@file:Suppress(\"DEPRECATION\")" - -/** - * This file adds [SUPPRESS_DEPRECATION] to the top of a Kotlin file generated - * by Protobuf compiler. - */ -fun suppressDeprecationsInKotlin(generatedDir: String, ssn: String) { - val kotlinDir = File("${generatedDir}/${ssn}/kotlin") - - kotlinDir.walk().iterator().forEachRemaining { - val file = it - if (!file.name.endsWith(".kt")) { - return@forEachRemaining - } - val lines = file.readLines() - if (lines.isEmpty()) { - return@forEachRemaining - } - if (lines[0] == suppressionComment) { - return@forEachRemaining - } - val withSuppression = mutableListOf() - withSuppression.add(suppressionComment) - withSuppression.add(SUPPRESS_DEPRECATION + lineSeparator()) - withSuppression.addAll(lines) - val text = withSuppression.joinToString(lineSeparator()) - file.writeText(text) - } -} diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/publish/Artifacts.kt b/buildSrc/src/main/kotlin/io/spine/internal/gradle/publish/Artifacts.kt deleted file mode 100644 index e6860cd..0000000 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/publish/Artifacts.kt +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright 2022, TeamDev. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Redistribution and use in source and/or binary forms, with or without - * modification, must retain the above copyright notice and the following - * disclaimer. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package io.spine.internal.gradle.publish - -import io.spine.internal.gradle.sourceSets -import org.gradle.api.Project -import org.gradle.api.file.FileTreeElement -import org.gradle.api.tasks.TaskContainer -import org.gradle.api.tasks.TaskProvider -import org.gradle.api.tasks.bundling.Jar -import org.gradle.kotlin.dsl.get -import org.gradle.kotlin.dsl.named -import org.gradle.kotlin.dsl.register -import org.gradle.kotlin.dsl.withType - -/** - * Excludes Google `.proto` sources from all artifacts. - * - * Goes through all registered `Jar` tasks and filters out Google's files. - */ -@Suppress("unused") -fun TaskContainer.excludeGoogleProtoFromArtifacts() { - withType().configureEach { - exclude { it.isGoogleProtoSource() } - } -} - -/** - * Checks if the given file belongs to the Google `.proto` sources. - */ -private fun FileTreeElement.isGoogleProtoSource(): Boolean { - val pathSegments = relativePath.segments - return pathSegments.isNotEmpty() && pathSegments[0].equals("google") -} - -/** - * Locates or creates `sourcesJar` task in this [Project]. - * - * The output of this task is a `jar` archive. The archive contains sources from `main` source set. - * The task makes sure that sources from the directories below will be included into - * a resulted archive: - * - * - Kotlin - * - Java - * - Proto - * - * Java and Kotlin sources are default to `main` source set since it is created by `java` plugin. - * For Proto sources to be included – [special treatment][protoSources] is needed. - */ -internal fun Project.sourcesJar() = tasks.getOrCreate("sourcesJar") { - archiveClassifier.set("sources") - from(sourceSets["main"].allSource) // Puts Java and Kotlin sources. - from(protoSources()) // Puts Proto sources. -} - -/** - * Locates or creates `protoJar` task in this [Project]. - * - * The output of this task is a `jar` archive. The archive contains only - * [Proto sources][protoSources] from `main` source set. - */ -internal fun Project.protoJar() = tasks.getOrCreate("protoJar") { - archiveClassifier.set("proto") - from(protoSources()) -} - -/** - * Locates or creates `testJar` task in this [Project]. - * - * The output of this task is a `jar` archive. The archive contains compilation output - * of `test` source set. - */ -internal fun Project.testJar() = tasks.getOrCreate("testJar") { - archiveClassifier.set("test") - from(sourceSets["test"].output) -} - -/** - * Locates or creates `javadocJar` task in this [Project]. - * - * The output of this task is a `jar` archive. The archive contains Javadoc, - * generated upon Java sources from `main` source set. If javadoc for Kotlin is also needed, - * apply Dokka plugin. It tunes `javadoc` task to generate docs upon Kotlin sources as well. - */ -internal fun Project.javadocJar() = tasks.getOrCreate("javadocJar") { - archiveClassifier.set("javadoc") - from(files("$buildDir/docs/javadoc")) - dependsOn("javadoc") -} - -/** - * Locates or creates `dokkaJar` task in this [Project]. - * - * The output of this task is a `jar` archive. The archive contains the Dokka output, generated upon - * Java sources from `main` source set. Requires Dokka to be configured in the target project by - * applying `dokka-for-java` plugin. - */ -internal fun Project.dokkaJar() = tasks.getOrCreate("dokkaJar") { - archiveClassifier.set("dokka") - from(files("$buildDir/docs/dokka")) - dependsOn("dokkaHtml") -} - -private fun TaskContainer.getOrCreate(name: String, init: Jar.() -> Unit): TaskProvider = - if (names.contains(name)) { - named(name) - } else { - register(name) { - init() - } - } diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/publish/Publications.kt b/buildSrc/src/main/kotlin/io/spine/internal/gradle/publish/Publications.kt deleted file mode 100644 index ad8f8fe..0000000 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/publish/Publications.kt +++ /dev/null @@ -1,201 +0,0 @@ -/* - * Copyright 2022, TeamDev. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Redistribution and use in source and/or binary forms, with or without - * modification, must retain the above copyright notice and the following - * disclaimer. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package io.spine.internal.gradle.publish - -import io.spine.internal.gradle.Repository -import io.spine.internal.gradle.isSnapshot -import org.gradle.api.Project -import org.gradle.api.artifacts.dsl.RepositoryHandler -import org.gradle.api.publish.maven.MavenPublication -import org.gradle.api.tasks.TaskProvider -import org.gradle.api.tasks.bundling.Jar -import org.gradle.kotlin.dsl.create -import org.gradle.kotlin.dsl.get - -/** - * Abstract base for handlers of publications in a project - * with [spinePublishing] settings declared. - */ -internal sealed class PublicationHandler( - private val artifactId: String, - private val destinations: Set -) { - - /** - * Registers this publication in the given project. - */ - fun registerIn(project: Project) { - handlePublications(project) - registerDestinations(project) - } - - /** - * Either handles publications already declared in the given project, - * or creates new ones. - */ - abstract fun handlePublications(project: Project) - - /** - * Takes a group name and a version from the given [project] and assigns - * them to this publication. - */ - protected fun MavenPublication.assignMavenCoordinates(project: Project) { - groupId = project.group.toString() - artifactId = this@PublicationHandler.artifactId - version = project.version.toString() - } - - /** - * Goes through the [destinations] and registers each as a repository for publishing - * in the given Gradle project. - */ - private fun registerDestinations(project: Project) { - val gradleRepositories = project.publishingExtension.repositories - destinations.forEach { destination -> - gradleRepositories.register(project, destination) - } - } - - /** - * Adds a Maven repository to the project specifying credentials, if they are - * [available][Repository.credentials] from the root project. - */ - private fun RepositoryHandler.register(project: Project, repository: Repository) { - val isSnapshot = project.version.toString().isSnapshot() - val target = if (isSnapshot) repository.snapshots else repository.releases - val credentials = repository.credentials(project.rootProject) - maven { - url = project.uri(target) - credentials { - username = credentials?.username - password = credentials?.password - } - } - } -} - -/** - * A publication for a typical Java project. - * - * In Gradle, in order to publish something somewhere one should create a publication. - * A publication has a name and consists of one or more artifacts plus information about - * those artifacts – the metadata. - * - * An instance of this class represents [MavenPublication] named "mavenJava". It is generally - * accepted that a publication with this name contains a Java project published to one or - * more Maven repositories. - * - * By default, only a jar with the compilation output of `main` source set and its - * metadata files are published. Other artifacts are specified through the - * [constructor parameter][jars]. Please, take a look on [specifyArtifacts] for additional info. - * - * @param artifactId - * a name that a project is known by. - * @param jars - * list of artifacts to be published along with the compilation output. - * @param destinations - * Maven repositories to which the produced artifacts will be sent. - * @see - * Maven Publish Plugin | Publications - */ -internal class MavenJavaPublication( - artifactId: String, - private val jars: Set>, - destinations: Set, -) : PublicationHandler(artifactId, destinations) { - - /** - * Creates a new "mavenJava" [MavenPublication] in the given project. - */ - override fun handlePublications(project: Project) { - project.publications.create("mavenJava") { - assignMavenCoordinates(project) - specifyArtifacts(project, jars) - } - } -} - -/** - * Specifies which artifacts this [MavenPublication] will contain. - * - * A typical Maven publication contains: - * - * 1. Jar archives. For example: compilation output, sources, javadoc, etc. - * 2. Maven metadata file that has ".pom" extension. - * 3. Gradle metadata file that has ".module" extension. - * - * Metadata files contain information about a publication itself, its artifacts and their - * dependencies. Presence of ".pom" file is mandatory for publication to be consumed by - * `mvn` build tool itself or other build tools that understand Maven notation (Gradle, Ivy). - * Presence of ".module" is optional, but useful when a publication is consumed by Gradle. - * - * @see Maven – POM Reference - * @see - * Understanding Gradle Module Metadata - */ -private fun MavenPublication.specifyArtifacts(project: Project, jars: Set>) { - - /* "java" component provides a jar with compilation output of "main" source set. - It is NOT defined as another `Jar` task intentionally. Doing that will leave the - publication without correct ".pom" and ".module" metadata files generated. - */ - from(project.components["java"]) - - /* Other artifacts are represented by `Jar` tasks. Those artifacts don't bring any other - metadata in comparison with `Component` (such as dependencies notation). - */ - jars.forEach { - artifact(it) - } -} - -/** - * A handler for custom publications, which are declared under the [publications] - * section of a module. - * - * Such publications should be treated differently than [MavenJavaPublication], - * which is created for a module. Instead, since the publications are already declared, - * this class only [assigns maven coordinates][assignMavenCoordinates]. - * - * A module which declares custom publications must be specified in - * the [SpinePublishing.modulesWithCustomPublishing] property. - * - * If a module with [publications] declared locally is not specified as one with custom publishing, - * it may cause a name clash between an artifact produced by the [standard][MavenPublication] - * publication, and custom ones. In order to have both standard and custom publications, - * please specify custom artifact IDs or classifiers for each custom publication. - */ -internal class CustomPublications(artifactId: String, destinations: Set) : - PublicationHandler(artifactId, destinations) { - - override fun handlePublications(project: Project) { - project.publications.forEach { - val publication = it as MavenPublication - publication.assignMavenCoordinates(project) - } - } -} diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/publish/PublishingConfig.kt b/buildSrc/src/main/kotlin/io/spine/internal/gradle/publish/PublishingConfig.kt deleted file mode 100644 index 4d9a3f6..0000000 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/publish/PublishingConfig.kt +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright 2022, TeamDev. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Redistribution and use in source and/or binary forms, with or without - * modification, must retain the above copyright notice and the following - * disclaimer. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package io.spine.internal.gradle.publish - -import io.spine.internal.gradle.Repository -import org.gradle.api.Project -import org.gradle.api.tasks.TaskProvider -import org.gradle.api.tasks.bundling.Jar -import org.gradle.kotlin.dsl.apply - -/** - * Information, required to set up publishing of a project using `maven-publish` plugin. - * - * @param artifactId - * a name that a project is known by. - * @param destinations - * set of repositories, to which the resulting artifacts will be sent. - * @param includeProtoJar - * tells whether [protoJar] artifact should be published. - * @param includeTestJar - * tells whether [testJar] artifact should be published. - * @param includeDokkaJar - * tells whether [dokkaJar] artifact should be published. - * @param customPublishing - * tells whether subproject declares own publishing and standard one - * should not be applied. - */ -internal class PublishingConfig private constructor( - val artifactId: String, - val destinations: Set, - val customPublishing: Boolean, - val includeTestJar: Boolean, - val includeDokkaJar: Boolean, - val includeProtoJar: Boolean -) { - /** - * Creates an instance for standard publishing of a project module, - * specified under [SpinePublishing.modules]. - */ - constructor( - artifactId: String, - destinations: Set, - includeProtoJar: Boolean = true, - includeTestJar: Boolean = false, - includeDokkaJar: Boolean = false - ) : this(artifactId, destinations, false, includeTestJar, includeDokkaJar, includeProtoJar) - - /** - * Creates an instance for publishing a module specified - * under [SpinePublishing.modulesWithCustomPublishing]. - */ - constructor(artifactId: String, destinations: Set) : - this(artifactId, destinations, customPublishing = true, - includeTestJar = false, includeDokkaJar = false, includeProtoJar = false) -} -/** - * Applies this configuration to the given project. - * - * This method does the following: - * - * 1. Applies `maven-publish` plugin to the project. - * 2. Registers [MavenJavaPublication] in Gradle's - * [PublicationContainer][org.gradle.api.publish.PublicationContainer]. - * 4. Configures "publish" task. - * - * The actual list of resulted artifacts is determined by [registerArtifacts]. - */ -internal fun PublishingConfig.apply(project: Project) = with(project) { - apply(plugin = "maven-publish") - handlePublication(project) - configurePublishTask(destinations) -} - -private fun PublishingConfig.handlePublication(project: Project) { - if (customPublishing) { - handleCustomPublications(project) - } else { - createStandardPublication(project) - } -} - -private fun PublishingConfig.handleCustomPublications(project: Project) { - project.logger.info("The project `${project.name}` is set to provide custom publishing.") - val publications = CustomPublications( - artifactId = artifactId, - destinations = destinations - ) - publications.registerIn(project) -} - -private fun PublishingConfig.createStandardPublication(project: Project) { - val artifacts = project.registerArtifacts(includeProtoJar, includeTestJar, includeDokkaJar) - val publication = MavenJavaPublication( - artifactId = artifactId, - jars = artifacts, - destinations = destinations - ) - publication.registerIn(project) -} - -/** - * Registers [Jar] tasks, output of which is used as Maven artifacts. - * - * By default, only a jar with java compilation output is included into publication. This method - * registers tasks which produce additional artifacts. - * - * The list of additional artifacts to be registered: - * - * 1. [sourcesJar] – Java, Kotlin and Proto source files. - * 2. [protoJar] – only Proto source files. - * 3. [javadocJar] – documentation, generated upon Java files. - * 4. [testJar] – compilation output of "test" source set. - * 5. [dokkaJar] - documentation generated by Dokka. - * - * Registration of [protoJar], [testJar] and [dokkaJar] is optional. It can be controlled by the - * method's parameters. - * - * @return the list of the registered tasks. - */ -private fun Project.registerArtifacts( - includeProtoJar: Boolean = true, - includeTestJar: Boolean = false, - includeDokkaJar: Boolean = false -): Set> { - - val artifacts = mutableSetOf( - sourcesJar(), - javadocJar(), - ) - - // We don't want to have an empty "proto.jar" when a project doesn't have any Proto files. - if (hasProto() && includeProtoJar) { - artifacts.add(protoJar()) - } - - // Here, we don't have the corresponding `hasTests()` check, since this artifact is disabled - // by default. And turning it on means "We have tests and need them to be published." - if (includeTestJar) { - artifacts.add(testJar()) - } - - if(includeDokkaJar) { - artifacts.add(dokkaJar()) - } - - return artifacts -} diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/publish/Tasks.kt b/buildSrc/src/main/kotlin/io/spine/internal/gradle/publish/Tasks.kt deleted file mode 100644 index b132638..0000000 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/publish/Tasks.kt +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright 2022, TeamDev. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Redistribution and use in source and/or binary forms, with or without - * modification, must retain the above copyright notice and the following - * disclaimer. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package io.spine.internal.gradle.publish - -import io.spine.internal.gradle.Repository -import java.util.* -import org.gradle.api.InvalidUserDataException -import org.gradle.api.Project -import org.gradle.api.Task -import org.gradle.api.tasks.TaskContainer -import org.gradle.api.tasks.TaskProvider - -private const val PUBLISH = "publish" - -/** - * Locates `publish` task in this [TaskContainer]. - * - * This task publishes all defined publications to all defined repositories. To achieve that, - * the task depends on all `publish`*PubName*`PublicationTo`*RepoName*`Repository` tasks. - * - * Please note, task execution would not copy publications to the local Maven cache. - * - * @see - * Tasks | Maven Publish Plugin - */ -internal val TaskContainer.publish: TaskProvider - get() = named(PUBLISH) - -/** - * Sets dependencies for `publish` task in this [Project]. - * - * This method performs the following: - * - * 1. When this [Project] is not a root, makes `publish` task in a root project - * depend on a local `publish`. - * 2. Makes local `publish` task verify that credentials are present for each - * of destination repositories. - */ -internal fun Project.configurePublishTask(destinations: Set) { - attachCredentialsVerification(destinations) - bindToRootPublish() -} - -private fun Project.attachCredentialsVerification(destinations: Set) { - val checkCredentials = tasks.registerCheckCredentialsTask(destinations) - val localPublish = tasks.publish - localPublish.configure { dependsOn(checkCredentials) } -} - -private fun Project.bindToRootPublish() { - if (project == rootProject) { - return - } - - val localPublish = tasks.publish - val rootPublish = rootProject.tasks.getOrCreatePublishTask() - rootPublish.configure { dependsOn(localPublish) } -} - -/** - * Use this task accessor when it is not guaranteed that the task is present - * in this [TaskContainer]. - */ -private fun TaskContainer.getOrCreatePublishTask() = - if (names.contains(PUBLISH)) { - named(PUBLISH) - } else { - register(PUBLISH) - } - -private fun TaskContainer.registerCheckCredentialsTask(destinations: Set) = - register("checkCredentials") { - doLast { - destinations.forEach { it.ensureCredentials(project) } - } - } - -private fun Repository.ensureCredentials(project: Project) { - val credentials = credentials(project) - if (Objects.isNull(credentials)) { - throw InvalidUserDataException( - "No valid credentials for repository `${this}`. Please make sure " + - "to pass username/password or a valid `.properties` file." - ) - } -} diff --git a/buildSrc/src/main/kotlin/jacoco-kotlin-jvm.gradle.kts b/buildSrc/src/main/kotlin/jacoco-kotlin-jvm.gradle.kts new file mode 100644 index 0000000..48fb126 --- /dev/null +++ b/buildSrc/src/main/kotlin/jacoco-kotlin-jvm.gradle.kts @@ -0,0 +1,67 @@ +/* + * Copyright 2025, TeamDev. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +import io.spine.gradle.buildDirectory + +plugins { + jacoco +} + +/** + * Configures [JacocoReport] task to run in a Kotlin Multiplatform project for + * `commonMain` and `jvmMain` source sets. + * + * This script plugin must be applied using the following construct at the end of + * a `build.gradle.kts` file of a module: + * + * ```kotlin + * apply(plugin="jacoco-kotlin-jvm") + * ``` + * Please do not apply this script plugin in the `plugins {}` block because `jacocoTestReport` + * task is not yet available at this stage. + */ +@Suppress("unused") +private val about = "" + +/** + * Configure Jacoco task with custom input from this Kotlin Multiplatform project. + */ +@Suppress("unused") +val jacocoTestReport: JacocoReport by tasks.getting(JacocoReport::class) { + + val classFiles = File("$buildDirectory/classes/kotlin/jvm/") + .walkBottomUp() + .toSet() + classDirectories.setFrom(classFiles) + + val coverageSourceDirs = arrayOf( + "src/commonMain", + "src/jvmMain" + ) + sourceDirectories.setFrom(files(coverageSourceDirs)) + + executionData.setFrom(files("$buildDirectory/jacoco/jvmTest.exec")) +} diff --git a/buildSrc/src/main/kotlin/jvm-module.gradle.kts b/buildSrc/src/main/kotlin/jvm-module.gradle.kts new file mode 100644 index 0000000..5b1577e --- /dev/null +++ b/buildSrc/src/main/kotlin/jvm-module.gradle.kts @@ -0,0 +1,204 @@ +/* + * Copyright 2025, TeamDev. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +import BuildSettings.javaVersion +import io.spine.dependency.build.CheckerFramework +import io.spine.dependency.build.Dokka +import io.spine.dependency.build.ErrorProne +import io.spine.dependency.lib.Guava +import io.spine.dependency.lib.JavaX +import io.spine.dependency.lib.Protobuf +import io.spine.dependency.local.Logging +import io.spine.dependency.local.Reflect +import io.spine.dependency.local.TestLib +import io.spine.dependency.test.JUnit +import io.spine.dependency.test.Jacoco +import io.spine.dependency.test.Kotest +import io.spine.gradle.checkstyle.CheckStyleConfig +import io.spine.gradle.github.pages.updateGitHubPages +import io.spine.gradle.javac.configureErrorProne +import io.spine.gradle.javac.configureJavac +import io.spine.gradle.javadoc.JavadocConfig +import io.spine.gradle.kotlin.applyJvmToolchain +import io.spine.gradle.kotlin.setFreeCompilerArgs +import io.spine.gradle.report.license.LicenseReporter +import io.spine.gradle.testing.configureLogging +import io.spine.gradle.testing.registerTestTasks + +plugins { + `java-library` + id("net.ltgt.errorprone") + id("pmd-settings") + id("project-report") + id("dokka-for-java") + kotlin("jvm") + id("io.kotest") + id("org.jetbrains.kotlinx.kover") + id("detekt-code-analysis") + id("dokka-for-kotlin") +} + +LicenseReporter.generateReportIn(project) +JavadocConfig.applyTo(project) +CheckStyleConfig.applyTo(project) + +project.run { + configureJava(javaVersion) + configureKotlin(javaVersion) + addDependencies() + forceConfigurations() + + val generatedDir = "$projectDir/generated" + setTaskDependencies(generatedDir) + setupTests() + + configureGitHubPages() +} + +typealias Module = Project + +fun Module.configureJava(javaVersion: JavaLanguageVersion) { + java { + toolchain.languageVersion.set(javaVersion) + } + + tasks { + withType().configureEach { + configureJavac() + configureErrorProne() + } + } +} + +fun Module.configureKotlin(javaVersion: JavaLanguageVersion) { + kotlin { + applyJvmToolchain(javaVersion.asInt()) + explicitApi() + compilerOptions { + jvmTarget.set(BuildSettings.jvmTarget) + setFreeCompilerArgs() + } + } + + kover { + useJacoco(version = Jacoco.version) + } + + koverReport { + defaults { + xml { + onCheck = true + } + } + } +} + +/** + * These dependencies are applied to all subprojects and do not have to + * be included explicitly. + * + * We expose production code dependencies as API because they are used + * by the framework parts that depend on `base`. + */ +fun Module.addDependencies() = dependencies { + errorprone(ErrorProne.core) + + Protobuf.libs.forEach { api(it) } + api(Guava.lib) + + compileOnlyApi(CheckerFramework.annotations) + compileOnlyApi(JavaX.annotations) + ErrorProne.annotations.forEach { compileOnlyApi(it) } + + implementation(Logging.lib) + + testImplementation(Guava.testLib) + testImplementation(JUnit.runner) + testImplementation(JUnit.pioneer) + JUnit.api.forEach { testImplementation(it) } + + testImplementation(TestLib.lib) + testImplementation(Kotest.frameworkEngine) + testImplementation(Kotest.datatest) + testImplementation(Kotest.runnerJUnit5Jvm) + testImplementation(JUnit.runner) +} + +fun Module.forceConfigurations() { + with(configurations) { + forceVersions() + excludeProtobufLite() + all { + resolutionStrategy { + force( + JUnit.bom, + JUnit.runner, + Dokka.BasePlugin.lib, + Reflect.lib, + ) + } + } + } +} + +fun Module.setupTests() { + tasks { + registerTestTasks() + test.configure { + useJUnitPlatform { + includeEngines("junit-jupiter") + } + configureLogging() + } + } +} + +fun Module.setTaskDependencies(generatedDir: String) { + tasks { + val cleanGenerated by registering(Delete::class) { + delete(generatedDir) + } + clean.configure { + dependsOn(cleanGenerated) + } + + project.afterEvaluate { + val publish = tasks.findByName("publish") + publish?.dependsOn("${project.path}:updateGitHubPages") + } + } + afterEvaluate { + configureTaskDependencies() + } +} + +fun Module.configureGitHubPages() { + val docletVersion = project.version.toString() + updateGitHubPages(docletVersion) { + allowInternalJavadoc.set(true) + rootFolder.set(rootDir) + } +} diff --git a/buildSrc/src/main/kotlin/pmd-settings.gradle.kts b/buildSrc/src/main/kotlin/pmd-settings.gradle.kts index 03e69a6..0373ee0 100644 --- a/buildSrc/src/main/kotlin/pmd-settings.gradle.kts +++ b/buildSrc/src/main/kotlin/pmd-settings.gradle.kts @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,7 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -import io.spine.internal.dependency.Pmd +import io.spine.dependency.build.Pmd plugins { pmd diff --git a/buildSrc/src/main/kotlin/write-manifest.gradle.kts b/buildSrc/src/main/kotlin/write-manifest.gradle.kts index 2898ec8..b63d327 100644 --- a/buildSrc/src/main/kotlin/write-manifest.gradle.kts +++ b/buildSrc/src/main/kotlin/write-manifest.gradle.kts @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,7 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -import io.spine.internal.gradle.publish.SpinePublishing +import io.spine.gradle.publish.SpinePublishing import java.nio.file.Files.createDirectories import java.nio.file.Files.createFile import java.text.SimpleDateFormat @@ -91,7 +91,8 @@ val manifestAttributes = mapOf( "Build-OS" to buildOs(), IMPLEMENTATION_TITLE.toString() to implementationTitle(), IMPLEMENTATION_VERSION.toString() to project.version, - IMPLEMENTATION_VENDOR.toString() to "TeamDev" + IMPLEMENTATION_VENDOR.toString() to "TeamDev", + "Bundle-License" to "https://www.apache.org/licenses/LICENSE-2.0.txt" ) /** @@ -102,7 +103,7 @@ val manifestAttributes = mapOf( * when running tests. We cannot depend on the `Jar` from `resources` because it would * form a circular dependency. */ -val exposeManifestForTests by tasks.creating { +val exposeManifestForTests by tasks.registering { val outputFile = layout.buildDirectory.file("resources/main/META-INF/MANIFEST.MF") outputs.file(outputFile).withPropertyName("manifestFile") @@ -111,7 +112,7 @@ val exposeManifestForTests by tasks.creating { val manifest = Manifest() // The manifest version attribute is crucial for writing. - // It it's absent nothing would be written. + // If it's absent, nothing would be written. manifest.mainAttributes[MANIFEST_VERSION] = "1.0" manifestAttributes.forEach { entry -> diff --git a/buildSrc/src/main/resources/dokka/styles/custom-styles.css b/buildSrc/src/main/resources/dokka/styles/custom-styles.css index 83545f3..ca629f9 100644 --- a/buildSrc/src/main/resources/dokka/styles/custom-styles.css +++ b/buildSrc/src/main/resources/dokka/styles/custom-styles.css @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following diff --git a/change/build.gradle.kts b/change/build.gradle.kts index e86264b..d5e48d5 100644 --- a/change/build.gradle.kts +++ b/change/build.gradle.kts @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -24,9 +24,11 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -import io.spine.internal.dependency.Spine -import io.spine.internal.gradle.protobuf.suppressDeprecationsInKotlin -import io.spine.internal.gradle.publish.IncrementGuard +import io.spine.dependency.local.Base +import io.spine.dependency.local.Spine +import io.spine.dependency.local.Time +import io.spine.dependency.local.Validation +import io.spine.gradle.publish.IncrementGuard import io.spine.protodata.gradle.plugin.LaunchProtoData plugins { @@ -38,56 +40,7 @@ plugins { apply() dependencies { - val spine = Spine(project) - protoData(spine.validation.java) - implementation(spine.base) - implementation(spine.validation.runtime) - testImplementation(spine.testUtilTime) -} - -val generatedDir:String by extra("$projectDir/generated") - -/** - * Manually add generated directories to source sets so that IDEA sees them. - */ -sourceSets { - main { - java.srcDir("$generatedDir/main/java") - kotlin.srcDir("$generatedDir/main/kotlin") - } - test { - java.srcDir("$generatedDir/test/java") - kotlin.srcDir("$generatedDir/test/kotlin") - } -} - -/** - * Suppress the "legacy" validation from McJava in favour of tha based on ProtoData. - */ -modelCompiler.java.codegen.validation().skipValidation() - -protoData { - renderers( - "io.spine.validation.java.PrintValidationInsertionPoints", - "io.spine.validation.java.JavaValidationRenderer", - - // Suppress warnings in the generated code. - "io.spine.protodata.codegen.java.file.PrintBeforePrimaryDeclaration", - "io.spine.protodata.codegen.java.suppress.SuppressRenderer" - - ) - plugins( - "io.spine.validation.ValidationPlugin", - ) -} - -/** - * Manually suppress deprecations in the generated Kotlin code until ProtoData does it. - */ -tasks.withType().forEach { task -> - task.doLast { - sourceSets.forEach { sourceSet -> - suppressDeprecationsInKotlin(generatedDir, sourceSet.name) - } - } + implementation(Base.lib) + implementation(Validation.runtime) + testImplementation(Time.testLib) } diff --git a/config b/config index 44b4fae..99fb7ce 160000 --- a/config +++ b/config @@ -1 +1 @@ -Subproject commit 44b4faead5eb87f944974aa38c87ded7a126f241 +Subproject commit 99fb7ce679e6c71713fd6c21c24e0cd19304b118 diff --git a/license-report.md b/license-report.md deleted file mode 100644 index 1c46789..0000000 --- a/license-report.md +++ /dev/null @@ -1,736 +0,0 @@ - - -# Dependencies of `io.spine:spine-change:2.0.0-SNAPSHOT.118` - -## Runtime -1. **Group** : com.google.code.findbugs. **Name** : jsr305. **Version** : 3.0.2. - * **Project URL:** [http://findbugs.sourceforge.net/](http://findbugs.sourceforge.net/) - * **License:** [The Apache Software License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : com.google.code.gson. **Name** : gson. **Version** : 2.9.0. - * **Project URL:** [https://github.com/google/gson/gson](https://github.com/google/gson/gson) - * **License:** [Apache-2.0](https://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : com.google.errorprone. **Name** : error_prone_annotations. **Version** : 2.16. - * **License:** [Apache 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : com.google.flogger. **Name** : flogger. **Version** : 0.7.4. - * **Project URL:** [https://github.com/google/flogger](https://github.com/google/flogger) - * **License:** [Apache 2.0](https://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : com.google.flogger. **Name** : flogger-system-backend. **Version** : 0.7.4. - * **Project URL:** [https://github.com/google/flogger](https://github.com/google/flogger) - * **License:** [Apache 2.0](https://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : com.google.guava. **Name** : failureaccess. **Version** : 1.0.1. - * **Project URL:** [https://github.com/google/guava/](https://github.com/google/guava/) - * **License:** [The Apache Software License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : com.google.guava. **Name** : guava. **Version** : 31.1-jre. - * **Project URL:** [https://github.com/google/guava](https://github.com/google/guava) - * **License:** [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : com.google.guava. **Name** : listenablefuture. **Version** : 9999.0-empty-to-avoid-conflict-with-guava. - * **License:** [The Apache Software License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : com.google.j2objc. **Name** : j2objc-annotations. **Version** : 1.3. - * **Project URL:** [https://github.com/google/j2objc/](https://github.com/google/j2objc/) - * **License:** [The Apache Software License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : com.google.protobuf. **Name** : protobuf-java. **Version** : 3.19.6. - * **Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) - * **License:** [3-Clause BSD License](https://opensource.org/licenses/BSD-3-Clause) - -1. **Group** : com.google.protobuf. **Name** : protobuf-java-util. **Version** : 3.19.6. - * **Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) - * **License:** [3-Clause BSD License](https://opensource.org/licenses/BSD-3-Clause) - -1. **Group** : com.google.protobuf. **Name** : protobuf-kotlin. **Version** : 3.19.6. - * **License:** [3-Clause BSD License](https://opensource.org/licenses/BSD-3-Clause) - -1. **Group** : io.spine.validation. **Name** : spine-validation-java-runtime. **Version** : 2.0.0-SNAPSHOT.61.**No license information found** -1. **Group** : org.checkerframework. **Name** : checker-compat-qual. **Version** : 2.5.5. - * **Project URL:** [https://checkerframework.org](https://checkerframework.org) - * **License:** [GNU General Public License, version 2 (GPL2), with the classpath exception](http://www.gnu.org/software/classpath/license.html) - * **License:** [The MIT License](http://opensource.org/licenses/MIT) - -1. **Group** : org.checkerframework. **Name** : checker-qual. **Version** : 3.21.3. - * **Project URL:** [https://checkerframework.org](https://checkerframework.org) - * **License:** [The MIT License](http://opensource.org/licenses/MIT) - -1. **Group** : org.jetbrains. **Name** : annotations. **Version** : 13.0. - * **Project URL:** [http://www.jetbrains.org](http://www.jetbrains.org) - * **License:** [The Apache Software License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : org.jetbrains.kotlin. **Name** : kotlin-reflect. **Version** : 1.7.20. - * **Project URL:** [https://kotlinlang.org/](https://kotlinlang.org/) - * **License:** [The Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : org.jetbrains.kotlin. **Name** : kotlin-stdlib. **Version** : 1.7.20. - * **Project URL:** [https://kotlinlang.org/](https://kotlinlang.org/) - * **License:** [The Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : org.jetbrains.kotlin. **Name** : kotlin-stdlib-common. **Version** : 1.7.20. - * **Project URL:** [https://kotlinlang.org/](https://kotlinlang.org/) - * **License:** [The Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : org.jetbrains.kotlin. **Name** : kotlin-stdlib-jdk7. **Version** : 1.7.20. - * **Project URL:** [https://kotlinlang.org/](https://kotlinlang.org/) - * **License:** [The Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : org.jetbrains.kotlin. **Name** : kotlin-stdlib-jdk8. **Version** : 1.7.20. - * **Project URL:** [https://kotlinlang.org/](https://kotlinlang.org/) - * **License:** [The Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -## Compile, tests, and tooling -1. **Group** : com.beust. **Name** : jcommander. **Version** : 1.48. - * **Project URL:** [http://beust.com/jcommander](http://beust.com/jcommander) - * **License:** [The Apache Software License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : com.beust. **Name** : jcommander. **Version** : 1.82. - * **Project URL:** [https://jcommander.org](https://jcommander.org) - * **License:** [Apache License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : com.fasterxml.jackson. **Name** : jackson-bom. **Version** : 2.13.4.**No license information found** -1. **Group** : com.fasterxml.jackson.core. **Name** : jackson-annotations. **Version** : 2.13.4. - * **Project URL:** [http://github.com/FasterXML/jackson](http://github.com/FasterXML/jackson) - * **License:** [The Apache Software License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : com.fasterxml.jackson.core. **Name** : jackson-core. **Version** : 2.13.4. - * **Project URL:** [https://github.com/FasterXML/jackson-core](https://github.com/FasterXML/jackson-core) - * **License:** [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - * **License:** [The Apache Software License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : com.fasterxml.jackson.core. **Name** : jackson-databind. **Version** : 2.13.4.2. - * **Project URL:** [http://github.com/FasterXML/jackson](http://github.com/FasterXML/jackson) - * **License:** [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - * **License:** [The Apache Software License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : com.fasterxml.jackson.dataformat. **Name** : jackson-dataformat-xml. **Version** : 2.13.4. - * **Project URL:** [https://github.com/FasterXML/jackson-dataformat-xml](https://github.com/FasterXML/jackson-dataformat-xml) - * **License:** [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - * **License:** [The Apache Software License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : com.fasterxml.jackson.module. **Name** : jackson-module-kotlin. **Version** : 2.13.4. - * **Project URL:** [https://github.com/FasterXML/jackson-module-kotlin](https://github.com/FasterXML/jackson-module-kotlin) - * **License:** [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - * **License:** [The Apache Software License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : com.fasterxml.woodstox. **Name** : woodstox-core. **Version** : 6.3.1. - * **Project URL:** [https://github.com/FasterXML/woodstox](https://github.com/FasterXML/woodstox) - * **License:** [The Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - * **License:** [The Apache Software License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : com.github.ben-manes.caffeine. **Name** : caffeine. **Version** : 3.0.5. - * **Project URL:** [https://github.com/ben-manes/caffeine](https://github.com/ben-manes/caffeine) - * **License:** [Apache License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : com.github.kevinstern. **Name** : software-and-algorithms. **Version** : 1.0. - * **Project URL:** [https://www.github.com/KevinStern/software-and-algorithms](https://www.github.com/KevinStern/software-and-algorithms) - * **License:** [MIT License](http://www.opensource.org/licenses/mit-license.php) - -1. **Group** : com.google.android. **Name** : annotations. **Version** : 4.1.1.4. - * **Project URL:** [http://source.android.com/](http://source.android.com/) - * **License:** [Apache 2.0](http://www.apache.org/licenses/LICENSE-2.0) - -1. **Group** : com.google.api.grpc. **Name** : proto-google-common-protos. **Version** : 2.0.1. - * **Project URL:** [https://github.com/googleapis/java-iam/proto-google-common-protos](https://github.com/googleapis/java-iam/proto-google-common-protos) - * **License:** [Apache-2.0](https://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : com.google.auto. **Name** : auto-common. **Version** : 1.2.1. - * **Project URL:** [https://github.com/google/auto/tree/master/common](https://github.com/google/auto/tree/master/common) - * **License:** [Apache 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : com.google.auto.service. **Name** : auto-service-annotations. **Version** : 1.0.1. - * **Project URL:** [https://github.com/google/auto/tree/master/service](https://github.com/google/auto/tree/master/service) - * **License:** [Apache 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : com.google.auto.value. **Name** : auto-value-annotations. **Version** : 1.9. - * **Project URL:** [https://github.com/google/auto/tree/master/value](https://github.com/google/auto/tree/master/value) - * **License:** [Apache 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : com.google.code.findbugs. **Name** : jsr305. **Version** : 3.0.2. - * **Project URL:** [http://findbugs.sourceforge.net/](http://findbugs.sourceforge.net/) - * **License:** [The Apache Software License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : com.google.code.gson. **Name** : gson. **Version** : 2.9.0. - * **Project URL:** [https://github.com/google/gson/gson](https://github.com/google/gson/gson) - * **License:** [Apache-2.0](https://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : com.google.errorprone. **Name** : error_prone_annotation. **Version** : 2.16. - * **License:** [Apache 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : com.google.errorprone. **Name** : error_prone_annotations. **Version** : 2.16. - * **License:** [Apache 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : com.google.errorprone. **Name** : error_prone_check_api. **Version** : 2.16. - * **License:** [Apache 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : com.google.errorprone. **Name** : error_prone_core. **Version** : 2.16. - * **License:** [Apache 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : com.google.errorprone. **Name** : error_prone_type_annotations. **Version** : 2.16. - * **License:** [Apache 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : com.google.errorprone. **Name** : javac. **Version** : 9+181-r4173-1. - * **Project URL:** [https://github.com/google/error-prone-javac](https://github.com/google/error-prone-javac) - * **License:** [GNU General Public License, version 2, with the Classpath Exception](http://openjdk.java.net/legal/gplv2+ce.html) - -1. **Group** : com.google.flogger. **Name** : flogger. **Version** : 0.7.4. - * **Project URL:** [https://github.com/google/flogger](https://github.com/google/flogger) - * **License:** [Apache 2.0](https://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : com.google.flogger. **Name** : flogger-system-backend. **Version** : 0.7.4. - * **Project URL:** [https://github.com/google/flogger](https://github.com/google/flogger) - * **License:** [Apache 2.0](https://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : com.google.gradle. **Name** : osdetector-gradle-plugin. **Version** : 1.7.0. - * **Project URL:** [https://github.com/google/osdetector-gradle-plugin](https://github.com/google/osdetector-gradle-plugin) - * **License:** [Apache License 2.0](http://opensource.org/licenses/Apache-2.0) - -1. **Group** : com.google.guava. **Name** : failureaccess. **Version** : 1.0.1. - * **Project URL:** [https://github.com/google/guava/](https://github.com/google/guava/) - * **License:** [The Apache Software License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : com.google.guava. **Name** : guava. **Version** : 31.1-jre. - * **Project URL:** [https://github.com/google/guava](https://github.com/google/guava) - * **License:** [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : com.google.guava. **Name** : guava-testlib. **Version** : 31.1-jre. - * **License:** [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : com.google.guava. **Name** : listenablefuture. **Version** : 9999.0-empty-to-avoid-conflict-with-guava. - * **License:** [The Apache Software License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : com.google.j2objc. **Name** : j2objc-annotations. **Version** : 1.3. - * **Project URL:** [https://github.com/google/j2objc/](https://github.com/google/j2objc/) - * **License:** [The Apache Software License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : com.google.protobuf. **Name** : protobuf-gradle-plugin. **Version** : 0.8.19. - * **Project URL:** [https://github.com/google/protobuf-gradle-plugin](https://github.com/google/protobuf-gradle-plugin) - * **License:** [BSD 3-Clause](http://opensource.org/licenses/BSD-3-Clause) - -1. **Group** : com.google.protobuf. **Name** : protobuf-java. **Version** : 3.19.6. - * **Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) - * **License:** [3-Clause BSD License](https://opensource.org/licenses/BSD-3-Clause) - -1. **Group** : com.google.protobuf. **Name** : protobuf-java-util. **Version** : 3.19.6. - * **Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) - * **License:** [3-Clause BSD License](https://opensource.org/licenses/BSD-3-Clause) - -1. **Group** : com.google.protobuf. **Name** : protobuf-kotlin. **Version** : 3.19.6. - * **License:** [3-Clause BSD License](https://opensource.org/licenses/BSD-3-Clause) - -1. **Group** : com.google.protobuf. **Name** : protoc. **Version** : 3.19.6. - * **Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) - * **License:** [3-Clause BSD License](https://opensource.org/licenses/BSD-3-Clause) - * **License:** [The Apache Software License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : com.google.truth. **Name** : truth. **Version** : 1.1.3. - * **License:** [The Apache Software License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : com.google.truth.extensions. **Name** : truth-java8-extension. **Version** : 1.1.3. - * **License:** [The Apache Software License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : com.google.truth.extensions. **Name** : truth-liteproto-extension. **Version** : 1.1.3. - * **License:** [The Apache Software License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : com.google.truth.extensions. **Name** : truth-proto-extension. **Version** : 1.1.3. - * **License:** [The Apache Software License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : com.puppycrawl.tools. **Name** : checkstyle. **Version** : 10.3.4. - * **Project URL:** [https://checkstyle.org/](https://checkstyle.org/) - * **License:** [LGPL-2.1+](http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt) - -1. **Group** : com.soywiz.korlibs.korte. **Name** : korte-jvm. **Version** : 2.7.0. - * **Project URL:** [https://github.com/korlibs/korge-next](https://github.com/korlibs/korge-next) - * **License:** [MIT](https://raw.githubusercontent.com/korlibs/korge-next/master/korge/LICENSE.txt) - -1. **Group** : com.squareup. **Name** : javapoet. **Version** : 1.13.0. - * **Project URL:** [http://github.com/square/javapoet/](http://github.com/square/javapoet/) - * **License:** [Apache 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : commons-beanutils. **Name** : commons-beanutils. **Version** : 1.9.4. - * **Project URL:** [https://commons.apache.org/proper/commons-beanutils/](https://commons.apache.org/proper/commons-beanutils/) - * **License:** [Apache License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : commons-codec. **Name** : commons-codec. **Version** : 1.15. - * **Project URL:** [https://commons.apache.org/proper/commons-codec/](https://commons.apache.org/proper/commons-codec/) - * **License:** [Apache License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : commons-collections. **Name** : commons-collections. **Version** : 3.2.2. - * **Project URL:** [http://commons.apache.org/collections/](http://commons.apache.org/collections/) - * **License:** [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : commons-lang. **Name** : commons-lang. **Version** : 2.6. - * **Project URL:** [http://commons.apache.org/lang/](http://commons.apache.org/lang/) - * **License:** [The Apache Software License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : info.picocli. **Name** : picocli. **Version** : 4.6.3. - * **Project URL:** [http://picocli.info](http://picocli.info) - * **License:** [The Apache Software License, version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : io.github.davidburstrom.contester. **Name** : contester-breakpoint. **Version** : 0.2.0. - * **Project URL:** [https://github.com/davidburstrom/contester](https://github.com/davidburstrom/contester) - * **License:** [The Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : io.github.detekt.sarif4k. **Name** : sarif4k. **Version** : 0.0.1. - * **Project URL:** [https://detekt.github.io/detekt](https://detekt.github.io/detekt) - * **License:** [The Apache Software License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : io.github.java-diff-utils. **Name** : java-diff-utils. **Version** : 4.0. - * **Project URL:** [https://github.com/java-diff-utils/java-diff-utils](https://github.com/java-diff-utils/java-diff-utils) - * **License:** [The Apache Software License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : io.gitlab.arturbosch.detekt. **Name** : detekt-api. **Version** : 1.21.0. - * **Project URL:** [https://detekt.dev](https://detekt.dev) - * **License:** [The Apache Software License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : io.gitlab.arturbosch.detekt. **Name** : detekt-cli. **Version** : 1.21.0. - * **Project URL:** [https://detekt.dev](https://detekt.dev) - * **License:** [The Apache Software License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : io.gitlab.arturbosch.detekt. **Name** : detekt-core. **Version** : 1.21.0. - * **Project URL:** [https://detekt.dev](https://detekt.dev) - * **License:** [The Apache Software License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : io.gitlab.arturbosch.detekt. **Name** : detekt-metrics. **Version** : 1.21.0. - * **Project URL:** [https://detekt.dev](https://detekt.dev) - * **License:** [The Apache Software License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : io.gitlab.arturbosch.detekt. **Name** : detekt-parser. **Version** : 1.21.0. - * **Project URL:** [https://detekt.dev](https://detekt.dev) - * **License:** [The Apache Software License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : io.gitlab.arturbosch.detekt. **Name** : detekt-psi-utils. **Version** : 1.21.0. - * **Project URL:** [https://detekt.dev](https://detekt.dev) - * **License:** [The Apache Software License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : io.gitlab.arturbosch.detekt. **Name** : detekt-report-html. **Version** : 1.21.0. - * **Project URL:** [https://detekt.dev](https://detekt.dev) - * **License:** [The Apache Software License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : io.gitlab.arturbosch.detekt. **Name** : detekt-report-md. **Version** : 1.21.0. - * **Project URL:** [https://detekt.dev](https://detekt.dev) - * **License:** [The Apache Software License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : io.gitlab.arturbosch.detekt. **Name** : detekt-report-sarif. **Version** : 1.21.0. - * **Project URL:** [https://detekt.dev](https://detekt.dev) - * **License:** [The Apache Software License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : io.gitlab.arturbosch.detekt. **Name** : detekt-report-txt. **Version** : 1.21.0. - * **Project URL:** [https://detekt.dev](https://detekt.dev) - * **License:** [The Apache Software License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : io.gitlab.arturbosch.detekt. **Name** : detekt-report-xml. **Version** : 1.21.0. - * **Project URL:** [https://detekt.dev](https://detekt.dev) - * **License:** [The Apache Software License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : io.gitlab.arturbosch.detekt. **Name** : detekt-rules. **Version** : 1.21.0. - * **Project URL:** [https://detekt.dev](https://detekt.dev) - * **License:** [The Apache Software License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : io.gitlab.arturbosch.detekt. **Name** : detekt-rules-complexity. **Version** : 1.21.0. - * **Project URL:** [https://detekt.dev](https://detekt.dev) - * **License:** [The Apache Software License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : io.gitlab.arturbosch.detekt. **Name** : detekt-rules-coroutines. **Version** : 1.21.0. - * **Project URL:** [https://detekt.dev](https://detekt.dev) - * **License:** [The Apache Software License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : io.gitlab.arturbosch.detekt. **Name** : detekt-rules-documentation. **Version** : 1.21.0. - * **Project URL:** [https://detekt.dev](https://detekt.dev) - * **License:** [The Apache Software License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : io.gitlab.arturbosch.detekt. **Name** : detekt-rules-empty. **Version** : 1.21.0. - * **Project URL:** [https://detekt.dev](https://detekt.dev) - * **License:** [The Apache Software License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : io.gitlab.arturbosch.detekt. **Name** : detekt-rules-errorprone. **Version** : 1.21.0. - * **Project URL:** [https://detekt.dev](https://detekt.dev) - * **License:** [The Apache Software License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : io.gitlab.arturbosch.detekt. **Name** : detekt-rules-exceptions. **Version** : 1.21.0. - * **Project URL:** [https://detekt.dev](https://detekt.dev) - * **License:** [The Apache Software License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : io.gitlab.arturbosch.detekt. **Name** : detekt-rules-naming. **Version** : 1.21.0. - * **Project URL:** [https://detekt.dev](https://detekt.dev) - * **License:** [The Apache Software License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : io.gitlab.arturbosch.detekt. **Name** : detekt-rules-performance. **Version** : 1.21.0. - * **Project URL:** [https://detekt.dev](https://detekt.dev) - * **License:** [The Apache Software License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : io.gitlab.arturbosch.detekt. **Name** : detekt-rules-style. **Version** : 1.21.0. - * **Project URL:** [https://detekt.dev](https://detekt.dev) - * **License:** [The Apache Software License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : io.gitlab.arturbosch.detekt. **Name** : detekt-tooling. **Version** : 1.21.0. - * **Project URL:** [https://detekt.dev](https://detekt.dev) - * **License:** [The Apache Software License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : io.gitlab.arturbosch.detekt. **Name** : detekt-utils. **Version** : 1.21.0. - * **Project URL:** [https://detekt.dev](https://detekt.dev) - * **License:** [The Apache Software License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : io.grpc. **Name** : grpc-api. **Version** : 1.46.0. - * **Project URL:** [https://github.com/grpc/grpc-java](https://github.com/grpc/grpc-java) - * **License:** [Apache 2.0](https://opensource.org/licenses/Apache-2.0) - -1. **Group** : io.grpc. **Name** : grpc-context. **Version** : 1.46.0. - * **Project URL:** [https://github.com/grpc/grpc-java](https://github.com/grpc/grpc-java) - * **License:** [Apache 2.0](https://opensource.org/licenses/Apache-2.0) - -1. **Group** : io.grpc. **Name** : grpc-core. **Version** : 1.46.0. - * **Project URL:** [https://github.com/grpc/grpc-java](https://github.com/grpc/grpc-java) - * **License:** [Apache 2.0](https://opensource.org/licenses/Apache-2.0) - -1. **Group** : io.grpc. **Name** : grpc-protobuf. **Version** : 1.46.0. - * **Project URL:** [https://github.com/grpc/grpc-java](https://github.com/grpc/grpc-java) - * **License:** [Apache 2.0](https://opensource.org/licenses/Apache-2.0) - -1. **Group** : io.grpc. **Name** : grpc-protobuf-lite. **Version** : 1.46.0. - * **Project URL:** [https://github.com/grpc/grpc-java](https://github.com/grpc/grpc-java) - * **License:** [Apache 2.0](https://opensource.org/licenses/Apache-2.0) - -1. **Group** : io.grpc. **Name** : grpc-stub. **Version** : 1.46.0. - * **Project URL:** [https://github.com/grpc/grpc-java](https://github.com/grpc/grpc-java) - * **License:** [Apache 2.0](https://opensource.org/licenses/Apache-2.0) - -1. **Group** : io.grpc. **Name** : protoc-gen-grpc-java. **Version** : 1.46.0. - * **Project URL:** [https://github.com/grpc/grpc-java](https://github.com/grpc/grpc-java) - * **License:** [Apache 2.0](https://opensource.org/licenses/Apache-2.0) - -1. **Group** : io.perfmark. **Name** : perfmark-api. **Version** : 0.25.0. - * **Project URL:** [https://github.com/perfmark/perfmark](https://github.com/perfmark/perfmark) - * **License:** [Apache 2.0](https://opensource.org/licenses/Apache-2.0) - -1. **Group** : io.spine.protodata. **Name** : protodata-codegen-java. **Version** : 0.3.0.**No license information found** -1. **Group** : io.spine.protodata. **Name** : protodata-fat-cli. **Version** : 0.3.0.**No license information found** -1. **Group** : io.spine.protodata. **Name** : protodata-protoc. **Version** : 0.3.0.**No license information found** -1. **Group** : io.spine.validation. **Name** : spine-validation-configuration. **Version** : 2.0.0-SNAPSHOT.61.**No license information found** -1. **Group** : io.spine.validation. **Name** : spine-validation-context. **Version** : 2.0.0-SNAPSHOT.61.**No license information found** -1. **Group** : io.spine.validation. **Name** : spine-validation-java. **Version** : 2.0.0-SNAPSHOT.61.**No license information found** -1. **Group** : io.spine.validation. **Name** : spine-validation-java-runtime. **Version** : 2.0.0-SNAPSHOT.61.**No license information found** -1. **Group** : io.spine.validation. **Name** : spine-validation-model. **Version** : 2.0.0-SNAPSHOT.61.**No license information found** -1. **Group** : javax.annotation. **Name** : javax.annotation-api. **Version** : 1.3.2. - * **Project URL:** [http://jcp.org/en/jsr/detail?id=250](http://jcp.org/en/jsr/detail?id=250) - * **License:** [CDDL + GPLv2 with classpath exception](https://github.com/javaee/javax.annotation/blob/master/LICENSE) - -1. **Group** : junit. **Name** : junit. **Version** : 4.13.1. - * **Project URL:** [http://junit.org](http://junit.org) - * **License:** [Eclipse Public License 1.0](http://www.eclipse.org/legal/epl-v10.html) - -1. **Group** : kr.motd.maven. **Name** : os-maven-plugin. **Version** : 1.7.0. - * **Project URL:** [https://github.com/trustin/os-maven-plugin/](https://github.com/trustin/os-maven-plugin/) - * **License:** [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0) - -1. **Group** : net.java.dev.jna. **Name** : jna. **Version** : 5.6.0. - * **Project URL:** [https://github.com/java-native-access/jna](https://github.com/java-native-access/jna) - * **License:** [Apache License v2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - * **License:** [LGPL, version 2.1](http://www.gnu.org/licenses/licenses.html) - -1. **Group** : net.ltgt.gradle. **Name** : gradle-errorprone-plugin. **Version** : 3.0.1.**No license information found** -1. **Group** : net.sf.saxon. **Name** : Saxon-HE. **Version** : 11.4. - * **Project URL:** [http://www.saxonica.com/](http://www.saxonica.com/) - * **License:** [Mozilla Public License Version 2.0](http://www.mozilla.org/MPL/2.0/) - -1. **Group** : net.sourceforge.pmd. **Name** : pmd-core. **Version** : 6.50.0. - * **License:** [BSD-style](http://pmd.sourceforge.net/license.html) - -1. **Group** : net.sourceforge.pmd. **Name** : pmd-java. **Version** : 6.50.0. - * **License:** [BSD-style](http://pmd.sourceforge.net/license.html) - -1. **Group** : net.sourceforge.saxon. **Name** : saxon. **Version** : 9.1.0.8. - * **Project URL:** [http://saxon.sourceforge.net/](http://saxon.sourceforge.net/) - * **License:** [Mozilla Public License Version 1.0](http://www.mozilla.org/MPL/MPL-1.0.txt) - -1. **Group** : org.antlr. **Name** : antlr4-runtime. **Version** : 4.11.1. - * **Project URL:** [https://www.antlr.org/](https://www.antlr.org/) - * **License:** [BSD-3-Clause](https://www.antlr.org/license.html) - -1. **Group** : org.antlr. **Name** : antlr4-runtime. **Version** : 4.7.2. - * **Project URL:** [http://www.antlr.org](http://www.antlr.org) - * **License:** [The BSD License](http://www.antlr.org/license.html) - -1. **Group** : org.apache.commons. **Name** : commons-lang3. **Version** : 3.8.1. - * **Project URL:** [http://commons.apache.org/proper/commons-lang/](http://commons.apache.org/proper/commons-lang/) - * **License:** [Apache License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : org.apache.httpcomponents.client5. **Name** : httpclient5. **Version** : 5.1.3. - * **License:** [Apache License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : org.apache.httpcomponents.core5. **Name** : httpcore5. **Version** : 5.1.3. - * **License:** [Apache License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : org.apache.httpcomponents.core5. **Name** : httpcore5-h2. **Version** : 5.1.3. - * **License:** [Apache License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : org.apiguardian. **Name** : apiguardian-api. **Version** : 1.1.2. - * **Project URL:** [https://github.com/apiguardian-team/apiguardian](https://github.com/apiguardian-team/apiguardian) - * **License:** [The Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : org.checkerframework. **Name** : checker-compat-qual. **Version** : 2.5.5. - * **Project URL:** [https://checkerframework.org](https://checkerframework.org) - * **License:** [GNU General Public License, version 2 (GPL2), with the classpath exception](http://www.gnu.org/software/classpath/license.html) - * **License:** [The MIT License](http://opensource.org/licenses/MIT) - -1. **Group** : org.checkerframework. **Name** : checker-qual. **Version** : 3.21.3. - * **Project URL:** [https://checkerframework.org](https://checkerframework.org) - * **License:** [The MIT License](http://opensource.org/licenses/MIT) - -1. **Group** : org.checkerframework. **Name** : dataflow-errorprone. **Version** : 3.24.0. - * **Project URL:** [https://checkerframework.org](https://checkerframework.org) - * **License:** [GNU General Public License, version 2 (GPL2), with the classpath exception](http://www.gnu.org/software/classpath/license.html) - -1. **Group** : org.codehaus.mojo. **Name** : animal-sniffer-annotations. **Version** : 1.21. - * **License:** [MIT license](http://www.opensource.org/licenses/mit-license.php) - * **License:** [The Apache Software License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : org.codehaus.woodstox. **Name** : stax2-api. **Version** : 4.2.1. - * **Project URL:** [http://github.com/FasterXML/stax2-api](http://github.com/FasterXML/stax2-api) - * **License:** [The Apache Software License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - * **License:** [The BSD License](http://www.opensource.org/licenses/bsd-license.php) - -1. **Group** : org.eclipse.jgit. **Name** : org.eclipse.jgit. **Version** : 4.4.1.201607150455-r. - * **License:** Eclipse Distribution License (New BSD License) - -1. **Group** : org.freemarker. **Name** : freemarker. **Version** : 2.3.31. - * **Project URL:** [https://freemarker.apache.org/](https://freemarker.apache.org/) - * **License:** [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : org.hamcrest. **Name** : hamcrest-core. **Version** : 1.3. - * **License:** [New BSD License](http://www.opensource.org/licenses/bsd-license.php) - -1. **Group** : org.jacoco. **Name** : org.jacoco.agent. **Version** : 0.8.8. - * **License:** [Eclipse Public License 2.0](https://www.eclipse.org/legal/epl-2.0/) - -1. **Group** : org.jacoco. **Name** : org.jacoco.ant. **Version** : 0.8.8. - * **License:** [Eclipse Public License 2.0](https://www.eclipse.org/legal/epl-2.0/) - -1. **Group** : org.jacoco. **Name** : org.jacoco.core. **Version** : 0.8.8. - * **License:** [Eclipse Public License 2.0](https://www.eclipse.org/legal/epl-2.0/) - -1. **Group** : org.jacoco. **Name** : org.jacoco.report. **Version** : 0.8.8. - * **License:** [Eclipse Public License 2.0](https://www.eclipse.org/legal/epl-2.0/) - -1. **Group** : org.javassist. **Name** : javassist. **Version** : 3.28.0-GA. - * **Project URL:** [http://www.javassist.org/](http://www.javassist.org/) - * **License:** [Apache License 2.0](http://www.apache.org/licenses/) - * **License:** [LGPL 2.1](http://www.gnu.org/licenses/lgpl-2.1.html) - * **License:** [MPL 1.1](http://www.mozilla.org/MPL/MPL-1.1.html) - -1. **Group** : org.jboss.forge.roaster. **Name** : roaster-api. **Version** : 2.24.0.Final. - * **License:** [Eclipse Public License version 1.0](http://www.eclipse.org/legal/epl-v10.html) - * **License:** [Public Domain](http://repository.jboss.org/licenses/cc0-1.0.txt) - -1. **Group** : org.jboss.forge.roaster. **Name** : roaster-jdt. **Version** : 2.24.0.Final. - * **License:** [Eclipse Public License version 1.0](http://www.eclipse.org/legal/epl-v10.html) - * **License:** [Public Domain](http://repository.jboss.org/licenses/cc0-1.0.txt) - -1. **Group** : org.jetbrains. **Name** : annotations. **Version** : 13.0. - * **Project URL:** [http://www.jetbrains.org](http://www.jetbrains.org) - * **License:** [The Apache Software License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : org.jetbrains. **Name** : markdown. **Version** : 0.3.1.**No license information found** -1. **Group** : org.jetbrains. **Name** : markdown-jvm. **Version** : 0.3.1. - * **Project URL:** [https://github.com/JetBrains/markdown](https://github.com/JetBrains/markdown) - * **License:** [The Apache Software License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : org.jetbrains.dokka. **Name** : dokka-analysis. **Version** : 1.7.20. - * **Project URL:** [https://github.com/Kotlin/dokka](https://github.com/Kotlin/dokka) - * **License:** [The Apache Software License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : org.jetbrains.dokka. **Name** : dokka-base. **Version** : 1.7.20. - * **Project URL:** [https://github.com/Kotlin/dokka](https://github.com/Kotlin/dokka) - * **License:** [The Apache Software License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : org.jetbrains.dokka. **Name** : dokka-core. **Version** : 1.7.20. - * **Project URL:** [https://github.com/Kotlin/dokka](https://github.com/Kotlin/dokka) - * **License:** [The Apache Software License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : org.jetbrains.dokka. **Name** : javadoc-plugin. **Version** : 1.7.20. - * **Project URL:** [https://github.com/Kotlin/dokka](https://github.com/Kotlin/dokka) - * **License:** [The Apache Software License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : org.jetbrains.dokka. **Name** : kotlin-analysis-compiler. **Version** : 1.7.20. - * **Project URL:** [https://github.com/Kotlin/dokka](https://github.com/Kotlin/dokka) - * **License:** [The Apache Software License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : org.jetbrains.dokka. **Name** : kotlin-analysis-intellij. **Version** : 1.7.20. - * **Project URL:** [https://github.com/Kotlin/dokka](https://github.com/Kotlin/dokka) - * **License:** [The Apache Software License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : org.jetbrains.dokka. **Name** : kotlin-as-java-plugin. **Version** : 1.7.20. - * **Project URL:** [https://github.com/Kotlin/dokka](https://github.com/Kotlin/dokka) - * **License:** [The Apache Software License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : org.jetbrains.intellij.deps. **Name** : trove4j. **Version** : 1.0.20200330. - * **Project URL:** [https://github.com/JetBrains/intellij-deps-trove4j](https://github.com/JetBrains/intellij-deps-trove4j) - * **License:** [GNU LESSER GENERAL PUBLIC LICENSE 2.1](https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html) - -1. **Group** : org.jetbrains.kotlin. **Name** : kotlin-compiler-embeddable. **Version** : 1.6.21. - * **Project URL:** [https://kotlinlang.org/](https://kotlinlang.org/) - * **License:** [The Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : org.jetbrains.kotlin. **Name** : kotlin-compiler-embeddable. **Version** : 1.7.20. - * **Project URL:** [https://kotlinlang.org/](https://kotlinlang.org/) - * **License:** [The Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : org.jetbrains.kotlin. **Name** : kotlin-daemon-embeddable. **Version** : 1.6.21. - * **Project URL:** [https://kotlinlang.org/](https://kotlinlang.org/) - * **License:** [The Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : org.jetbrains.kotlin. **Name** : kotlin-daemon-embeddable. **Version** : 1.7.20. - * **Project URL:** [https://kotlinlang.org/](https://kotlinlang.org/) - * **License:** [The Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : org.jetbrains.kotlin. **Name** : kotlin-klib-commonizer-embeddable. **Version** : 1.7.20. - * **Project URL:** [https://kotlinlang.org/](https://kotlinlang.org/) - * **License:** [The Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : org.jetbrains.kotlin. **Name** : kotlin-reflect. **Version** : 1.7.20. - * **Project URL:** [https://kotlinlang.org/](https://kotlinlang.org/) - * **License:** [The Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : org.jetbrains.kotlin. **Name** : kotlin-script-runtime. **Version** : 1.6.21. - * **Project URL:** [https://kotlinlang.org/](https://kotlinlang.org/) - * **License:** [The Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : org.jetbrains.kotlin. **Name** : kotlin-script-runtime. **Version** : 1.7.20. - * **Project URL:** [https://kotlinlang.org/](https://kotlinlang.org/) - * **License:** [The Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : org.jetbrains.kotlin. **Name** : kotlin-scripting-common. **Version** : 1.7.20. - * **Project URL:** [https://kotlinlang.org/](https://kotlinlang.org/) - * **License:** [The Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : org.jetbrains.kotlin. **Name** : kotlin-scripting-compiler-embeddable. **Version** : 1.7.20. - * **Project URL:** [https://kotlinlang.org/](https://kotlinlang.org/) - * **License:** [The Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : org.jetbrains.kotlin. **Name** : kotlin-scripting-compiler-impl-embeddable. **Version** : 1.7.20. - * **Project URL:** [https://kotlinlang.org/](https://kotlinlang.org/) - * **License:** [The Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : org.jetbrains.kotlin. **Name** : kotlin-scripting-jvm. **Version** : 1.7.20. - * **Project URL:** [https://kotlinlang.org/](https://kotlinlang.org/) - * **License:** [The Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : org.jetbrains.kotlin. **Name** : kotlin-stdlib. **Version** : 1.7.20. - * **Project URL:** [https://kotlinlang.org/](https://kotlinlang.org/) - * **License:** [The Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : org.jetbrains.kotlin. **Name** : kotlin-stdlib-common. **Version** : 1.7.20. - * **Project URL:** [https://kotlinlang.org/](https://kotlinlang.org/) - * **License:** [The Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : org.jetbrains.kotlin. **Name** : kotlin-stdlib-jdk7. **Version** : 1.7.20. - * **Project URL:** [https://kotlinlang.org/](https://kotlinlang.org/) - * **License:** [The Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : org.jetbrains.kotlin. **Name** : kotlin-stdlib-jdk8. **Version** : 1.7.20. - * **Project URL:** [https://kotlinlang.org/](https://kotlinlang.org/) - * **License:** [The Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : org.jetbrains.kotlinx. **Name** : kotlinx-coroutines-bom. **Version** : 1.6.3.**No license information found** -1. **Group** : org.jetbrains.kotlinx. **Name** : kotlinx-coroutines-core. **Version** : 1.6.3.**No license information found** -1. **Group** : org.jetbrains.kotlinx. **Name** : kotlinx-coroutines-core-jvm. **Version** : 1.6.3. - * **Project URL:** [https://github.com/Kotlin/kotlinx.coroutines](https://github.com/Kotlin/kotlinx.coroutines) - * **License:** [The Apache Software License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : org.jetbrains.kotlinx. **Name** : kotlinx-html-jvm. **Version** : 0.7.5. - * **Project URL:** [https://github.com/Kotlin/kotlinx.html](https://github.com/Kotlin/kotlinx.html) - * **License:** [The Apache License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : org.jetbrains.kotlinx. **Name** : kotlinx-serialization-core. **Version** : 1.1.0.**No license information found** -1. **Group** : org.jetbrains.kotlinx. **Name** : kotlinx-serialization-core-jvm. **Version** : 1.1.0. - * **Project URL:** [https://github.com/Kotlin/kotlinx.serialization](https://github.com/Kotlin/kotlinx.serialization) - * **License:** [The Apache Software License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : org.jetbrains.kotlinx. **Name** : kotlinx-serialization-json. **Version** : 1.1.0.**No license information found** -1. **Group** : org.jetbrains.kotlinx. **Name** : kotlinx-serialization-json-jvm. **Version** : 1.1.0. - * **Project URL:** [https://github.com/Kotlin/kotlinx.serialization](https://github.com/Kotlin/kotlinx.serialization) - * **License:** [The Apache Software License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : org.jsoup. **Name** : jsoup. **Version** : 1.14.3. - * **Project URL:** [https://jsoup.org/](https://jsoup.org/) - * **License:** [The MIT License](https://jsoup.org/license) - -1. **Group** : org.junit. **Name** : junit-bom. **Version** : 5.9.1.**No license information found** -1. **Group** : org.junit.jupiter. **Name** : junit-jupiter-api. **Version** : 5.9.1. - * **Project URL:** [https://junit.org/junit5/](https://junit.org/junit5/) - * **License:** [Eclipse Public License v2.0](https://www.eclipse.org/legal/epl-v20.html) - -1. **Group** : org.junit.jupiter. **Name** : junit-jupiter-engine. **Version** : 5.9.1. - * **Project URL:** [https://junit.org/junit5/](https://junit.org/junit5/) - * **License:** [Eclipse Public License v2.0](https://www.eclipse.org/legal/epl-v20.html) - -1. **Group** : org.junit.jupiter. **Name** : junit-jupiter-params. **Version** : 5.9.1. - * **Project URL:** [https://junit.org/junit5/](https://junit.org/junit5/) - * **License:** [Eclipse Public License v2.0](https://www.eclipse.org/legal/epl-v20.html) - -1. **Group** : org.junit.platform. **Name** : junit-platform-commons. **Version** : 1.9.1. - * **Project URL:** [https://junit.org/junit5/](https://junit.org/junit5/) - * **License:** [Eclipse Public License v2.0](https://www.eclipse.org/legal/epl-v20.html) - -1. **Group** : org.junit.platform. **Name** : junit-platform-engine. **Version** : 1.9.1. - * **Project URL:** [https://junit.org/junit5/](https://junit.org/junit5/) - * **License:** [Eclipse Public License v2.0](https://www.eclipse.org/legal/epl-v20.html) - -1. **Group** : org.opentest4j. **Name** : opentest4j. **Version** : 1.2.0. - * **Project URL:** [https://github.com/ota4j-team/opentest4j](https://github.com/ota4j-team/opentest4j) - * **License:** [The Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : org.ow2.asm. **Name** : asm. **Version** : 9.1. - * **Project URL:** [http://asm.ow2.io/](http://asm.ow2.io/) - * **License:** [BSD-3-Clause](https://asm.ow2.io/license.html) - * **License:** [The Apache Software License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : org.ow2.asm. **Name** : asm. **Version** : 9.2. - * **Project URL:** [http://asm.ow2.io/](http://asm.ow2.io/) - * **License:** [BSD-3-Clause](https://asm.ow2.io/license.html) - * **License:** [The Apache Software License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : org.ow2.asm. **Name** : asm. **Version** : 9.3. - * **Project URL:** [http://asm.ow2.io/](http://asm.ow2.io/) - * **License:** [BSD-3-Clause](https://asm.ow2.io/license.html) - * **License:** [The Apache Software License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : org.ow2.asm. **Name** : asm-analysis. **Version** : 9.2. - * **Project URL:** [http://asm.ow2.io/](http://asm.ow2.io/) - * **License:** [BSD-3-Clause](https://asm.ow2.io/license.html) - * **License:** [The Apache Software License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : org.ow2.asm. **Name** : asm-commons. **Version** : 9.2. - * **Project URL:** [http://asm.ow2.io/](http://asm.ow2.io/) - * **License:** [BSD-3-Clause](https://asm.ow2.io/license.html) - * **License:** [The Apache Software License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : org.ow2.asm. **Name** : asm-tree. **Version** : 9.2. - * **Project URL:** [http://asm.ow2.io/](http://asm.ow2.io/) - * **License:** [BSD-3-Clause](https://asm.ow2.io/license.html) - * **License:** [The Apache Software License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - -1. **Group** : org.pcollections. **Name** : pcollections. **Version** : 3.1.4. - * **Project URL:** [https://github.com/hrldcpr/pcollections](https://github.com/hrldcpr/pcollections) - * **License:** [The MIT License](https://opensource.org/licenses/mit-license.php) - -1. **Group** : org.reflections. **Name** : reflections. **Version** : 0.10.2. - * **Project URL:** [http://github.com/ronmamo/reflections](http://github.com/ronmamo/reflections) - * **License:** [The Apache Software License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - * **License:** [WTFPL](http://www.wtfpl.net/) - -1. **Group** : org.xmlresolver. **Name** : xmlresolver. **Version** : 4.4.3. - * **Project URL:** [https://github.com/xmlresolver/xmlresolver](https://github.com/xmlresolver/xmlresolver) - * **License:** [Apache License version 2.0](https://www.apache.org/licenses/LICENSE-2.0) - -1. **Group** : org.yaml. **Name** : snakeyaml. **Version** : 1.30. - * **Project URL:** [https://bitbucket.org/snakeyaml/snakeyaml](https://bitbucket.org/snakeyaml/snakeyaml) - * **License:** [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) - - -The dependencies distributed under several licenses, are used according their commercial-use-friendly license. - -This report was generated on **Mon Nov 07 15:31:30 EET 2022** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). \ No newline at end of file diff --git a/version.gradle.kts b/version.gradle.kts index 893fb4a..b5f69ec 100644 --- a/version.gradle.kts +++ b/version.gradle.kts @@ -1,11 +1,11 @@ /* - * Copyright 2022, TeamDev. All rights reserved. + * Copyright 2025, TeamDev. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following @@ -27,6 +27,6 @@ /** * The version of this library. * - * For dependencies on Spine modules please see [io.spine.internal.dependency.Spine]. + * For dependencies on Spine modules please see [io.spine.dependency.local.Spine]. */ val versionToPublish by extra("2.0.0-SNAPSHOT.118") From 800c0387ea52df9757e6f02d6966442169e009ad Mon Sep 17 00:00:00 2001 From: alexander-yevsyukov Date: Wed, 26 Mar 2025 20:57:55 +0000 Subject: [PATCH 02/15] Bump Gradle -> `8.13` --- gradle/wrapper/gradle-wrapper.jar | Bin 61574 -> 43705 bytes gradle/wrapper/gradle-wrapper.properties | 3 ++- gradlew | 33 +++++++++++++---------- gradlew.bat | 22 ++++++++------- 4 files changed, 33 insertions(+), 25 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 943f0cbfa754578e88a3dae77fce6e3dea56edbf..9bbc975c742b298b441bfb90dbc124400a3751b9 100644 GIT binary patch literal 43705 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 DHx0+F literal 61574 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 ScNgau(U?ep-K_E5zy1%ZQTdPn diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 52f73a8..37f853b 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-rc-1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip networkTimeout=10000 +validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index 65dcd68..965e398 100755 --- a/gradlew +++ b/gradlew @@ -7,7 +7,7 @@ # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# https://www.apache.org/licenses/LICENSE-2.0 +# https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, @@ -55,7 +55,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -83,10 +83,8 @@ done # This is normally unused # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -133,10 +131,13 @@ location of your Java installation." fi else JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." + fi fi # Increase the maximum file descriptors if we can. @@ -144,7 +145,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then case $MAX_FD in #( max*) # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 + # shellcheck disable=SC2039,SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac @@ -152,7 +153,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then '' | soft) :;; #( *) # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 + # shellcheck disable=SC2039,SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac @@ -197,11 +198,15 @@ if "$cygwin" || "$msys" ; then done fi -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ diff --git a/gradlew.bat b/gradlew.bat index 93e3f59..9d21a21 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -43,11 +45,11 @@ set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 if %ERRORLEVEL% equ 0 goto execute -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail @@ -57,11 +59,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe if exist "%JAVA_EXE%" goto execute -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail From 087f880015235f78fdd24e3ab0ce658fc3b83546 Mon Sep 17 00:00:00 2001 From: alexander-yevsyukov Date: Wed, 26 Mar 2025 20:58:07 +0000 Subject: [PATCH 03/15] Update `config` --- .github/workflows/gradle-wrapper-validation.yml | 6 +++--- .github/workflows/increment-guard.yml | 7 ++++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/.github/workflows/gradle-wrapper-validation.yml b/.github/workflows/gradle-wrapper-validation.yml index 47e2938..858cebb 100644 --- a/.github/workflows/gradle-wrapper-validation.yml +++ b/.github/workflows/gradle-wrapper-validation.yml @@ -9,11 +9,11 @@ on: jobs: validation: - name: Validation + name: Gradle Wrapper Validation runs-on: ubuntu-latest steps: - name: Checkout latest code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Validate Gradle Wrapper - uses: gradle/wrapper-validation-action@v1 + uses: gradle/actions/wrapper-validation@v4 diff --git a/.github/workflows/increment-guard.yml b/.github/workflows/increment-guard.yml index ea2c48f..1993841 100644 --- a/.github/workflows/increment-guard.yml +++ b/.github/workflows/increment-guard.yml @@ -10,16 +10,17 @@ on: jobs: build: + name: Check version increment runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: submodules: 'true' - - uses: actions/setup-java@v3 + - uses: actions/setup-java@v4 with: - java-version: 11 + java-version: 17 distribution: zulu cache: gradle From 0b5c863ee7c4c620621aabd76940dc4ad74fd121 Mon Sep 17 00:00:00 2001 From: alexander-yevsyukov Date: Wed, 26 Mar 2025 20:58:43 +0000 Subject: [PATCH 04/15] Add `@Route` annotation to consider used --- .idea/misc.xml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.idea/misc.xml b/.idea/misc.xml index 3a87034..31f80ae 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,13 +1,14 @@ - + + @@ -39,5 +40,5 @@ - + From a69564ee44072e2d747cf9915251be4e126922ac Mon Sep 17 00:00:00 2001 From: alexander-yevsyukov Date: Wed, 26 Mar 2025 20:58:54 +0000 Subject: [PATCH 05/15] Update dependency report --- pom.xml | 108 ++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 74 insertions(+), 34 deletions(-) diff --git a/pom.xml b/pom.xml index f9ccb8f..56923a1 100644 --- a/pom.xml +++ b/pom.xml @@ -26,43 +26,64 @@ all modules and does not describe the project structure per-subproject. io.spine spine-base - 2.0.0-SNAPSHOT.120 + 2.0.0-SNAPSHOT.307 compile io.spine.validation spine-validation-java-runtime - 2.0.0-SNAPSHOT.61 + 2.0.0-SNAPSHOT.305 compile org.jetbrains.kotlin - kotlin-stdlib-jdk8 - 1.7.20 + kotlin-stdlib + 2.1.20 compile io.spine.tools spine-testlib - 2.0.0-SNAPSHOT.120 + 2.0.0-SNAPSHOT.185 test io.spine.tools - spine-testutil-time - 2.0.0-SNAPSHOT.120 + spine-time-testlib + 2.0.0-SNAPSHOT.136 test org.junit.jupiter junit-jupiter-engine - 5.9.1 + 5.10.0 test + + com.google.auto.service + auto-service-annotations + 1.1.1 + provided + + + com.google.devtools.ksp + symbol-processing + 2.1.20-1.0.31 + + + com.google.devtools.ksp + symbol-processing-api + 2.1.20-1.0.31 + + + com.google.devtools.ksp + symbol-processing-cmdline + 2.1.20-1.0.31 + com.google.errorprone error_prone_core - 2.16 + 2.36.0 com.google.errorprone @@ -77,103 +98,122 @@ all modules and does not describe the project structure per-subproject. com.puppycrawl.tools checkstyle - 10.3.4 + 10.12.1 + + + dev.zacsweers.autoservice + auto-service-ksp + 1.2.0 io.gitlab.arturbosch.detekt detekt-cli - 1.21.0 + 1.23.8 io.grpc protoc-gen-grpc-java - 1.46.0 + 1.59.0 io.spine.protodata protodata-fat-cli - 0.3.0 + 0.93.4 io.spine.protodata protodata-protoc - 0.3.0 + 0.93.4 io.spine.tools spine-dokka-extensions - 2.0.0-SNAPSHOT.4 + 2.0.0-SNAPSHOT.6 io.spine.tools - spine-mc-java-checks - 2.0.0-SNAPSHOT.105 - provided + spine-mc-java-plugins + 2.0.0-SNAPSHOT.306 io.spine.tools - spine-mc-java-plugins - 2.0.0-SNAPSHOT.105 + spine-mc-java-routing + 2.0.0-SNAPSHOT.306 io.spine.validation - spine-validation-java - 2.0.0-SNAPSHOT.61 + spine-validation-java-bundle + 2.0.0-SNAPSHOT.302 net.sourceforge.pmd pmd-java - 6.50.0 + 6.55.0 org.jacoco org.jacoco.agent - 0.8.8 + 0.8.12 org.jacoco org.jacoco.ant - 0.8.8 + 0.8.12 org.jetbrains.dokka - dokka-analysis - 1.7.20 + analysis-kotlin-descriptors + 1.9.20 org.jetbrains.dokka dokka-base - 1.7.20 + 1.9.20 org.jetbrains.dokka dokka-core - 1.7.20 + 1.9.20 + + + org.jetbrains.dokka + gfm-plugin + 1.9.20 org.jetbrains.dokka javadoc-plugin - 1.7.20 + 1.9.20 + + + org.jetbrains.dokka + jekyll-plugin + 1.9.20 org.jetbrains.dokka kotlin-as-java-plugin - 1.7.20 + 1.9.20 + + + org.jetbrains.kotlin + kotlin-build-tools-impl + 2.1.20 org.jetbrains.kotlin kotlin-compiler-embeddable - 1.7.20 + 2.1.20 org.jetbrains.kotlin kotlin-klib-commonizer-embeddable - 1.7.20 + 2.1.20 org.jetbrains.kotlin kotlin-scripting-compiler-embeddable - 1.7.20 + 2.1.20 From 500bbd1b274275d9539df58c62da80c1cf39d659 Mon Sep 17 00:00:00 2001 From: alexander-yevsyukov Date: Wed, 26 Mar 2025 20:59:26 +0000 Subject: [PATCH 06/15] Update IDEA settings --- .idea/inspectionProfiles/Project_Default.xml | 26 +++++++++++--------- .idea/kotlinc.xml | 8 +++--- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml index 35bbdff..229f1d3 100644 --- a/.idea/inspectionProfiles/Project_Default.xml +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -146,13 +146,11 @@ - - @@ -194,7 +192,6 @@ - @@ -258,6 +255,18 @@ + + + + + + - @@ -623,6 +631,9 @@ + + + @@ -690,7 +701,6 @@ - @@ -711,7 +721,6 @@ -