Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
713ae14
Rename ProtoData to Spine Compiler
alexander-yevsyukov Nov 27, 2025
d28b64a
Bump version -> `2.0.0-SNAPSHOT.355`
alexander-yevsyukov Nov 27, 2025
998b59f
Fix references, add Kotlin example
alexander-yevsyukov Nov 27, 2025
a7efa88
Add initial doc sections
alexander-yevsyukov Nov 27, 2025
d8e8193
Add Getting Started intro
alexander-yevsyukov Nov 27, 2025
e16c674
Move doc pieces out of `README`
alexander-yevsyukov Nov 27, 2025
e230579
Update `config` and local dependencies
alexander-yevsyukov Nov 27, 2025
1de40e7
`TEMPORARILY_DISABLE_PROTOBUF_VERSION_CHECK`
alexander-yevsyukov Nov 28, 2025
bbcb9d2
Bump dependencies
alexander-yevsyukov Nov 28, 2025
c66fda5
Remove Kotest Multiplatform Gradle Plugin
alexander-yevsyukov Nov 28, 2025
a6b989b
Rollback Protobuf -> `4.33.0`
alexander-yevsyukov Nov 28, 2025
46034f8
Bump CoreJvm Compiler -> `2.0.0-SNAPSHOT.030`
alexander-yevsyukov Nov 28, 2025
3df1e15
Force versions of dependencies
alexander-yevsyukov Nov 28, 2025
674df75
Update `config` ref.
alexander-yevsyukov Nov 28, 2025
ccdfd0c
Bump Base and CoreJvm Compiler
alexander-yevsyukov Dec 2, 2025
e21ff29
Add `org.gradle.debug` property
alexander-yevsyukov Dec 2, 2025
d7325b3
Bump local dependencies
alexander-yevsyukov Dec 2, 2025
6903947
Rollback Compiler -> `2.0.0-SNAPSHOT.030`
alexander-yevsyukov Dec 2, 2025
48f3556
Use `io.spine.descriptor-set-file` plugin
alexander-yevsyukov Dec 3, 2025
63e2028
Rollback CoreJvm -> `2.0.0-SNAPSHOT.346`
alexander-yevsyukov Dec 3, 2025
049ca1f
Merge only existing files
alexander-yevsyukov Dec 3, 2025
3bcbdc6
Bump Protobuf -> `4.33.1`
alexander-yevsyukov Dec 3, 2025
d94de52
Update dependency reports
alexander-yevsyukov Dec 3, 2025
8023c58
Fix `REPO_SLUG` value
alexander-yevsyukov Dec 3, 2025
7133829
Bump CoreJvm Compiler -> `2.0.0-SNAPSHOT.034`
alexander-yevsyukov Dec 3, 2025
f1ce3bf
Update dependency reports
alexander-yevsyukov Dec 3, 2025
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
Binary file modified .github/readme/high_level_overview.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified .github/readme/typical_custom_option.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,6 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
FORMAL_GIT_HUB_PAGES_AUTHOR: [email protected]
# https://docs.github.com/en/actions/reference/environment-variables
REPO_SLUG: $GITHUB_REPOSITORY # e.g. SpineEventEngine/core-java
REPO_SLUG: ${{ github.repository }} # e.g. SpineEventEngine/core-jvm
GOOGLE_APPLICATION_CREDENTIALS: ./maven-publisher.json
NPM_TOKEN: ${{ secrets.NPM_SECRET }}
39 changes: 10 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,13 @@ At build time, Spine Validation injects assertions into the generated Java class
```java
var card = CardNumber.newBuilder()
.setDigits("invalid")
.build(); <- Validates here.
.build(); // <- Validates here.
```

```kotlin
val card = cardNumber {
digits = "invalid"
} // <- Validates here.
```

If any constraint is violated, a `ValidationException` is thrown from `build()`.
Expand All @@ -65,7 +71,7 @@ You can also validate without throwing:
```java
var card = CardNumber.newBuilder()
.setDigits("invalid")
.buildPartial(); <- No validation.
.buildPartial(); // <- No validation.
var optionalError = card.validate();
optionalError.ifPresent(err -> {
System.out.println(err.getMessage());
Expand All @@ -76,7 +82,7 @@ optionalError.ifPresent(err -> {

Validation options are defined by the following files:

1. [options.proto](https://github.com/SpineEventEngine/base/blob/master/base/src/main/proto/spine/options.proto).
1. [options.proto](https://github.com/SpineEventEngine/base-libraries/blob/master/base/src/main/proto/spine/options.proto).
2. [time_options.proto](https://github.com/SpineEventEngine/time/blob/master/time/src/main/proto/spine/time_options.proto).

Users must import these .proto files to use the options they define.
Expand All @@ -86,32 +92,7 @@ import "spine/options.proto"; // Brings all options, except for time-related one
import "spine/time_options.proto"; // Brings time-related options.
```

