diff --git a/buildSrc/src/main/kotlin/BuildExtensions.kt b/buildSrc/src/main/kotlin/BuildExtensions.kt index 9e51bca3..87739c3d 100644 --- a/buildSrc/src/main/kotlin/BuildExtensions.kt +++ b/buildSrc/src/main/kotlin/BuildExtensions.kt @@ -1,5 +1,5 @@ /* - * Copyright 2023, TeamDev. All rights reserved. + * 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. @@ -31,6 +31,7 @@ import io.spine.internal.dependency.GradleDoctor import io.spine.internal.dependency.Kotest import io.spine.internal.dependency.Kover import io.spine.internal.dependency.ProtoData +import io.spine.internal.dependency.ProtoTap import io.spine.internal.dependency.Protobuf import io.spine.internal.dependency.Spine import io.spine.internal.gradle.standardToSpineSdk @@ -81,8 +82,9 @@ val PluginDependenciesSpec.mcJava: Spine.McJava /** * Shortcut to [ProtoData] dependency object. * - * This plugin is in Gradle Portal. But when used in pair with [mcJava], it cannot be applied - * directly to a project. It is so, because [mcJava] uses [protoData] as its dependency. + * This plugin is published at Gradle Portal. But when used in a pair with [mcJava], + * it cannot be applied directly to a project. + * It is so, because [mcJava] uses [protoData] as its dependency. * And buildscript's classpath ends up with both of them. */ val PluginDependenciesSpec.protoData: ProtoData @@ -95,8 +97,8 @@ val PluginDependenciesSpec.protoData: ProtoData * declared in auto-generated `org.gradle.kotlin.dsl.PluginAccessors.kt` file. * It conflicts with our own declarations. * - * Declaring of top-level shortcuts eliminates need in applying plugins - * using fully-qualified name of dependency objects. + * Declaring of top-level shortcuts eliminates the need in applying plugins + * using fully qualified name of dependency objects. * * It is still possible to apply a plugin with a custom version, if needed. * Just declare a version again on the returned [PluginDependencySpec]. @@ -117,6 +119,9 @@ val PluginDependenciesSpec.errorprone: PluginDependencySpec val PluginDependenciesSpec.protobuf: PluginDependencySpec get() = id(Protobuf.GradlePlugin.id) +val PluginDependenciesSpec.prototap: PluginDependencySpec + get() = id(ProtoTap.gradlePluginId).version(ProtoTap.version) + val PluginDependenciesSpec.`gradle-doctor`: PluginDependencySpec get() = id(GradleDoctor.pluginId).version(GradleDoctor.version) @@ -132,9 +137,9 @@ val PluginDependenciesSpec.kover: PluginDependencySpec * Configures the dependencies between third-party Gradle tasks * and those defined via ProtoData and Spine Model Compiler. * - * It is required in order to avoid warnings in build logs, detecting the undeclared + * It is required to avoid warnings in build logs, detecting the undeclared * usage of Spine-specific task output by other tasks, - * e.g. the output of `launchProtoData` is used by `compileKotlin`. + * e.g., the output of `launchProtoData` is used by `compileKotlin`. */ @Suppress("unused") fun Project.configureTaskDependencies() { diff --git a/buildSrc/src/main/kotlin/DependencyResolution.kt b/buildSrc/src/main/kotlin/DependencyResolution.kt index aa2eb715..7016e404 100644 --- a/buildSrc/src/main/kotlin/DependencyResolution.kt +++ b/buildSrc/src/main/kotlin/DependencyResolution.kt @@ -1,5 +1,5 @@ /* - * Copyright 2023, TeamDev. All rights reserved. + * 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. @@ -57,7 +57,7 @@ import org.gradle.api.artifacts.ConfigurationContainer import org.gradle.api.artifacts.ResolutionStrategy /** - * The function to be used in `buildscript` when a fully-qualified call must be made. + * The function to be used in `buildscript` when a fully qualified call must be made. */ @Suppress("unused") fun doForceVersions(configurations: ConfigurationContainer) { @@ -122,6 +122,10 @@ private fun ResolutionStrategy.forceTestDependencies() { private fun ResolutionStrategy.forceTransitiveDependencies() { force( Asm.lib, + Asm.tree, + Asm.analysis, + Asm.util, + Asm.commons, AutoValue.annotations, CommonsCli.lib, CommonsCodec.lib, diff --git a/buildSrc/src/main/kotlin/io/spine/internal/dependency/Asm.kt b/buildSrc/src/main/kotlin/io/spine/internal/dependency/Asm.kt index 82550efe..a6339fb5 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/dependency/Asm.kt +++ b/buildSrc/src/main/kotlin/io/spine/internal/dependency/Asm.kt @@ -29,6 +29,14 @@ package io.spine.internal.dependency // https://asm.ow2.io/ @Suppress("unused", "ConstPropertyName") object Asm { - private const val version = "9.2" + private const val version = "9.6" const val lib = "org.ow2.asm:asm:$version" + + // We use the following artifacts only to force the versions + // of the dependencies which are transitive for us. + // + const val tree = "org.ow2.asm:asm-tree:$version" + const val analysis = "org.ow2.asm:asm-analysis:$version" + const val util = "org.ow2.asm:asm-util:$version" + const val commons = "org.ow2.asm:asm-commons:$version" } diff --git a/buildSrc/src/main/kotlin/io/spine/internal/dependency/Caffeine.kt b/buildSrc/src/main/kotlin/io/spine/internal/dependency/Caffeine.kt new file mode 100644 index 00000000..1ad7a6bc --- /dev/null +++ b/buildSrc/src/main/kotlin/io/spine/internal/dependency/Caffeine.kt @@ -0,0 +1,41 @@ +/* + * 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 + * + * 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. + */ + +package io.spine.internal.dependency + +/** + * A [high performance](https://github.com/ben-manes/caffeine/wiki/Benchmarks), + * [near optimal](https://github.com/ben-manes/caffeine/wiki/Efficiency) caching library. + * + * This library is a transitive dependency for us via ErrorProne. + * + * @see Caffeine at GitHub + */ +@Suppress("unused") +object Caffeine { + private const val version = "3.0.5" + const val lib = "com.github.ben-manes.caffeine:caffeine:$version" +} diff --git a/buildSrc/src/main/kotlin/io/spine/internal/dependency/Jacoco.kt b/buildSrc/src/main/kotlin/io/spine/internal/dependency/Jacoco.kt new file mode 100644 index 00000000..50772418 --- /dev/null +++ b/buildSrc/src/main/kotlin/io/spine/internal/dependency/Jacoco.kt @@ -0,0 +1,37 @@ +/* + * Copyright 2023, 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. + */ + +package io.spine.internal.dependency + +/** + * Code coverage library for Java. + * + * @see Releases + */ +@Suppress("ConstPropertyName") +object Jacoco { + const val version = "0.8.12" +} diff --git a/buildSrc/src/main/kotlin/io/spine/internal/dependency/Kover.kt b/buildSrc/src/main/kotlin/io/spine/internal/dependency/Kover.kt index 30f81f5c..a4dca1f7 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/dependency/Kover.kt +++ b/buildSrc/src/main/kotlin/io/spine/internal/dependency/Kover.kt @@ -29,7 +29,7 @@ package io.spine.internal.dependency // https://github.com/Kotlin/kotlinx-kover @Suppress("unused", "ConstPropertyName") object Kover { - const val version = "0.7.4" + const val version = "0.7.6" const val id = "org.jetbrains.kotlinx.kover" const val classpath = "org.jetbrains.kotlinx:kover-gradle-plugin:$version" } diff --git a/buildSrc/src/main/kotlin/io/spine/internal/dependency/Log4j2.kt b/buildSrc/src/main/kotlin/io/spine/internal/dependency/Log4j2.kt new file mode 100644 index 00000000..1da0d72c --- /dev/null +++ b/buildSrc/src/main/kotlin/io/spine/internal/dependency/Log4j2.kt @@ -0,0 +1,42 @@ +/* + * 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 + * + * 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. + */ + +package io.spine.internal.dependency + +/** + * An open-source logging framework. + * + * Spine uses its own [logging library][Spine.Logging], but also + * provides a backend implementation for [Log4j2]. This is why + * this dependency is needed. + * + * @see Log4j2 releases at GitHub + */ +@Suppress("unused", "ConstPropertyName") +object Log4j2 { + private const val version = "2.20.0" + const val core = "org.apache.logging.log4j:log4j-core:$version" +} diff --git a/buildSrc/src/main/kotlin/io/spine/internal/dependency/ProtoData.kt b/buildSrc/src/main/kotlin/io/spine/internal/dependency/ProtoData.kt index b127c2fe..d6d7ce54 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/dependency/ProtoData.kt +++ b/buildSrc/src/main/kotlin/io/spine/internal/dependency/ProtoData.kt @@ -65,7 +65,7 @@ object ProtoData { * The version of ProtoData dependencies. */ val version: String - private const val fallbackVersion = "0.20.7" + private const val fallbackVersion = "0.21.3" /** * The distinct version of ProtoData used by other build tools. @@ -74,7 +74,7 @@ object ProtoData { * transitional dependencies, this is the version used to build the project itself. */ val dogfoodingVersion: String - private const val fallbackDfVersion = "0.20.7" + private const val fallbackDfVersion = "0.21.3" /** * The artifact for the ProtoData Gradle plugin. diff --git a/buildSrc/src/main/kotlin/io/spine/internal/dependency/ProtoTap.kt b/buildSrc/src/main/kotlin/io/spine/internal/dependency/ProtoTap.kt new file mode 100644 index 00000000..8afeb34b --- /dev/null +++ b/buildSrc/src/main/kotlin/io/spine/internal/dependency/ProtoTap.kt @@ -0,0 +1,46 @@ +/* + * 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 + * + * 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. + */ + +package io.spine.internal.dependency + +/** + * Dependencies on ProtoTap plugins. + * + * See [`SpineEventEngine/ProtoTap`](https://github.com/SpineEventEngine/ProtoTap/). + */ +@Suppress( + "unused" /* Some subprojects do not use ProtoData directly. */, + "ConstPropertyName" /* We use custom convention for artifact properties. */, + "MemberVisibilityCanBePrivate" /* The properties are used directly by other subprojects. */, +) +object ProtoTap { + const val group = "io.spine.tools" + const val version = "0.8.3" + const val gradlePluginId = "io.spine.prototap" + const val api = "$group:prototap-api:$version" + const val gradlePlugin = "$group:prototap-gradle-plugin:$version" + const val protocPlugin = "$group:prototap-protoc-plugin:$version" +} diff --git a/buildSrc/src/main/kotlin/io/spine/internal/dependency/Protobuf.kt b/buildSrc/src/main/kotlin/io/spine/internal/dependency/Protobuf.kt index be80d2df..de40557a 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/dependency/Protobuf.kt +++ b/buildSrc/src/main/kotlin/io/spine/internal/dependency/Protobuf.kt @@ -34,12 +34,23 @@ package io.spine.internal.dependency object Protobuf { private const val group = "com.google.protobuf" const val version = "3.25.1" + + /** + * The Java library with Protobuf data types. + */ + const val javaLib = "${group}:protobuf-java:${version}" + + /** + * The Java library containing proto definitions of Google Protobuf types. + */ + @Suppress("unused") + const val protoSrcLib = javaLib + /** - * The Java library containing proto definitions of Google Protobuf. + * All Java and Kotlin libraries we depend on. */ - const val protoSrcLib = "${group}:protobuf-java:${version}" val libs = listOf( - protoSrcLib, + javaLib, "${group}:protobuf-java-util:${version}", "${group}:protobuf-kotlin:${version}" ) diff --git a/buildSrc/src/main/kotlin/io/spine/internal/dependency/Spine.kt b/buildSrc/src/main/kotlin/io/spine/internal/dependency/Spine.kt index e4093e70..91a91d73 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/dependency/Spine.kt +++ b/buildSrc/src/main/kotlin/io/spine/internal/dependency/Spine.kt @@ -52,7 +52,7 @@ object Spine { * * @see spine-reflect */ - const val reflect = "2.0.0-SNAPSHOT.183" + const val reflect = "2.0.0-SNAPSHOT.184" /** * The version of [Spine.Logging]. @@ -89,7 +89,7 @@ object Spine { * * @see spine-mc-java */ - const val mcJava = "2.0.0-SNAPSHOT.205" + const val mcJava = "2.0.0-SNAPSHOT.206" /** * The version of [Spine.baseTypes]. @@ -124,7 +124,7 @@ object Spine { * * @see spine-tool-base */ - const val toolBase = "2.0.0-SNAPSHOT.208" + const val toolBase = "2.0.0-SNAPSHOT.212" /** * The version of [Spine.javadocTools]. diff --git a/buildSrc/src/main/kotlin/io/spine/internal/dependency/SystemLambda.kt b/buildSrc/src/main/kotlin/io/spine/internal/dependency/SystemLambda.kt new file mode 100644 index 00000000..593c3ae2 --- /dev/null +++ b/buildSrc/src/main/kotlin/io/spine/internal/dependency/SystemLambda.kt @@ -0,0 +1,35 @@ +/* + * 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 + * + * 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. + */ + +package io.spine.internal.dependency + +// https://github.com/stefanbirkner/system-lambda +@Suppress("unused", "ConstPropertyName") +object SystemLambda { + const val version = "1.2.1" + const val group = "com.github.stefanbirkner" + const val lib = "$group:system-lambda:$version" +} diff --git a/buildSrc/src/main/kotlin/io/spine/internal/dependency/Validation.kt b/buildSrc/src/main/kotlin/io/spine/internal/dependency/Validation.kt index ded15d83..ab1a8259 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/dependency/Validation.kt +++ b/buildSrc/src/main/kotlin/io/spine/internal/dependency/Validation.kt @@ -36,7 +36,7 @@ object Validation { /** * The version of the Validation library artifacts. */ - const val version = "2.0.0-SNAPSHOT.132" + const val version = "2.0.0-SNAPSHOT.133" /** * The distinct version of the Validation library used by build tools during @@ -46,7 +46,7 @@ object Validation { * transitional dependencies, this is the version used to build the project itself to * avoid errors caused by incompatible API changes. */ - const val dogfoodingVersion = "2.0.0-SNAPSHOT.132" + const val dogfoodingVersion = "2.0.0-SNAPSHOT.133" const val group = "io.spine.validation" private const val prefix = "spine-validation" diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/ProjectExtensions.kt b/buildSrc/src/main/kotlin/io/spine/internal/gradle/ProjectExtensions.kt index 2ef4bd8e..13535b8e 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/ProjectExtensions.kt +++ b/buildSrc/src/main/kotlin/io/spine/internal/gradle/ProjectExtensions.kt @@ -27,6 +27,7 @@ package io.spine.internal.gradle import io.spine.internal.gradle.publish.SpinePublishing +import java.io.File import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.api.Task @@ -91,3 +92,9 @@ val Project.artifactId: String val artifactId = spinePublishing?.artifactId(this) return artifactId ?: name } + +/** + * Returns project's build directory as [File]. + */ +val Project.buildDirectory: File + get() = layout.buildDirectory.get().asFile diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/dokka/DokkaExtensions.kt b/buildSrc/src/main/kotlin/io/spine/internal/gradle/dokka/DokkaExtensions.kt new file mode 100644 index 00000000..b3b14584 --- /dev/null +++ b/buildSrc/src/main/kotlin/io/spine/internal/gradle/dokka/DokkaExtensions.kt @@ -0,0 +1,48 @@ +/* + * Copyright 2022, 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. + */ + +package io.spine.internal.gradle.dokka + +import java.io.File +import org.gradle.api.file.FileCollection +import org.jetbrains.dokka.gradle.GradleDokkaSourceSetBuilder + +/** + * Returns only Java source roots out of all present in the source set. + * + * It is a helper method for generating documentation by Dokka only for Java code. + * It is helpful when both Java and Kotlin source files are present in a source set. + * Dokka can properly generate documentation for either Kotlin or Java depending on + * the configuration, but not both. + */ +@Suppress("unused") +internal fun GradleDokkaSourceSetBuilder.onlyJavaSources(): FileCollection { + return sourceRoots.filter(File::isJavaSourceDirectory) +} + +private fun File.isJavaSourceDirectory(): Boolean { + return isDirectory && name == "java" +} diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/dokka/TaskContainerExtensions.kt b/buildSrc/src/main/kotlin/io/spine/internal/gradle/dokka/TaskContainerExtensions.kt new file mode 100644 index 00000000..fb116851 --- /dev/null +++ b/buildSrc/src/main/kotlin/io/spine/internal/gradle/dokka/TaskContainerExtensions.kt @@ -0,0 +1,36 @@ +/* + * Copyright 2022, 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. + */ + +package io.spine.internal.gradle.dokka + +import org.gradle.api.tasks.TaskContainer +import org.jetbrains.dokka.gradle.DokkaTask + +/** + * Finds the `dokkaHtml` Gradle task. + */ +@Suppress("unused") +fun TaskContainer.dokkaHtmlTask() = this.getByName("dokkaHtml") as DokkaTask diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/kotlin/KotlinConfig.kt b/buildSrc/src/main/kotlin/io/spine/internal/gradle/kotlin/KotlinConfig.kt index b2964cee..7a94730a 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/kotlin/KotlinConfig.kt +++ b/buildSrc/src/main/kotlin/io/spine/internal/gradle/kotlin/KotlinConfig.kt @@ -58,6 +58,7 @@ fun KotlinCompile.setFreeCompilerArgs() { "-Xskip-prerelease-check", "-Xjvm-default=all", "-Xinline-classes", + "-Xexpect-actual-classes", "-opt-in=" + "kotlin.contracts.ExperimentalContracts," + "kotlin.io.path.ExperimentalPathApi," + diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/protobuf/ProtoTaskExtensions.kt b/buildSrc/src/main/kotlin/io/spine/internal/gradle/protobuf/ProtoTaskExtensions.kt index 0c4c8b41..de78a5ec 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/protobuf/ProtoTaskExtensions.kt +++ b/buildSrc/src/main/kotlin/io/spine/internal/gradle/protobuf/ProtoTaskExtensions.kt @@ -1,5 +1,5 @@ /* - * Copyright 2023, TeamDev. All rights reserved. + * 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. @@ -134,7 +134,8 @@ private fun GenerateProtoTask.setupDescriptorSetFileCreation() { // The name of the generated file reflects project's Maven coordinates. val ssn = sourceSet.name generateDescriptorSet = true - val descriptorsDir = "${project.buildDir}/descriptors/${ssn}" + val buildDir = project.layout.buildDirectory.asFile.get().path + val descriptorsDir = "$buildDir/descriptors/${ssn}" val descriptorName = project.descriptorSetName(sourceSet) with(descriptorSetOptions) { path = "$descriptorsDir/$descriptorName" diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/publish/GitHubPackages.kt b/buildSrc/src/main/kotlin/io/spine/internal/gradle/publish/GitHubPackages.kt index fef06821..68b68a2b 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/publish/GitHubPackages.kt +++ b/buildSrc/src/main/kotlin/io/spine/internal/gradle/publish/GitHubPackages.kt @@ -28,6 +28,7 @@ package io.spine.internal.gradle.publish import io.spine.internal.gradle.Credentials import io.spine.internal.gradle.Repository +import io.spine.internal.gradle.buildDirectory import net.lingala.zip4j.ZipFile import org.gradle.api.Project @@ -90,7 +91,7 @@ private fun Project.readGitHubToken(): String { * use such a workaround. */ private fun Project.readTokenFromArchive(): String { - val targetDir = "${buildDir}/token" + val targetDir = "$buildDirectory/token" file(targetDir).mkdirs() val fileToUnzip = "${rootDir}/buildSrc/aus.weis" diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/publish/IncrementGuard.kt b/buildSrc/src/main/kotlin/io/spine/internal/gradle/publish/IncrementGuard.kt index b97a5ee5..d7c6745e 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/publish/IncrementGuard.kt +++ b/buildSrc/src/main/kotlin/io/spine/internal/gradle/publish/IncrementGuard.kt @@ -1,5 +1,5 @@ /* - * Copyright 2023, TeamDev. All rights reserved. + * 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. @@ -45,11 +45,13 @@ class IncrementGuard : Plugin { /** * Adds the [CheckVersionIncrement] task to the project. * - * Only adds the check if the project is built on Travis CI and the job is a pull request. + * The task is created anyway, but it is enabled only if: + * 1. The project is built on GitHub CI, and + * 2. The job is a pull request. * - * The task only runs on non-master branches on GitHub Actions. This is done - * to prevent unexpected CI fails when re-building `master` multiple times, creating git - * tags, and in other cases that go outside of the "usual" development cycle. + * The task only runs on non-master branches on GitHub Actions. + * This is done to prevent unexpected CI fails when re-building `master` multiple times, + * creating git tags, and in other cases that go outside the "usual" development cycle. */ override fun apply(target: Project) { val tasks = target.tasks @@ -57,7 +59,6 @@ class IncrementGuard : Plugin { repository = CloudRepo.published tasks.getByName("check").dependsOn(this) - shouldRunAfter("test") if (!shouldCheckVersion()) { logger.info( "The build does not represent a GitHub Actions feature branch job, " + @@ -72,7 +73,7 @@ class IncrementGuard : Plugin { * Returns `true` if the current build is a GitHub Actions build which represents a push * to a feature branch. * - * Returns `false` if the associated reference is not a branch (e.g. a tag) or if it has + * Returns `false` if the associated reference is not a branch (e.g., a tag) or if it has * the name which ends with `master` or `main`. * * For example, on the following branches the method would return `false`: diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/publish/PublishingExts.kt b/buildSrc/src/main/kotlin/io/spine/internal/gradle/publish/PublishingExts.kt index 78e73954..fc985cce 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/publish/PublishingExts.kt +++ b/buildSrc/src/main/kotlin/io/spine/internal/gradle/publish/PublishingExts.kt @@ -38,11 +38,11 @@ import org.gradle.api.publish.PublishingExtension import org.gradle.api.tasks.TaskContainer import org.gradle.api.tasks.TaskProvider import org.gradle.api.tasks.bundling.Jar +import org.gradle.kotlin.dsl.findByType import org.gradle.kotlin.dsl.get import org.gradle.kotlin.dsl.getByType import org.gradle.kotlin.dsl.named import org.gradle.kotlin.dsl.register -import org.gradle.kotlin.dsl.the import org.gradle.kotlin.dsl.withType /** @@ -58,10 +58,23 @@ internal val Project.publications: PublicationContainer get() = publishingExtension.publications /** - * Obtains [SpinePublishing] extension from the root project. + * Obtains [SpinePublishing] extension from this [Project]. + * + * If this [Project] doesn't have one, it returns [SpinePublishing] + * declared in the root project. */ internal val Project.spinePublishing: SpinePublishing - get() = this.rootProject.the() + get() { + val local = this.extensions.findByType() + if (local != null) { + return local + } + val fromRoot = this.rootProject.extensions.findByType() + if (fromRoot != null) { + return fromRoot + } + error("`SpinePublishing` is not found in `${project.name}`.") + } /** * Tells if this project has custom publishing. @@ -212,7 +225,8 @@ internal fun Project.testJar(): TaskProvider = tasks.getOrCreate("testJar") */ fun Project.javadocJar(): TaskProvider = tasks.getOrCreate("javadocJar") { archiveClassifier.set("javadoc") - from(files("$buildDir/docs/javadoc")) + val javadocFiles = layout.buildDirectory.files("/docs/javadoc") + from(javadocFiles) dependsOn("javadoc") } diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/publish/SpinePublishing.kt b/buildSrc/src/main/kotlin/io/spine/internal/gradle/publish/SpinePublishing.kt index f55b85f3..fb920371 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/publish/SpinePublishing.kt +++ b/buildSrc/src/main/kotlin/io/spine/internal/gradle/publish/SpinePublishing.kt @@ -24,6 +24,8 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +@file:Suppress("TooManyFunctions") + package io.spine.internal.gradle.publish import dokkaJavaJar @@ -152,6 +154,22 @@ open class SpinePublishing(private val project: Project) { */ var modules: Set = emptySet() + /** + * Controls whether the published module needs standard publications. + * + * If `true`, the module should configure publications on its own. + * Otherwise, the extension will configure standard [ones][StandardJavaPublicationHandler]. + * + * This property is analogue of [modulesWithCustomPublishing] for projects, + * for which [spinePublishing] is configured individually. + * + * Setting of this property and having a non-empty [modules] will lead + * to an exception. + * + * Default value is `false`. + */ + var customPublishing = false + /** * Set of modules that have custom publications and do not need standard ones. * @@ -299,7 +317,8 @@ open class SpinePublishing(private val project: Project) { internal fun configured() { ensureProtoJarExclusionsArePublished() ensureTestJarInclusionsArePublished() - ensuresModulesNotDuplicated() + ensureModulesNotDuplicated() + ensureCustomPublishingNotMisused() val projectsToPublish = projectsToPublish() projectsToPublish.forEach { project -> @@ -352,7 +371,7 @@ open class SpinePublishing(private val project: Project) { * we configure publishing for it. */ private fun Project.setUpPublishing(jarFlags: JarFlags) { - val customPublishing = modulesWithCustomPublishing.contains(name) + val customPublishing = modulesWithCustomPublishing.contains(name) || customPublishing val handler = if (customPublishing) { CustomPublicationHandler(project, destinations) } else { @@ -409,7 +428,7 @@ open class SpinePublishing(private val project: Project) { * We allow configuration of publishing from two places - a root project and module itself. * Here we verify that publishing of a module is not configured in both places simultaneously. */ - private fun ensuresModulesNotDuplicated() { + private fun ensureModulesNotDuplicated() { val rootProject = project.rootProject if (rootProject == project) { return @@ -425,4 +444,11 @@ open class SpinePublishing(private val project: Project) { } } } + + private fun ensureCustomPublishingNotMisused() { + if (modules.isNotEmpty() && customPublishing) { + error("`customPublishing` property can be set only if `spinePublishing` extension " + + "is open in an individual module, so `modules` property should be empty.") + } + } } diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/report/coverage/JacocoConfig.kt b/buildSrc/src/main/kotlin/io/spine/internal/gradle/report/coverage/JacocoConfig.kt index 4d789a59..36a4c204 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/report/coverage/JacocoConfig.kt +++ b/buildSrc/src/main/kotlin/io/spine/internal/gradle/report/coverage/JacocoConfig.kt @@ -26,6 +26,7 @@ package io.spine.internal.gradle.report.coverage +import io.spine.internal.dependency.Jacoco import io.spine.internal.gradle.applyPlugin import io.spine.internal.gradle.findTask import io.spine.internal.gradle.report.coverage.TaskName.check @@ -36,7 +37,6 @@ import io.spine.internal.gradle.sourceSets import java.io.File import java.util.* import org.gradle.api.Project -import org.gradle.api.Task import org.gradle.api.file.ConfigurableFileCollection import org.gradle.api.plugins.BasePlugin import org.gradle.api.tasks.Copy @@ -45,7 +45,9 @@ import org.gradle.api.tasks.SourceSetOutput import org.gradle.api.tasks.TaskContainer import org.gradle.api.tasks.TaskProvider import org.gradle.kotlin.dsl.get +import org.gradle.kotlin.dsl.the import org.gradle.testing.jacoco.plugins.JacocoPlugin +import org.gradle.testing.jacoco.plugins.JacocoPluginExtension import org.gradle.testing.jacoco.tasks.JacocoReport /** @@ -90,7 +92,8 @@ class JacocoConfig( fun applyTo(project: Project) { project.applyPlugin(BasePlugin::class.java) val javaProjects: Iterable = eligibleProjects(project) - val reportsDir = project.rootProject.buildDir.resolve(reportsDirSuffix) + val reportsDir = project.rootProject.layout + .buildDirectory.dir(reportsDirSuffix).get().asFile JacocoConfig(project.rootProject, reportsDir, javaProjects).configure() } @@ -117,12 +120,22 @@ class JacocoConfig( } private fun configure() { + configureVersion() + configureTask() + } + + private fun configureVersion() { + val jacoco = rootProject.the() + jacoco.toolVersion = Jacoco.version + } + + private fun configureTask() { val tasks = rootProject.tasks val copyReports = registerCopy(tasks) val rootReport = registerRootReport(tasks, copyReports) - rootProject - .findTask(check.name) - .dependsOn(rootReport) + tasks.named(check.name) { + dependsOn(rootReport) + } } private fun registerRootReport( diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/report/license/LicenseReporter.kt b/buildSrc/src/main/kotlin/io/spine/internal/gradle/report/license/LicenseReporter.kt index f7f1a312..500a2516 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/report/license/LicenseReporter.kt +++ b/buildSrc/src/main/kotlin/io/spine/internal/gradle/report/license/LicenseReporter.kt @@ -1,5 +1,5 @@ /* - * Copyright 2023, TeamDev. All rights reserved. + * 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. @@ -80,7 +80,7 @@ object LicenseReporter { */ fun generateReportIn(project: Project) { project.applyPlugin(LicenseReportPlugin::class.java) - val reportOutputDir = project.buildDir.resolve(Paths.relativePath) + val reportOutputDir = project.layout.buildDirectory.dir(Paths.relativePath).get().asFile with(project.the()) { outputDir = reportOutputDir.absolutePath @@ -146,7 +146,8 @@ object LicenseReporter { rootProject: Project ) { val paths = sourceProjects.map { - "${it.buildDir}/${Paths.relativePath}/${Paths.outputFilename}" + val buildDir = it.layout.buildDirectory.asFile.get() + "$buildDir/${Paths.relativePath}/${Paths.outputFilename}" } println("Merging the license reports from the all projects.") val mergedContent = paths.joinToString("\n\n\n") { (File(it)).readText() } diff --git a/buildSrc/src/main/kotlin/io/spine/internal/gradle/testing/Tasks.kt b/buildSrc/src/main/kotlin/io/spine/internal/gradle/testing/Tasks.kt index 1d7a656e..f501940c 100644 --- a/buildSrc/src/main/kotlin/io/spine/internal/gradle/testing/Tasks.kt +++ b/buildSrc/src/main/kotlin/io/spine/internal/gradle/testing/Tasks.kt @@ -75,7 +75,7 @@ private const val SLOW_TAG = "slow" /** * Executes JUnit tests filtering out the ones tagged as `slow`. */ -private open class FastTest : Test() { +private abstract class FastTest : Test() { init { description = "Executes all JUnit tests but the ones tagged as `slow`." group = "Verification" @@ -89,7 +89,7 @@ private open class FastTest : Test() { /** * Executes JUnit tests tagged as `slow`. */ -private open class SlowTest : Test() { +private abstract class SlowTest : Test() { init { description = "Executes JUnit tests tagged as `slow`." group = "Verification" diff --git a/buildSrc/src/main/kotlin/jacoco-kotlin-jvm.gradle.kts b/buildSrc/src/main/kotlin/jacoco-kotlin-jvm.gradle.kts index b6b49326..a0ee4a66 100644 --- a/buildSrc/src/main/kotlin/jacoco-kotlin-jvm.gradle.kts +++ b/buildSrc/src/main/kotlin/jacoco-kotlin-jvm.gradle.kts @@ -24,6 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +import io.spine.internal.gradle.buildDirectory import java.io.File import org.gradle.kotlin.dsl.getValue import org.gradle.kotlin.dsl.getting @@ -55,7 +56,7 @@ private val about = "" */ val jacocoTestReport: JacocoReport by tasks.getting(JacocoReport::class) { - val classFiles = File("${buildDir}/classes/kotlin/jvm/") + val classFiles = File("$buildDirectory/classes/kotlin/jvm/") .walkBottomUp() .toSet() classDirectories.setFrom(classFiles) @@ -66,5 +67,5 @@ val jacocoTestReport: JacocoReport by tasks.getting(JacocoReport::class) { ) sourceDirectories.setFrom(files(coverageSourceDirs)) - executionData.setFrom(files("${buildDir}/jacoco/jvmTest.exec")) + executionData.setFrom(files("$buildDirectory/jacoco/jvmTest.exec")) } diff --git a/buildSrc/src/main/kotlin/jvm-module.gradle.kts b/buildSrc/src/main/kotlin/jvm-module.gradle.kts index 4f7b9d09..24b071a4 100644 --- a/buildSrc/src/main/kotlin/jvm-module.gradle.kts +++ b/buildSrc/src/main/kotlin/jvm-module.gradle.kts @@ -1,5 +1,5 @@ /* - * Copyright 2023, TeamDev. All rights reserved. + * 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. @@ -30,6 +30,7 @@ import io.spine.internal.dependency.Dokka import io.spine.internal.dependency.ErrorProne import io.spine.internal.dependency.Guava import io.spine.internal.dependency.JUnit +import io.spine.internal.dependency.Jacoco import io.spine.internal.dependency.JavaX import io.spine.internal.dependency.Kotest import io.spine.internal.dependency.Protobuf @@ -119,7 +120,7 @@ fun Module.configureKotlin(javaVersion: JavaLanguageVersion) { } kover { - useJacoco() + useJacoco(version = Jacoco.version) } koverReport { @@ -171,7 +172,8 @@ fun Module.forceConfigurations() { force( JUnit.bom, JUnit.runner, - Dokka.BasePlugin.lib + Dokka.BasePlugin.lib, + Spine.reflect ) } }