diff --git a/.agents/documentation-guidelines.md b/.agents/documentation-guidelines.md index 914dcc8737..6c9c1bae76 100644 --- a/.agents/documentation-guidelines.md +++ b/.agents/documentation-guidelines.md @@ -9,6 +9,6 @@ ## Avoid widows, runts, orphans, or rivers Agents should **AVOID** text flow patters illustrated -on [this diagram](widow-runt-orphan-river.jpg). +on [this diagram](widow-runt-orphan.jpg). [todo-comments]: https://github.com/SpineEventEngine/documentation/wiki/TODO-comments diff --git a/.agents/skills/writer/SKILL.md b/.agents/skills/writer/SKILL.md new file mode 100644 index 0000000000..5c720265b3 --- /dev/null +++ b/.agents/skills/writer/SKILL.md @@ -0,0 +1,51 @@ +--- +name: writer +description: > + Write, edit, and restructure user-facing and developer-facing documentation. + Use when asked to create/update docs such as `README.md`, `docs/**`, and + other Markdown documentation; + when drafting tutorials, guides, troubleshooting pages, or migration notes; and + when improving inline API documentation (KDoc) and examples. +--- + +# Write documentation (repo-specific) + +## Decide the target and audience + +- Identify the target reader: end user, contributor, maintainer, or tooling/automation. +- Identify the task type: new doc, update, restructure, or documentation audit. +- Identify the acceptance criteria: “what is correct when the reader is done?” + +## Choose where the content should live + +- Prefer updating an existing doc over creating a new one. +- Place content in the most discoverable location: + - `README.md`: project entry point and “what is this?”. + - `docs/`: longer-form docs (follow existing conventions in that tree). + - Source KDoc: API usage, examples, and semantics that belong with the code. + +## Follow local documentation conventions + +- Follow `.agents/documentation-guidelines.md` and `.agents/documentation-tasks.md`. +- Use fenced code blocks for commands and examples; format file/dir names as code. +- Avoid widows, runts, orphans, and rivers by reflowing paragraphs when needed. + +## Make docs actionable + +- Prefer steps the reader can execute (commands + expected outcome). +- Prefer concrete examples over abstract descriptions. +- Include prerequisites (versions, OS, environment) when they are easy to miss. +- Use consistent terminology (match code identifiers and existing docs). + +## KDoc-specific guidance + +- For public/internal APIs, include at least one example snippet demonstrating common usage. +- When converting from Javadoc/inline comments to KDoc: + - Remove HTML like `