## Architecture

The library is a set of plugins for [ProtoData](https://github.com/SpineEventEngine/ProtoData).

Each target language is a separate ProtoData plugin.

Take a look at the following diagram to grasp a high-level library structure:

![High-level library structure overview](.github/readme/high_level_overview.png)

The workflow is the following:

- (1), (2) – user defines Protobuf messages with validation options.
- (3) – Protobuf compiler generates Java classes.
- (4), (5) – policies and views build the validation model.
- (6), (7) – Java plugin generates and injects validation code.

### Key Modules

| Module | Description |
|-----------|----------------------------------------------------------------------|
| :model | The language-agnostic model for the built-in options. |
| :java | Generates and injects Java validation code based on applied options. |
| :java-api | Extension API for custom options in Java. |

# Extending the Library
# Adding custom validation

Users can extend the library by providing custom Protobuf options and code generation logic.

Expand Down
33 changes: 19 additions & 14 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,14 @@

@file:Suppress("RemoveRedundantQualifierName") // To prevent IDEA replacing FQN imports.

import io.spine.dependency.lib.Grpc
import io.spine.dependency.lib.KotlinPoet
import io.spine.dependency.lib.Roaster
import io.spine.dependency.local.Base
import io.spine.dependency.local.Compiler
import io.spine.dependency.local.CoreJava
import io.spine.dependency.local.Logging
import io.spine.dependency.local.Compiler
import io.spine.dependency.local.Spine
import io.spine.dependency.local.Time
import io.spine.dependency.local.ToolBase
import io.spine.gradle.publish.PublishingRepos
import io.spine.gradle.publish.spinePublishing
Expand All @@ -58,6 +59,11 @@ buildscript {

// Make sure we have the right Protobuf Runtime by adding it explicitly.
classpath(io.spine.dependency.lib.Protobuf.javaLib)

// For `io.spine.generated-sources` plugin.
classpath(io.spine.dependency.local.ToolBase.protobufSetupPlugins)

classpath(io.spine.dependency.kotlinx.DateTime.lib)
}
}

Expand Down Expand Up @@ -88,11 +94,6 @@ spinePublishing {
)
}
artifactPrefix = "spine-validation-"

dokkaJar {
java = true
kotlin = true
}
}

