Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ plugins {
}

spinePublishing {
artifactPrefix = "spine-validation-"
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Avoid double spine prefix for jvm-runtime publication

Setting the root artifactPrefix to spine-validation- causes jvm-runtime to generate a doubled artifact ID because jvm-runtime/build.gradle.kts already does artifactId = "$defaultPrefix$projectPrefix${project.name}" with defaultPrefix = "spine-"; this now resolves to spine-spine-validation-jvm-runtime. That will publish runtime under an unexpected coordinate and break consumers expecting spine-validation-jvm-runtime.

Useful? React with 👍 / 👎.

toolArtifactPrefix = "validation-"
modules = setOf(
"context",
"java",
Expand All @@ -96,7 +98,6 @@ spinePublishing {
cloudArtifactRegistry
)
}
artifactPrefix = "validation-"
}

allprojects {
Expand Down
17 changes: 16 additions & 1 deletion buildSrc/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,20 @@ val koverVersion = "0.9.1"
*/
val shadowVersion = "9.2.2"

/**
* The version of JUnit used to test the build scripts.
*
* @see [io.spine.dependency.test.JUnit]
*/
val junitVersion = "6.0.3"

/**
* The version of Kotest used to test the build scripts.
*
* @see [io.spine.dependency.test.Kotest]
*/
val kotestVersion = "6.1.10"

configurations.all {
resolutionStrategy {
force(
Expand Down Expand Up @@ -193,8 +207,9 @@ dependencies {
implementation(it)
}

testImplementation(platform("org.junit:junit-bom:5.11.4"))
testImplementation(platform("org.junit:junit-bom:$junitVersion"))
testImplementation("org.junit.jupiter:junit-jupiter")
testImplementation("io.kotest:kotest-assertions-core:$kotestVersion")
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
}

Expand Down
4 changes: 2 additions & 2 deletions buildSrc/src/main/kotlin/io/spine/dependency/local/Base.kt
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ package io.spine.dependency.local
*/
@Suppress("ConstPropertyName", "unused")
object Base {
const val version = "2.0.0-SNAPSHOT.386"
const val versionForBuildScript = "2.0.0-SNAPSHOT.386"
const val version = "2.0.0-SNAPSHOT.387"
const val versionForBuildScript = "2.0.0-SNAPSHOT.387"
const val group = Spine.group
private const val prefix = "spine"
const val libModule = "$prefix-base"
Expand Down
45 changes: 35 additions & 10 deletions buildSrc/src/main/kotlin/io/spine/dependency/local/Time.kt
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -26,18 +26,43 @@

package io.spine.dependency.local

import io.spine.dependency.Dependency

/**
* Spine Time library.
*
* @see <a href="https://github.com/SpineEventEngine/time">spine-time</a>
*/
@Suppress("ConstPropertyName")
object Time {
const val version = "2.0.0-SNAPSHOT.232"
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.235"
private const val infix = "spine-time"

fun lib(version: String): String = "$group:$infix:$version"
val lib get() = lib(version)
const val libArtifact: String = infix

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"
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

testLib() uses the artifact time-testlib, which is inconsistent with the infix (spine-time) and with the established naming pattern for other *-testlib artifacts in this repo (e.g. spine-logging-testlib, spine-core-testlib). This looks like a wrong Maven coordinate and may lead to unresolved dependencies; consider deriving it from infix (e.g. spine-time-testlib) to keep it consistent.

Suggested change
fun testLib(version: String): String = "${Spine.toolsGroup}:time-testlib:$version"
fun testLib(version: String): String = "${Spine.toolsGroup}:${infix}-testlib:$version"

Copilot uses AI. Check for mistakes.
val testLib get() = testLib(version)

override val modules: List<String>
get() = listOf(
lib,
javaExtensions,
kotlinExtensions,
testLib
).map {
it.split(":").let { (g, artifact) -> "$g:$artifact" }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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.375"
const val dogfoodingVersion = "2.0.0-SNAPSHOT.375"
const val version = "2.0.0-SNAPSHOT.376"
const val dogfoodingVersion = "2.0.0-SNAPSHOT.376"

const val lib = "$group:tool-base:$version"
const val classicCodegen = "$group:classic-codegen:$version"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ object Validation {
/**
* The version of the Validation library artifacts.
*/
const val version = "2.0.0-SNAPSHOT.408"
const val version = "2.0.0-SNAPSHOT.409"

/**
* The last version of Validation compatible with ProtoData.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ package io.spine.dependency.test
*/
@Suppress("unused", "ConstPropertyName")
object Kotest {
const val version = "6.0.4"
const val version = "6.1.10"
const val group = "io.kotest"
const val gradlePluginId = "io.kotest"
const val assertions = "$group:kotest-assertions-core:$version"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,12 @@ abstract class UpdatePluginVersion : DefaultTask() {
}
}

@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()
val pluginId = Regex.escape(id)
// Regex to match: id("pluginId") version "version-number"
val regex = """id\("$pluginId"\)\s+version\s+"([^"]+)"""".toRegex()

if (regex.containsMatchIn(content)) {
val updatedContent = regex.replace(content) {
Expand Down
Original file line number Diff line number Diff line change
@@ -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.
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -145,16 +146,18 @@ import org.gradle.kotlin.dsl.findByType
* @see [artifacts]
* @see SpinePublishing
*/
fun Project.spinePublishing(block: SpinePublishing.() -> Unit) {
fun Project.spinePublishing(block: SpinePublishing.() -> Unit): SpinePublishing {
apply<MavenPublishPlugin>()
val name = SpinePublishing::class.java.simpleName
.replaceFirstChar { it.lowercase(Locale.getDefault()) }
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using Locale.getDefault() when deriving the Gradle extension name can produce different names on machines with different default locales (e.g., Turkish locale casing), which may break Kotlin DSL accessors and reduce build reproducibility. Consider using a locale-invariant option such as Locale.ROOT when lowercasing the first character.

Suggested change
.replaceFirstChar { it.lowercase(Locale.getDefault()) }
.replaceFirstChar { it.lowercase(Locale.ROOT) }

Copilot uses AI. Check for mistakes.
val extension = with(extensions) {
findByType<SpinePublishing>() ?: create(name, project)
}
extension.run {
block()
configured()
}
return extension
}

/**
Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -250,10 +259,23 @@ open class SpinePublishing(private val project: Project) {
lateinit var destinations: Set<Repository>

/**
* 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 = ""
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Apply toolArtifactPrefix when computing published artifact IDs

This adds toolArtifactPrefix, but the publication path still ignores it: PublicationHandler.copyProjectAttributes() continues to prepend project.spinePublishing.artifactPrefix for every module, and nothing calls SpinePublishing.artifactId(project). In a mixed project, tool modules (group == io.spine.tools) will still be published as spine-validation-* even when toolArtifactPrefix = "validation-", which breaks expected coordinates (for example, pom.xml still references io.spine.tools:validation-java-bundle).

Useful? React with 👍 / 👎.


/**
* Allows enabling publishing of [testJar] artifact, containing compilation output
* of "test" source set.
Expand Down Expand Up @@ -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]:
* `<artifactPrefix><project.name>`.
* @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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,15 @@

package io.spine.gradle.docs

import io.kotest.matchers.string.shouldContain
import java.io.File
import org.gradle.testfixtures.ProjectBuilder
import org.junit.jupiter.api.Assertions.assertTrue
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.DisplayName
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.io.TempDir

@DisplayName("`UpdatePluginVersion` should")
class UpdatePluginVersionTest {

@TempDir
Expand Down Expand Up @@ -64,8 +66,8 @@ class UpdatePluginVersionTest {
task.get().update()

val updatedContent = buildFile.readText()
assertTrue(updatedContent.contains("""id("io.spine.validation") version "2.0.0-TEST""""))
assertTrue(updatedContent.contains("""id("other-plugin") version "0.1.0""""))
updatedContent shouldContain """id("io.spine.validation") version "2.0.0-TEST""""
updatedContent shouldContain """id("other-plugin") version "0.1.0""""
}

@Test
Expand All @@ -90,8 +92,8 @@ class UpdatePluginVersionTest {
task.get().update()

val updatedContent = buildFile.readText()
assertTrue(updatedContent.contains("""kotlin("jvm") version "2.2.21"""))
assertTrue(updatedContent.contains("""id("io.spine.validation") version "2.0.0-TEST"""))
updatedContent shouldContain """kotlin("jvm") version "2.2.21""""
updatedContent shouldContain """id("io.spine.validation") version "2.0.0-TEST""""
}

@Test
Expand All @@ -112,6 +114,6 @@ class UpdatePluginVersionTest {
task.get().update()

val updatedContent = buildFile.readText()
assertTrue(updatedContent.contains("""id("io.spine.validation") version "2.0.0-TEST""""))
updatedContent shouldContain """id("io.spine.validation") version "2.0.0-TEST""""
}
}
Loading
Loading