diff --git a/.gitattributes b/.gitattributes index 810ea7ffd9..84a8f15676 100644 --- a/.gitattributes +++ b/.gitattributes @@ -24,6 +24,10 @@ LICENSE text # Java sources *.java text +# Kotlin sources +*.kt text +*.kts text + # Python sources *.py text diff --git a/dependencies.md b/dependencies.md index 089847728b..035c68aeed 100644 --- a/dependencies.md +++ b/dependencies.md @@ -1,6 +1,6 @@ -# Dependencies of `io.spine.tools:validation-context:2.0.0-SNAPSHOT.418` +# Dependencies of `io.spine.tools:validation-context:2.0.0-SNAPSHOT.419` ## Runtime 1. **Group** : com.fasterxml.jackson. **Name** : jackson-bom. **Version** : 2.20.0. @@ -1090,14 +1090,14 @@ The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 08 20:07:49 WEST 2026** using +This report was generated on **Tue May 12 16:13:31 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.tools:validation-context-tests:2.0.0-SNAPSHOT.418` +# Dependencies of `io.spine.tools:validation-context-tests:2.0.0-SNAPSHOT.419` ## Runtime 1. **Group** : com.fasterxml.jackson. **Name** : jackson-bom. **Version** : 2.20.0. @@ -1791,28 +1791,28 @@ This report was generated on **Fri May 08 20:07:49 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 08 20:07:48 WEST 2026** using +This report was generated on **Tue May 12 16:13:31 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.tools:validation-docs:2.0.0-SNAPSHOT.418` +# Dependencies of `io.spine.tools:validation-docs:2.0.0-SNAPSHOT.416` ## Runtime ## Compile, tests, and tooling The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Thu May 07 21:35:57 WEST 2026** using +This report was generated on **Thu May 07 19:54:38 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.tools:validation-gradle-plugin:2.0.0-SNAPSHOT.418` +# Dependencies of `io.spine.tools:validation-gradle-plugin:2.0.0-SNAPSHOT.419` ## Runtime 1. **Group** : com.fasterxml.jackson. **Name** : jackson-bom. **Version** : 2.20.0. @@ -2864,14 +2864,14 @@ This report was generated on **Thu May 07 21:35:57 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 08 20:07:49 WEST 2026** using +This report was generated on **Tue May 12 16:13:31 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.tools:validation-java:2.0.0-SNAPSHOT.418` +# Dependencies of `io.spine.tools:validation-java:2.0.0-SNAPSHOT.419` ## Runtime 1. **Group** : com.fasterxml.jackson. **Name** : jackson-bom. **Version** : 2.20.0. @@ -3961,14 +3961,14 @@ This report was generated on **Fri May 08 20:07:49 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 08 20:07:49 WEST 2026** using +This report was generated on **Tue May 12 16:13:31 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.tools:validation-java-bundle:2.0.0-SNAPSHOT.418` +# Dependencies of `io.spine.tools:validation-java-bundle:2.0.0-SNAPSHOT.419` ## Runtime 1. **Group** : org.jetbrains. **Name** : annotations. **Version** : 13.0. @@ -4015,14 +4015,14 @@ This report was generated on **Fri May 08 20:07:49 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 08 20:07:46 WEST 2026** using +This report was generated on **Tue May 12 16:13:28 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-validation-jvm-runtime:2.0.0-SNAPSHOT.418` +# Dependencies of `io.spine:spine-validation-jvm-runtime:2.0.0-SNAPSHOT.419` ## Runtime 1. **Group** : com.google.code.findbugs. **Name** : jsr305. **Version** : 3.0.2. @@ -4822,14 +4822,14 @@ This report was generated on **Fri May 08 20:07:46 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 08 20:07:49 WEST 2026** using +This report was generated on **Tue May 12 16:13:31 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.tools:validation-consumer:2.0.0-SNAPSHOT.418` +# Dependencies of `io.spine.tools:validation-consumer:2.0.0-SNAPSHOT.419` ## Runtime 1. **Group** : com.fasterxml.jackson. **Name** : jackson-bom. **Version** : 2.20.0. @@ -5511,14 +5511,14 @@ This report was generated on **Fri May 08 20:07:49 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 08 20:07:48 WEST 2026** using +This report was generated on **Tue May 12 16:13:31 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.tools:validation-consumer-dependency:2.0.0-SNAPSHOT.418` +# Dependencies of `io.spine.tools:validation-consumer-dependency:2.0.0-SNAPSHOT.419` ## Runtime 1. **Group** : com.google.code.findbugs. **Name** : jsr305. **Version** : 3.0.2. @@ -5976,14 +5976,14 @@ This report was generated on **Fri May 08 20:07:48 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 08 20:07:48 WEST 2026** using +This report was generated on **Tue May 12 16:13:31 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.tools:validation-extensions:2.0.0-SNAPSHOT.418` +# Dependencies of `io.spine.tools:validation-extensions:2.0.0-SNAPSHOT.419` ## Runtime 1. **Group** : com.fasterxml.jackson. **Name** : jackson-bom. **Version** : 2.20.0. @@ -6602,14 +6602,14 @@ This report was generated on **Fri May 08 20:07:48 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 08 20:07:48 WEST 2026** using +This report was generated on **Tue May 12 16:13:31 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.tools:validation-runtime:2.0.0-SNAPSHOT.418` +# Dependencies of `io.spine.tools:validation-runtime:2.0.0-SNAPSHOT.419` ## Runtime 1. **Group** : com.google.code.findbugs. **Name** : jsr305. **Version** : 3.0.2. @@ -7170,14 +7170,14 @@ This report was generated on **Fri May 08 20:07:48 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 08 20:07:48 WEST 2026** using +This report was generated on **Tue May 12 16:13:31 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.tools:validation-validating:2.0.0-SNAPSHOT.418` +# Dependencies of `io.spine.tools:validation-validating:2.0.0-SNAPSHOT.419` ## Runtime 1. **Group** : com.google.code.findbugs. **Name** : jsr305. **Version** : 3.0.2. @@ -7781,14 +7781,14 @@ This report was generated on **Fri May 08 20:07:48 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 08 20:07:48 WEST 2026** using +This report was generated on **Tue May 12 16:13:31 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.tools:validation-validator:2.0.0-SNAPSHOT.418` +# Dependencies of `io.spine.tools:validation-validator:2.0.0-SNAPSHOT.419` ## Runtime 1. **Group** : com.fasterxml.jackson. **Name** : jackson-bom. **Version** : 2.20.0. @@ -8526,14 +8526,14 @@ This report was generated on **Fri May 08 20:07:48 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 08 20:07:48 WEST 2026** using +This report was generated on **Tue May 12 16:13:31 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.tools:validation-validator-dependency:2.0.0-SNAPSHOT.418` +# Dependencies of `io.spine.tools:validation-validator-dependency:2.0.0-SNAPSHOT.419` ## Runtime 1. **Group** : com.google.code.findbugs. **Name** : jsr305. **Version** : 3.0.2. @@ -8766,14 +8766,14 @@ This report was generated on **Fri May 08 20:07:48 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 08 20:07:47 WEST 2026** using +This report was generated on **Tue May 12 16:13:30 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.tools:validation-vanilla:2.0.0-SNAPSHOT.418` +# Dependencies of `io.spine.tools:validation-vanilla:2.0.0-SNAPSHOT.419` ## Runtime 1. **Group** : com.google.code.findbugs. **Name** : jsr305. **Version** : 3.0.2. @@ -9116,6 +9116,6 @@ This report was generated on **Fri May 08 20:07:47 WEST 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Fri May 08 20:07:47 WEST 2026** using +This report was generated on **Tue May 12 16:13:30 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/docs/GRADLE.md b/docs/GRADLE.md deleted file mode 100644 index dad2871c00..0000000000 --- a/docs/GRADLE.md +++ /dev/null @@ -1,62 +0,0 @@ -# Gradle project of the Validation Documentation - -This document describes the Gradle project structure and build configuration for -building the documentation [preview site](./_preview) for the Spine Validation library. - -The site built by this project is used for development and preview purposes. -It is not meant to be published as-is, but rather to be used as a staging area for -the documentation before it is merged into the main [documentation][main-documentation] project. - -## Build tasks - -The [Gradle build](build.gradle.kts) under the `docs/` provides the following tasks: - -1. **`buildAll`** — building the code of the examples embedded in the documentation. - This ensures that all code snippets are valid and can be compiled. - -2. **`embedCode`** — embedding the source code of the examples into the Markdown files. - This allows the documentation to include up-to-date code snippets from the source files. - This task is meant to be run manually when you write or update the documentation. - -3. **`checkSamples`** — checking that the embedded code snippets in the Markdown files are - consistent with the source code. - This is a validation step to ensure that the documentation accurately reflects the example code. - This task is executed automatically via the [GitHub workflow][check-code-embedding]. - -4. **`buildSite`** — building the documentation site using Hugo. - The site is generated in the [_preview/](./_preview) directory. - -5. **`runSite`** — running a local Hugo server to preview the documentation site. - This allows you to view the documentation in a web browser during development. - -6. **`installDependencies`** — installing the Node dependencies for the preview site. - Tasks related to Hugo depend on this task. It is not meant to be run manually. - -## Paths in the scripts - -The shell [scripts](./_script) used by the Gradle build assume that **this** `docs/` -directory is the current working directory. - -So when you start working with the documentation, make sure to `cd` into -it before running any of the scripts or Gradle tasks. - -## Including example sources - -It is done in the [`settings.gradle.kts`](settings.gradle.kts) file via `includeBuild` directive. -If you add another example project, please remember to update -the [`settings.gradle.kts`](settings.gradle.kts) file. - -## Linking to the main project build - -The example projects share the following directories and files with -the main code project via symlinks: - * `buildSrc` - * `gradle.properties` - * `gradlew` - * `gradlew.bat` - -When you add an example project, make sure to create the necessary symlinks to -these files and directories. - -[check-code-embedding]: ../.github/workflows/check-code-embedding.yml -[main-documentation]: https://github.com/SpineEventEngine/documentation/ diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000000..5fbba1de6c --- /dev/null +++ b/docs/README.md @@ -0,0 +1,22 @@ +# Spine Validation — `docs/` module + +This directory hosts the source of the Spine Validation documentation. +It is a Hugo project supplemented by Gradle wiring and a Go-based +code-embedding tool. The content under `content/` and `data/` is the +contributor-editable source; the rest of the directories — `_preview/`, +`_examples/`, `_time/`, `_settings/`, `_script/`, `_bin/` — +support local rendering, code embedding, and the example projects the +documentation references. + +The `docs/` module is a **staging area**, not a published site. Content +under `content/` is merged into the main documentation project at +[SpineEventEngine/documentation][main-documentation] and published from +there to the spine.io website. + +For the full technical description of the documentation pipeline — the +Gradle tasks, the embedded-examples mechanism, the external tooling, and +the recurring contributor procedures — see the in-repository overview at +[content/docs/validation/developer/documentation/_index.md][overview]. + +[main-documentation]: https://github.com/SpineEventEngine/documentation +[overview]: content/docs/validation/developer/documentation/_index.md diff --git a/docs/_examples b/docs/_examples index 4d5a45bc1b..cb986af5d7 160000 --- a/docs/_examples +++ b/docs/_examples @@ -1 +1 @@ -Subproject commit 4d5a45bc1b62a7f7a640e3782b572c2ee66135c4 +Subproject commit cb986af5d7a72ee58c1d73a3e50e4dae1a90c4d3 diff --git a/docs/_options/options.proto b/docs/_options/options.proto deleted file mode 100644 index 31f02bfa67..0000000000 --- a/docs/_options/options.proto +++ /dev/null @@ -1,1566 +0,0 @@ -/* - * Copyright 2024, 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. - */ -syntax = "proto3"; - -// API Note on Packaging -// --------------------- -// We do not define the package for this file to allow shorter options for user-defined types. -// This allows to write: -// -// option (internal) = true; -// -// instead of: -// -// option (spine.base.internal) = true; -// - -// Custom Type Prefix Option -// ------------------------- -// The custom `type_url_prefix` option allows to define specify custom type URL prefix for messages -// defined in a proto file. This option is declared in this file. Other proto files must import -// `options.proto` to be able to specify custom type URL prefix. -// -// It is recommended that the import statement is provided before the line with `type_url_prefix` -// option to make it obvious that custom option is defined in the imported file. -// -// For example: -// -// syntax = "proto3"; -// -// package my.package; -// -// import "spine/options.proto"; -// -// option (type_url_prefix) = "type.example.org"; -// - -option (type_url_prefix) = "type.spine.io"; -option java_multiple_files = true; -option java_outer_classname = "OptionsProto"; -option java_package = "io.spine.option"; - -import "google/protobuf/descriptor.proto"; - -// -// Reserved Range of Option Field Numbers -// -------------------------------------- -// Spine Options use the range of option field numbers from the internal range reserved for -// individual organizations. For details of custom Protobuf options and this range please see: -// -// https://developers.google.com/protocol-buffers/docs/proto#customoptions -// -// The whole range reserved for individual organizations is 50000-99999. -// The range used by Spine Options is 73812-75000. -// In order to prevent number collision with custom options used by a project based on Spine, -// numbers for custom options defined in this project should be in the range 50000-73811 or -// 75001-99999. -// - -extend google.protobuf.FieldOptions { - - // Field Validation Constraints - //----------------------------- - // For constraints defined via message-based types, please see documentation of corresponding - // message types. - // - - // The option to mark a field as required. - // - // When this option is set: - // - // 1. For message or enum fields, the field must be set to a non-default instance. - // 2. For `string` and `bytes` fields, the value must be set to a non-empty string or an array. - // 3. For repeated fields and maps, at least one element must be present. - // - // Other field types are not supported by the option. - // - // Unlike the `required` keyword in Protobuf 2, this option does not affect message - // serialization or deserialization. Even if a message content violates the requirement - // set by the option, it would still be a valid message for the Protobuf library. - // - // Example: Using `(required)` field validation constraint. - // - // message MyOuterMessage { - // MyMessage field = 1 [(required) = true]; - // } - // - bool required = 73812; - - // See `IfMissingOption` - IfMissingOption if_missing = 73813; - - // Reserved 73814 and 73815 for deleted options `decimal_max` and `decimal_min`. - - // A higher boundary to the range of values of a number. - MaxOption max = 73816; - - // A lower boundary to the range of values of a number. - MinOption min = 73817; - - // 73818 reserved for the (digits) option. - - // 73819 reserved for the (when) option. - - // See `PatternOption`. - PatternOption pattern = 73820; - - // Enables in-depth validation for fields that refer to a message. - // - // This option applies only to fields that reference a message: - // - // 1. Singular message fields. - // 2. Repeated fields of message types. - // 3. Map fields with message types as values. - // - // When set to `true`, the field is valid only if its value satisfies the validation - // constraints defined in the corresponding message type: - // - // 1. For singular message fields: the message must meet its constraints. - // - // Note: default instances are considered valid even if the message has required fields. - // In such cases, it is unclear whether the field is set with an invalid instance or - // simply unset. - // - // Example: - // - // ``` - // // Note that the default instance of `Address` is not valid because the `value` field - // // is mandatory. - // message Address { - // string value = 1 [(required) = true]; - // } - // - // // However, the default instance of `Address` in `Student.address` is valid, despite - // // having `(validate)` constraint that forces the message to meet its constraints. - // // Since the `address` field is optional for `Student`, `(validate)` would allow - // // default instances for this field treating them as "no value set". - // message Student { - // Address address = 1 [(validate) = true]; // implicit `(required) = false`. - // } - // - // // Make the validated field required to avoid this behavior. In this case, `(validate)` - // // continues to bypass default instances, but the `(required)` option will report them. - // message Student { - // Address address = 1 [(validate) = true, (required) = true]; - // } - // ``` - // - // 2. For repeated fields: every element in the repeated field must meet the constraints - // of its message type. - // - // Example: - // - // ``` - // // Note that the default instance of `PhoneNumber` is not valid because the `value` - // // field is mandatory. - // message PhoneNumber { - // string value = 1 [(required) = true, (pattern).regex = "^\+?[0-9\s\-()]{1,30}$"]; - // } - // - // // In contrast to singular fields, the default instances in `repeated` will also be - // // reported by the `(validate)` constraint, with those that do not match the pattern. - // message Student { - // repeated PhoneNumber number = 1 [(validate) = true]; - // } - // ``` - // - // 3. For map fields: each value in the map must meet the constraints of message type. - // Note: Protobuf does not allow messages to be used as map keys. - // - // Example: - // - // ``` - // // Note that the default instance of `PhoneNumber` is not valid because the `value` - // // field is mandatory. - // message PhoneNumber { - // string value = 1 [(required) = true, (pattern).regex = "^\+?[0-9\s\-()]{1,30}$"]; - // } - // - // // In contrast to singular fields, the default instances in `map` values will also be - // // reported by the `(validate)` constraint, with those that do not match the pattern. - // message Contacts { - // map map = 1 [(validate) = true]; - // } - // ``` - // - // If the field contains `google.protobuf.Any`, the option will first attempt to unpack - // the enclosed message, and only then validate it. However, unpacking is not always possible: - // - // 1. The default instance of `Any` is always valid because there is nothing to unpack - // and validate. - // 2. Instances with type URLs that are unknown to the application are also valid. - // - // Unpacking requires a corresponding Java class to deserialize the message, but if - // the application does not recognize the type URL, it has no way to determine which - // class to use. - // - // Such may happen when the packed message comes from a newer app version, an external - // system, or is simply not included in the application’s dependencies. - // - bool validate = 73821; - - // See `IfInvalidOption`. - IfInvalidOption if_invalid = 73822 [deprecated = true]; - - // See `GoesOption`. - GoesOption goes = 73823; - - // Indicates that a field can only be set once. - // - // This option allows the target field to accept assignments only if one of the following - // conditions is met: - // - // 1. The current field value is the default for its type. - // Refer to the official docs on default values: https://protobuf.dev/programming-guides/proto3/#default. - // 2. The current field value equals to the proposed new value. - // - // The option can be applied to the following singular field types: - // - // - any message or enum type; - // - any numeric type; - // - `bool`, `string` and `bytes`. - // - // Repeated fields, maps, and fields with explicit `optional` cardinality are not supported. - // Such declarations will lead to build-time errors. For more information on field cardinality, - // refer to the official docs: https://protobuf.dev/programming-guides/proto3/#field-labels. - // - // Assigning a value to a message field can be done in various ways in the generated code. - // It depends on the target language and specific implementation of `protoc`. This option - // doesn't enforce field immutability at the binary representation level. Also, it does not - // prevent the use of Protobuf utilities that can construct new messages without using field - // setters or properties. The primary purpose of this option is to support standard use cases, - // such as assigning values through setters or retrieving them during data merging. - // - // For example, let's take a look on how it works for the generated Java code. The following - // use cases are supported and validated by the option: - // - // 1. Assigning a field value using the field setter. - // 2. Assigning a field value using the field descriptor. - // 3. Merging data from another instance of the message class. - // 4. Merging data from a message's binary representation. - // 5. Merging specific fields (available for Message fields). - // - // Unsupported Java use cases include: - // - // 1. Constructing a message using the `DynamicMessage` class. - // 2. Merging data from messages provided by third-party Protobuf implementations. - // 3. Clearing a specific field or an entire message. - // - // For unsupported scenarios, the option performs no validation. It does not throw errors - // or print warnings. - // - // A typical use case involves a field, such as an ID, which remains constant throughout - // the lifecycle of an entity. - // - // Example: using `(set_once)` field validation constraint. - // - // message User { - // UserId id = 1 [(set_once) = true]; - // } - // - // Once set, the `id` field cannot be changed. - // - // Use `(if_set_again).error_msg` option to specify a custom error message that will be used for - // composing the error upon attempting to re-assign the field value. Refer to the documentation - // for the corresponding option for an example of its usage. - // - bool set_once = 73824; - - // The option to enforce uniqueness for collection fields. - // - // When the option is set to `true`, the behavior is as follows: - // - // 1. For `repeated` fields: all elements must be unique. - // 2. For `map` fields: while the map keys are inherently unique, all associated values - // must also be unique. - // - // Other field types are not supported. - // - // Uniqueness is determined by comparing the elements themselves, using their full equality. - // For example, in Java, it is defined by the `equals()` method. No special cases are applied, - // such as comparing only specific fields like IDs. - // - // Example: using `(distinct)` constraint for a `repeated` field. - // - // message Blizzard { - // - // // All snowflakes must be unique in this blizzard. - // // - // // Attempting to add a snowflake that is equal to an existing one would result - // // in a constraint violation error. - // // - // repeated Snowflake snowflakes = 1 [(distinct) = true]; - // } - // - // Example: using `(distinct)` constraint for a `map` field. - // - // message UniqueEmails { - // - // // The associated email values must be unique. - // // - // // Attempting to add a key/value pair where the `Email` value duplicates - // // an existing one would result in a constraint violation error. - // // - // map emails = 1 [(distinct) = true]; - // } - // - bool distinct = 73825; - - // Reserved 73826 for deleted `range` option, which had `string` type. - - // Defines the error message used if a `set_once` field is set again. - // - // Applies only to the fields marked as `set_once`. - // - IfSetAgainOption if_set_again = 73827; - - // Defines the error message used if a `distinct` field has duplicates. - // - // Applies only to the repeated fields marked as `distinct`. - // - IfHasDuplicatesOption if_has_duplicates = 73828; - - // The option to indicate that a numeric field is required to have a value which belongs - // to the specified bounded range. - // - // For unbounded ranges, please use `(min)` and `(max) options. - // - RangeOption range = 73829; - - // Reserved 73830 to 73849 for future validation options. - - // API Annotations - //----------------- - - // Indicates a field which is internal to Spine, not part of the public API, and should not be - // used by users of the framework. - // - // If you plan to implement an extension of the framework, which is going to be - // wired into the framework, you may use the internal parts. Please consult with the Spine - // team, as the internal APIs do not have the same stability API guarantee as public ones. - // - bool internal = 73850; - - // Reserved 73851 for the deleted SPI option. - - // Indicates a field that can change at any time, and has no guarantee of API stability and - // backward-compatibility. - // - // Usage guidelines: - // 1. This annotation is used only on public API. Internal interfaces should not use it. - // 2. This annotation can only be added to new API. Adding it to an existing API is considered - // API-breaking. - // 3. Removing this annotation from an API gives it stable status. - // - bool experimental = 73852; - - // Signifies that a public API is subject to incompatible changes, or even removal, in a future - // release. - // - // An API bearing this annotation is exempt from any compatibility guarantees made by its - // containing library. Note that the presence of this annotation implies nothing about the - // quality of the API in question, only the fact that it is not "API-frozen." - // It is generally safe for applications to depend on beta APIs, at the cost of - // some extra work during upgrades. - // - bool beta = 73853; - - // Marks an entity state field as column. - // - // The column fields are stored separately from the entity record and can be specified as - // filtering criteria during entity querying. - // - // The column field should be declared as follows: - // - // message UserProfile { - // ... - // int32 year_of_registration = 8 [(column) = true]; - // } - // - // The `year_of_registration` field value can then be used as query parameter when reading - // entities of `UserProfile` type from the server side. - // - // The value of a column field can be updated in two ways: - // - // 1. In the receptors of the entity, just like any other part of entity state. - // 2. Using the language-specific tools like `EntityWithColumns` interface in Java. - // - // All column fields are considered optional by the framework. - // - // Currently, only entities of projection and process manager type are - // eligible for having columns (see `EntityOption`). - // For all other message types the column declarations are ignored. - // - // The `repeated` and `map` fields cannot be columns. - // - bool column = 73854; - - // Reserved 73855 to 73890 for future options. - - // Reserved 73900 for removed `by` option. -} - -extend google.protobuf.OneofOptions { - - // Deprecated: use the `(choice)` option instead. - bool is_required = 73891 [deprecated = true]; - - // Controls whether a `oneof` group must always have one of its fields set. - ChoiceOption choice = 73892; - - // Reserved 73893 to 73899 for future options. -} - -extend google.protobuf.MessageOptions { - - // Validation Constraints - //------------------------ - - // The default validation error message. - // - // Please note, this option is intended for INTERNAL USE only. It applies to message types - // that extend `FieldOptions` and is not intended for external usage. - // - // If a validation option detects a constraint violation and no custom error message is defined - // for that specific option, it will fall back to the message specified by `(default_message)`. - // - // For example, here is how to declare the default message for `(goes)` option: - // - // ``` - // message GoesOption { - // // The default error message. - // option (default_message) = "The field `${goes.companion}` must also be set when `${field.path}` is set."; - // } - // ``` - // - // Note: The placeholders available within `(default_message)` depend solely on the particular - // validation option that uses it. Each option may define its own set of placeholders, or none. - // - string default_message = 73901 [(internal) = true]; - - // Deprecated: use the `(require)` option instead. - string required_field = 73902 [deprecated = true]; - - // See `EntityOption`. - EntityOption entity = 73903; - - // An external validation constraint for a field. - // - // WARNING: This option is deprecated and is scheduled for removal in Spine v2.0.0. - // - // Allows to re-define validation constraints for a message when its usage as a field of - // another type requires alternative constraints. This includes definition of constraints for - // a message which does not have them defined within the type. - // - // A target field of an external constraint should be specified using a fully-qualified - // field name (e.g. `mypackage.MessageName.field_name`). - // - // Example: defining external validation constraint. - // - // package io.spine.example; - // - // // Defines a change in a string value. - // // - // // Both of the fields of this message are not `required` to be able to describe - // // a change from empty value to non-empty value, or from a non-empty value to - // // an empty string. - // // - // message StringChange { - // - // // The value of the field that's changing. - // string previous_value = 1; - // - // // The new value of the field. - // string new_value = 2; - // } - // - // // A command to change a name of a task. - // // - // // The task has a non-empty name. A new name cannot be empty. - // // - // message RenameTask { - // - // // The ID of the task to rename. - // string task_id = 1; - // - // // Instruction for changing the name. - // // - // // The value of `change.previous_value` is the current name of the task. - // // It cannot be empty. - // // - // // The value of `change.new_value` is the new name of the task. - // // It cannot be empty either. - // // - // StringChange change = 1 [(validate) = true]; - // } - // - // // External validation constraint for both fields of the `StringChange` message - // // in the scope of the `RenameTask` command. - // // - // message RequireTaskNames { - // option (constraint_for) = "spine.example.RenameTask.change"; - // - // string previous_value = 1 [(required) = true]; - // string new_value = 2 [(required) = true]; - // } - // - // NOTE: A target field for an external validation constraint must be have the option `(validate)` - // set to `true`. See the definition of the `RenameTask.change` field in the example - // above. If there is no such option defined, or it is set to `false`, the external - // constraint will not be applied. - // - // External validation constraints can be applied to fields of several types. - // To do so, separate fully-qualified references to these fields with comma. - // - // Example: external validation constraints for multiple fields. - // - // // External validation constraint for requiring a new value in renaming commands. - // message RequireNewName { - // option (constraint_for) = "spine.example.RenameTask.change," - // "spine.example.RenameProject.change,"; - // "spine.example.UpdateComment.text_change; - // - // string new_value = 1 [(required) = true]; - // } - // - // NOTE: An external validation constraint for a field must be defined only once. - // Spine Model Compiler does not check such an "overwriting". - // See the issue: https://github.com/SpineEventEngine/base/issues/318. - // - string constraint_for = 73904 [deprecated = true]; - - // Reserved 73905 to 73910 for future validation options. - - // API Annotations - //----------------- - - // Indicates a type usage of which is restricted in one of the following ways. - // - // 1. This type is internal to the Spine Event Engine framework. It is not a part of - // the public API, and must not be used by framework users. - // - // 2. The type is internal to a bounded context, artifact of which exposes the type to - // the outside world (presumably for historical reasons). - // - // The type with such an option can be used only inside the bounded context which declares it. - // - // The type must not be used neither for inbound (i.e. being sent to the bounded context - // which declares this type) nor for outbound communication (i.e. being sent by this - // bounded context outside). - // - // An attempt to violate these usage restrictions will result in a runtime error. - // - bool internal_type = 73911; - - // Indicates a file which contains elements of Service Provider Interface (SPI). - bool SPI_type = 73912; - - // Indicates a public API that can change at any time, and has no guarantee of - // API stability and backward-compatibility. - bool experimental_type = 73913; - - // Signifies that a public API is subject to incompatible changes, or even removal, - // in a future release. - bool beta_type = 73914; - - // Specifies a characteristic inherent in the the given message type. - // - // Example: using `(is)` message option. - // - // message CreateProject { - // option (is).java_type = "ProjectCommand"; - // - // // Remainder omitted. - // } - // - // In the example above, `CreateProject` message is a `ProjectCommand`. - // - // To specify a characteristic for every message in a `.proto` file, - // please use `(every_is)` file option. - // - // If both `(is)` and `(every_is)` options are applicable for a type, both are applied. - // - // When targeting Java, specify the name of a Java interface to be implemented by this - // message via `(is).java_type`. - // - IsOption is = 73915; - - // Reserved 73916 to 73921 for future API annotation options. - - // Reserved 73922 for removed `enrichment_for` option. - - // Specifies the natural ordering strategy for this type. - // - // Code generators should generate language-specific comparisons based on the field paths. - // - // Runtime comparators may use the reflection API to compare field values. - // - CompareByOption compare_by = 73923; - - // The constraint to require at least one of the fields or combinations of fields. - RequireOption require = 73924; - - // Reserved 73925 to 73938 for future options. - - // Reserved 73939 and 73940 for the deleted options `events` and `rejections`. -} - -extend google.protobuf.FileOptions { - - // Specifies a type URL prefix for all types within a file. - // - // This type URL will be used when packing messages into `Any`. - // See `any.proto` for more details. - // - string type_url_prefix = 73941; - - // Indicates a file which contains types usage of which is restricted. - // - // For more information on such restrictions please see the documentation of - // the type option called `internal_type`. - // - // If a file contains a declaration of a `service`, this option will NOT be applied to it. - // A service is not a data type, and therefore, this option does not apply to it. - // Internal services are not supported. - // - bool internal_all = 73942; - - // Indicates a file which contains elements of Service Provider Interface (SPI). - // - // This option applies to messages, enums, and services. - // - bool SPI_all = 73943; - - // Indicates a file declaring public data type API which that can change at any time, - // has no guarantee of API stability and backward-compatibility. - // - // If a file contains a declaration of a `service`, this option will NOT be applied to it. - // A service is not a data type, and therefore, this option does not apply to it. - // Experimental services are not supported. - // - bool experimental_all = 73944; - - // Signifies that a public data type API is subject to incompatible changes, or even removal, - // in a future release. - // - // If a file contains a declaration of a `service`, this option will NOT be applied to it. - // A service is not a data type, and therefore, this option does not apply to it. - // Beta services are not supported. - // - bool beta_all = 73945; - - // Specifies a characteristic common for all the message types in the given file. - // - // Example: marking all the messages using the `(every_is)` file option. - // ``` - // option (every_is).java_type = "ProjectCommand"; - // - // message CreateProject { - // // ... - // - // message WithAssignee { - // // ... - // } - // } - // - // message DeleteProject { /*...*/ } - // ``` - // - // In the example above, `CreateProject`, `CreateProject.WithAssignee`, and `DeleteProject` - // messages are `ProjectCommand`-s. - // - // To specify a characteristic for a single message, please use `(is)` message option. - // If both `(is)` and `(every_is)` options are applicable for a type, both are applied. - // - // When targeting Java, specify the name of a Java interface to be implemented by these - // message types via `(every_is).java_type`. - // - EveryIsOption every_is = 73946; - - // Reserved 73947 to 73970 for future use. -} - -extend google.protobuf.ServiceOptions { - - // Indicates that the service is a part of Service Provider Interface (SPI). - bool SPI_service = 73971; - - // Reserved 73971 to 73980. -} - -// Reserved 73981 to 74000 for other future Spine Options numbers. - -// -// Validation Option Types -//--------------------------- - -// Defines the error message used if a `required` field is not set. -// -// Applies only to the fields marked as `required`. -// -message IfMissingOption { - - // The default error message. - option (default_message) = "The field `${parent.type}.${field.path}`" - " of the type `${field.type}` must have a non-default value."; - - // A user-defined validation error format message. - // - // Use `error_msg` instead. - // - string msg_format = 1 [deprecated = true]; - - // A user-defined error message. - // - // The specified message may include the following placeholders: - // - // 1. `${field.path}` – the field path. - // 2. `${field.type}` – the fully qualified name of the field type. - // 3. `${parent.type}` – the fully qualified name of the validated message. - // - // The placeholders will be replaced at runtime when the error is constructed. - // - // Example: using the `(if_missing)` option. - // - // message Student { - // Name name = 1 [(required) = true, - // (if_missing).error_msg = "The `${field.path}` field is mandatory for `${parent.type}`."]; - // } - // - string error_msg = 2; -} - -// Indicates that the numeric field must be greater than or equal to the specified value. -// -// The option supports all singular and repeated numeric fields. -// -message MinOption { - - // The default error message. - option (default_message) = "The field `${parent.type}.${field.path}`" - " must be ${min.operator} ${min.value}. The passed value: `${field.value}`."; - - // The string representation of the minimum field value. - // - // ## Integer and floating-point values - // - // A minimum value for an integer field must use an integer number. Specifying a decimal - // number is not allowed, even if it has no fractional part (e.g., `5.0` is invalid). - // - // A minimum value for a floating-point field must use a decimal separator (`.`), even if - // the value has no fractional part. An exponent part represented by `E` or `e`, followed - // by an optional sign and digits is allowed (e.g., `1.2E3`, `0.5e-2`). - // - // Example: defining minimum values for integer and floating-point fields. - // - // message Measurements { - // int32 temperature = 1 [(min).value = "0"]; - // uint32 mass = 2 [(min).value = "5"]; - // float degree = 3 [(min).value = "0.0"]; - // double angle = 4 [(min).value = "30.0"]; - // float pressure = 5 [(min).value = "950.0E-2"]; - // } - // - // ## Field Type Limitations - // - // A minimum value must not fall below the limits of the field type. - // - // Example: invalid values that fall below the field type limits. - // - // message OverflowMeasurements { - // float pressure = 1 [(min).value = "-5.5E38"]; // Falls below the `float` minimum. - // uint32 mass = 2 [(min).value = "-5"]; // Falls below the `uint32` minimum. - // } - // - // ## Field references - // - // Instead of numeric literals, you can reference another numeric field. - // At runtime, the field’s value will be used as the bound. Nested fields are supported. - // - // Example: defining minimum values using field references. - // - // message Measurements { - // - // int32 min_length = 1; - // int32 length = 2 [(min).value = "min_length"]; - // - // Limits limits = 3; - // int32 temperature = 4 [(min).value = "limits.min_temperature"]; - // float pressure = 5 [(min).value = "limits.min_pressure"]; - // } - // - // message Limits { - // int32 min_temperature = 1; - // float min_pressure = 2; - // } - // - // Note: Field type compatibility is not required in this case; the value is - // automatically converted. However, only numeric fields can be referenced. - // Repeated and map fields are not supported. - // - string value = 1; - - // Specifies if the field should be strictly greater than the specified minimum. - // - // The default value is false, i.e. the bound is inclusive. - // - bool exclusive = 2; - - // A user-defined validation error format message. - string msg_format = 3 [deprecated = true]; - - // A user-defined error message. - // - // The specified message may include the following placeholders: - // - // 1. `${field.value}` - the field value. - // 2. `${field.path}` – the field path. - // 3. `${field.type}` – the fully qualified name of the field type. - // 4. `${parent.type}` – the fully qualified name of the validated message. - // 5. `${min.value}` – the specified minimum `value`. For referenced fields, the actual - // field value is also printed in round brackets along with the reference itself. - // 6. `${min.operator}` – if `exclusive` is set to `true`, this placeholder equals to ">". - // Otherwise, ">=". - // - // The placeholders will be replaced at runtime when the error is constructed. - // - string error_msg = 4; -} - -// Indicates that the numeric field must be less than or equal to the specified value. -// -// The option supports all singular and repeated numeric fields. -// -message MaxOption { - - // The default error message. - option (default_message) = "The field `${parent.type}.${field.path}`" - " must be ${max.operator} ${max.value}. The passed value: `${field.value}`."; - - // The string representation of the maximum field value. - // - // ## Integer and floating-point values - // - // A maximum value for an integer field must use an integer number. Specifying a decimal - // number is not allowed, even if it has no fractional part (e.g., `5.0` is invalid). - // - // A maximum value for a floating-point field must use a decimal separator (`.`), even if - // the value has no fractional part. An exponent part represented by `E` or `e`, followed - // by an optional sign and digits is allowed (e.g., `1.2E3`, `0.5e-2`). - // - // Example: defining maximum values for integer and floating-point fields. - // - // message Measurements { - // int32 temperature = 1 [(max).value = "270"]; - // uint32 mass = 2 [(max).value = "1200"]; - // float degree = 3 [(max).value = "360.0"]; - // double angle = 4 [(max).value = "90.0"]; - // float pressure = 5 [(max).value = "1050.0E-2"]; - // } - // - // ## Field Type Limitations - // - // A maximum value must not exceed the limits of the field type. - // - // Example: invalid values that exceed the field type limits. - // - // message OverflowMeasurements { - // float pressure = 1 [(min).value = "5.5E38"]; // Exceeds the `float` maximum. - // int32 mass = 2 [(min).value = "2147483648"]; // Exceeds the `int32` maximum. - // } - // - // ## Field references - // - // Instead of numeric literals, you can reference another numeric field. - // At runtime, the field’s value will be used as the bound. Nested fields are supported. - // - // Example: defining maximum values using field references. - // - // message Measurements { - // - // int32 max_length = 1; - // int32 length = 2 [(max).value = "max_length"]; - // - // Limits limits = 3; - // int32 temperature = 4 [(max).value = "limits.max_temperature"]; - // float pressure = 5 [(max).value = "limits.max_pressure"]; - // } - // - // message Limits { - // int32 max_temperature = 1; - // float max_pressure = 2; - // } - // - // Note: Field type compatibility is not required in this case; the value is - // automatically converted. However, only numeric fields can be referenced. - // Repeated and map fields are not supported. - // - string value = 1; - - // Specifies if the field should be strictly less than the specified maximum - // - // The default value is false, i.e. the bound is inclusive. - // - bool exclusive = 2; - - // A user-defined validation error format message. - string msg_format = 3 [deprecated = true]; - - // A user-defined error message. - // - // The specified message may include the following placeholders: - // - // 1. `${field.path}` – the field path. - // 2. `${field.value}` - the field value. - // 3. `${field.type}` – the fully qualified name of the field type. - // 4. `${parent.type}` – the fully qualified name of the validated message. - // 5. `${max.value}` – the specified maximum `value`. For referenced fields, the actual - // field value is also printed in round brackets along with the reference itself. - // 6. `${max.operator}` – if `exclusive` is set to `true`, this placeholder equals to "<". - // Otherwise, "<=". - // - // The placeholders will be replaced at runtime when the error is constructed. - // - string error_msg = 4; -} - -// A string field value must match the given regular expression. -// -// This option is applicable only to string fields, -// including those that are repeated. -// -// Example: using the `(pattern)` option. -// -// message CreateAccount { -// string id = 1 [(pattern).regex = "^[A-Za-z0-9+]+$", -// (pattern).error_msg = "ID must be alphanumerical in `${parent.type}`. Provided: `${field.value}`."]; -// } -// -message PatternOption { - - // The default error message. - option (default_message) = "The `${parent.type}.${field.path}` field" - " must match the regular expression `${regex.pattern}` (modifiers: `${regex.modifiers}`)." - " The passed value: `${field.value}`."; - - // The regular expression that the field value must match. - // - // Please use the Java regex dialect for the syntax baseline: - // https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/regex/Pattern.html - // - // Note: in Java, regex patterns are not wrapped in explicit delimiters like in Perl or PHP. - // Instead, the pattern is provided as a string literal. Therefore, `/` symbol does not need - // to be escaped. - // - // The provided string literal is passed directly to the regex engine. So, it must be exactly - // what you would supply to the `java.util.regex.Pattern.compile()` method. - // - string regex = 1; - - reserved 2; - reserved "flag"; - - // Modifiers for this pattern. - Modifier modifier = 4; - - // A user-defined validation error format message. - string msg_format = 3 [deprecated = true]; - - // A user-defined validation error format message. - // - // The specified message may include the following placeholders: - // - // 1. `${field.path}` – the field path. - // 2. `${field.value}` - the field value. - // 3. `${field.type}` – the fully qualified name of the field type. - // 4. `${parent.type}` – the fully qualified name of the validated message. - // 5. `${regex.pattern}` – the specified regex pattern. - // 6. `${regex.modifiers}` – the specified modifiers, if any. For example, `[dot_all, unicode]`. - // - // The placeholders will be replaced at runtime when the error is constructed. - // - string error_msg = 5; - - // Regular expression modifiers. - // - // These modifiers are specifically selected to be supported in many implementation platforms. - // - message Modifier { - - // Enables the dot (`.`) symbol to match all the characters. - // - // By default, the dot does not match line break characters. - // - // May also be known in some platforms as "single line" mode and be encoded with - // the `s` flag. - // - bool dot_all = 1; - - // Allows to ignore the case of the matched symbols. - // - // For example, this modifier is specified, string `ABC` would be a complete match for - // the regex `[a-z]+`. - // - // On some platforms may be represented by the `i` flag. - // - bool case_insensitive = 2; - - // Enables the `^` (caret) and `$` (dollar) signs to match a start and an end of a line - // instead of a start and an end of the whole expression. - // - // On some platforms may be represented by the `m` flag. - // - bool multiline = 3; - - // Enables matching the whole UTF-8 sequences, - // - // On some platforms may be represented by the `u` flag. - // - bool unicode = 4; - - // Allows the matched strings to contain a full match to the pattern and some other - // characters as well. - // - // By default, a string only matches a pattern if it is a full match, i.e. there are no - // unaccounted for leading and/or trailing characters. - // - // This modifier is usually not represented programming languages, as the control over - // weather to match an entire string or only its part is provided to the user by other - // language means. For example, in Java, this would be the difference between methods - // `matches()` and `find()` of the `java.util.regex.Matcher` class. - // - bool partial_match = 5; - } -} - -// Specifies the message to show if a validated field happens to be invalid. -// -// It is applicable only to fields marked with `(validate)`. -// -message IfInvalidOption { - - // Do not specify error message for `(validate)`, it is no longer used by - // the validation library. - option deprecated = true; - - // The default error message. - option (default_message) = "The field `${parent.type}.${field.path}` of the type" - " `${field.type}` is invalid. The field value: `${field.value}`."; - - // A user-defined validation error format message. - // - // Use `error_msg` instead. - // - string msg_format = 1 [deprecated = true]; - - // A user-defined error message. - // - // The specified message may include the following placeholders: - // - // 1. `${field.path}` – the field path. - // 2. `${field.value}` - the field value. - // 3. `${field.type}` – the fully qualified name of the field type. - // 4. `${parent.type}` – the fully qualified name of the field declaring type. - // - // The placeholders will be replaced at runtime when the error is constructed. - // - // Example: using the `(if_invalid)` option. - // - // message Transaction { - // TransactionDetails details = 1 [(validate) = true, - // (if_invalid).error_msg = "The `${field.path}` field is invalid."]; - // } - // - string error_msg = 2; -} - -// Specifies that another field must be present if the option's target field is present. -// -// Unlike the `required_field` that handles combination of required fields, this option is useful -// when it is needed to say that an optional field makes sense only when another optional field -// is present. -// -// This option can be applied to the same field types as `(required)`, including both the -// target field and its companion. Supported field types are: -// -// - Messages and enums. -// - Repeated fields and maps. -// - `string` and `bytes`. -// -// Example: requiring mutual presence of optional fields. -// -// message ScheduledItem { -// ... -// spine.time.LocalDate date = 4; -// spine.time.LocalTime time = 5 [(goes).with = "date"]; -// } -// -message GoesOption { - - // The default error message. - option (default_message) = "The field `${goes.companion}` must also be set when `${field.path}`" - " is set in `${parent.type}`."; - - // The name of the companion field whose presence is required for this field to be valid. - string with = 1; - - // A user-defined validation error format message. - string msg_format = 2 [deprecated = true]; - - // A user-defined error message. - // - // The specified message may include the following placeholders: - // - // 1. `${field.path}` – the field path. - // 2. `${field.value}` – the field value. - // 3. `${field.type}` – the fully qualified name of the field type. - // 4. `${parent.type}` – the fully qualified name of the validated message. - // 5. `${goes.companion}` – the name of the companion specified in `with`. - // - // The placeholders will be replaced at runtime when the error is constructed. - // - string error_msg = 3; -} - -// Defines options of a message representing a state of an entity. -message EntityOption { - - // A type of an entity for state of which the message is defined. - enum Kind { - option allow_alias = true; - - // Reserved for errors. - KIND_UNKNOWN = 0; - - // The message is an aggregate state. - AGGREGATE = 1; - - // The message is a state of a projection (same as "view"). - PROJECTION = 2; - - // The message is a state of a view (same as "projection"). - VIEW = 2; - - // The message is a state of a process manager. - PROCESS_MANAGER = 3; - - // The message is a state of an entity, which is not of the type - // defined by other members of this enumeration. - ENTITY = 4; - } - - // The type of the entity. - Kind kind = 1; - - // The level of visibility of the entity to queries. - enum Visibility { - - // Default visibility is different for different types of entities: - // - for projections, "FULL" is default; - // - for aggregates, process managers, and other entities, "NONE" is default. - // - DEFAULT = 0; - - // The entity is not visible to queries. - NONE = 1; - - // Client-side applications can subscribe to updates of entities of this type. - SUBSCRIBE = 2; - - // Client-side applications can query this type of entities. - QUERY = 3; - - // Client-side applications can subscribe and query this type of entity. - FULL = 4; - } - - // The visibility of the entity. - // - // If not defined, the value of this option is `DEFAULT`. - // - Visibility visibility = 2; -} - -// Defines a common type for message types declared in the same proto file. -// -// The nature of the type depends on the target programming language. -// For example, the `java_type` property defines a name of the Java interface common -// to all message classes generated for the proto file having this option. -// -// The option triggers creation of the common type if the `generate` property is set to true. -// Otherwise, it is expected that the user provides the reference to an existing type. -// -message EveryIsOption { - - // Enables the generation of the common type. - // - // The default value is `false`. - // - bool generate = 1; - - // The reference to a Java top-level interface. - // - // The interface cannot be nested into a class or another interface. - // If a nested interface is provided, the code generation should fail the build process. - // - // The value may be a fully-qualified or a simple name. - // - // When a simple name is set, it is assumed that the interface belongs to - // the package of the generated message classes. - // - // If the value of the `generate` field is set to `false` the referenced interface must exist. - // Otherwise, a compilation error will occur. - // - // If the value of the `generate` field is set to `true`, the framework will - // generate the interface using the given name and the package as described above. - // - // The generated interface will extend `com.google.protobuf.Message` and - // will have no declared methods. - // - string java_type = 2; -} - -// Defines additional type for a message type in which this option is declared. -// -// The nature of the type depends on the target programming language. -// For example, the `java_type` property defines a name of the Java interface which -// the generated message class will implement. -// -message IsOption { - - // The reference to a Java top-level interface. - // - // The interface cannot be nested into a class or another interface. - // If a nested interface is provided, the code generation should fail the build process. - // - // The value may be a fully-qualified or a simple name. - // - // When a simple name is set, it is assumed that the interface belongs to - // the package of the generated message classes. - // - // The referenced interface must exist. Otherwise, a compilation error will occur. - // - string java_type = 1; -} - -// Defines the way to compare two messages of the same type to one another. -// -// Comparisons can be used to sort values. -// -// See the `(compare_by)` option. -// -message CompareByOption { - - // Field paths used for comparisons. - // - // The allowed field types are: - // - any number type; - // - `bool` (`false` is less than `true`); - // - `string` (in the order of respective Unicode values); - // - enumerations (following the order of numbers associated with each constant); - // - local messages (generated within the current build) marked with `(compare_by)`; - // - external messages (from dependencies), which either marked with `(compare_by)` - // OR have a comparator provided in `io.spine.compare.ComparatorRegistry`. - // - // Other types are not permitted. Repeated or map fields are not permitted either. - // Such declarations will lead to build-time errors. - // - // To refer to nested fields, separate the field names with a dot (`.`). - // No fields in the path can be repeated or maps. - // - // When multiple field paths are specified, comparison is executed in the order of reference. - // For example, specifying `["seconds", "nanos"]` makes the comparison mechanism prioritize - // the `seconds` field and refer to `nanos` only when `seconds` are equal. - // - // NOTE: When comparing fields with a message type, a non-set message is always less than - // a set message. But if a message is set to a default value, the comparison falls back to - // the field-wise comparison, i.e. number values are treated as zeros, `bool` — as `false`, - // and so on. - // - repeated string field = 1; - - // If true, the default order is reversed. For example, numbers are ordered from the greater to - // the lower, enums — from the last number value to the 0th value, etc. - bool descending = 2; -} - -// Defines the error message used if a `set_once` field is set again. -// -// Applies only to the fields marked as `set_once`. -// -message IfSetAgainOption { - - // The default error message. - option (default_message) = "The field `${parent.type}.${field.path}` of the type" - " `${field.type}` already has the value `${field.value}` and cannot be reassigned" - " to `${field.proposed_value}`."; - - // A user-defined error message. - // - // The specified message may include the following placeholders: - // - // 1. `${field.path}` – the field path. - // 2. `${field.type}` – the fully qualified name of the field type. - // 3. `${field.value}` – the current field value. - // 4. `${field.proposed_value}` – the value, which was attempted to be set. - // 5. `${parent.type}` – the fully qualified name of the validated message. - // - // The placeholders will be replaced at runtime when the error is constructed. - // - // Example: using the `(set_once)` option. - // - // message User { - // UserId id = 1 [(set_once) = true, - // (if_set_again).error_msg = "A student ID is used as a permanent identifier within academic system, and cannot be re-assigned."]; - // } - // - string error_msg = 1; -} - -// Defines the error message used if a `distinct` field has duplicates. -// -// Applies only to the `repeated` and `map` fields marked with the `(distinct)` option. -// -message IfHasDuplicatesOption { - - // The default error message. - option (default_message) = "The field `${parent.type}.${field.path}` of the type" - " `${field.type}` must not contain duplicates." - " The duplicates found: `${field.duplicates}`."; - - // A user-defined error message. - // - // The specified message may include the following placeholders: - // - // 1. `${field.path}` – the field path. - // 2. `${field.type}` – the fully qualified name of the field type. - // 3. `${field.value}` – the field value (the whole collection). - // 4. `${field.duplicates}` – the duplicates found (elements that occur more than once). - // 5. `${parent.type}` – the fully qualified name of the validated message. - // - // The placeholders will be replaced at runtime when the error is constructed. - // - // Example: using the `(distinct)` option. - // - // message Blizzard { - // repeated Snowflake = 1 [(distinct) = true, - // (if_has_duplicates).error_msg = "Every snowflake must be unique! The duplicates found: `${field.duplicates}`."]; - // } - // - string error_msg = 1; -} - -// Indicate that the numeric field must belong to the specified bounded range. -// -// For unbounded ranges, please use `(min)` and `(max) options. -// -// The option supports all singular and repeated numeric fields. -// -message RangeOption { - - // The default error message. - option (default_message) = "The field `${parent.type}.${field.path}` must be within" - " the following range: `${range.value}`. The passed value: `${field.value}`."; - - // The string representation of the range. - // - // A range consists of two bounds: a lower bound and an upper bound. These bounds are - // separated by either the `..` or ` .. ` delimiter. Each bound can be either open - // or closed. The format of the bounds and the valid values depend on the type of field. - // - // ## Bound Types - // - // - Closed bounds include the endpoint and are indicated using square brackets (`[`, `]`). - // Example: `[0..10]` represents values from 0 to 10, inclusive. - // - // - Open bounds exclude the endpoint and are indicated using parentheses (`(`, `)`). - // Example: `(0..10)` represents values strictly between 0 and 10. - // - // The lower bound must be less than or equal to the upper bound. - // - // ## Integer Fields - // - // A range for an integer field must use integer numbers. Specifying a decimal number - // is not allowed, even if it has no fractional part (e.g., `5.0` is invalid). - // - // Example: defining ranges for integer fields. - // - // message Measurements { - // int32 length = 1 [(range).value = "[0..100)"]; - // uint32 mass = 2 [(range).value = "(0..100]"]; - // } - // - // ## Floating-Point Fields - // - // A range for a floating-point field must use a decimal separator (`.`), even if the value - // has no fractional part. An exponent part represented by `E` or `e`, followed by an optional - // sign and digits is allowed (e.g., `1.2E3`, `0.5e-2`). - // - // Example: defining ranges for floating-point fields. - // - // message Measurements { - // float degree = 1 [(range).value = "[0.0 .. 360.0)"]; - // double angle = 2 [(range).value = "(0.0 .. 180.0)"]; - // float pressure = 3 [(range).value = "[950.0E-2 .. 1050.0E-2]"]; - // } - // - // ## Field Type Limitations - // - // A range must not exceed the limits of the field type. - // - // Example: invalid ranges that exceed the field type limits. - // - // message OverflowMeasurements { - // float price = 1 [(range).value = "[0, 5.5E38]"]; // Exceeds the `float` maximum. - // uint32 size = 2 [(range).value = "[-5; 10]"]; // Falls below the `uint32` minimum. - // } - // - // ## Field references - // - // Instead of numeric literals, you can reference another numeric field. - // At runtime, the field’s value will be used as the bound. Nested fields are supported. - // - // Example: defining ranges using field references. - // - // message Measurements { - // - // int32 max_length = 1; - // int32 length = 2 [(range).value = "[1 .. max_length"]; - // - // Limits limits = 3; - // int32 temperature = 4 [(range).value = "[limits.low_temp .. limits.high_temp]"]; - // } - // - // message Limits { - // int32 low_temp = 1; - // int32 high_temp = 2; - // } - // - // Note: Field type compatibility is not required in this case; the value is - // automatically converted. However, only numeric fields can be referenced. - // Repeated and map fields are not supported. - // - string value = 1; - - // A user-defined error message. - // - // The specified message may include the following placeholders: - // - // 1. `${field.path}` – the field path. - // 2. `${field.value}` - the field value. - // 3. `${field.type}` – the fully qualified name of the field type. - // 4. `${parent.type}` – the fully qualified name of the validated message. - // 5. `${range.value}` – the specified range. For referenced fields, the actual - // field value is also printed in round brackets along with the reference itself. - // - // The placeholders will be replaced at runtime when the error is constructed. - // - string error_msg = 2; -} - -// Controls whether a `oneof` group must always have one of its fields set. -// -// Note that unlike the `(required)` constraint, this option supports any field types -// within the group cases. -// -message ChoiceOption { - - // The default error message. - option (default_message) = "The `oneof` group `${parent.type}.${group.path}` must" - " have one of its fields set."; - - // Enables or disables the requirement for the `oneof` group to have a value. - bool required = 1; - - // A user-defined error message. - // - // The specified message may include the following placeholders: - // - // 1. `${group.path}` – the group path. - // 2. `${parent.type}` – the fully qualified name of the validated message. - // - // The placeholders will be replaced at runtime when the error is constructed. - // - string error_msg = 2; -} - -// Declares the field groups, at least one of which must have all of its fields set. -// -// Unlike the `(required)` field constraint, which requires the presence of -// a specific field, this option allows to specify alternative field groups. -// -message RequireOption { - - // The default error message. - option (default_message) = "The message `${message.type}` must have at least one of" - " the following field groups set: `${require.fields}`."; - - // A set of field groups, at least one of which must have all of its fields set. - // - // A field group can include one or more fields joined by the ampersand (`&`) symbol. - // `oneof` group names are also valid and can be used along with field names. - // Groups are separated using the pipe (`|`) symbol. - // - // The field type determines when the field is considered set: - // - // 1. For message or enum fields, it must have a non-default instance. - // 2. For `string` and `bytes` fields, it must be non-empty. - // 3. For repeated fields and maps, it must contain at least one element. - // - // Fields of other types are not supported by this option. - // - // For `oneof`s, the restrictions above do not apply. Any `oneof` group can be used - // without considering the field types, and its value will be checked directly without - // relying on the default values of the fields within the `oneof`. - // - // Example: defining two field groups. - // - // message PersonName { - // option (require).fields = "given_name | honorific_prefix & family_name"; - // - // string honorific_prefix = 1; - // string given_name = 2; - // string middle_name = 3; - // string family_name = 4; - // string honorific_suffix = 5; - // } - // - // In this example, at least `given_name` or a group of `honorific_prefix` - // and `family_name` fields must be set. - // - string fields = 1; - - // A user-defined error message. - // - // The specified message may include the following placeholders: - // - // 1. `${message.type}` – the fully qualified name of the validated message. - // 2. `${require.fields}` – the specified field groups. - // - // The placeholders will be replaced at runtime when the error is constructed. - // - string error_msg = 2; -} diff --git a/docs/_script/embed-code b/docs/_script/embed-code index fdaf56a789..e68bb9d3ba 100755 --- a/docs/_script/embed-code +++ b/docs/_script/embed-code @@ -1,29 +1,4 @@ #!/usr/bin/env bash -# -# Copyright 2020, TeamDev. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Redistribution and use in source and/or binary forms, with or without -# modification, must retain the above copyright notice and the following -# disclaimer. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# # Load environment variables for the case of execution from the Gradle build if they exist. BASH_PROFILE=~/.bash_profile diff --git a/docs/_settings/embed-code.yml b/docs/_settings/embed-code.yml index 38fd9a97c6..5d7e00574a 100644 --- a/docs/_settings/embed-code.yml +++ b/docs/_settings/embed-code.yml @@ -9,6 +9,10 @@ code-path: path: "../../java" - name: "context" path: "../../context" + - name: "time" + path: "../_time" + - name: "docs" + path: ".." docs-path: "../content/docs/" code-includes: - ".gitignore" diff --git a/docs/build.gradle.kts b/docs/build.gradle.kts index 5d8c984a31..c652ba5682 100644 --- a/docs/build.gradle.kts +++ b/docs/build.gradle.kts @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Redistribution and use in source and/or binary forms, with or without * modification, must retain the above copyright notice and the following diff --git a/docs/content/docs/validation/developer/build-and-release.md b/docs/content/docs/validation/developer/build-and-release.md index 87c8cccd21..88c7ff12f1 100644 --- a/docs/content/docs/validation/developer/build-and-release.md +++ b/docs/content/docs/validation/developer/build-and-release.md @@ -47,7 +47,7 @@ through Gradle's `extra` properties: end="val validationVersion"> ```kotlin -val validationVersion by extra("2.0.0-SNAPSHOT.418") +val validationVersion by extra("2.0.0-SNAPSHOT.419") ``` The root build script applies this file under `allprojects { … }` and assigns diff --git a/docs/content/docs/validation/developer/documentation/_index.md b/docs/content/docs/validation/developer/documentation/_index.md new file mode 100644 index 0000000000..a2476fb71a --- /dev/null +++ b/docs/content/docs/validation/developer/documentation/_index.md @@ -0,0 +1,76 @@ +--- +title: Documentation process +description: How the Spine Validation documentation is authored, built, previewed, and released. +headline: Documentation +--- + +# Documentation process + +This section describes the technical side of the Spine Validation +documentation: how the `docs/` module is organized, which Gradle tasks drive +the build, how source code is embedded into pages, which external tools the +build depends on, and the recurring procedures contributors need to perform. + +The `docs/` module is a *staging area*, not a published site. The pages and +data under it are merged into the [main documentation project][main-documentation] +and published from there to the [spine.io][spine-io] website. The build wiring on this page +exists to let contributors preview, validate, and iterate on the content of +this repository before that merge happens. + +## What lives under `docs/` + +The module is laid out as a Hugo project supplemented by Gradle wiring and a +Go-based code-embedding tool. The top-level layout is: + +| Path | Role | +|------------------|----------------------------------------------------------------------------| +| `content/` | Markdown pages of the documentation, organized by section and version. | +| `data/` | Site data files, including the per-version `sidenav.yml` navigation. | +| `layouts/` | Hugo layout overrides specific to the Validation site. | +| `build.gradle.kts` | Gradle build script for the `:docs` subproject. See "[Build tasks](build-tasks.md)". | +| `_preview/` | Hugo project root used to render and serve the site locally. | +| `_examples/` | Git submodule with the Hello Validation example projects. | +| `_time/` | Git submodule with the Spine Time library, used as the implementation example for custom validation. | +| `_settings/` | Configuration for the code-embedding tool — see "[Embedded examples](embedded-examples.md)". | +| `_script/` | Shell scripts that the Gradle tasks shell out to. | +| `_bin/` | Prebuilt `embed-code-go` binaries for Linux, macOS, and Windows. | + +The underscore prefix marks directories that are *not* part of the Hugo site +tree — Hugo ignores top-level paths starting with `_`. Everything Hugo +actually renders lives under `content/`, `data/`, and `layouts/`. + +## Relationship to the spine.io website + +There is no automated deployment from this repository. The CI workflows +under `.github/workflows/` only build the example sources +(`:docs:buildAll`) and verify that the embedded snippets are in sync with +their sources (`:docs:checkSamples`). Publication happens through the main +documentation project, which pulls the Markdown content of `docs/content/` +together with content from other Spine projects and renders the unified +[spine.io](https://spine.io) site. + +This split has two practical consequences for contributors: + +- The Hugo site rendered under `_preview/public/` is for local inspection + only; treat it as a staging artifact, not as the published site. +- Anything that the main documentation project does not pick up — for + example, files outside `content/` and `data/` — is *not* shipped, no + matter how it renders locally. + +## How to read the rest of this section + +- "[Build tasks](build-tasks.md)" — every Gradle task defined in + `docs/build.gradle.kts`, what each does, and how they depend on each + other. +- "[Embedded examples](embedded-examples.md)" — how source code from the + Validation modules and the `_examples`/`_time` submodules ends up inside + the documentation pages. +- "[External tooling](tooling.md)" — the `site-commons` Hugo theme and the + `embed-code-go` tool, including how each is wired into the build. +- "[Procedures](procedures.md)" — step-by-step recipes for the recurring + documentation tasks (version bumps, submodule refresh, adding pages and + embedded examples, updating external tooling, building and previewing + locally). + +[main-documentation]: https://github.com/SpineEventEngine/documentation +[spine-io]: https://spine.io/ diff --git a/docs/content/docs/validation/developer/documentation/build-tasks.md b/docs/content/docs/validation/developer/documentation/build-tasks.md new file mode 100644 index 0000000000..5d93c17d4e --- /dev/null +++ b/docs/content/docs/validation/developer/documentation/build-tasks.md @@ -0,0 +1,181 @@ +--- +title: Build tasks +description: The Gradle tasks defined for the documentation module, what they do, and how they are wired. +headline: Documentation +--- + +# Build tasks + +The `:docs` subproject is configured in [`docs/build.gradle.kts`][docs-build]. +The tasks declared there are thin Gradle wrappers around shell scripts in +`docs/_script/` and the `embed-code-go` binaries in `docs/_bin/`. This page +documents every task, what it does, where it lands its output, and how the +tasks depend on each other. + +## Working directory and paths + +All shell scripts under `docs/_script/` assume that `docs/` is the current +working directory. The Gradle tasks take care of this automatically — the +`Exec` tasks invoke each script with an absolute path under `$projectDir`, so +running them as `./gradlew :docs:` from the repository root works. + +When invoking the scripts directly (for example, during debugging), `cd` into +`docs/` first: + +```bash +cd docs +./_script/hugo-serve +``` + +The scripts navigate further on their own — for example, `_script/hugo-serve` +enters `_preview/` before launching `hugo server`, and `_script/embed-code` +enters `_bin/` before invoking the embedding tool. + +## Hugo tasks + +These tasks drive Hugo via the scripts in `docs/_script/`. + +### `installDependencies` + +Runs `_script/install-dependencies`, which executes `npm install` inside +`_preview/`. The script installs the Node devDependencies declared in +`_preview/package.json` (`postcss`, `autoprefixer`, +`@fullhuman/postcss-purgecss`, and so on). All Hugo-related tasks depend on +this task, so it is rarely invoked manually. + +### `runSite` + +Runs `_script/hugo-serve` → `hugo server` from `_preview/`. The Hugo dev +server hot-reloads pages on edits to `docs/content/`. This is the standard +way to preview documentation changes locally; see the “Previewing the +documentation locally” recipe in "[Procedures](procedures.md)". + +### `buildSite` + +Runs `_script/hugo-build` → `hugo` from `_preview/`. The Hugo build emits the +static site under `docs/_preview/public/`. The output is intended for local +inspection only — it is *not* the artifact published to spine.io. See the +"Building the documentation locally" recipe in +"[Procedures](procedures.md)". + +## Plugin-version tasks + +These tasks keep the plugin coordinates in the example projects under +`docs/_examples/` aligned with the versions used elsewhere in the +repository. + +The task type is [`UpdatePluginVersion`][update-plugin-version], defined in +`buildSrc/`. It scans recursively for `build.gradle.kts` files under the +configured directory and rewrites declarations of the form +`id("") version ""`. When `kotlinVersion` is also set, +it additionally rewrites `kotlin("") version ""` lines. + +### `updateValidationPluginVersion` + +Updates `id("io.spine.validation") version "…"` in every `build.gradle.kts` +under `docs/_examples/` to `validationVersion` from +[`version.gradle.kts`][version-gradle], and updates `kotlin("…") version "…"` +to `Kotlin.version`. + +### `updateCoreJvmPluginVersion` + +Updates `id("io.spine.core-jvm") version "…"` to `CoreJvmCompiler.version` +from the [`CoreJvmCompiler`][core-jvm-compiler-dep] dependency object in +`buildSrc/`. + +### `updatePluginVersions` + +Aggregator that depends on both tasks above. This is the task contributors +run after bumping the Validation version or the CoreJvm Compiler version; +see the recipes in "[Procedures](procedures.md)". + +## Code-embedding tasks + +These tasks invoke the `embed-code-go` binaries under `docs/_bin/`. Both +depend on `updatePluginVersions`, so the example sources always reflect the +current plugin versions before snippets are embedded or checked. + +### `embedCode` + +Runs `_script/embed-code`. The script first runs + +```bash +git submodule update --remote --merge --recursive +``` + +so that `_examples/` and `_time/` track their default remote branches. It +then invokes `embed-code-macos` with `-mode="embed"` and the configuration at +`_settings/embed-code.yml`, which rewrites the fenced regions in the Markdown +pages under `content/` from their source snippets. Run this task manually +after editing an embedded snippet or after pointing a source root at a new +commit. See "[Embedded examples](embedded-examples.md)" for the +configuration format and "[Procedures](procedures.md)" for the day-to-day +recipe. + +### `checkSamples` + +Runs `_script/check-samples`. The script selects `embed-code-linux` when the +`GITHUB_ACTIONS` environment variable is `true`, and `embed-code-macos` +otherwise, then invokes it with `-mode="check"`. The tool exits non-zero if +any embedded snippet drifts from its source. This task is executed by the +[Code Embedding][check-code-embedding] GitHub workflow on every pull +request. + +## Aggregate tasks + +These tasks tie the example projects under `docs/_examples/` into the main +build so that the embedded code is actually compilable. + +### `publishAllToMavenLocal` + +Aggregator that depends on every `PublishToMavenLocal` task across the root +project's subprojects. Running it stages the current Validation artifacts to +the local Maven repository, where the example projects can resolve them +through `mavenLocal()`. + +### `buildExamples` + +Custom `RunGradle` task that delegates to the `buildAll` task inside +`docs/_examples/`. It depends on `publishAllToMavenLocal` (so the examples +build against the just-published artifacts) and on `updatePluginVersions` +(so the example build files reference the current plugin versions). + +### `buildAll` + +The conventional "build everything for the documentation" entry point. +Depends on `publishAllToMavenLocal` and `buildExamples`. This is the task +invoked by the [Code Embedding][check-code-embedding] GitHub workflow to +validate that every embedded snippet still compiles inside a real Gradle +build. + +## Task dependency map + +| Task | Depends on | +|---------------------------------|-------------------------------------------------------------| +| `installDependencies` | — | +| `runSite` | `installDependencies` | +| `buildSite` | `installDependencies` | +| `updateValidationPluginVersion` | — | +| `updateCoreJvmPluginVersion` | — | +| `updatePluginVersions` | `updateValidationPluginVersion`, `updateCoreJvmPluginVersion` | +| `embedCode` | `updatePluginVersions` | +| `checkSamples` | `updatePluginVersions` | +| `publishAllToMavenLocal` | all `PublishToMavenLocal` tasks across the root project | +| `buildExamples` | `publishAllToMavenLocal`, `updatePluginVersions` | +| `buildAll` | `publishAllToMavenLocal`, `buildExamples` | + +## What's next + +- "[Embedded examples](embedded-examples.md)" — how `embedCode` and + `checkSamples` decide what source goes into which page. +- "[External tooling](tooling.md)" — the `site-commons` Hugo theme that the + Hugo tasks render against, and how the `embed-code-go` binaries get into + `_bin/`. +- "[Procedures](procedures.md)" — the recipes that combine these tasks into + end-to-end contributor workflows. + +[docs-build]: https://github.com/SpineEventEngine/validation/blob/master/docs/build.gradle.kts +[update-plugin-version]: https://github.com/SpineEventEngine/validation/blob/master/buildSrc/src/main/kotlin/io/spine/gradle/docs/UpdatePluginVersion.kt +[version-gradle]: https://github.com/SpineEventEngine/validation/blob/master/version.gradle.kts +[core-jvm-compiler-dep]: https://github.com/SpineEventEngine/validation/blob/master/buildSrc/src/main/kotlin/io/spine/dependency/local/CoreJvmCompiler.kt +[check-code-embedding]: https://github.com/SpineEventEngine/validation/blob/master/.github/workflows/check-code-embedding.yml diff --git a/docs/content/docs/validation/developer/documentation/embedded-examples.md b/docs/content/docs/validation/developer/documentation/embedded-examples.md new file mode 100644 index 0000000000..e6671c378a --- /dev/null +++ b/docs/content/docs/validation/developer/documentation/embedded-examples.md @@ -0,0 +1,208 @@ +--- +title: Embedded examples +description: How example source code is embedded into the documentation pages. +headline: Documentation +--- + +# Embedded examples + +The documentation embeds snippets from real source files instead of copying their +content into Markdown files. This keeps the snippets in lock-step with the code +they document: when a method signature, a Protobuf option, or an example +project file changes, the documentation either updates automatically (when +`:docs:embedCode` runs) or fails CI (when `:docs:checkSamples` runs against +a stale page). There are four source pools the documentation pulls from: + +1. The Validation library code itself — the repository root and the + production modules under it, exposed through the `root`, `runtime`, + `java`, and `context` source roots. +2. The Validation examples — the `docs/_examples/` Git submodule, exposed + through the `examples` source root. +3. The Spine Time library — the `docs/_time/` Git submodule, exposed + through the `time` source root. +4. The documentation tree — the `docs/` directory, exposed through the + `docs` source root. + +## Example sources + +The `docs/_examples/` directory is a Git submodule pointing to the +[`spine-examples/hello-validation`][hello-validation] repository. It hosts +the small, runnable example projects that the User's Guide walks through: + +| Project | Purpose | +|-------------------------------|------------------------------------------------------------------------------------------| +| `first-model` | The minimal Protobuf model with field-level constraints used in "[Getting started](../../user/01-getting-started/)". | +| `first-model-with-framework` | The same model extended with `MessageValidator` and registry wiring. | +| `external` | A consumer project that depends on validated messages from another module. | + +These projects compile and run against the just-built Validation artifacts. +The `:docs:buildExamples` task delegates a `buildAll` invocation into +`docs/_examples/`, and `:docs:publishAllToMavenLocal` stages the Validation +artifacts the example projects resolve through `mavenLocal()`. See +"[Build tasks](build-tasks.md)" for the wiring. + +## Spine Time as the implementation example + +The custom-validation chapter needs a real, non-trivial implementation of +the extension points described in "[Extension points](../extension-points.md)" +and "[Adding a new built-in validation option](../adding-a-built-in-option.md)". +[Spine Time][spine-time] is that example: it defines its own validation +options (`(when)`, `(time)`) and implements them through the same +extension points the documentation describes. + +To embed snippets from Spine Time's actual source — not a copy that would +inevitably drift — the library is included as the `docs/_time/` Git +submodule pointing at [`SpineEventEngine/time`][spine-time]. The +code-embedding tool then reads snippets from that working tree through +the `$time` source root. + +## The `_settings/embed-code.yml` file + +The configuration file [`docs/_settings/embed-code.yml`][embed-code-yml] +declares the source roots the embedding tool understands, where the +documentation pages live, and which files are considered embeddable. + + + +```yaml +code-path: + - name: "root" + path: "../.." + - name: "examples" + path: "../_examples" + - name: "runtime" + path: "../../jvm-runtime" + - name: "java" + path: "../../java" + - name: "context" + path: "../../context" + - name: "time" + path: "../_time" + - name: "docs" + path: ".." +docs-path: "../content/docs/" +code-includes: + - ".gitignore" + - "**/*.kts" + - "**/*.md" + - "**/*.proto" + - "**/*.java" + - "**/*.kt" + - "**/*.yml" +``` + +### Source roots (`code-path`) + +Each entry maps a logical *name* to a directory *path*, resolved relative +to `docs/_bin/` (because the scripts `cd _bin` before invoking the +binary). A page references a source root by its name, prefixed with `$`. + +| Name | Path | What it exposes | +|------------|---------------------|--------------------------------------------------------------------------| +| `root` | `../..` | The Validation repository root — top-level files (`version.gradle.kts`, `build.gradle.kts`, …) and any module not separately mapped. | +| `examples` | `../_examples` | The Hello Validation example projects (the submodule above). | +| `runtime` | `../../jvm-runtime` | The `:jvm-runtime` module — runtime library sources used in "[Runtime library](../runtime-library.md)". | +| `java` | `../../java` | The `:java` module — Java code-generation sources used in "[Java code generation](../java-code-generation.md)". | +| `context` | `../../context` | The `:context` module — the custom-validation context sources. | +| `time` | `../_time` | The Spine Time submodule used as the implementation example for custom validation. | +| `docs` | `..` | The `docs/` directory — documentation settings, scripts, and other documentation-local files. | + +To embed from Spine Time, use the `$time` source root with a path relative +to `docs/_time/`. + +### Pages directory (`docs-path`) + +`docs-path: "../content/docs/"` points the tool at the Markdown tree it +should scan when running `embedCode` or `checkSamples`. Only files under +this directory are considered for embedding. + +### Embeddable file types (`code-includes`) + +The globs under `code-includes` filter which source files the tool will +read when resolving an `` block. Adding a new file extension +(for example, `**/*.json` for embedded JSON snippets) means appending it +to this list. + +## Embedding syntax on the page side + +An `` element marks a region in a Markdown page that the tool +manages. The tool replaces the *fenced code block* immediately following +the element with the content extracted from the referenced source file. +When the element has `start` and `end` attributes, the tool embeds only +the lines between the matching patterns. When it has only `file`, the +tool embeds the whole file. + +This page describes the syntax used in the Validation documentation. +For the complete `embed-code-go` syntax — including named fragments, +multi-piece fragments, omitted boundaries, and the exact line-pattern +rules — see the upstream [embedding guide][embed-code-go-embedding]. + +````markdown + + +```kotlin +val validationVersion by extra("2.0.0-SNAPSHOT.419") +``` +```` + +The attributes used most often in Validation pages are: + +- `file` — `$source-root/relative/path/to/file.ext` where `source-root` + is a name from `code-path`. +- `start` — an extended glob-style pattern matched against a single line. + The matching line is the *first* line included. +- `end` — an extended glob-style pattern matched against a single line. + The matching line is the *last* line included. To include a single line, + use the same pattern for both. +- The language tag on the fenced block (`kotlin`, `java`, `proto`, …) + controls syntax highlighting; the tool does not derive it from the + source extension. + +Patterns match anywhere in a line by default. Use `^` at the beginning +or `$` at the end when the match must be anchored to the start or end of +the line. + +Other working examples in the repository to copy from: + +- A Java method body — see [`runtime-library.md`][runtime-library] for + patterns like `start="public static M check"` with + `end="^ \}"`. +- A Kotlin class declaration — same page, the `DetectedViolation` snippet. +- A Gradle DSL block — see [`build-and-release.md`][build-and-release] + for the `spinePublishing { … }` example, anchored with `end="^}"`. + +## How embedding runs + +The two Gradle tasks that drive the embedding flow are documented on +"[Build tasks](build-tasks.md)": + +- `:docs:embedCode` rewrites the fenced regions in place. Use it after + editing a `start`/`end` pattern, adding a new `` element, + or pointing a source root at a new commit. +- `:docs:checkSamples` verifies that every fenced region matches what + the tool would produce now, without writing. The + [Code Embedding][check-code-embedding] workflow runs this on every + pull request. + +Both tasks shell out to the `embed-code-go` binaries checked in under +`docs/_bin/`. See "[External tooling](tooling.md)" for how those +binaries are kept up to date. + +## What's next + +- "[External tooling](tooling.md)" — the `site-commons` Hugo theme and + the `embed-code-go` tool, including how each is updated. +- "[Procedures](procedures.md)" — the day-to-day recipes for adding a + new embedded example and for refreshing the Spine Time submodule. + +[hello-validation]: https://github.com/spine-examples/hello-validation +[spine-time]: https://github.com/SpineEventEngine/time +[embed-code-yml]: https://github.com/SpineEventEngine/validation/blob/master/docs/_settings/embed-code.yml +[embed-code-go-embedding]: https://github.com/SpineEventEngine/embed-code-go/blob/master/EMBEDDING.md +[runtime-library]: https://github.com/SpineEventEngine/validation/blob/master/docs/content/docs/validation/developer/runtime-library.md +[build-and-release]: https://github.com/SpineEventEngine/validation/blob/master/docs/content/docs/validation/developer/build-and-release.md +[check-code-embedding]: https://github.com/SpineEventEngine/validation/blob/master/.github/workflows/check-code-embedding.yml diff --git a/docs/content/docs/validation/developer/documentation/procedures.md b/docs/content/docs/validation/developer/documentation/procedures.md new file mode 100644 index 0000000000..03d73ad86c --- /dev/null +++ b/docs/content/docs/validation/developer/documentation/procedures.md @@ -0,0 +1,318 @@ +--- +title: Procedures +description: Step-by-step recipes for recurring documentation-related tasks. +headline: Documentation +--- + +# Procedures + +Each section below is an executable recipe. Unless stated otherwise, run +commands from the repository root and prefix Gradle tasks with `./gradlew`. +The conceptual background for each procedure lives on the sibling pages: +"[Build tasks](build-tasks.md)", "[Embedded examples](embedded-examples.md)", +and "[External tooling](tooling.md)". + +## Incrementing the version of Validation + +1. Update the version literal in [`version.gradle.kts`][version-gradle]: + + ```kotlin + val validationVersion by extra("") + ``` + For the detailed instructions on selecting an increment, + see the [Versioning policy][versioning-policy] of the Spine SDK. + +2. Propagate the new version into the example projects' plugin coordinates: + + ```bash + ./gradlew :docs:updatePluginVersions + ``` + + This rewrites the `io.spine.validation` plugin version (and the + `io.spine.core-jvm` plugin version) in every `build.gradle.kts` under + `docs/_examples/`. + +3. Commit `version.gradle.kts` on its own with: + + ```text + Bump version -> `` + ``` + +4. Commit the remaining files touched by step 2 with: + + ```text + Bump Validation -> `` + ``` +5. Push the changes to the `hello-validation` repository, + which the `docs/_examples/` submodule points to: + + ```bash + cd docs/_examples + git push + cd - + ``` + +6. Run a clean build and refresh the dependency reports: + + ```bash + ./gradlew clean build + ``` + + Then commit the regenerated `pom.xml` and `dependencies.md` with: + `Update dependency reports` message. + + + This step follows the same convention used elsewhere in the Spine SDK + projects. + +## Updating the version of the CoreJvm Compiler + +1. Update the version in the `CoreJvmCompiler` dependency object under + [`buildSrc`][core-jvm-compiler-dep]. + +2. Propagate the new version into the example projects' plugin coordinates: + + ```bash + ./gradlew :docs:updatePluginVersions + ``` + + This rewrites the `io.spine.core-jvm` plugin version (and the + `io.spine.validation` plugin version) in every `build.gradle.kts` under + `docs/_examples/`. + +## Refreshing embedded example sources from Spine Time + +The Spine Time library at `docs/_time/` is a Git submodule. Use these +steps when first cloning the repository, when refreshing the submodule to +its default remote branch, or when intentionally pinning it to a specific +commit. + +1. Initialize and fetch the submodule on a fresh clone: + + ```bash + git submodule update --init --recursive docs/_time + ``` + +2. To refresh `_time/` to its default remote branch and re-embed snippets + from that revision, run: + + ```bash + ./gradlew :docs:embedCode + ./gradlew :docs:checkSamples + ``` + + The `:docs:embedCode` task runs + `git submodule update --remote --merge --recursive` before invoking the + embedding tool, so this path intentionally accepts the latest remote + revision selected by the submodule configuration. + +3. To pin `_time/` to a specific commit instead, fetch and check it out + inside the submodule: + + ```bash + cd docs/_time + git fetch origin + git checkout + cd - + ``` + +4. Re-embed snippets without running `:docs:embedCode`, because that task + would move the submodule back to the default remote branch before + embedding: + + ```bash + ./gradlew :docs:updatePluginVersions + cd docs/_bin + ./embed-code-macos -config-path="../_settings/embed-code.yml" -mode="embed" + cd - + ./gradlew :docs:checkSamples + ``` + +5. Commit the updated submodule pointer and any snippets changed by the + embedding step: + + ```bash + git add docs/_time docs/content/docs + git commit -m "Update Spine Time submodule -> " + ``` + +## Adding a new embedded code example + +1. If the source file lives outside the existing source roots in + [`_settings/embed-code.yml`][embed-code-yml], add a new entry under + `code-path` (a `name` plus a path relative to `docs/_bin/`). If the + file extension is not yet listed, add a glob under `code-includes`. + +2. In the target Markdown page, write an `` element followed + by an empty fenced code block. For example: + + ```markdown + + + ``` + + The `start` and `end` attributes are regular expressions matched + against single lines; the matching lines are included. + +3. Embed and verify: + + ```bash + ./gradlew :docs:embedCode + ./gradlew :docs:checkSamples + ``` + + The fenced block under the element is now populated with the snippet. + +4. Preview the page locally (see "Previewing the documentation locally" + below) and confirm the snippet renders with the right syntax + highlighting. + +5. Commit the page, the snippet contents, and any changes to + `_settings/embed-code.yml`. + +For the underlying mechanics, see "[Embedded examples](embedded-examples.md)". + +## Adding or updating a documentation page + +1. Create or edit the Markdown file under + `docs/content/docs/validation/
/`. Match the frontmatter + convention used by the surrounding pages (`title`, `description`, + `headline: Documentation`). + +2. Keep the navigation in sync. Update + `docs/data/docs/validation/2-0-0-snapshot/sidenav.yml`: + + - For a new page, add a `page`/`file_path` entry under the + appropriate parent. The `file_path` is relative to + `docs/content/docs/validation/` and omits the `.md` extension; an + `_index.md` maps to its directory path (for example, + `developer/documentation`). + - For a renamed or moved page, update the existing `file_path`. + - For a deleted page, remove the entry. + + Do not edit `sidenav.yml` files under other version directories + unless you are intentionally amending a historical version. + +3. Preview locally (see "Previewing the documentation locally") and + click through every internal link. + +4. Follow the project documentation guidelines in + [`documentation-guidelines.md`][doc-guidelines] — formatting of file + and directory names as code, reference-style external links, no + widows/runts/orphans/rivers. + +## Updating `site-commons` + +This is the procedure documented under "[Theme updates][theme-updates]" +in the `site-commons` README, wrapped with the verification steps used +in this repository. + +1. From `docs/_preview/`, pull the latest theme version: + + ```bash + cd docs/_preview + hugo mod get -u github.com/SpineEventEngine/site-commons + cd - + ``` + +2. Preview the site and click through the navigation, code blocks, and + embedded snippets: + + ```bash + ./gradlew :docs:runSite + ``` + +3. Commit and push the resulting changes to + `docs/_preview/go.mod` and `docs/_preview/go.sum`: + + ```bash + git add docs/_preview/go.mod docs/_preview/go.sum + git commit -m "Update site-commons" + ``` + +## Updating `embed-code-go` + +The tool is consumed as prebuilt binaries under `docs/_bin/`. The +authoritative copies are published by the upstream project under +[`embed-code-go/bin`][embed-code-bin]. We do *not* build the tool as +part of the Validation documentation build — see the upstream repository +for any build, test, or release questions. + +1. From [`embed-code-go/bin`][embed-code-bin], download the three + binaries on the branch or tag you want to ship: + `embed-code-linux`, `embed-code-macos`, `embed-code-windows.exe`. + +2. Replace the files of the same names under `docs/_bin/`. + +3. Make sure the macOS and Linux binaries are executable: + + ```bash + chmod +x docs/_bin/embed-code-macos docs/_bin/embed-code-linux + ``` + +4. Verify that the new binaries still produce the same embedded output + the repository expects: + + ```bash + ./gradlew :docs:checkSamples + ``` + + If `checkSamples` reports drift caused by the tool itself (formatting, + whitespace, …), run `./gradlew :docs:embedCode` and inspect the diff + before committing. + +5. Commit the updated binaries under `docs/_bin/` with a message that + names the upstream commit they were pulled from. + +## Building the documentation locally + +1. Build the site: + + ```bash + ./gradlew :docs:buildSite + ``` + +2. The generated static site appears under `docs/_preview/public/`. Open + `docs/_preview/public/index.html` in a browser to inspect the output, + or serve the directory through any static file server. + +3. Treat this output as a *staging artifact only*. Publication to + spine.io happens through the main documentation project, not from + this repository — see "[Documentation process](_index.md)" for the + relationship. + +## Previewing the documentation locally + +1. Start the Hugo dev server: + + ```bash + ./gradlew :docs:runSite + ``` + +2. Open the URL printed by `hugo server`, typically + `http://localhost:1313/`. + +3. Edits to Markdown files under `docs/content/` hot-reload + automatically. Edits to `docs/data/` files (including `sidenav.yml`) + and to Hugo layouts require a restart of the server. + +4. To stop the server, press `Ctrl+C` in the terminal running the task. + +## What's next + +- "[Documentation process](_index.md)" — overview and how this section + fits into the wider documentation pipeline. +- "[Build tasks](build-tasks.md)" — reference for every Gradle task + these recipes invoke. + +[version-gradle]: https://github.com/SpineEventEngine/validation/blob/master/version.gradle.kts +[core-jvm-compiler-dep]: https://github.com/SpineEventEngine/validation/blob/master/buildSrc/src/main/kotlin/io/spine/dependency/local/CoreJvmCompiler.kt +[embed-code-yml]: https://github.com/SpineEventEngine/validation/blob/master/docs/_settings/embed-code.yml +[doc-guidelines]: https://github.com/SpineEventEngine/validation/blob/master/.agents/documentation-guidelines.md +[theme-updates]: https://github.com/SpineEventEngine/site-commons#theme-updates +[embed-code-go]: https://github.com/SpineEventEngine/embed-code-go +[embed-code-bin]: https://github.com/SpineEventEngine/embed-code-go/tree/master/bin +[versioning-policy]: https://github.com/SpineEventEngine/documentation/wiki/Versioning diff --git a/docs/content/docs/validation/developer/documentation/tooling.md b/docs/content/docs/validation/developer/documentation/tooling.md new file mode 100644 index 0000000000..90be11e87b --- /dev/null +++ b/docs/content/docs/validation/developer/documentation/tooling.md @@ -0,0 +1,139 @@ +--- +title: External tooling +description: The external tools the documentation build depends on and how they are consumed. +headline: Documentation +--- + +# External tooling + +The documentation build leans on three external pieces of tooling: the +[`site-commons`][site-commons] Hugo theme, the [`embed-code-go`][embed-code-go] +tool, and the Hugo + Node toolchain that drives the static-site build. This +page documents what each is, how it is wired into the build, and where it is +pinned. The step-by-step recipes for updating each live in +"[Procedures](procedures.md)". + +## `site-commons` + +[`site-commons`][site-commons] is the shared Hugo theme and layout library +used by the documentation sites of Spine projects. It provides the +navigation chrome, the sidenav rendering that consumes the +[`sidenav.yml`][sidenav-yml] files, code-highlighting partials, and other +Hugo components that are common across Spine sites. + +It is consumed as a Hugo module. Two files wire it in: + +- `docs/_preview/hugo.toml` imports `site-commons` and the local `../..` + module (the `docs/` directory itself) under `[module] [[module.imports]]`: + + ```toml + [module] + [[module.imports]] + path = '../..' + [[module.imports]] + path = 'github.com/SpineEventEngine/site-commons' + ``` + + Hugo modules sit on top of a Go module, so this import is resolved through + `_preview/go.mod`. + +- `docs/_preview/go.mod` pins the exact `site-commons` version, expressed as + a pseudo-version timestamp: + + ```text + require ( + github.com/SpineEventEngine/site-commons v0.0.0-20260507130158-84db050dfe11 // indirect + github.com/gohugoio/hugo-mod-bootstrap-scss/v5 v5.20300.20800 // indirect + ) + ``` + +The `hugo-mod-bootstrap-scss` dependency is a transitive Hugo module pulled +in by `site-commons`; it is listed here because Hugo resolves the full +module graph through this `go.mod`. + +The repository-root `docs/go.mod` is a separate file for tooling that +inspects the `docs/` directory as a Go module on its own. The +*authoritative* pin for what gets rendered locally is the one in +`_preview/go.mod`. + +### Updating `site-commons` + +The procedure is the one documented under "[Theme updates][theme-updates]" +in the `site-commons` README. From `docs/_preview/`, run: + +```bash +hugo mod get -u github.com/SpineEventEngine/site-commons +``` + +Then commit and push the resulting changes to `go.mod` and `go.sum`. The +companion "Updating `site-commons`" recipe in +"[Procedures](procedures.md)" wraps this command with the surrounding +verification steps (preview, sanity check). + +## `embed-code-go` + +[`embed-code-go`][embed-code-go] is the command-line tool that powers +`:docs:embedCode` and `:docs:checkSamples`. It reads the +`` elements described in "[Embedded examples](embedded-examples.md)", +resolves each `file` reference against the source roots in +[`_settings/embed-code.yml`][embed-code-yml], and either rewrites the +fenced code block beneath the element (`-mode="embed"`) or fails non-zero +on drift (`-mode="check"`). + +The tool is consumed as **prebuilt binaries checked into the repository**, +not as a Go module or downloaded artifact. The binaries live under +`docs/_bin/`: + +| File | When it is used | +|----------------------------|--------------------------------------------------------------| +| `embed-code-linux` | `_script/check-samples` when `GITHUB_ACTIONS=true` (CI). | +| `embed-code-macos` | `_script/check-samples` locally; `_script/embed-code` always. | +| `embed-code-windows.exe` | Currently not selected by either script. | + +There is no version string recorded in this repository, and the +documentation build does *not* compile the tool. Updating to a new +release means downloading the corresponding binaries from +[`embed-code-go/bin`][embed-code-bin] in the upstream repository and +replacing the files under `docs/_bin/`. The step-by-step recipe is +"Updating `embed-code-go`" in "[Procedures](procedures.md)". + +## Hugo and the Node toolchain + +The `:docs:installDependencies` task runs `npm install` inside `_preview/` +to install the Node packages that Hugo's asset pipeline consumes. The +relevant declarations are in `docs/_preview/package.json`: + +```json +"devDependencies": { + "@fullhuman/postcss-purgecss": "^7.0.2", + "autoprefixer": "^10.4.22", + "postcss": "^8.5.10", + "postcss-cli": "^11.0.1", + "postcss-discard-comments": "^7.0.5" +} +``` + +These power the PostCSS processing chain that Hugo invokes for CSS assets +(autoprefixing, purging unused rules from the Bootstrap-based theme). +`package-lock.json` is committed and is the authoritative pin. + +Hugo itself is *not* installed by the build — the `_script/hugo-serve` and +`_script/hugo-build` scripts assume that `hugo` is on the `PATH`. Install it +from the [Hugo project][hugo-install] before running `:docs:runSite` or +`:docs:buildSite` for the first time. The version is not pinned in this +repository; use a recent extended release that matches what `site-commons` +expects. + +## What's next + +- "[Procedures](procedures.md)" — the recipes for updating `site-commons` + and `embed-code-go`, plus the local build and preview commands that use + the Hugo and Node toolchain described above. + +[site-commons]: https://github.com/SpineEventEngine/site-commons +[theme-updates]: https://github.com/SpineEventEngine/site-commons#theme-updates +[sidenav-yml]: https://github.com/SpineEventEngine/validation/blob/master/docs/data/docs/validation/2-0-0-snapshot/sidenav.yml +[embed-code-yml]: https://github.com/SpineEventEngine/validation/blob/master/docs/_settings/embed-code.yml +[embed-code-go]: https://github.com/SpineEventEngine/embed-code-go +[embed-code-bin]: https://github.com/SpineEventEngine/embed-code-go/tree/master/bin +[hugo-install]: https://gohugo.io/installation/ diff --git a/docs/content/docs/validation/user/01-getting-started/adding-to-build.md b/docs/content/docs/validation/user/01-getting-started/adding-to-build.md index 40094039a8..fad7d89420 100644 --- a/docs/content/docs/validation/user/01-getting-started/adding-to-build.md +++ b/docs/content/docs/validation/user/01-getting-started/adding-to-build.md @@ -90,7 +90,7 @@ Add the Validation plugin to the build. ```kotlin plugins { module - id("io.spine.validation") version "2.0.0-SNAPSHOT.418" + id("io.spine.validation") version "2.0.0-SNAPSHOT.419" } ``` diff --git a/docs/data/docs/validation/2-0-0-snapshot/sidenav.yml b/docs/data/docs/validation/2-0-0-snapshot/sidenav.yml index 464e618c4d..3430f06d37 100644 --- a/docs/data/docs/validation/2-0-0-snapshot/sidenav.yml +++ b/docs/data/docs/validation/2-0-0-snapshot/sidenav.yml @@ -102,3 +102,16 @@ file_path: developer/testing-strategy - page: Build, packaging, and release file_path: developer/build-and-release + - page: Documentation process + key: documentation + children: + - page: Overview + file_path: developer/documentation + - page: Build tasks + file_path: developer/documentation/build-tasks + - page: Embedded examples + file_path: developer/documentation/embedded-examples + - page: External tooling + file_path: developer/documentation/tooling + - page: Procedures + file_path: developer/documentation/procedures diff --git a/pom.xml b/pom.xml index 47985d6de3..a4ae4397ce 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ all modules and does not describe the project structure per-subproject. --> io.spine.tools validation -2.0.0-SNAPSHOT.418 +2.0.0-SNAPSHOT.419 2015 diff --git a/version.gradle.kts b/version.gradle.kts index 2672854e00..aae97b27a8 100644 --- a/version.gradle.kts +++ b/version.gradle.kts @@ -27,4 +27,4 @@ /** * The version of the Validation library to publish. */ -val validationVersion by extra("2.0.0-SNAPSHOT.418") +val validationVersion by extra("2.0.0-SNAPSHOT.419")