allprojects {
Expand All @@ -108,20 +109,24 @@ allprojects {
resolutionStrategy {
@Suppress("DEPRECATION") // `Kotlin.stdLibJdk7` is a transitive dependency.
force(
Roaster.api,
Roaster.jdt,
Base.lib,
Compiler.api,
Compiler.params,
Compiler.pluginLib,
Compiler.backend,
Compiler.gradleApi,
Compiler.jvm,
Base.lib,
Logging.lib,
Compiler.params,
Compiler.pluginLib,
CoreJava.client,
CoreJava.server,
Grpc.bom,
KotlinPoet.lib,
Logging.lib,
Roaster.api,
Roaster.jdt,
Time.lib,
Time.javaExtensions,
ToolBase.lib,
ToolBase.pluginBase,
KotlinPoet.lib,
)
}
}
Expand Down
14 changes: 4 additions & 10 deletions buildSrc/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ plugins {
`kotlin-dsl`

// https://github.com/jk1/Gradle-License-Report/releases
id("com.github.jk1.dependency-license-report").version("2.7")
id("com.github.jk1.dependency-license-report").version("2.9")
}

repositories {
Expand All @@ -65,7 +65,7 @@ val jacksonVersion = "2.18.3"
*/
val googleAuthToolVersion = "2.1.5"

val licenseReportVersion = "2.9"
val licenseReportVersion = "2.7"

val grGitVersion = "4.1.1"

Expand All @@ -75,7 +75,7 @@ val grGitVersion = "4.1.1"
* This version may change from the [version of Kotlin][io.spine.dependency.lib.Kotlin.version]
* used by the project.
*/
val kotlinEmbeddedVersion = "2.2.20"
val kotlinEmbeddedVersion = "2.2.21"

/**
* The version of Guava used in `buildSrc`.
Expand Down Expand Up @@ -113,7 +113,7 @@ val protobufPluginVersion = "0.9.5"
* @see <a href="https://github.com/Kotlin/dokka/releases">
* Dokka Releases</a>
*/
val dokkaVersion = "2.0.0"
val dokkaVersion = "2.1.0"

/**
* The version of Detekt Gradle Plugin.
Expand All @@ -127,11 +127,6 @@ val detektVersion = "1.23.8"
*/
val kotestJvmPluginVersion = "0.4.10"

/**
* @see [io.spine.dependency.test.Kotest.MultiplatformGradlePlugin]
*/
val kotestMultiplatformPluginVersion = "5.9.1"

/**
* @see [io.spine.dependency.test.Kover]
*/
Expand Down Expand Up @@ -185,7 +180,6 @@ dependencies {
"com.gradleup.shadow:shadow-gradle-plugin:$shadowVersion",
"io.gitlab.arturbosch.detekt:detekt-gradle-plugin:$detektVersion",
"io.kotest:kotest-gradle-plugin:$kotestJvmPluginVersion",
"io.kotest:kotest-framework-multiplatform-plugin-gradle:$kotestMultiplatformPluginVersion",
// https://github.com/srikanth-lingala/zip4j
"net.lingala.zip4j:zip4j:2.10.0",
"net.ltgt.gradle:gradle-errorprone-plugin:$errorPronePluginVersion",
Expand Down
27 changes: 9 additions & 18 deletions buildSrc/src/main/kotlin/BuildExtensions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -156,15 +156,15 @@ 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)
get() = Kotest.let {
return id(it.gradlePluginId).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)
get() = id(Ksp.id).version(Ksp.dogfoodingVersion)

val PluginDependenciesSpec.`plugin-publish`: PluginDependencySpec
get() = id(PluginPublishPlugin.id).version(PluginPublishPlugin.version)
Expand Down Expand Up @@ -199,43 +199,34 @@ fun Project.configureTaskDependencies() {
}

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 {
val dokkaGenerate = "dokkaGenerate"
dokkaGenerate.run {
dependOn(generateProto)
dependOn(launchProtoData)
dependOn(kspKotlin)
}
val dokkaJavadoc = "dokkaJavadoc"
dokkaJavadoc.run {
dependOn(launchProtoData)
dependOn(kspKotlin)
}
val dokkaGeneratePublicationJavadoc = "dokkaGeneratePublicationJavadoc"
dokkaGeneratePublicationJavadoc.dependOn(kspKotlin)
"publishPluginJar".dependOn(createVersionFile)
compileKotlin.dependOn(kspKotlin)
compileTestKotlin.dependOn("kspTestKotlin")
"compileTestFixturesKotlin".dependOn("kspTestFixturesKotlin")
"javadocJar".dependOn(dokkaHtml)
"dokkaKotlinJar".dependOn(dokkaJavadoc)
"javadocJar".dependOn(dokkaGeneratePublicationJavadoc)
"htmlDocsJar".dependOn(dokkaGenerate)
}
}

Expand Down
40 changes: 38 additions & 2 deletions buildSrc/src/main/kotlin/DocumentationSettings.kt
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

import org.gradle.api.Project

/**
* The documentation settings specific to this project.
*
Expand All @@ -33,6 +35,36 @@
@Suppress("ConstPropertyName")
object DocumentationSettings {

/**
* The organization infix for the Spine SDK.
*/
private const val orgPath = "github.com/SpineEventEngine"

/**
* The organization URL of the Spine SDK.
*/
private const val orgUrl = "https://$orgPath"

/**
* Obtains the repository URL for the given project.
*/
fun repoUrl(project: Project) = "https://${repoPath(project)}"

/**
* Obtains the repository path for the given project.
*/
private fun repoPath(project: Project) = "$orgPath/${project.rootProject.name}"

/**
* Obtains the connection URL for the given project.
*/
fun connectionUrl(project: Project) = "scm:git:git://${repoPath(project)}.git"

/**
* Obtains the developer connection URL for the given project.
*/
fun developerConnectionUrl(project: Project) = "scm:git:ssh://${repoPath(project)}.git"

/**
* Settings passed to Dokka for
* [sourceLink][[org.jetbrains.dokka.gradle.engine.parameters.DokkaSourceLinkSpec]
Expand All @@ -43,12 +75,16 @@ object DocumentationSettings {
* The URL of the remote source code
* [location][org.jetbrains.dokka.gradle.engine.parameters.DokkaSourceLinkSpec.remoteUrl].
*/
const val url: String = "https://github.com/SpineEventEngine/base/tree/master/src"
fun url(project: Project): String {
val root = project.rootProject.name
val module = project.name
return "$orgUrl/$root/tree/master/$module/src/main/kotlin"
}

/**
* The suffix used to append the source code line number to the URL.
*
* The suffix depends on the online code repository.
* The value depends on the online code repository and is set for GitHub (`#L`).
*
* @see <a href="https://kotlinlang.org/docs/dokka-gradle.html#fwor0d_534">
* remoteLineSuffix</a>
Expand Down
Loading
Loading