` and preserve meaning. + - Prefer short paragraphs and blank lines over HTML formatting. + +## Validate changes + +- For code changes, follow `.agents/running-builds.md`. +- For documentation-only changes in Kotlin/Java sources, prefer `./gradlew dokka`. + diff --git a/.agents/skills/writer/agents/openai.yaml b/.agents/skills/writer/agents/openai.yaml new file mode 100644 index 0000000000..44eaa4e241 --- /dev/null +++ b/.agents/skills/writer/agents/openai.yaml @@ -0,0 +1,5 @@ +interface: + display_name: "Writer" + short_description: "Write and update user/developer docs" + default_prompt: "Write or revise documentation in this repository (for example: README.md, docs/**, CONTRIBUTING.md, and API documentation/KDoc). Follow local documentation guidelines in .agents/*.md, keep changes concise and actionable, and include concrete examples and commands where appropriate." + diff --git a/.agents/skills/writer/assets/templates/doc-page.md b/.agents/skills/writer/assets/templates/doc-page.md new file mode 100644 index 0000000000..f405b71e15 --- /dev/null +++ b/.agents/skills/writer/assets/templates/doc-page.md @@ -0,0 +1,23 @@ +# Title + +## Goal + +State what the reader will accomplish. + +## Prerequisites + +- List versions/tools the reader needs. + +## Steps + +1. Do the first thing. +2. Do the next thing. + +## Verify + +Show how the reader can confirm success. + +## Troubleshooting + +- Common failure: likely cause → fix. + diff --git a/.agents/skills/writer/assets/templates/kdoc-example.md b/.agents/skills/writer/assets/templates/kdoc-example.md new file mode 100644 index 0000000000..fdbd9b6a0d --- /dev/null +++ b/.agents/skills/writer/assets/templates/kdoc-example.md @@ -0,0 +1,11 @@ +````kotlin +/** + * Explain what this API does in one sentence. + * + * ## Example + * ```kotlin + * // Show the typical usage pattern. + * val result = doThing() + * ``` + */ +```` diff --git a/.agents/skills/writer/assets/templates/kotlin-java-example.md b/.agents/skills/writer/assets/templates/kotlin-java-example.md new file mode 100644 index 0000000000..5517516f56 --- /dev/null +++ b/.agents/skills/writer/assets/templates/kotlin-java-example.md @@ -0,0 +1,13 @@ +{{< code-tabs langs="Kotlin, Java">}} + +{{< code-tab lang="Kotlin" >}} +```kotlin +``` +{{< /code-tab >}} + +{{< code-tab lang="Java" >}} +```java +``` +{{< /code-tab >}} + +{{< /code-tabs >}} diff --git a/.agents/widow-runt-orphan.jpg b/.agents/widow-runt-orphan.jpg new file mode 100644 index 0000000000..284b02a47d Binary files /dev/null and b/.agents/widow-runt-orphan.jpg differ diff --git a/.idea/misc.xml b/.idea/misc.xml index 31f80aec85..5358548ef6 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,4 +1,3 @@ - @@ -41,4 +40,4 @@ - + \ No newline at end of file diff --git a/base/src/main/java/io/spine/type/KnownTypes.java b/base/src/main/java/io/spine/type/KnownTypes.java index 4847fe2f9a..213acbe793 100644 --- a/base/src/main/java/io/spine/type/KnownTypes.java +++ b/base/src/main/java/io/spine/type/KnownTypes.java @@ -52,7 +52,6 @@ import static com.google.common.collect.ImmutableList.toImmutableList; import static io.spine.string.Strings.joinByLines; import static io.spine.util.Predicates2.distinctBy; -import static java.lang.String.format; import static java.lang.System.lineSeparator; import static java.util.Comparator.comparing; import static java.util.stream.Collectors.toSet; diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 227e6d2625..fdcb94aee2 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -192,6 +192,15 @@ dependencies { ).forEach { implementation(it) } + + testImplementation(platform("org.junit:junit-bom:5.11.4")) + testImplementation("org.junit.jupiter:junit-jupiter") + testImplementation("io.kotest:kotest-assertions-core:6.0.4") + testRuntimeOnly("org.junit.platform:junit-platform-launcher") +} + +tasks.test { + useJUnitPlatform() } dependOnBuildSrcJar() diff --git a/buildSrc/src/main/kotlin/BuildExtensions.kt b/buildSrc/src/main/kotlin/BuildExtensions.kt index 4122975f62..f7a11e3e04 100644 --- a/buildSrc/src/main/kotlin/BuildExtensions.kt +++ b/buildSrc/src/main/kotlin/BuildExtensions.kt @@ -227,6 +227,8 @@ fun Project.configureTaskDependencies() { "compileTestFixturesKotlin".dependOn("kspTestFixturesKotlin") "javadocJar".dependOn(dokkaGeneratePublicationJavadoc) "htmlDocsJar".dependOn(dokkaGenerate) + + "kspTestKotlin".dependOn("launchTestSpineCompiler") } } diff --git a/buildSrc/src/main/kotlin/io/spine/dependency/build/Ksp.kt b/buildSrc/src/main/kotlin/io/spine/dependency/build/Ksp.kt index b1146e97a5..b81c2b2896 100644 --- a/buildSrc/src/main/kotlin/io/spine/dependency/build/Ksp.kt +++ b/buildSrc/src/main/kotlin/io/spine/dependency/build/Ksp.kt @@ -35,7 +35,7 @@ import io.spine.dependency.Dependency */ @Suppress("unused") object Ksp : Dependency() { - override val version = "2.3.0" + override val version = "2.3.6" val dogfoodingVersion = version override val group = "com.google.devtools.ksp" diff --git a/buildSrc/src/main/kotlin/io/spine/dependency/local/Base.kt b/buildSrc/src/main/kotlin/io/spine/dependency/local/Base.kt index af6c40095f..b999a75d2c 100644 --- a/buildSrc/src/main/kotlin/io/spine/dependency/local/Base.kt +++ b/buildSrc/src/main/kotlin/io/spine/dependency/local/Base.kt @@ -33,8 +33,8 @@ package io.spine.dependency.local */ @Suppress("ConstPropertyName", "unused") object Base { - const val version = "2.0.0-SNAPSHOT.383" - const val versionForBuildScript = "2.0.0-SNAPSHOT.383" + const val version = "2.0.0-SNAPSHOT.386" + const val versionForBuildScript = "2.0.0-SNAPSHOT.386" const val group = Spine.group private const val prefix = "spine" const val libModule = "$prefix-base" diff --git a/buildSrc/src/main/kotlin/io/spine/dependency/local/BaseTypes.kt b/buildSrc/src/main/kotlin/io/spine/dependency/local/BaseTypes.kt index 23c7da75bd..27147386e1 100644 --- a/buildSrc/src/main/kotlin/io/spine/dependency/local/BaseTypes.kt +++ b/buildSrc/src/main/kotlin/io/spine/dependency/local/BaseTypes.kt @@ -33,7 +33,7 @@ package io.spine.dependency.local */ @Suppress("ConstPropertyName") object BaseTypes { - const val version = "2.0.0-SNAPSHOT.212" + const val version = "2.0.0-SNAPSHOT.223" 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 index 24365800d3..7809c9cd6c 100644 --- a/buildSrc/src/main/kotlin/io/spine/dependency/local/Change.kt +++ b/buildSrc/src/main/kotlin/io/spine/dependency/local/Change.kt @@ -33,7 +33,7 @@ package io.spine.dependency.local */ @Suppress("ConstPropertyName") object Change { - const val version = "2.0.0-SNAPSHOT.200" + const val version = "2.0.0-SNAPSHOT.206" 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/Compiler.kt b/buildSrc/src/main/kotlin/io/spine/dependency/local/Compiler.kt index c3ca673886..31cbfb3fac 100644 --- a/buildSrc/src/main/kotlin/io/spine/dependency/local/Compiler.kt +++ b/buildSrc/src/main/kotlin/io/spine/dependency/local/Compiler.kt @@ -72,7 +72,7 @@ object Compiler : Dependency() { * The version of the Compiler dependencies. */ override val version: String - private const val fallbackVersion = "2.0.0-SNAPSHOT.035" + private const val fallbackVersion = "2.0.0-SNAPSHOT.041" /** * The distinct version of the Compiler used by other build tools. @@ -81,7 +81,7 @@ object Compiler : Dependency() { * transitive dependencies, this is the version used to build the project itself. */ val dogfoodingVersion: String - private const val fallbackDfVersion = "2.0.0-SNAPSHOT.035" + private const val fallbackDfVersion = "2.0.0-SNAPSHOT.041" /** * The artifact for the Compiler Gradle plugin. diff --git a/buildSrc/src/main/kotlin/io/spine/dependency/local/CoreJvm.kt b/buildSrc/src/main/kotlin/io/spine/dependency/local/CoreJvm.kt index 2e224754f8..2e0b6973b5 100644 --- a/buildSrc/src/main/kotlin/io/spine/dependency/local/CoreJvm.kt +++ b/buildSrc/src/main/kotlin/io/spine/dependency/local/CoreJvm.kt @@ -39,7 +39,7 @@ typealias CoreJava = CoreJvm @Suppress("ConstPropertyName", "unused") object CoreJvm { const val group = Spine.group - const val version = "2.0.0-SNAPSHOT.358" + const val version = "2.0.0-SNAPSHOT.372" const val coreArtifact = "spine-core" const val clientArtifact = "spine-client" diff --git a/buildSrc/src/main/kotlin/io/spine/dependency/local/CoreJvmCompiler.kt b/buildSrc/src/main/kotlin/io/spine/dependency/local/CoreJvmCompiler.kt index 582272c8a9..344e8a13fc 100644 --- a/buildSrc/src/main/kotlin/io/spine/dependency/local/CoreJvmCompiler.kt +++ b/buildSrc/src/main/kotlin/io/spine/dependency/local/CoreJvmCompiler.kt @@ -26,9 +26,6 @@ package io.spine.dependency.local -import io.spine.dependency.local.CoreJvmCompiler.dogfoodingVersion -import io.spine.dependency.local.CoreJvmCompiler.version - /** * Dependencies on the CoreJvm Compiler artifacts. * @@ -49,12 +46,12 @@ object CoreJvmCompiler { /** * The version used to in the build classpath. */ - const val dogfoodingVersion = "2.0.0-SNAPSHOT.042" + const val dogfoodingVersion = "2.0.0-SNAPSHOT.058" /** * The version to be used for integration tests. */ - const val version = "2.0.0-SNAPSHOT.042" + const val version = "2.0.0-SNAPSHOT.058" /** * The ID of the Gradle plugin. diff --git a/buildSrc/src/main/kotlin/io/spine/dependency/local/ModelCompiler.kt b/buildSrc/src/main/kotlin/io/spine/dependency/local/ModelCompiler.kt index 5f9e54117d..fb4359d891 100644 --- a/buildSrc/src/main/kotlin/io/spine/dependency/local/ModelCompiler.kt +++ b/buildSrc/src/main/kotlin/io/spine/dependency/local/ModelCompiler.kt @@ -33,7 +33,7 @@ package io.spine.dependency.local */ @Suppress("ConstPropertyName") object ModelCompiler { - const val version = "2.0.0-SNAPSHOT.133" + const val version = "2.0.0-SNAPSHOT.200" 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/Time.kt b/buildSrc/src/main/kotlin/io/spine/dependency/local/Time.kt index 4bfe22cdfc..363e8a3056 100644 --- a/buildSrc/src/main/kotlin/io/spine/dependency/local/Time.kt +++ b/buildSrc/src/main/kotlin/io/spine/dependency/local/Time.kt @@ -1,5 +1,5 @@ /* - * Copyright 2025, TeamDev. All rights reserved. + * Copyright 2026, 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. @@ -26,18 +26,42 @@ package io.spine.dependency.local +import io.spine.dependency.Dependency + /** * Spine Time library. * * @see spine-time */ -@Suppress("ConstPropertyName") -object Time { - const val version = "2.0.0-SNAPSHOT.220" - const val group = Spine.group - const val artifact = "spine-time" - const val lib = "$group:$artifact:$version" - const val javaExtensions = "$group:$artifact-java:$version" - const val kotlinExtensions = "$group:$artifact-kotlin:$version" - const val testLib = "${Spine.toolsGroup}:spine-time-testlib:$version" +@Suppress( + "unused" /* Some subprojects do not use all Time artifacts. */, + "ConstPropertyName" /* We use custom convention for artifact properties. */, + "MemberVisibilityCanBePrivate" /* The properties are used directly by other subprojects. */, +) +object Time : Dependency() { + override val group = Spine.group + override val version = "2.0.0-SNAPSHOT.234" + private const val infix = "spine-time" + + fun lib(version: String): String = "$group:$infix:$version" + val lib get() = lib(version) + + fun javaExtensions(version: String): String = "$group:$infix-java:$version" + val javaExtensions get() = javaExtensions(version) + + fun kotlinExtensions(version: String): String = "$group:$infix-kotlin:$version" + val kotlinExtensions get() = kotlinExtensions(version) + + fun testLib(version: String): String = "${Spine.toolsGroup}:time-testlib:$version" + val testLib get() = testLib(version) + + override val modules: List + get() = listOf( + lib, + javaExtensions, + kotlinExtensions, + testLib + ).map { + it.split(":").let { (g, artifact) -> "$g:$artifact" } + } } diff --git a/buildSrc/src/main/kotlin/io/spine/dependency/local/ToolBase.kt b/buildSrc/src/main/kotlin/io/spine/dependency/local/ToolBase.kt index 1df8dd1f47..872127af22 100644 --- a/buildSrc/src/main/kotlin/io/spine/dependency/local/ToolBase.kt +++ b/buildSrc/src/main/kotlin/io/spine/dependency/local/ToolBase.kt @@ -34,8 +34,8 @@ package io.spine.dependency.local @Suppress("ConstPropertyName", "unused") object ToolBase { const val group = Spine.toolsGroup - const val version = "2.0.0-SNAPSHOT.371" - const val dogfoodingVersion = "2.0.0-SNAPSHOT.371" + const val version = "2.0.0-SNAPSHOT.375" + const val dogfoodingVersion = "2.0.0-SNAPSHOT.375" const val lib = "$group:tool-base:$version" const val classicCodegen = "$group:classic-codegen:$version" diff --git a/buildSrc/src/main/kotlin/io/spine/dependency/local/Validation.kt b/buildSrc/src/main/kotlin/io/spine/dependency/local/Validation.kt index 92a71d798c..cf429bf432 100644 --- a/buildSrc/src/main/kotlin/io/spine/dependency/local/Validation.kt +++ b/buildSrc/src/main/kotlin/io/spine/dependency/local/Validation.kt @@ -36,7 +36,7 @@ object Validation { /** * The version of the Validation library artifacts. */ - const val version = "2.0.0-SNAPSHOT.378" + const val version = "2.0.0-SNAPSHOT.408" /** * The last version of Validation compatible with ProtoData. @@ -53,6 +53,9 @@ object Validation { fun runtime(version: String) = "$runtimeModule:$version" val runtime = runtime(version) + @Deprecated("Use `runtime` instead.", ReplaceWith("runtime")) + const val oldRuntime = "io.spine.validation:spine-validation-java-runtime:2.0.0-SNAPSHOT.354" + const val javaModule = "$group:$prefix-java" const val java = "$javaModule:$version" const val javaBundleModule = "$group:$prefix-java-bundle" diff --git a/buildSrc/src/main/kotlin/io/spine/dependency/test/JUnit.kt b/buildSrc/src/main/kotlin/io/spine/dependency/test/JUnit.kt index 6e9021fb0c..a4962175ae 100644 --- a/buildSrc/src/main/kotlin/io/spine/dependency/test/JUnit.kt +++ b/buildSrc/src/main/kotlin/io/spine/dependency/test/JUnit.kt @@ -33,7 +33,7 @@ import io.spine.dependency.DependencyWithBom @Suppress("unused", "ConstPropertyName") object JUnit : DependencyWithBom() { - override val version = "6.0.0" + override val version = "6.0.3" override val group: String = "org.junit" /** diff --git a/buildSrc/src/main/kotlin/io/spine/gradle/docs/UpdatePluginVersion.kt b/buildSrc/src/main/kotlin/io/spine/gradle/docs/UpdatePluginVersion.kt new file mode 100644 index 0000000000..a7f269f94a --- /dev/null +++ b/buildSrc/src/main/kotlin/io/spine/gradle/docs/UpdatePluginVersion.kt @@ -0,0 +1,125 @@ +/* + * Copyright 2026, 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.docs + +import java.io.File +import org.gradle.api.DefaultTask +import org.gradle.api.file.DirectoryProperty +import org.gradle.api.provider.Property +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.InputDirectory +import org.gradle.api.tasks.Optional +import org.gradle.api.tasks.TaskAction + +/** + * Updates the version of a Gradle plugin in `build.gradle.kts` files. + * + * The task searches for plugin declarations in the format + * `id("plugin-id") version "version-number"` and replaces + * the version number with the one found in the version script file. + * + * @property directory + * The directory to scan recursively for `build.gradle.kts` files. + * @property version + * The version number to set for the plugin. + * @property pluginId + * The ID of the plugin whose version should be updated. + * @property kotlinVersion + * Optional. If set, updates the version of the Kotlin plugin declared with + * `kotlin("…") version "…"` syntax in the `plugins` block. + * This option works in combination with the [version] and [pluginId] properties. + */ +abstract class UpdatePluginVersion : DefaultTask() { + + @get:InputDirectory + abstract val directory: DirectoryProperty + + @get:Input + abstract val version: Property + + @get:Input + abstract val pluginId: Property + + @get:Input + @get:Optional + abstract val kotlinVersion: Property + + /** + * Updates plugin versions in build files within the path in the [directory]. + */ + @TaskAction + fun update() { + val rootDir = directory.get().asFile + + val kotlinVersionSet = kotlinVersion.isPresent + val kotlinVer = kotlinVersion.orNull + val id = pluginId.get() + val ver = version.get() + + rootDir.walkTopDown() + .filter { it.name == "build.gradle.kts" } + .forEach { file -> + if (kotlinVersionSet && kotlinVer != null) { + updateKotlinPluginVersion(file, kotlinVer) + } + updatePluginVersion(file, id, ver) + } + } + + @Suppress("MemberNameEqualsClassName") + private fun updatePluginVersion(file: File, id: String, version: String) { + val content = file.readText() + // Regex to match: id("plugin-id") version "version-number" + val regex = """id\("$id"\)\s+version\s+"([^"]+)"""".toRegex() + + if (regex.containsMatchIn(content)) { + val updatedContent = regex.replace(content) { + "id(\"$id\") version \"$version\"" + } + if (content != updatedContent) { + file.writeText(updatedContent) + logger.info("Updated version of '$id' in `${file.absolutePath}`.") + } + } + } + + private fun updateKotlinPluginVersion(file: File, kotlinVersion: String) { + val content = file.readText() + // Regex to match Kotlin plugin declarations like: kotlin("jvm") version "1.9.0" + val regex = """kotlin\("([^"]+)"\)\s+version\s+"([^"]+)"""".toRegex() + if (regex.containsMatchIn(content)) { + val updatedContent = regex.replace(content) { matchResult -> + val plugin = matchResult.groupValues[1] + "kotlin(\"$plugin\") version \"$kotlinVersion\"" + } + if (content != updatedContent) { + file.writeText(updatedContent) + logger.info("Updated Kotlin plugin version in `${file.absolutePath}`.") + } + } + } +} diff --git a/buildSrc/src/main/kotlin/io/spine/gradle/kotlin/KotlinConfig.kt b/buildSrc/src/main/kotlin/io/spine/gradle/kotlin/KotlinConfig.kt index f6bed9a066..92b7a38743 100644 --- a/buildSrc/src/main/kotlin/io/spine/gradle/kotlin/KotlinConfig.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/kotlin/KotlinConfig.kt @@ -27,10 +27,10 @@ package io.spine.gradle.kotlin import org.gradle.jvm.toolchain.JavaLanguageVersion +import org.jetbrains.kotlin.gradle.dsl.JvmDefaultMode import org.jetbrains.kotlin.gradle.dsl.KotlinCommonCompilerOptions import org.jetbrains.kotlin.gradle.dsl.KotlinJvmCompilerOptions import org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension -import org.jetbrains.kotlin.gradle.dsl.JvmDefaultMode /** * Sets [Java toolchain](https://kotlinlang.org/docs/gradle.html#gradle-java-toolchains-support) @@ -56,7 +56,7 @@ fun KotlinJvmProjectExtension.applyJvmToolchain(version: String) = @Suppress("unused") fun KotlinCommonCompilerOptions.setFreeCompilerArgs() { if (this is KotlinJvmCompilerOptions) { - jvmDefault.set(JvmDefaultMode.ENABLE) + jvmDefault.set(JvmDefaultMode.NO_COMPATIBILITY) } freeCompilerArgs.addAll( listOf( diff --git a/buildSrc/src/main/kotlin/io/spine/gradle/publish/SpinePublishing.kt b/buildSrc/src/main/kotlin/io/spine/gradle/publish/SpinePublishing.kt index 480175fef1..37fdf5f7db 100644 --- a/buildSrc/src/main/kotlin/io/spine/gradle/publish/SpinePublishing.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/publish/SpinePublishing.kt @@ -1,5 +1,5 @@ /* - * Copyright 2025, TeamDev. All rights reserved. + * Copyright 2026, 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. @@ -29,6 +29,7 @@ package io.spine.gradle.publish import io.spine.gradle.repo.Repository +import java.util.Locale import org.gradle.api.Project import org.gradle.api.publish.maven.plugins.MavenPublishPlugin import org.gradle.kotlin.dsl.apply @@ -145,9 +146,10 @@ import org.gradle.kotlin.dsl.findByType * @see [artifacts] * @see SpinePublishing */ -fun Project.spinePublishing(block: SpinePublishing.() -> Unit) { +fun Project.spinePublishing(block: SpinePublishing.() -> Unit): SpinePublishing { apply() val name = SpinePublishing::class.java.simpleName + .replaceFirstChar { it.lowercase(Locale.getDefault()) } val extension = with(extensions) { findByType() ?: create(name, project) } @@ -155,6 +157,7 @@ fun Project.spinePublishing(block: SpinePublishing.() -> Unit) { block() configured() } + return extension } /** @@ -182,6 +185,12 @@ open class SpinePublishing(private val project: Project) { * The default prefix added before a module name when publishing artifacts. */ const val DEFAULT_PREFIX = "spine-" + + /** + * The reserved value that means that no prefix should be added + * to a tool module's artifact ID. + */ + const val NONE_PREFIX = "NONE" } private val testJar = TestJar() @@ -250,10 +259,23 @@ open class SpinePublishing(private val project: Project) { lateinit var destinations: Set /** - * A prefix to be added before the name of each artifact. + * A prefix to be added before the name of each artifact, if it does not belong + * to the Maven group `"io.spine.tools"`. + * + * @see toolArtifactPrefix */ var artifactPrefix: String = DEFAULT_PREFIX + /** + * A prefix to be added before a module name if it belongs to + * the Maven group `"io.spine.tools"`. + * + * Use `"NONE"` if you need no prefix before tool module names. + * + * @see artifactPrefix + */ + var toolArtifactPrefix: String = "" + /** * Allows enabling publishing of [testJar] artifact, containing compilation output * of "test" source set. @@ -389,10 +411,26 @@ open class SpinePublishing(private val project: Project) { /** * Obtains an artifact ID for the given project. * - * It consists of a project's name and [prefix][artifactPrefix]: - * ``. + * @see artifactPrefix + * @see toolArtifactPrefix */ - fun artifactId(project: Project): String = "$artifactPrefix${project.name}" + fun artifactId(project: Project): String { + if (project.isTool) { + check(!toolArtifactPrefix.isEmpty()) { + "Artifact prefix cannot be empty for tool modules. " + + "Please set the `toolArtifactPrefix` property in `spinePublishing`. " + + "Use `\"NONE\"` to have an empty prefix for tool modules." + } + val prefix = + if (toolArtifactPrefix == NONE_PREFIX) { "" } + else { toolArtifactPrefix } + return "$prefix${project.name}" + } + return "$artifactPrefix${project.name}" + } + + private val Project.isTool: Boolean + get() = group == "io.spine.tools" /** * Ensures that all modules, marked as included into [testJar] publishing, diff --git a/buildSrc/src/main/kotlin/io/spine/gradle/repo/Repositories.kt b/buildSrc/src/main/kotlin/io/spine/gradle/repo/Repositories.kt index de91e33ff6..e6c3f677d9 100644 --- a/buildSrc/src/main/kotlin/io/spine/gradle/repo/Repositories.kt +++ b/buildSrc/src/main/kotlin/io/spine/gradle/repo/Repositories.kt @@ -96,11 +96,14 @@ fun RepositoryHandler.spineArtifacts(): MavenArtifactRepository = maven { 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") + val RepositoryHandler.intellijDependencies: MavenArtifactRepository get() = maven("https://packages.jetbrains.team/maven/p/ij/intellij-dependencies") { content { - includeGroupByRegex("com\\.jetbrains\\.intellij.*") - includeGroupByRegex("org\\.jetbrains\\.intellij.*") + includeGroupByRegex("com\\.jetbrains.*") + includeGroupByRegex("org\\.jetbrains.*") includeGroupByRegex("com\\.intellij.*") } } @@ -129,6 +132,7 @@ fun RepositoryHandler.standardToSpineSdk() { } intellijReleases + jetBrainsCacheRedirector intellijDependencies maven { diff --git a/buildSrc/src/test/kotlin/io/spine/gradle/docs/UpdatePluginVersionTest.kt b/buildSrc/src/test/kotlin/io/spine/gradle/docs/UpdatePluginVersionTest.kt new file mode 100644 index 0000000000..b34ca71fce --- /dev/null +++ b/buildSrc/src/test/kotlin/io/spine/gradle/docs/UpdatePluginVersionTest.kt @@ -0,0 +1,118 @@ +/* + * Copyright 2026, 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.docs + +import io.kotest.matchers.shouldBe +import io.kotest.matchers.string.shouldContain +import java.io.File +import org.gradle.testfixtures.ProjectBuilder +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.io.TempDir + +class UpdatePluginVersionTest { + + @TempDir + lateinit var tempDir: File + + private lateinit var buildFile: File + + @BeforeEach + fun setUp() { + val subDir = File(tempDir, "subproject") + subDir.mkdir() + buildFile = File(subDir, "build.gradle.kts") + buildFile.writeText(""" + plugins { + id("io.spine.validation") version "1.0.0" + id("other-plugin") version "0.1.0" + } + """.trimIndent()) + } + + @Test + fun `update plugin version in build file`() { + val project = ProjectBuilder.builder().build() + val task = project.tasks.register("updatePluginVersion", UpdatePluginVersion::class.java) { + directory.set(tempDir) + version.set("2.0.0-TEST") + pluginId.set("io.spine.validation") + } + task.get().update() + + val updatedContent = buildFile.readText() + updatedContent shouldContain """id("io.spine.validation") version "2.0.0-TEST"""" + updatedContent shouldContain """id("other-plugin") version "0.1.0"""" + } + + @Test + fun `update 'kotlin' plugin version when 'kotlinVersion' is set`() { + // Overwrite with a file that uses kotlin("jvm") syntax + buildFile.writeText( + """ + plugins { + kotlin("jvm") version "1.9.10" + id("io.spine.validation") version "1.0.0" + } + """.trimIndent() + ) + + val project = ProjectBuilder.builder().build() + val task = project.tasks.register("updatePluginVersion", UpdatePluginVersion::class.java) { + directory.set(tempDir) + version.set("2.0.0-TEST") + pluginId.set("io.spine.validation") + kotlinVersion.set("2.2.21") + } + task.get().update() + + val updatedContent = buildFile.readText() + updatedContent shouldContain """kotlin("jvm") version "2.2.21"""" + updatedContent shouldContain """id("io.spine.validation") version "2.0.0-TEST"""" + } + + @Test + fun `handle multiple spaces between id and version`() { + buildFile.writeText(""" + plugins { + id("io.spine.validation") version "1.0.0" + } + """.trimIndent()) + + val project = ProjectBuilder.builder().build() + val task = project.tasks.register("updatePluginVersion", UpdatePluginVersion::class.java) { + directory.set(tempDir) + version.set("2.0.0-TEST") + pluginId.set("io.spine.validation") + } + + task.get().update() + + val updatedContent = buildFile.readText() + updatedContent shouldContain """id("io.spine.validation") version "2.0.0-TEST"""" + } +} diff --git a/buildSrc/src/test/kotlin/io/spine/gradle/publish/SpinePublishingTest.kt b/buildSrc/src/test/kotlin/io/spine/gradle/publish/SpinePublishingTest.kt new file mode 100644 index 0000000000..37f58e0403 --- /dev/null +++ b/buildSrc/src/test/kotlin/io/spine/gradle/publish/SpinePublishingTest.kt @@ -0,0 +1,261 @@ +/* + * Copyright 2026, 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.kotest.assertions.throwables.shouldThrow +import io.kotest.matchers.collections.shouldContain +import io.kotest.matchers.collections.shouldHaveSize +import io.kotest.matchers.shouldBe +import io.kotest.matchers.string.shouldContain +import io.spine.gradle.repo.Repository +import org.gradle.api.Project +import org.gradle.kotlin.dsl.create +import org.gradle.testfixtures.ProjectBuilder +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.DisplayName +import org.junit.jupiter.api.Nested +import org.junit.jupiter.api.Test + +@DisplayName("`SpinePublishing` should") +class SpinePublishingTest { + + private lateinit var project: Project + private lateinit var extension: SpinePublishing + + @BeforeEach + fun setUp() { + project = ProjectBuilder.builder().build() + extension = project.spinePublishing { } + } + + @Nested + inner class `calculate 'artifactId'` { + + @Test + fun `with default prefix for non-tool projects`() { + val subproject = ProjectBuilder.builder() + .withParent(project) + .withName("base") + .build() + subproject.group = "io.spine" + + extension.artifactId(subproject) shouldBe "spine-base" + } + + @Test + fun `with custom prefix for non-tool projects`() { + extension.artifactPrefix = "custom-" + val subproject = ProjectBuilder.builder() + .withParent(project) + .withName("core") + .build() + subproject.group = "io.spine" + + extension.artifactId(subproject) shouldBe "custom-core" + } + + @Test + fun `with tool prefix for tool projects`() { + extension.toolArtifactPrefix = "tool-" + val toolProject = ProjectBuilder.builder() + .withParent(project) + .withName("model-compiler") + .build() + toolProject.group = "io.spine.tools" + + extension.artifactId(toolProject) shouldBe "tool-model-compiler" + } + + @Test + fun `without prefix for tool projects if 'NONE' is specified`() { + extension.toolArtifactPrefix = "NONE" + val toolProject = ProjectBuilder.builder() + .withParent(project) + .withName("proto-js") + .build() + toolProject.group = "io.spine.tools" + + extension.artifactId(toolProject) shouldBe "proto-js" + } + + @Test + fun `throwing IllegalStateException if tool prefix is empty for tool projects`() { + extension.toolArtifactPrefix = "" + val toolProject = ProjectBuilder.builder() + .withParent(project) + .withName("tool") + .build() + toolProject.group = "io.spine.tools" + + shouldThrow { + extension.artifactId(toolProject) + } + } + } + + @Nested + inner class `validate configuration` { + + @Test + fun `ensuring 'testJar' inclusions are published`() { + extension.modules = setOf("pub-module") + extension.testJar { + inclusions = setOf("non-pub-module") + } + + val exception = shouldThrow { + extension.configured() + } + exception.message!! shouldContain "non-pub-module" + } + + @Test + fun `ensuring 'customPublishing' is not misused with modules`() { + extension.modules = setOf("some-module") + extension.customPublishing = true + + val exception = shouldThrow { + extension.configured() + } + exception.message!! shouldContain "customPublishing" + } + + @Test + fun `ensuring modules are not duplicated in root and subproject`() { + val rootProject = project + val subproject = ProjectBuilder.builder() + .withParent(rootProject) + .withName("sub") + .build() + + // Root project already has the 'spinePublishing' extension created in 'setUp'. + // Let's use it instead of creating a second one with a different name. + extension.modules = setOf("sub") + + // Subproject's extension must be named 'SpinePublishing' + // to be found by SpinePublishing::class.java.simpleName + val extensionName = SpinePublishing::class.java.simpleName + val subExtension = subproject.extensions.create(extensionName, subproject) + + val exception = shouldThrow { + subExtension.configured() + } + exception.message!! shouldContain "already configured in a root project" + } + } + + @Nested + inner class `identify 'projectsToPublish'` { + + @Test + fun `as the project itself if no modules are specified`() { + val projects = extension.invokeProjectsToPublish() + projects shouldHaveSize 1 + projects shouldContain project + } + + @Test + fun `as the specified modules`() { + val sub1 = ProjectBuilder.builder().withParent(project).withName("sub1").build() + val sub2 = ProjectBuilder.builder().withParent(project).withName("sub2").build() + + extension.modules = setOf("sub1", "sub2") + + val projects = extension.invokeProjectsToPublish() + projects shouldHaveSize 2 + projects shouldContain sub1 + projects shouldContain sub2 + } + + @Test + fun `including modules with custom publishing`() { + val sub1 = ProjectBuilder.builder().withParent(project).withName("sub1").build() + val sub2 = ProjectBuilder.builder().withParent(project).withName("sub2").build() + + extension.modules = setOf("sub1") + extension.modulesWithCustomPublishing = setOf("sub2") + + val projects = extension.invokeProjectsToPublish() + projects shouldHaveSize 2 + projects shouldContain sub1 + projects shouldContain sub2 + } + } + + @Nested + inner class `resolve 'publishTo' repositories` { + + @Test + fun `from the extension itself if destinations are initialized`() { + val repo = Repository( + "test-repo", + "https://example.com/release", + "https://example.com/snapshot" + ) + extension.destinations = setOf(repo) + + val repos = project.invokePublishTo(extension) + repos shouldHaveSize 1 + repos shouldContain repo + } + + @Test + fun `from the parent project if not specified locally`() { + val repo = Repository( + "parent-repo", + "https://example.com/release", + "https://example.com/snapshot" + ) + // Root project has its extension named 'spinePublishing' from setUp. + extension.destinations = setOf(repo) + + val subproject = ProjectBuilder.builder().withParent(project).withName("sub").build() + // Subproject has no local 'spinePublishing' extension. + + val repos = subproject.invokePublishTo(extension) + repos shouldHaveSize 1 + repos shouldContain repo + } + } +} + +/** + * Accesses private/internal methods of [SpinePublishing] for testing purposes. + */ +private fun SpinePublishing.invokeProjectsToPublish(): Collection { + val method = SpinePublishing::class.java.getDeclaredMethod("projectsToPublish") + method.isAccessible = true + @Suppress("UNCHECKED_CAST") + return method.invoke(this) as Collection +} + +private fun Project.invokePublishTo(extension: SpinePublishing): Set { + val method = SpinePublishing::class.java.getDeclaredMethod("publishTo", Project::class.java) + method.isAccessible = true + @Suppress("UNCHECKED_CAST") + return method.invoke(extension, this) as Set +} diff --git a/config b/config index 21366d370b..3986ebdd1e 160000 --- a/config +++ b/config @@ -1 +1 @@ -Subproject commit 21366d370b26c28690a42b313c172d6dbb4f4d36 +Subproject commit 3986ebdd1ebece40e9433122ab9d46b4253fca03 diff --git a/dependencies.md b/dependencies.md index 41fc1053f1..e6a0426694 100644 --- a/dependencies.md +++ b/dependencies.md @@ -1,6 +1,6 @@ -# Dependencies of `io.spine:spine-annotations:2.0.0-SNAPSHOT.386` +# Dependencies of `io.spine:spine-annotations:2.0.0-SNAPSHOT.387` ## Runtime 1. **Group** : org.jetbrains. **Name** : annotations. **Version** : 26.0.2. @@ -681,7 +681,7 @@ * **Project URL:** [http://jspecify.org/](http://jspecify.org/) * **License:** [The Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) -1. **Group** : org.junit. **Name** : junit-bom. **Version** : 6.0.0. +1. **Group** : org.junit. **Name** : junit-bom. **Version** : 6.0.3. * **Project URL:** [https://junit.org/](https://junit.org/) * **License:** [Eclipse Public License v2.0](https://www.eclipse.org/legal/epl-v20.html) @@ -689,27 +689,27 @@ * **Project URL:** [https://junit-pioneer.org/](https://junit-pioneer.org/) * **License:** [Eclipse Public License v2.0](https://www.eclipse.org/legal/epl-v20.html) -1. **Group** : org.junit.jupiter. **Name** : junit-jupiter-api. **Version** : 6.0.0. +1. **Group** : org.junit.jupiter. **Name** : junit-jupiter-api. **Version** : 6.0.3. * **Project URL:** [https://junit.org/](https://junit.org/) * **License:** [Eclipse Public License v2.0](https://www.eclipse.org/legal/epl-v20.html) -1. **Group** : org.junit.jupiter. **Name** : junit-jupiter-engine. **Version** : 6.0.0. +1. **Group** : org.junit.jupiter. **Name** : junit-jupiter-engine. **Version** : 6.0.3. * **Project URL:** [https://junit.org/](https://junit.org/) * **License:** [Eclipse Public License v2.0](https://www.eclipse.org/legal/epl-v20.html) -1. **Group** : org.junit.jupiter. **Name** : junit-jupiter-params. **Version** : 6.0.0. +1. **Group** : org.junit.jupiter. **Name** : junit-jupiter-params. **Version** : 6.0.3. * **Project URL:** [https://junit.org/](https://junit.org/) * **License:** [Eclipse Public License v2.0](https://www.eclipse.org/legal/epl-v20.html) -1. **Group** : org.junit.platform. **Name** : junit-platform-commons. **Version** : 6.0.0. +1. **Group** : org.junit.platform. **Name** : junit-platform-commons. **Version** : 6.0.3. * **Project URL:** [https://junit.org/](https://junit.org/) * **License:** [Eclipse Public License v2.0](https://www.eclipse.org/legal/epl-v20.html) -1. **Group** : org.junit.platform. **Name** : junit-platform-engine. **Version** : 6.0.0. +1. **Group** : org.junit.platform. **Name** : junit-platform-engine. **Version** : 6.0.3. * **Project URL:** [https://junit.org/](https://junit.org/) * **License:** [Eclipse Public License v2.0](https://www.eclipse.org/legal/epl-v20.html) -1. **Group** : org.junit.platform. **Name** : junit-platform-launcher. **Version** : 6.0.0. +1. **Group** : org.junit.platform. **Name** : junit-platform-launcher. **Version** : 6.0.3. * **Project URL:** [https://junit.org/](https://junit.org/) * **License:** [Eclipse Public License v2.0](https://www.eclipse.org/legal/epl-v20.html) @@ -764,14 +764,14 @@ The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Mon Mar 23 19:28:01 WET 2026** using +This report was generated on **Fri Apr 03 16:59:29 WEST 2026** 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). -# Dependencies of `io.spine:spine-base:2.0.0-SNAPSHOT.386` +# Dependencies of `io.spine:spine-base:2.0.0-SNAPSHOT.387` ## Runtime 1. **Group** : com.google.code.findbugs. **Name** : jsr305. **Version** : 3.0.2. @@ -909,11 +909,11 @@ This report was generated on **Mon Mar 23 19:28:01 WET 2026** using * **Project URL:** [https://github.com/google/gson](https://github.com/google/gson) * **License:** [Apache-2.0](https://www.apache.org/licenses/LICENSE-2.0.txt) -1. **Group** : com.google.devtools.ksp. **Name** : symbol-processing. **Version** : 2.3.0. +1. **Group** : com.google.devtools.ksp. **Name** : symbol-processing. **Version** : 2.3.6. * **Project URL:** [https://goo.gle/ksp](https://goo.gle/ksp) * **License:** [The Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) -1. **Group** : com.google.devtools.ksp. **Name** : symbol-processing-api. **Version** : 2.3.0. +1. **Group** : com.google.devtools.ksp. **Name** : symbol-processing-api. **Version** : 2.3.6. * **Project URL:** [https://goo.gle/ksp](https://goo.gle/ksp) * **License:** [The Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) @@ -1533,7 +1533,7 @@ This report was generated on **Mon Mar 23 19:28:01 WET 2026** using * **Project URL:** [http://jspecify.org/](http://jspecify.org/) * **License:** [The Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) -1. **Group** : org.junit. **Name** : junit-bom. **Version** : 6.0.0. +1. **Group** : org.junit. **Name** : junit-bom. **Version** : 6.0.3. * **Project URL:** [https://junit.org/](https://junit.org/) * **License:** [Eclipse Public License v2.0](https://www.eclipse.org/legal/epl-v20.html) @@ -1541,27 +1541,27 @@ This report was generated on **Mon Mar 23 19:28:01 WET 2026** using * **Project URL:** [https://junit-pioneer.org/](https://junit-pioneer.org/) * **License:** [Eclipse Public License v2.0](https://www.eclipse.org/legal/epl-v20.html) -1. **Group** : org.junit.jupiter. **Name** : junit-jupiter-api. **Version** : 6.0.0. +1. **Group** : org.junit.jupiter. **Name** : junit-jupiter-api. **Version** : 6.0.3. * **Project URL:** [https://junit.org/](https://junit.org/) * **License:** [Eclipse Public License v2.0](https://www.eclipse.org/legal/epl-v20.html) -1. **Group** : org.junit.jupiter. **Name** : junit-jupiter-engine. **Version** : 6.0.0. +1. **Group** : org.junit.jupiter. **Name** : junit-jupiter-engine. **Version** : 6.0.3. * **Project URL:** [https://junit.org/](https://junit.org/) * **License:** [Eclipse Public License v2.0](https://www.eclipse.org/legal/epl-v20.html) -1. **Group** : org.junit.jupiter. **Name** : junit-jupiter-params. **Version** : 6.0.0. +1. **Group** : org.junit.jupiter. **Name** : junit-jupiter-params. **Version** : 6.0.3. * **Project URL:** [https://junit.org/](https://junit.org/) * **License:** [Eclipse Public License v2.0](https://www.eclipse.org/legal/epl-v20.html) -1. **Group** : org.junit.platform. **Name** : junit-platform-commons. **Version** : 6.0.0. +1. **Group** : org.junit.platform. **Name** : junit-platform-commons. **Version** : 6.0.3. * **Project URL:** [https://junit.org/](https://junit.org/) * **License:** [Eclipse Public License v2.0](https://www.eclipse.org/legal/epl-v20.html) -1. **Group** : org.junit.platform. **Name** : junit-platform-engine. **Version** : 6.0.0. +1. **Group** : org.junit.platform. **Name** : junit-platform-engine. **Version** : 6.0.3. * **Project URL:** [https://junit.org/](https://junit.org/) * **License:** [Eclipse Public License v2.0](https://www.eclipse.org/legal/epl-v20.html) -1. **Group** : org.junit.platform. **Name** : junit-platform-launcher. **Version** : 6.0.0. +1. **Group** : org.junit.platform. **Name** : junit-platform-launcher. **Version** : 6.0.3. * **Project URL:** [https://junit.org/](https://junit.org/) * **License:** [Eclipse Public License v2.0](https://www.eclipse.org/legal/epl-v20.html) @@ -1616,14 +1616,14 @@ This report was generated on **Mon Mar 23 19:28:01 WET 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Mon Mar 23 19:28:01 WET 2026** using +This report was generated on **Fri Apr 03 16:59:29 WEST 2026** 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). -# Dependencies of `io.spine:spine-environment:2.0.0-SNAPSHOT.386` +# Dependencies of `io.spine:spine-environment:2.0.0-SNAPSHOT.387` ## Runtime 1. **Group** : com.google.code.findbugs. **Name** : jsr305. **Version** : 3.0.2. @@ -2363,7 +2363,7 @@ This report was generated on **Mon Mar 23 19:28:01 WET 2026** using * **Project URL:** [http://jspecify.org/](http://jspecify.org/) * **License:** [The Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) -1. **Group** : org.junit. **Name** : junit-bom. **Version** : 6.0.0. +1. **Group** : org.junit. **Name** : junit-bom. **Version** : 6.0.3. * **Project URL:** [https://junit.org/](https://junit.org/) * **License:** [Eclipse Public License v2.0](https://www.eclipse.org/legal/epl-v20.html) @@ -2371,27 +2371,27 @@ This report was generated on **Mon Mar 23 19:28:01 WET 2026** using * **Project URL:** [https://junit-pioneer.org/](https://junit-pioneer.org/) * **License:** [Eclipse Public License v2.0](https://www.eclipse.org/legal/epl-v20.html) -1. **Group** : org.junit.jupiter. **Name** : junit-jupiter-api. **Version** : 6.0.0. +1. **Group** : org.junit.jupiter. **Name** : junit-jupiter-api. **Version** : 6.0.3. * **Project URL:** [https://junit.org/](https://junit.org/) * **License:** [Eclipse Public License v2.0](https://www.eclipse.org/legal/epl-v20.html) -1. **Group** : org.junit.jupiter. **Name** : junit-jupiter-engine. **Version** : 6.0.0. +1. **Group** : org.junit.jupiter. **Name** : junit-jupiter-engine. **Version** : 6.0.3. * **Project URL:** [https://junit.org/](https://junit.org/) * **License:** [Eclipse Public License v2.0](https://www.eclipse.org/legal/epl-v20.html) -1. **Group** : org.junit.jupiter. **Name** : junit-jupiter-params. **Version** : 6.0.0. +1. **Group** : org.junit.jupiter. **Name** : junit-jupiter-params. **Version** : 6.0.3. * **Project URL:** [https://junit.org/](https://junit.org/) * **License:** [Eclipse Public License v2.0](https://www.eclipse.org/legal/epl-v20.html) -1. **Group** : org.junit.platform. **Name** : junit-platform-commons. **Version** : 6.0.0. +1. **Group** : org.junit.platform. **Name** : junit-platform-commons. **Version** : 6.0.3. * **Project URL:** [https://junit.org/](https://junit.org/) * **License:** [Eclipse Public License v2.0](https://www.eclipse.org/legal/epl-v20.html) -1. **Group** : org.junit.platform. **Name** : junit-platform-engine. **Version** : 6.0.0. +1. **Group** : org.junit.platform. **Name** : junit-platform-engine. **Version** : 6.0.3. * **Project URL:** [https://junit.org/](https://junit.org/) * **License:** [Eclipse Public License v2.0](https://www.eclipse.org/legal/epl-v20.html) -1. **Group** : org.junit.platform. **Name** : junit-platform-launcher. **Version** : 6.0.0. +1. **Group** : org.junit.platform. **Name** : junit-platform-launcher. **Version** : 6.0.3. * **Project URL:** [https://junit.org/](https://junit.org/) * **License:** [Eclipse Public License v2.0](https://www.eclipse.org/legal/epl-v20.html) @@ -2446,14 +2446,14 @@ This report was generated on **Mon Mar 23 19:28:01 WET 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Mon Mar 23 19:28:02 WET 2026** using +This report was generated on **Fri Apr 03 16:59:29 WEST 2026** 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). -# Dependencies of `io.spine:spine-format:2.0.0-SNAPSHOT.386` +# Dependencies of `io.spine:spine-format:2.0.0-SNAPSHOT.387` ## Runtime 1. **Group** : com.fasterxml.jackson. **Name** : jackson-bom. **Version** : 2.20.0. @@ -3269,7 +3269,7 @@ This report was generated on **Mon Mar 23 19:28:02 WET 2026** using * **Project URL:** [http://jspecify.org/](http://jspecify.org/) * **License:** [The Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt) -1. **Group** : org.junit. **Name** : junit-bom. **Version** : 6.0.0. +1. **Group** : org.junit. **Name** : junit-bom. **Version** : 6.0.3. * **Project URL:** [https://junit.org/](https://junit.org/) * **License:** [Eclipse Public License v2.0](https://www.eclipse.org/legal/epl-v20.html) @@ -3277,27 +3277,27 @@ This report was generated on **Mon Mar 23 19:28:02 WET 2026** using * **Project URL:** [https://junit-pioneer.org/](https://junit-pioneer.org/) * **License:** [Eclipse Public License v2.0](https://www.eclipse.org/legal/epl-v20.html) -1. **Group** : org.junit.jupiter. **Name** : junit-jupiter-api. **Version** : 6.0.0. +1. **Group** : org.junit.jupiter. **Name** : junit-jupiter-api. **Version** : 6.0.3. * **Project URL:** [https://junit.org/](https://junit.org/) * **License:** [Eclipse Public License v2.0](https://www.eclipse.org/legal/epl-v20.html) -1. **Group** : org.junit.jupiter. **Name** : junit-jupiter-engine. **Version** : 6.0.0. +1. **Group** : org.junit.jupiter. **Name** : junit-jupiter-engine. **Version** : 6.0.3. * **Project URL:** [https://junit.org/](https://junit.org/) * **License:** [Eclipse Public License v2.0](https://www.eclipse.org/legal/epl-v20.html) -1. **Group** : org.junit.jupiter. **Name** : junit-jupiter-params. **Version** : 6.0.0. +1. **Group** : org.junit.jupiter. **Name** : junit-jupiter-params. **Version** : 6.0.3. * **Project URL:** [https://junit.org/](https://junit.org/) * **License:** [Eclipse Public License v2.0](https://www.eclipse.org/legal/epl-v20.html) -1. **Group** : org.junit.platform. **Name** : junit-platform-commons. **Version** : 6.0.0. +1. **Group** : org.junit.platform. **Name** : junit-platform-commons. **Version** : 6.0.3. * **Project URL:** [https://junit.org/](https://junit.org/) * **License:** [Eclipse Public License v2.0](https://www.eclipse.org/legal/epl-v20.html) -1. **Group** : org.junit.platform. **Name** : junit-platform-engine. **Version** : 6.0.0. +1. **Group** : org.junit.platform. **Name** : junit-platform-engine. **Version** : 6.0.3. * **Project URL:** [https://junit.org/](https://junit.org/) * **License:** [Eclipse Public License v2.0](https://www.eclipse.org/legal/epl-v20.html) -1. **Group** : org.junit.platform. **Name** : junit-platform-launcher. **Version** : 6.0.0. +1. **Group** : org.junit.platform. **Name** : junit-platform-launcher. **Version** : 6.0.3. * **Project URL:** [https://junit.org/](https://junit.org/) * **License:** [Eclipse Public License v2.0](https://www.eclipse.org/legal/epl-v20.html) @@ -3356,6 +3356,6 @@ This report was generated on **Mon Mar 23 19:28:02 WET 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Mon Mar 23 19:28:01 WET 2026** using +This report was generated on **Fri Apr 03 16:59:29 WEST 2026** 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/gradle.properties b/gradle.properties index 93bcb6923a..49ad30c59b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -9,7 +9,7 @@ org.gradle.parallel=true #org.gradle.caching=true # Dokka plugin eats more memory than usual. Therefore, all builds should have enough. -org.gradle.jvmargs=-Xmx4096m -XX:MaxMetaspaceSize=1024m -XX:+UseParallelGC +org.gradle.jvmargs=-Xmx4096m -XX:MaxMetaspaceSize=1024m -XX:+UseParallelGC -Dfile.encoding=UTF-8 # suppress inspection "UnusedProperty" # The below property enables generation of XML reports for tests. diff --git a/pom.xml b/pom.xml index d3dee4449b..4927f6f70e 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ all modules and does not describe the project structure per-subproject. --> io.spine base-libraries -2.0.0-SNAPSHOT.386 +2.0.0-SNAPSHOT.387 2015 @@ -164,7 +164,7 @@ all modules and does not describe the project structure per-subproject. org.junit junit-bom - 6.0.0 + 6.0.3 test @@ -176,19 +176,19 @@ all modules and does not describe the project structure per-subproject. org.junit.jupiter junit-jupiter-api - 6.0.0 + 6.0.3 test org.junit.jupiter junit-jupiter-engine - 6.0.0 + 6.0.3 test org.junit.jupiter junit-jupiter-params - 6.0.0 + 6.0.3 test @@ -200,12 +200,12 @@ all modules and does not describe the project structure per-subproject. com.google.devtools.ksp symbol-processing - 2.3.0 + 2.3.6 com.google.devtools.ksp symbol-processing-api - 2.3.0 + 2.3.6 com.google.errorprone diff --git a/version.gradle.kts b/version.gradle.kts index b1478b8ba9..6c1deba47d 100644 --- a/version.gradle.kts +++ b/version.gradle.kts @@ -24,4 +24,4 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -val versionToPublish: String by extra("2.0.0-SNAPSHOT.386") +val versionToPublish: String by extra("2.0.0-SNAPSHOT.387")