Skip to content

Commit c43d86b

Browse files
Merge pull request #261 from SpineEventEngine/docs-set-1
Add initial Validation library documentation with Hugo preview infrastructure
2 parents 7ba0c12 + 0d2d0ae commit c43d86b

80 files changed

Lines changed: 4680 additions & 315 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
name: Check Code Embedding
2+
3+
on:
4+
pull_request:
5+
6+
jobs:
7+
build-embedded-code:
8+
runs-on: ubuntu-latest
9+
steps:
10+
- uses: actions/checkout@v5
11+
with:
12+
submodules: 'recursive'
13+
14+
- uses: actions/setup-java@v5
15+
with:
16+
java-version: 17
17+
distribution: zulu
18+
19+
- run: ./gradlew :docs:buildAll
20+
21+
check-embedded-samples:
22+
runs-on: ubuntu-latest
23+
steps:
24+
- uses: actions/checkout@v5
25+
with:
26+
submodules: 'recursive'
27+
28+
- uses: actions/setup-java@v5
29+
with:
30+
java-version: 17
31+
distribution: zulu
32+
33+
- name: Check Embedding
34+
run: ./gradlew :docs:checkSamples

.idea/inspectionProfiles/Project_Default.xml

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

buildSrc/build.gradle.kts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,14 @@ dependencies {
192192
).forEach {
193193
implementation(it)
194194
}
195+
196+
testImplementation(platform("org.junit:junit-bom:5.11.4"))
197+
testImplementation("org.junit.jupiter:junit-jupiter")
198+
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
199+
}
200+
201+
tasks.test {
202+
useJUnitPlatform()
195203
}
196204

197205
dependOnBuildSrcJar()

buildSrc/src/main/kotlin/BuildSettings.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,8 @@ object BuildSettings {
3939
val javaVersionCompat = JavaVersion.toVersion(JVM_VERSION)
4040
val jvmTarget = JvmTarget.JVM_17
4141
const val REMOTE_DEBUG_PORT = 5566
42+
/**
43+
* Default timeout (in minutes) for long-running Gradle tasks in CI.
44+
*/
45+
const val TIMEOUT_MINUTES = 42L
4246
}

buildSrc/src/main/kotlin/io/spine/dependency/local/CoreJvmCompiler.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,12 @@ object CoreJvmCompiler {
4646
/**
4747
* The version used to in the build classpath.
4848
*/
49-
const val dogfoodingVersion = "2.0.0-SNAPSHOT.050"
49+
const val dogfoodingVersion = "2.0.0-SNAPSHOT.052"
5050

5151
/**
5252
* The version to be used for integration tests.
5353
*/
54-
const val version = "2.0.0-SNAPSHOT.050"
54+
const val version = "2.0.0-SNAPSHOT.052"
5555

5656
/**
5757
* The ID of the Gradle plugin.

buildSrc/src/main/kotlin/io/spine/dependency/local/Validation.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ object Validation {
3636
/**
3737
* The version of the Validation library artifacts.
3838
*/
39-
const val version = "2.0.0-SNAPSHOT.392"
39+
const val version = "2.0.0-SNAPSHOT.393"
4040

4141
/**
4242
* The last version of Validation compatible with ProtoData.

buildSrc/src/main/kotlin/io/spine/gradle/RunGradle.kt

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -171,13 +171,17 @@ open class RunGradle : DefaultTask() {
171171
return if (runsOnWindows) "gradlew.bat" else "gradlew"
172172
}
173173

174-
private fun startProcess(command: List<String>, errorOut: File, debugOut: File) =
175-
ProcessBuilder()
174+
private fun startProcess(command: List<String>, errorOut: File, debugOut: File): Process {
175+
val workingDir = project.file(directory)
176+
val builder = ProcessBuilder()
176177
.command(command)
177-
.directory(project.file(directory))
178+
.directory(workingDir)
178179
.redirectError(errorOut)
179180
.redirectOutput(debugOut)
180-
.start()
181+
System.err.println("[RunGradle] Running the command: '${command.joinToString(" ")}'." +
182+
" Directory: '${workingDir.absolutePath}'.")
183+
return builder.start()
184+
}
181185
}
182186

183187
private fun File.truncate() {
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
/*
2+
* Copyright 2026, TeamDev. All rights reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Redistribution and use in source and/or binary forms, with or without
11+
* modification, must retain the above copyright notice and the following
12+
* disclaimer.
13+
*
14+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
15+
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
16+
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
17+
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
18+
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
19+
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
20+
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21+
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22+
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25+
*/
26+
27+
package io.spine.gradle.docs
28+
29+
import java.io.File
30+
import org.gradle.api.DefaultTask
31+
import org.gradle.api.file.DirectoryProperty
32+
import org.gradle.api.provider.Property
33+
import org.gradle.api.tasks.Input
34+
import org.gradle.api.tasks.InputDirectory
35+
import org.gradle.api.tasks.Optional
36+
import org.gradle.api.tasks.TaskAction
37+
38+
/**
39+
* Updates the version of a Gradle plugin in `build.gradle.kts` files.
40+
*
41+
* The task searches for plugin declarations in the format
42+
* `id("plugin-id") version "version-number"` and replaces
43+
* the version number with the one found in the version script file.
44+
*
45+
* @property directory
46+
* The directory to scan recursively for `build.gradle.kts` files.
47+
* @property version
48+
* The version number to set for the plugin.
49+
* @property pluginId
50+
* The ID of the plugin whose version should be updated.
51+
* @property kotlinVersion
52+
* Optional. If set, updates the version of the Kotlin plugin declared with
53+
* `kotlin("…") version "…"` syntax in the `plugins` block.
54+
* This option works in combination with the [version] and [pluginId] properties.
55+
*/
56+
abstract class UpdatePluginVersion : DefaultTask() {
57+
58+
@get:InputDirectory
59+
abstract val directory: DirectoryProperty
60+
61+
@get:Input
62+
abstract val version: Property<String>
63+
64+
@get:Input
65+
abstract val pluginId: Property<String>
66+
67+
@get:Input
68+
@get:Optional
69+
abstract val kotlinVersion: Property<String>
70+
71+
/**
72+
* Updates plugin versions in build files within the path in the [directory].
73+
*/
74+
@TaskAction
75+
fun update() {
76+
val rootDir = directory.get().asFile
77+
78+
val kotlinVersionSet = kotlinVersion.isPresent
79+
val kotlinVer = kotlinVersion.orNull
80+
val id = pluginId.get()
81+
val ver = version.get()
82+
83+
rootDir.walkTopDown()
84+
.filter { it.name == "build.gradle.kts" }
85+
.forEach { file ->
86+
if (kotlinVersionSet && kotlinVer != null) {
87+
updateKotlinPluginVersion(file, kotlinVer)
88+
}
89+
updatePluginVersion(file, id, ver)
90+
}
91+
}
92+
93+
private fun updatePluginVersion(file: File, id: String, version: String) {
94+
val content = file.readText()
95+
// Regex to match: id("plugin-id") version "version-number"
96+
val regex = """id\("$id"\)\s+version\s+"([^"]+)"""".toRegex()
97+
98+
if (regex.containsMatchIn(content)) {
99+
val updatedContent = regex.replace(content) {
100+
"id(\"$id\") version \"$version\""
101+
}
102+
if (content != updatedContent) {
103+
file.writeText(updatedContent)
104+
logger.info("Updated version of '$id' in `${file.absolutePath}`.")
105+
}
106+
}
107+
}
108+
109+
private fun updateKotlinPluginVersion(file: File, kotlinVersion: String) {
110+
val content = file.readText()
111+
// Regex to match Kotlin plugin declarations like: kotlin("jvm") version "1.9.0"
112+
val regex = """kotlin\("([^"]+)"\)\s+version\s+"([^"]+)"""".toRegex()
113+
if (regex.containsMatchIn(content)) {
114+
val updatedContent = regex.replace(content) { matchResult ->
115+
val plugin = matchResult.groupValues[1]
116+
"kotlin(\"$plugin\") version \"$kotlinVersion\""
117+
}
118+
if (content != updatedContent) {
119+
file.writeText(updatedContent)
120+
logger.info("Updated Kotlin plugin version in `${file.absolutePath}`.")
121+
}
122+
}
123+
}
124+
}
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
/*
2+
* Copyright 2026, TeamDev. All rights reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Redistribution and use in source and/or binary forms, with or without
11+
* modification, must retain the above copyright notice and the following
12+
* disclaimer.
13+
*
14+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
15+
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
16+
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
17+
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
18+
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
19+
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
20+
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21+
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22+
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25+
*/
26+
27+
package io.spine.gradle.docs
28+
29+
import java.io.File
30+
import org.gradle.testfixtures.ProjectBuilder
31+
import org.junit.jupiter.api.Assertions.assertTrue
32+
import org.junit.jupiter.api.BeforeEach
33+
import org.junit.jupiter.api.Test
34+
import org.junit.jupiter.api.io.TempDir
35+
36+
class UpdatePluginVersionTest {
37+
38+
@TempDir
39+
lateinit var tempDir: File
40+
41+
private lateinit var buildFile: File
42+
43+
@BeforeEach
44+
fun setUp() {
45+
val subDir = File(tempDir, "subproject")
46+
subDir.mkdir()
47+
buildFile = File(subDir, "build.gradle.kts")
48+
buildFile.writeText("""
49+
plugins {
50+
id("io.spine.validation") version "1.0.0"
51+
id("other-plugin") version "0.1.0"
52+
}
53+
""".trimIndent())
54+
}
55+
56+
@Test
57+
fun `update plugin version in build file`() {
58+
val project = ProjectBuilder.builder().build()
59+
val task = project.tasks.register("updatePluginVersion", UpdatePluginVersion::class.java) {
60+
directory.set(tempDir)
61+
version.set("2.0.0-TEST")
62+
pluginId.set("io.spine.validation")
63+
}
64+
task.get().update()
65+
66+
val updatedContent = buildFile.readText()
67+
assertTrue(updatedContent.contains("""id("io.spine.validation") version "2.0.0-TEST""""))
68+
assertTrue(updatedContent.contains("""id("other-plugin") version "0.1.0""""))
69+
}
70+
71+
@Test
72+
fun `update 'kotlin' plugin version when 'kotlinVersion' is set`() {
73+
// Overwrite with a file that uses kotlin("jvm") syntax
74+
buildFile.writeText(
75+
"""
76+
plugins {
77+
kotlin("jvm") version "1.9.10"
78+
id("io.spine.validation") version "1.0.0"
79+
}
80+
""".trimIndent()
81+
)
82+
83+
val project = ProjectBuilder.builder().build()
84+
val task = project.tasks.register("updatePluginVersion", UpdatePluginVersion::class.java) {
85+
directory.set(tempDir)
86+
version.set("2.0.0-TEST")
87+
pluginId.set("io.spine.validation")
88+
kotlinVersion.set("2.2.21")
89+
}
90+
task.get().update()
91+
92+
val updatedContent = buildFile.readText()
93+
assertTrue(updatedContent.contains("""kotlin("jvm") version "2.2.21"""))
94+
assertTrue(updatedContent.contains("""id("io.spine.validation") version "2.0.0-TEST"""))
95+
}
96+
97+
@Test
98+
fun `handle multiple spaces between id and version`() {
99+
buildFile.writeText("""
100+
plugins {
101+
id("io.spine.validation") version "1.0.0"
102+
}
103+
""".trimIndent())
104+
105+
val project = ProjectBuilder.builder().build()
106+
val task = project.tasks.register("updatePluginVersion", UpdatePluginVersion::class.java) {
107+
directory.set(tempDir)
108+
version.set("2.0.0-TEST")
109+
pluginId.set("io.spine.validation")
110+
}
111+
112+
task.get().update()
113+
114+
val updatedContent = buildFile.readText()
115+
assertTrue(updatedContent.contains("""id("io.spine.validation") version "2.0.0-TEST""""))
116+
}
117+
}

0 commit comments

Comments
 (0)