diff --git a/.travis.yml b/.travis.yml index 38c0f5d09b..2e2089acf2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,6 +11,9 @@ env: # Encrypted `GCS_SECRET` variable. - secure: "i8MhONZu7QjyM2V887A1Tydr1WMqQP5jJZNjIJjc1Uae8F0/z8cJZIZ1hstodN7FpoR4VF92zyhUwbt6fz/dsdPEJFccsiMlEc9vlqecQCd267160wgRZneaB6Xe/y/EUmq9XsGdn/k1Ey+QZwX9au/8RU191v+fDsCtMRYXzyEa/BvbQuSwuYRgQDxTAxuJgTmG5Sxl9jWqKw1BfxUcEoErc/jqymU58w6z2TxKxVzIXT29Jy/Z12VuSiS8opigSrIP8e/1fctC84wI7S52mext2ZfhPYSTHFKS+xg1vQDYPb8m5aomL8E6Of7hVD5BTnEnyjj+/Gr63GAzHXtkHhWoxo+vB+xBFfDu8wxM5Aqna3H7LMDD5kGCxQEz8qmzHBHMAhLnhsRzjNVu2+tLCZdeMN88Ud2uemL2SCAcR8Juleg7DGMj3D0SAbPyUH3+9yYYWzSg6iaxgTdHBnJ+uXUJp0Nu+M2EK6Kl+pYAsCLVfZRPGaajFXVnJEPPeSr2PYzk7F4pIzgn/E8AtYEJ0gcEbjoTItS8EjliJKDXM4HdkluXBFLvzIH1O1nCtxKNv4UkUmPhFbfHrPXDcsYq2zsEe+NkvsJlxjAwYnOMkT4NLiEsec1a7K9bBC+iQA9e8rriMbu6/1w63JErQyx05avPjgO8XRDK8hxTf4rhBmY=" - GRADLE_OPTS="-Xmx2G" + # TODO:2020-05-18:dmytro.dashenkov: Remove these 2 lines when Travis stops failing when installing JDK 8. + - JAVA_HOME="/usr/lib/jvm/java-8-openjdk-amd64" + - PATH="$JAVA_HOME/bin:$PATH" before_install: - chmod +x gradlew diff --git a/base-validating-builders/build.gradle b/base-validating-builders/build.gradle index e5ecf222e9..4f86242182 100644 --- a/base-validating-builders/build.gradle +++ b/base-validating-builders/build.gradle @@ -19,7 +19,7 @@ */ buildscript { - apply from: "$projectDir/../version.gradle" + apply from: "$projectDir/../version.gradle.kts" apply from: "$projectDir/../config/gradle/dependencies.gradle" repositories { diff --git a/base/build.gradle b/base/build.gradle deleted file mode 100644 index 834d5b960e..0000000000 --- a/base/build.gradle +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright 2020, TeamDev. All rights reserved. - * - * 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. - */ - -import java.nio.file.Files - -group = 'io.spine' - -apply from: "$projectDir/script/protobuf.gradle" - -apply from: deps.scripts.testArtifacts -apply from: deps.scripts.runBuild - -dependencies { - annotationProcessor deps.build.autoService.processor - compileOnly deps.build.autoService.annotations - - // Since we use `@CanIgnoreReturnValue` when annotating Validating Builders - // ErrorProne Annotations is part of our API. - api deps.build.errorProneAnnotations - - testImplementation( - project(path: ":testlib"), - project(path: ":mute-logging") - ) -} - -sourceSets { - main { - resources.srcDirs += "$buildDir/descriptors/main" - proto.srcDirs = ["$projectDir/src/main/proto"] - } - test { - resources.srcDirs += "$buildDir/descriptors/test" - proto.srcDirs = ["$projectDir/src/test/proto"] - } -} - -/** - * The JAR task assembles class files with a respect to the re-built message classes. - * - * The task checks each input file for a newer version in the `base-validating-builders`. If such - * a version is found, the older version is excluded. - */ -jar { - // See `base-validating-builders/README.md` - final compiledProtoPath = "$rootDir/base-validating-builders/compiled-proto" - final compiledProtos = fileTree(compiledProtoPath) - - from compiledProtos - - eachFile { final file -> - logger.info "Appending $file" - final classFile = file.file.toPath() - final isProto = compiledProtos.filter { it.path.endsWith file.relativePath.toString() } - .filter { !Files.isSameFile(it.toPath(), classFile) } - if (!isProto.empty) { - logger.info "File $classFile is excluded" - file.exclude() - } else { - logger.debug "File $classFile is not excluded" - } - } -} - -apply from: deps.scripts.publishProto - -task rebuildProtobuf { - dependsOn(rootProject.subprojects*.getTasksByName('publishToMavenLocal', false)) - - doLast { - runBuild("$rootDir/base-validating-builders") - } -} - -project.getTasksByName('publish', false)*.dependsOn rebuildProtobuf - -build.finalizedBy rebuildProtobuf diff --git a/base/build.gradle.kts b/base/build.gradle.kts new file mode 100644 index 0000000000..ef2db74b57 --- /dev/null +++ b/base/build.gradle.kts @@ -0,0 +1,145 @@ +/* + * Copyright 2020, TeamDev. All rights reserved. + * + * 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. + */ + +import com.google.protobuf.gradle.ProtobufConfigurator.JavaGenerateProtoTaskCollection +import groovy.lang.Closure +import groovy.lang.GString +import io.spine.gradle.internal.DependencyResolution +import io.spine.gradle.internal.Deps +import io.spine.gradle.internal.RunBuild +import java.nio.file.Files.isSameFile + +plugins { + `java-library` + id("com.google.protobuf") +} + +group = "io.spine" + +apply(from = Deps.scripts.testArtifacts(project)) + +DependencyResolution.excludeProtobufLite(configurations) + +dependencies { + Deps.build.protobuf.forEach { protobuf(it) } + annotationProcessor(Deps.build.autoService.processor) + compileOnly(Deps.build.autoService.annotations) + Deps.build.errorProneAnnotations.forEach { api(it) } + testImplementation(project(":testlib")) + testImplementation(project(":mute-logging")) +} + +sourceSets { + main { + resources.srcDir("$buildDir/descriptors/main") + proto.setSrcDirs(listOf("$projectDir/src/main/proto")) + } + test { + resources.srcDir("$buildDir/descriptors/test") + proto.setSrcDirs(listOf("$projectDir/src/test/proto")) + } +} + +/** + * The JAR task assembles class files with a respect to the re-built message classes. + * + * The task checks each input file for a newer version in the `base-validating-builders`. If such + * a version is found, the older version is excluded. + */ +tasks.jar.configure { + // See `base-validating-builders/README.md` + val compiledProtoPath = "$rootDir/base-validating-builders/compiled-proto" + val compiledProtos = fileTree(compiledProtoPath) + + from(compiledProtos) + + eachFile { + logger.info("Appending $this") + val classFile = file.toPath() + val isProto = compiledProtos.filter { it.path.endsWith(relativePath.toString()) } + .filter { !isSameFile(it.toPath(), classFile) } + if (!isProto.isEmpty) { + logger.info("File $classFile is excluded") + this.exclude() + } else { + logger.debug("File $classFile is not excluded") + } + } +} + +apply(from = Deps.scripts.publishProto(project)) + +val rebuildProtobuf by tasks.registering(RunBuild::class) { + directory = "$rootDir/base-validating-builders" + dependsOn(rootProject.subprojects.map { p -> p.tasks["publishToMavenLocal"] }) +} + +tasks.publish.get().dependsOn(rebuildProtobuf) +tasks.build.get().finalizedBy(rebuildProtobuf) + +val compiledProtoRoot = "$projectDir/generated" +val googlePackagePrefix = "com/google" + +val pruneGoogleProtos by tasks.registering(type = Delete::class) { + delete("$compiledProtoRoot/main/java/$googlePackagePrefix") + tasks.compileJava.get().dependsOn(this) +} + +val pruneTestGoogleProtos by tasks.registering(type = Delete::class) { + delete("$compiledProtoRoot/test/java/$googlePackagePrefix") + tasks.compileTestJava.get().dependsOn(this) +} + +protobuf { + protobuf.generatedFilesBaseDir = compiledProtoRoot + protobuf.generateProtoTasks(object : Closure(this) { + private fun doCall(tasks: JavaGenerateProtoTaskCollection) { + for (task in tasks.all()) { + val scope = task.sourceSet.name + task.generateDescriptorSet = true + task.descriptorSetOptions.path = GString.EMPTY.plus("$buildDir/descriptors/$scope/known_types_${scope}.desc") + task.descriptorSetOptions.includeImports = true + task.descriptorSetOptions.includeSourceInfo = true + + if (scope.contains("test")) { + pruneTestGoogleProtos.configure { dependsOn(task) } + } else { + pruneGoogleProtos.configure { dependsOn(task) } + } + } + } + }) +} + +/** + * Checks if the given file belongs to the Google `.proto` sources. + */ +fun FileTreeElement.isGoogleProtoSource(): Boolean { + val pathSegments = relativePath.segments + return pathSegments.isNotEmpty() && pathSegments[0].equals("google") +} + +/** + * From all artifacts, exclude Google `.proto` sources. + */ +tasks.withType(Jar::class) { + exclude { it.isGoogleProtoSource() } +} + diff --git a/base/script/protobuf.gradle b/base/script/protobuf.gradle deleted file mode 100644 index 5de38d377e..0000000000 --- a/base/script/protobuf.gradle +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2020, TeamDev. All rights reserved. - * - * 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. - */ - -apply plugin: 'com.google.protobuf' - -configurations { - // Avoid collisions of Java classes defined both in `protobuf-lite` and `protobuf-java` - runtimeClasspath.exclude group: "com.google.protobuf", module: "protobuf-lite" - testRuntimeClasspath.exclude group: "com.google.protobuf", module: "protobuf-lite" -} - -dependencies { - // Re-generate standard Proto types, so they are included in `known_types.desc`. - protobuf deps.build.protobuf -} - -ext { - compiledProtoRoot = "$projectDir/generated" - mainCompiledProto = "$compiledProtoRoot/main/java" - testCompiledProto = "$compiledProtoRoot/test/java" - googlePackagePrefix = 'com/google' -} - -final def mainPruneTask = task pruneGoogleProtos(type: Delete) { - delete "$mainCompiledProto/$googlePackagePrefix" - compileJava.dependsOn it -} - -final def testPruneTask = task pruneTestGoogleProtos(type: Delete) { - delete "$testCompiledProto/$googlePackagePrefix" - compileTestJava.dependsOn it -} - -protobuf { - generatedFilesBaseDir = compiledProtoRoot - protoc { - artifact = deps.build.protoc - } - generateProtoTasks { - all().each { final task -> - final def scope = task.sourceSet.name - task.generateDescriptorSet = true - task.descriptorSetOptions.path = "$buildDir/descriptors/$scope/known_types_${scope}.desc" - task.descriptorSetOptions.includeImports = true - task.descriptorSetOptions.includeSourceInfo = true - - if (task.sourceSet.name.contains('test')) { - testPruneTask.dependsOn task - } else { - mainPruneTask.dependsOn task - } - } - } -} - -/** - * Checks if the given file belongs to the Google `.proto` sources. - */ -static boolean isGoogleProtoSource(final FileTreeElement file) { - final String[] pathSegments = file.relativePath.segments - return pathSegments.length >= 1 && pathSegments[0].equals('google') -} - -/** - * From all artifacts, exclude Google `.proto` sources. - */ -tasks.withType(Jar) { - it.exclude { final FileTreeElement file -> isGoogleProtoSource(file) } -} diff --git a/build.gradle b/build.gradle deleted file mode 100644 index d0af99995a..0000000000 --- a/build.gradle +++ /dev/null @@ -1,257 +0,0 @@ -/* - * Copyright 2020, TeamDev. All rights reserved. - * - * 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. - */ -buildscript { final scriptHandler -> - - // As long as `buildscript` section is always evaluated first, - // we need to apply explicitly here. - apply from: "$rootDir/config/gradle/dependencies.gradle" - apply from: "$rootDir/version.gradle" - - defaultRepositories(scriptHandler) - dependencies { - classpath deps.build.guava - classpath deps.build.gradlePlugins.protobuf - classpath deps.build.gradlePlugins.errorProne - } - - forceConfiguration(scriptHandler) -} - -apply from: 'version.gradle' - -ext { - groupId = 'io.spine' - credentialsPropertyFile = 'credentials.properties' - - projectsToPublish = [ - 'base', - 'tool-base', - 'testlib', - 'mute-logging', - 'errorprone-checks', - - // Gradle plugins - 'plugin-base', - 'javadoc-filter', - 'javadoc-prettifier', - 'proto-dart-plugin', - 'proto-js-plugin', - 'model-compiler', - - 'plugin-testlib', - - // Protoc compiler plugin - 'protoc-api', - 'validation-generator', - 'protoc-plugin' - ] -} - -allprojects { - apply plugin: 'jacoco' - apply plugin: 'idea' - apply plugin: 'project-report' - - // Use the same version numbering for the Spine Base library. - version = versionToPublish -} - -subprojects { - buildscript { final scriptHandler -> - - apply from: "$rootDir/version.gradle" - - defaultRepositories(scriptHandler) - dependencies { - classpath deps.build.guava - classpath deps.build.gradlePlugins.protobuf - } - - forceConfiguration(scriptHandler) - } - - project.ext { - spineProtobufPluginId = 'io.spine.tools.spine-model-compiler' - - sourcesRootDir = "$projectDir/src" - generatedRootDir = "$projectDir/generated" - - generatedJavaDir = "$generatedRootDir/main/java" - generatedTestJavaDir = "$generatedRootDir/test/java" - - generatedGrpcDir = "$generatedRootDir/main/grpc" - generatedTestGrpcDir = "$generatedRootDir/test/grpc" - - generatedSpineDir = "$generatedRootDir/main/spine" - generatedTestSpineDir = "$generatedRootDir/test/spine" - - runsOnWindows = org.gradle.internal.os.OperatingSystem.current().isWindows() - } - - apply plugin: 'java-library' - apply plugin: 'pmd' - apply plugin: 'com.google.protobuf' - apply plugin: 'net.ltgt.errorprone' - - apply plugin: 'maven-publish' - - apply from: deps.scripts.projectLicenseReport - - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 - - defaultRepositories(project) - dependencies { - errorprone deps.build.errorProneCore - errorproneJavac deps.build.errorProneJavac - // For dependencies config. based on version of Java, see: - // https://github.com/epeee/junit-jupiter-extension-testing/blob/57b7ba75ab64ed8c229d2a5b14a954d6ae359189/gradle/errorprone.gradle - - api( - deps.build.protobuf, - deps.build.flogger - ) - implementation( - deps.build.guava, - deps.build.checkerAnnotations, - deps.build.errorProneAnnotations, - deps.build.jsr305Annotations - ) - testImplementation( - deps.test.guavaTestlib, - deps.test.junit5Api, - deps.test.junit5Runner, - deps.test.junitPioneer - ) - runtimeOnly deps.runtime.floggerSystemBackend - } - - forceConfiguration(project) - configurations { - // Avoid collisions of Java classes defined both in `protobuf-lite` and `protobuf-java` - runtime.exclude group: "com.google.protobuf", module: "protobuf-lite" - testRuntime.exclude group: "com.google.protobuf", module: "protobuf-lite" - } - - sourceSets { - main { - java.srcDirs generatedJavaDir, "$sourcesRootDir/main/java", generatedSpineDir - resources.srcDirs "$sourcesRootDir/main/resources", "$generatedRootDir/main/resources" - } - test { - java.srcDirs generatedTestJavaDir, "$sourcesRootDir/test/java", generatedTestSpineDir - resources.srcDirs "$sourcesRootDir/test/resources", "$generatedRootDir/test/resources" - } - } - - protobuf { - generatedFilesBaseDir = generatedRootDir - - protoc { - artifact = deps.build.protoc - } - } - - test { - useJUnitPlatform { - includeEngines 'junit-jupiter' - } - - include "**/*Test.class" - } - - apply from: deps.scripts.testOutput - apply from: deps.scripts.javadocOptions - apply from: deps.scripts.javacArgs - - task sourceJar(type: Jar) { - from sourceSets.main.allJava - archiveClassifier.set("sources") - } - - task testOutputJar(type: Jar) { - from sourceSets.test.output - archiveClassifier.set("test") - } - - task javadocJar(type: Jar, dependsOn: 'javadoc') { - from "$projectDir/build/docs/javadoc" - archiveClassifier.set("javadoc") - } - - // Apply the same IDEA module configuration for each of sub-projects. - idea { - module { - generatedSourceDirs += file(generatedJavaDir) - testSourceDirs += file(generatedTestJavaDir) - downloadJavadoc = true - downloadSources = true - - iml { - beforeMerged { final module -> - module.dependencies.clear() - } - whenMerged { final module -> - module.dependencies*.exported = true - } - } - } - } - - task cleanGenerated(type: Delete) { - delete = "$projectDir/generated" - } - - clean.dependsOn cleanGenerated - - apply from: deps.scripts.pmd -} - -// IDEA project configuration. -idea { - project { - ipr { - beforeMerged { final project -> - project.modulePaths.clear() - } - withXml { final provider -> - provider.node.component - .find { it.@name == 'VcsDirectoryMappings' } - .mapping.@vcs = 'Git' - } - } - } -} - -apply from: deps.scripts.jacoco -apply from: deps.scripts.publish -apply from: deps.scripts.runBuild -apply from: deps.scripts.generatePom -apply from: deps.scripts.repoLicenseReport - -task smokeTests { - doLast { - runBuild("$rootDir/tools/smoke-tests") - } -} - -task buildAll { - dependsOn build, smokeTests -} diff --git a/build.gradle.kts b/build.gradle.kts new file mode 100644 index 0000000000..22c5dbcb5d --- /dev/null +++ b/build.gradle.kts @@ -0,0 +1,224 @@ +/* + * Copyright 2020, TeamDev. All rights reserved. + * + * 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. + */ + +import io.spine.gradle.internal.DependencyResolution +import io.spine.gradle.internal.Deps +import io.spine.gradle.internal.PublishingRepos +import io.spine.gradle.internal.RunBuild + +buildscript { + apply(from = "$rootDir/version.gradle.kts") + + @Suppress("RemoveRedundantQualifierName") // Cannot use imports here. + val resolution = io.spine.gradle.internal.DependencyResolution + @Suppress("RemoveRedundantQualifierName") + val deps = io.spine.gradle.internal.Deps + resolution.defaultRepositories(repositories) + resolution.forceConfiguration(configurations) +} + +// Apply some plugins to make type-safe extension accessors available in this script file. +plugins { + `java-library` + idea + @Suppress("RemoveRedundantQualifierName") // Cannot use imports here. + id("com.google.protobuf").version(io.spine.gradle.internal.Deps.versions.protobufPlugin) + @Suppress("RemoveRedundantQualifierName") // Cannot use imports here. + id("net.ltgt.errorprone").version(io.spine.gradle.internal.Deps.versions.errorPronePlugin) +} + +apply(from = "$rootDir/version.gradle.kts") + +extra.apply { + this["groupId"] = "io.spine" + this["publishToRepository"] = PublishingRepos.cloudRepo + this["projectsToPublish"] = listOf( + "base", + "tool-base", + "testlib", + "mute-logging", + "errorprone-checks", + + // Gradle plugins + "plugin-base", + "javadoc-filter", + "javadoc-prettifier", + "proto-dart-plugin", + "proto-js-plugin", + "model-compiler", + + "plugin-testlib", + + // Protoc compiler plugin + "protoc-api", + "validation-generator", + "protoc-plugin" + ) +} + +allprojects { + apply { + plugin("jacoco") + plugin("idea") + plugin("project-report") + from("$rootDir/config/gradle/dependencies.gradle") + } + version = rootProject.extra["versionToPublish"]!! +} + +subprojects { + buildscript { + apply(from = "$rootDir/version.gradle.kts") + + DependencyResolution.defaultRepositories(repositories) + dependencies { + classpath(Deps.build.gradlePlugins.protobuf) + classpath(Deps.build.gradlePlugins.errorProne) + } + DependencyResolution.forceConfiguration(configurations) + } + + apply(from = "$rootDir/version.gradle.kts") + + val sourcesRootDir by extra("$projectDir/src") + val generatedRootDir by extra("$projectDir/generated") + val generatedJavaDir by extra("$generatedRootDir/main/java") + val generatedTestJavaDir by extra("$generatedRootDir/test/java") + val generatedSpineDir by extra("$generatedRootDir/main/spine") + val generatedTestSpineDir by extra("$generatedRootDir/test/spine") + + apply { + plugin("java-library") + plugin("pmd") + plugin("com.google.protobuf") + plugin("net.ltgt.errorprone") + plugin("maven-publish") + from(Deps.scripts.projectLicenseReport(project)) + } + + the().apply { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 + } + + DependencyResolution.defaultRepositories(repositories) + dependencies { + errorprone(Deps.build.errorProneCore) + errorproneJavac(Deps.build.errorProneJavac) + Deps.build.protobuf.forEach { api(it) } + api(Deps.build.flogger) + implementation(Deps.build.guava) + implementation(Deps.build.checkerAnnotations) + implementation(Deps.build.jsr305Annotations) + Deps.build.errorProneAnnotations.forEach { implementation(it) } + testImplementation(Deps.test.guavaTestlib) + testImplementation(Deps.test.junit5Runner) + testImplementation(Deps.test.junitPioneer) + Deps.test.junit5Api.forEach { testImplementation(it) } + runtimeOnly(Deps.runtime.flogger.systemBackend) + } + + DependencyResolution.forceConfiguration(configurations) + DependencyResolution.excludeProtobufLite(configurations) + + sourceSets { + main { + java.srcDirs(generatedJavaDir, "$sourcesRootDir/main/java", generatedSpineDir) + resources.srcDirs("$sourcesRootDir/main/resources", "$generatedRootDir/main/resources") + } + test { + java.srcDirs(generatedTestJavaDir, "$sourcesRootDir/test/java", generatedTestSpineDir) + resources.srcDirs("$sourcesRootDir/test/resources", "$generatedRootDir/test/resources") + } + } + + protobuf { + protobuf.generatedFilesBaseDir = generatedRootDir + + protobuf.protoc(object : groovy.lang.Closure(this) { + private fun doCall(locator: com.google.protobuf.gradle.ExecutableLocator) { + locator.artifact = Deps.build.protoc + } + }) + } + + tasks.test.configure { + useJUnitPlatform { + includeEngines("junit-jupiter") + } + include("**/*Test.class") + } + + apply { + from(Deps.scripts.testOutput(project)) + from(Deps.scripts.javadocOptions(project)) + from(Deps.scripts.javacArgs(project)) + } + + tasks.create("sourceJar", Jar::class) { + from(sourceSets["main"].allJava) + archiveClassifier.set("sources") + } + + tasks.create("testOutputJar", Jar::class) { + from(sourceSets["test"].output) + archiveClassifier.set("test") + } + + tasks.register("javadocJar", Jar::class) { + from("$projectDir/build/docs/javadoc") + archiveClassifier.set("javadoc") + dependsOn("javadoc") + } + + idea { + module { + generatedSourceDirs.add(project.file(generatedJavaDir)) + testSourceDirs.add(project.file(generatedTestJavaDir)) + isDownloadJavadoc = true + isDownloadSources = true + } + } + + val cleanGenerated by tasks.registering(Delete::class) { + delete("$projectDir/generated") + } + + tasks.clean.configure { + dependsOn(cleanGenerated) + } + + apply(from = Deps.scripts.pmd(project)) +} + +apply { + from(Deps.scripts.jacoco(project)) + from(Deps.scripts.publish(project)) + from(Deps.scripts.generatePom(project)) + from(Deps.scripts.repoLicenseReport(project)) +} + +val smokeTests by tasks.registering(RunBuild::class) { + directory = "$rootDir/tools/smoke-tests" +} + +tasks.register("buildAll") { + dependsOn(tasks.build, smokeTests) +} diff --git a/tools/tool-base/build.gradle b/buildSrc/build.gradle.kts similarity index 87% rename from tools/tool-base/build.gradle rename to buildSrc/build.gradle.kts index 80fa4f7d7a..bdfd32a6d6 100644 --- a/tools/tool-base/build.gradle +++ b/buildSrc/build.gradle.kts @@ -18,11 +18,11 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -group = 'io.spine.tools' - -dependencies { - api project(':base') - implementation deps.gen.javaPoet +plugins { + kotlin("jvm").version("1.3.72") +} - testImplementation project(':testlib') +repositories { + mavenLocal() + jcenter() } diff --git a/buildSrc/src/main/kotlin/io/spine/gradle/internal/RunBuild.kt b/buildSrc/src/main/kotlin/io/spine/gradle/internal/RunBuild.kt new file mode 100644 index 0000000000..c083ad952a --- /dev/null +++ b/buildSrc/src/main/kotlin/io/spine/gradle/internal/RunBuild.kt @@ -0,0 +1,90 @@ +/* + * Copyright 2020, TeamDev. All rights reserved. + * + * 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.gradle.internal + +import org.gradle.api.GradleException +import org.gradle.api.internal.AbstractTask +import org.gradle.api.tasks.TaskAction +import org.gradle.internal.os.OperatingSystem +import java.io.File + +/** + * A Gradle task which runs another Gradle build. + * + * Launches Gradle wrapper under a given [directory] with the `build` task. The `clean` task is also + * run if current build includes a `clean` task. + * + * The build writes verbose log into `$directory/build/debug-out.txt`. The error output is written + * into `$directory/build/error-out.txt`. + */ +open class RunBuild : AbstractTask() { + + /** + * Path to the directory which contains a Gradle wrapper script. + */ + lateinit var directory: String + + @TaskAction + private fun execute() { + val runsOnWindows = OperatingSystem.current().isWindows() + val script = if (runsOnWindows) "gradlew.bat" else "gradlew" + val command = buildCommand(script) + + // Ensure build error output log. + // Since we're executing this task in another process, we redirect error output to + // the file under the `build` directory. + val buildDir = File(directory, "build") + if (!buildDir.exists()) { + buildDir.mkdir() + } + val errorOut = File(buildDir, "error-out.txt") + val debugOut = File(buildDir, "debug-out.txt") + + val process = buildProcess(command, errorOut, debugOut) + if (process.waitFor() != 0) { + throw GradleException("Build FAILED. See $errorOut for details.") + } + } + + private fun buildCommand(script: String): List { + val command = mutableListOf() + command.add("${project.rootDir}/$script") + val shouldClean = project.gradle + .taskGraph + .hasTask(":clean") + if (shouldClean) { + command.add("clean") + } + command.add("build") + command.add("--console=plain") + command.add("--debug") + command.add("--stacktrace") + return command + } + + private fun buildProcess(command: List, errorOut: File, debugOut: File) = + ProcessBuilder() + .command(command) + .directory(project.file(directory)) + .redirectError(errorOut) + .redirectOutput(debugOut) + .start() +} diff --git a/buildSrc/src/main/kotlin/io/spine/gradle/internal/deps.kt b/buildSrc/src/main/kotlin/io/spine/gradle/internal/deps.kt new file mode 100644 index 0000000000..2636036af2 --- /dev/null +++ b/buildSrc/src/main/kotlin/io/spine/gradle/internal/deps.kt @@ -0,0 +1,345 @@ +/* + * Copyright 2020, TeamDev. All rights reserved. + * + * 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.gradle.internal + +import org.gradle.api.Project +import org.gradle.api.artifacts.ConfigurationContainer +import org.gradle.api.artifacts.dsl.RepositoryHandler +import java.net.URI + +/* + * This file describes shared dependencies of Spine sub-projects. + * + * Inspired by dependency management of the Uber's NullAway project: + * https://github.com/uber/NullAway/blob/master/gradle/dependencies.gradle + */ + +data class Repository(val releases: String, + val snapshots: String, + val credentials: String) + +/** + * Repositories to which we may publish. Normally, only one repository will be used. + * + * See `publish.gradle` for details of the publishing process. + */ +object PublishingRepos { + val mavenTeamDev = Repository( + releases = "http://maven.teamdev.com/repository/spine", + snapshots = "http://maven.teamdev.com/repository/spine-snapshots", + credentials = "credentials.properties" + ) + val cloudRepo = Repository( + releases = "https://spine.mycloudrepo.io/public/repositories/releases", + snapshots = "https://spine.mycloudrepo.io/public/repositories/snapshots", + credentials = "cloudrepo.properties" + ) +} + +// Specific repositories. +object Repos { + val oldSpine: String = PublishingRepos.mavenTeamDev.releases + val oldSpineSnapshots: String = PublishingRepos.mavenTeamDev.snapshots + + val spine: String = PublishingRepos.cloudRepo.releases + val spineSnapshots: String = PublishingRepos.cloudRepo.snapshots + + val sonatypeSnapshots: String = "https://oss.sonatype.org/content/repositories/snapshots" + val gradlePlugins = "https://plugins.gradle.org/m2/" +} + +object Versions { + val checkerFramework = "3.3.0" + val errorProne = "2.3.4" + val errorProneJavac = "9+181-r4173-1" // taken from here: https://github.com/tbroyer/gradle-errorprone-plugin/blob/v0.8/build.gradle.kts + val errorPronePlugin = "1.1.1" + val pmd = "6.20.0" + val checkstyle = "8.29" + val protobufPlugin = "0.8.12" + val appengineApi = "1.9.79" + val appenginePlugin = "2.2.0" + val findBugs = "3.0.2" + val guava = "29.0-jre" + val protobuf = "3.11.4" + val grpc = "1.28.1" + val flogger = "0.5.1" + val junit4 = "4.12" + val junit5 = "5.6.2" + val junitPlatform = "1.6.2" + val junitPioneer = "0.4.2" + val truth = "1.0.1" + val httpClient = "1.34.2" + val apacheHttpClient = "2.1.2" + val firebaseAdmin = "6.12.2" + val roaster = "2.21.2.Final" + val licensePlugin = "1.13" + val javaPoet = "1.12.1" + val autoService = "1.0-rc6" + val autoCommon = "0.10" + val jackson = "2.9.10.4" + val animalSniffer = "1.18" + val apiguardian = "1.1.0" + + /** + * Version of the SLF4J library. + * + * Spine used to log with SLF4J. Now we use Flogger. Whenever a coice comes up, we recommend to + * use the latter. + * + * Some third-party libraries may clash with different versions of the library. Thus, we specify + * this version and force it via [forceConfiguration(..)][DependencyResolution.forceConfiguration]. + */ + @Deprecated("Use Flogger over SLF4J.", replaceWith = ReplaceWith("flogger")) + val slf4j = "1.7.29" +} + +object GradlePlugins { + val errorProne = "net.ltgt.gradle:gradle-errorprone-plugin:${Versions.errorPronePlugin}" + val protobuf = "com.google.protobuf:protobuf-gradle-plugin:${Versions.protobufPlugin}" + val appengine = "com.google.cloud.tools:appengine-gradle-plugin:${Versions.appenginePlugin}" + val licenseReport = "com.github.jk1:gradle-license-report:${Versions.licensePlugin}" +} + +object Build { + val errorProneJavac = "com.google.errorprone:javac:${Versions.errorProneJavac}" + val errorProneAnnotations = listOf( + "com.google.errorprone:error_prone_annotations:${Versions.errorProne}", + "com.google.errorprone:error_prone_type_annotations:${Versions.errorProne}" + ) + val errorProneCheckApi = "com.google.errorprone:error_prone_check_api:${Versions.errorProne}" + val errorProneCore = "com.google.errorprone:error_prone_core:${Versions.errorProne}" + val errorProneTestHelpers = "com.google.errorprone:error_prone_test_helpers:${Versions.errorProne}" + val checkerAnnotations = "org.checkerframework:checker-qual:${Versions.checkerFramework}" + val checkerDataflow = listOf( + "org.checkerframework:dataflow:${Versions.checkerFramework}", + "org.checkerframework:javacutil:${Versions.checkerFramework}" + ) + val autoCommon = "com.google.auto:auto-common:${Versions.autoCommon}" + val autoService = AutoService + val jsr305Annotations = "com.google.code.findbugs:jsr305:${Versions.findBugs}" + val guava = "com.google.guava:guava:${Versions.guava}" + val flogger = "com.google.flogger:flogger:${Versions.flogger}" + val protobuf = listOf( + "com.google.protobuf:protobuf-java:${Versions.protobuf}", + "com.google.protobuf:protobuf-java-util:${Versions.protobuf}" + ) + val protoc = "com.google.protobuf:protoc:${Versions.protobuf}" + val googleHttpClient = "com.google.http-client:google-http-client:${Versions.httpClient}" + val googleHttpClientApache = "com.google.http-client:google-http-client-apache:${Versions.apacheHttpClient}" + val appengineApi = "com.google.appengine:appengine-api-1.0-sdk:${Versions.appengineApi}" + val firebaseAdmin = "com.google.firebase:firebase-admin:${Versions.firebaseAdmin}" + val jacksonDatabind = "com.fasterxml.jackson.core:jackson-databind:${Versions.jackson}" + val roasterApi = "org.jboss.forge.roaster:roaster-api:${Versions.roaster}" + val roasterJdt = "org.jboss.forge.roaster:roaster-jdt:${Versions.roaster}" + val animalSniffer = "org.codehaus.mojo:animal-sniffer-annotations:${Versions.animalSniffer}" + val ci = "true".equals(System.getenv("CI")) + val gradlePlugins = GradlePlugins + @Deprecated("Use Flogger over SLF4J.", replaceWith = ReplaceWith("flogger")) + @Suppress("DEPRECATION") // Version of SLF4J. + val slf4j = "org.slf4j:slf4j-api:${Versions.slf4j}" + + object AutoService { + val annotations = "com.google.auto.service:auto-service-annotations:${Versions.autoService}" + val processor = "com.google.auto.service:auto-service:${Versions.autoService}" + } +} + +object Gen { + val javaPoet = "com.squareup:javapoet:${Versions.javaPoet}" +} + +object Grpc { + val core = "io.grpc:grpc-core:${Versions.grpc}" + val stub = "io.grpc:grpc-stub:${Versions.grpc}" + val okHttp = "io.grpc:grpc-okhttp:${Versions.grpc}" + val protobuf = "io.grpc:grpc-protobuf:${Versions.grpc}" + val netty = "io.grpc:grpc-netty:${Versions.grpc}" + val nettyShaded = "io.grpc:grpc-netty-shaded:${Versions.grpc}" + val context = "io.grpc:grpc-context:${Versions.grpc}" + + @Deprecated("Use the shorter form.", replaceWith = ReplaceWith("core")) + val grpcCore = core + @Deprecated("Use the shorter form.", replaceWith = ReplaceWith("stub")) + val grpcStub = stub + @Deprecated("Use the shorter form.", replaceWith = ReplaceWith("okHttp")) + val grpcOkHttp = okHttp + @Deprecated("Use the shorter form.", replaceWith = ReplaceWith("protobuf")) + val grpcProtobuf = protobuf + @Deprecated("Use the shorter form.", replaceWith = ReplaceWith("netty")) + val grpcNetty = netty + @Deprecated("Use the shorter form.", replaceWith = ReplaceWith("nettyShaded")) + val grpcNettyShaded = nettyShaded + @Deprecated("Use the shorter form.", replaceWith = ReplaceWith("context")) + val grpcContext = context +} + +object Runtime { + + val flogger = Flogger + + object Flogger { + val systemBackend = "com.google.flogger:flogger-system-backend:${Versions.flogger}" + val log4J = "com.google.flogger:flogger-log4j:${Versions.flogger}" + val slf4J = "com.google.flogger:slf4j-backend-factory:${Versions.flogger}" + } + + @Deprecated("Use the `flogger` object.", replaceWith = ReplaceWith("flogger.systemBackend")) + val floggerSystemBackend = flogger.systemBackend + @Deprecated("Use the `flogger` object.", replaceWith = ReplaceWith("flogger.log4J")) + val floggerLog4J = flogger.log4J + @Deprecated("Use the `flogger` object.", replaceWith = ReplaceWith("flogger.slf4J")) + val floggerSlf4J = flogger.slf4J +} + +object Test { + val junit4 = "junit:junit:${Versions.junit4}" + val junit5Api = listOf( + "org.junit.jupiter:junit-jupiter-api:${Versions.junit5}", + "org.junit.jupiter:junit-jupiter-params:${Versions.junit5}", + "org.apiguardian:apiguardian-api:${Versions.apiguardian}" + ) + val junit5Runner = "org.junit.jupiter:junit-jupiter-engine:${Versions.junit5}" + val junitPioneer = "org.junit-pioneer:junit-pioneer:${Versions.junitPioneer}" + val guavaTestlib = "com.google.guava:guava-testlib:${Versions.guava}" + val mockito = "org.mockito:mockito-core:2.12.0" + val hamcrest = "org.hamcrest:hamcrest-all:1.3" + val truth = listOf( + "com.google.truth:truth:${Versions.truth}", + "com.google.truth.extensions:truth-java8-extension:${Versions.truth}", + "com.google.truth.extensions:truth-proto-extension:${Versions.truth}" + ) + @Deprecated("Use Flogger over SLF4J.", + replaceWith = ReplaceWith("Deps.runtime.floggerSystemBackend")) + @Suppress("DEPRECATION") // Version of SLF4J. + val slf4j = "org.slf4j:slf4j-jdk14:${Versions.slf4j}" +} + +object Scripts { + + private const val COMMON_PATH = "/config/gradle/" + + fun testArtifacts(p: Project) = p.script("test-artifacts.gradle") + fun testOutput(p: Project) = p.script("test-output.gradle") + fun slowTests(p: Project) = p.script("slow-tests.gradle") + fun javadocOptions(p: Project) = p.script("javadoc-options.gradle") + fun filterInternalJavadocs(p: Project) = p.script("filter-internal-javadoc.gradle") + fun jacoco(p: Project) = p.script("jacoco.gradle") + fun publish(p: Project) = p.script("publish.gradle") + fun publishProto(p: Project) = p.script("publish-proto.gradle") + fun javacArgs(p: Project) = p.script("javac-args.gradle") + fun jsBuildTasks(p: Project) = p.script("js/build-tasks.gradle") + fun jsConfigureProto(p: Project) = p.script("js/configure-proto.gradle") + fun npmPublishTasks(p: Project) = p.script("js/npm-publish-tasks.gradle") + fun npmCli(p: Project) = p.script("js/npm-cli.gradle") + fun updatePackageVersion(p: Project) = p.script("js/update-package-version.gradle") + fun dartBuildTasks(p: Project) = p.script("dart/build-tasks.gradle") + fun pubPublishTasks(p: Project) = p.script("dart/pub-publish-tasks.gradle") + fun pmd(p: Project) = p.script("pmd.gradle") + fun checkstyle(p: Project) = p.script("checkstyle.gradle") + fun runBuild(p: Project) = p.script("run-build.gradle") + fun modelCompiler(p: Project) = p.script("model-compiler.gradle") + fun licenseReportCommon(p: Project) = p.script("license-report-common.gradle") + fun projectLicenseReport(p: Project) = p.script("license-report-project.gradle") + fun repoLicenseReport(p: Project) = p.script("license-report-repo.gradle") + fun generatePom(p: Project) = p.script("generate-pom.gradle") + fun updateGitHubPages(p: Project) = p.script("update-gh-pages.gradle") + + private fun Project.script(name: String) = "${rootDir}$COMMON_PATH$name" +} + +object Deps { + val build = Build + val grpc = Grpc + val gen = Gen + val runtime = Runtime + val test = Test + val versions = Versions + val scripts = Scripts +} + +object DependencyResolution { + + fun forceConfiguration(configurations: ConfigurationContainer) { + configurations.all { config -> + config.resolutionStrategy { strategy -> + strategy.failOnVersionConflict() + strategy.cacheChangingModulesFor(0, "seconds") + @Suppress("DEPRECATION") // Force SLF4J version. + strategy.force( + Deps.build.slf4j, + Deps.build.errorProneAnnotations, + Deps.build.jsr305Annotations, + Deps.build.checkerAnnotations, + Deps.build.autoCommon, + Deps.build.guava, + Deps.build.animalSniffer, + Deps.build.protobuf, + Deps.test.guavaTestlib, + Deps.test.truth, + Deps.test.junit5Api, + Deps.test.junit4, + + // Transitive dependencies of 3rd party components that we don't use directly. + "com.google.code.gson:gson:2.8.6", + "com.google.j2objc:j2objc-annotations:1.3", + "org.codehaus.plexus:plexus-utils:3.3.0", + "com.squareup.okio:okio:1.17.5", // Last version before next major. + "commons-cli:commons-cli:1.4", + + // Force discontinued transitive dependency until everybody migrates off it. + "org.checkerframework:checker-compat-qual:2.5.5", + + "commons-logging:commons-logging:1.2", + + // Force the Gradle Protobuf plugin version. + Deps.build.gradlePlugins.protobuf + ) + } + } + } + + fun excludeProtobufLite(configurations: ConfigurationContainer) { + excludeProtoLite(configurations, "runtime") + excludeProtoLite(configurations, "testRuntime") + } + + private fun excludeProtoLite(configurations: ConfigurationContainer, + configurationName: String) { + configurations.named(configurationName).get() + .exclude(mapOf("group" to "com.google.protobuf", "module" to "protobuf-lite")) + } + + fun defaultRepositories(repositories: RepositoryHandler) { + repositories.mavenLocal() + repositories.maven { repository -> + repository.url = URI(Repos.spine) + repository.content { descriptor -> + descriptor.includeGroup("io.spine") + descriptor.includeGroup("io.spine.tools") + descriptor.includeGroup("io.spine.gcloud") + } + } + repositories.jcenter() + repositories.maven { repository -> + repository.url = URI(Repos.gradlePlugins) + } + } +} diff --git a/config b/config index cb8f3e1700..5ffcb1a8db 160000 --- a/config +++ b/config @@ -1 +1 @@ -Subproject commit cb8f3e170024a9972d0b89cfa25044d83bfb9b3e +Subproject commit 5ffcb1a8dbe4b9f14aacb9ecf663c5e639eac4b5 diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index f3d88b1c2f..62d4c05355 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index a4b4429748..a4f0001d20 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.3-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.4.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index 2fe81a7d95..fbd7c51583 100755 --- a/gradlew +++ b/gradlew @@ -82,6 +82,7 @@ esac CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + # Determine the Java command to use to start the JVM. if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then @@ -129,6 +130,7 @@ fi if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then APP_HOME=`cygpath --path --mixed "$APP_HOME"` CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` # We build the pattern for arguments to be converted via cygpath diff --git a/gradlew.bat b/gradlew.bat index 62bd9b9cce..5093609d51 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -84,6 +84,7 @@ set CMD_LINE_ARGS=%* set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + @rem Execute Gradle "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% diff --git a/license-report.md b/license-report.md index acd9b28a8c..cac8d088b0 100644 --- a/license-report.md +++ b/license-report.md @@ -328,7 +328,7 @@ The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Mon Apr 27 19:58:27 EEST 2020** 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). +This report was generated on **Mon May 18 17:02:11 EEST 2020** 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). @@ -773,7 +773,7 @@ This report was generated on **Mon Apr 27 19:58:27 EEST 2020** using [Gradle-Lic The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Mon Apr 27 19:58:28 EEST 2020** 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). +This report was generated on **Mon May 18 17:02:16 EEST 2020** 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). @@ -1156,7 +1156,7 @@ This report was generated on **Mon Apr 27 19:58:28 EEST 2020** using [Gradle-Lic The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Mon Apr 27 19:58:29 EEST 2020** 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). +This report was generated on **Mon May 18 17:02:19 EEST 2020** 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). @@ -1521,7 +1521,7 @@ This report was generated on **Mon Apr 27 19:58:29 EEST 2020** using [Gradle-Lic The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Mon Apr 27 19:58:29 EEST 2020** 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). +This report was generated on **Mon May 18 17:02:23 EEST 2020** 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). @@ -1902,7 +1902,7 @@ This report was generated on **Mon Apr 27 19:58:29 EEST 2020** using [Gradle-Lic The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Mon Apr 27 19:58:30 EEST 2020** 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). +This report was generated on **Mon May 18 17:02:35 EEST 2020** 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). @@ -2281,7 +2281,7 @@ This report was generated on **Mon Apr 27 19:58:30 EEST 2020** using [Gradle-Lic The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Mon Apr 27 19:58:30 EEST 2020** 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). +This report was generated on **Mon May 18 17:02:38 EEST 2020** 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). @@ -2646,7 +2646,7 @@ This report was generated on **Mon Apr 27 19:58:30 EEST 2020** using [Gradle-Lic The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Mon Apr 27 19:58:31 EEST 2020** 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). +This report was generated on **Mon May 18 17:02:43 EEST 2020** 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). @@ -3065,7 +3065,7 @@ This report was generated on **Mon Apr 27 19:58:31 EEST 2020** using [Gradle-Lic The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Mon Apr 27 19:58:31 EEST 2020** 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). +This report was generated on **Mon May 18 17:02:49 EEST 2020** 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). @@ -3430,7 +3430,7 @@ This report was generated on **Mon Apr 27 19:58:31 EEST 2020** using [Gradle-Lic The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Mon Apr 27 19:58:32 EEST 2020** 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). +This report was generated on **Mon May 18 17:02:54 EEST 2020** 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). @@ -3795,7 +3795,7 @@ This report was generated on **Mon Apr 27 19:58:32 EEST 2020** using [Gradle-Lic The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Mon Apr 27 19:58:32 EEST 2020** 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). +This report was generated on **Mon May 18 17:03:04 EEST 2020** 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). @@ -4120,7 +4120,7 @@ This report was generated on **Mon Apr 27 19:58:32 EEST 2020** using [Gradle-Lic The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Mon Apr 27 19:58:33 EEST 2020** 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). +This report was generated on **Mon May 18 17:03:09 EEST 2020** 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). @@ -4453,7 +4453,7 @@ This report was generated on **Mon Apr 27 19:58:33 EEST 2020** using [Gradle-Lic The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Mon Apr 27 19:58:33 EEST 2020** 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). +This report was generated on **Mon May 18 17:03:09 EEST 2020** 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). @@ -4832,7 +4832,7 @@ This report was generated on **Mon Apr 27 19:58:33 EEST 2020** using [Gradle-Lic The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Mon Apr 27 19:58:33 EEST 2020** 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). +This report was generated on **Mon May 18 17:03:13 EEST 2020** 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). @@ -5165,7 +5165,7 @@ This report was generated on **Mon Apr 27 19:58:33 EEST 2020** using [Gradle-Lic The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Mon Apr 27 19:58:34 EEST 2020** 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). +This report was generated on **Mon May 18 17:03:17 EEST 2020** 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). @@ -5498,4 +5498,4 @@ This report was generated on **Mon Apr 27 19:58:34 EEST 2020** using [Gradle-Lic The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Mon Apr 27 19:58:34 EEST 2020** 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 +This report was generated on **Mon May 18 17:03:21 EEST 2020** 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/settings.gradle b/settings.gradle.kts similarity index 68% rename from settings.gradle rename to settings.gradle.kts index b84f12d402..165102efb7 100644 --- a/settings.gradle +++ b/settings.gradle.kts @@ -18,33 +18,33 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -rootProject.name = 'spine-base' +rootProject.name = "spine-base" -include 'base' +include("base") -include 'testlib' +include("testlib") /** * Includes a module and sets custom project directory to it. */ -final def module = { final String name -> - include name - project(":$name").projectDir = new File("$rootDir/tools/$name") +fun module(name: String) { + include(name) + project(":$name").projectDir = File("$rootDir/tools/$name") } -module 'tool-base' -module 'plugin-base' -module 'plugin-testlib' +module("tool-base") +module("plugin-base") +module("plugin-testlib") -module 'mute-logging' -module 'errorprone-checks' -module 'javadoc-filter' -module 'javadoc-prettifier' -module 'model-compiler' +module("mute-logging") +module("errorprone-checks") +module("javadoc-filter") +module("javadoc-prettifier") +module("model-compiler") -module 'proto-dart-plugin' -module 'proto-js-plugin' +module("proto-dart-plugin") +module("proto-js-plugin") -module 'protoc-api' -module 'validation-generator' -module 'protoc-plugin' +module("protoc-api") +module("validation-generator") +module("protoc-plugin") diff --git a/testlib/build.gradle b/testlib/build.gradle.kts similarity index 75% rename from testlib/build.gradle rename to testlib/build.gradle.kts index 10cd830716..4b5cedaa55 100644 --- a/testlib/build.gradle +++ b/testlib/build.gradle.kts @@ -1,3 +1,5 @@ +import io.spine.gradle.internal.Deps + /* * Copyright 2020, TeamDev. All rights reserved. * @@ -17,27 +19,18 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -group = 'io.spine' + +group = "io.spine" dependencies { /* Expose tools we use as transitive dependencies to simplify dependency management in sub-projects. */ - api(deps.build.protobuf, - deps.test.junit5Api, - deps.test.truth, - deps.test.guavaTestlib, - deps.test.hamcrest) - implementation project(':base') -} - -/* - * This module declares protobuf messages and uses them in tests, hence the need for the Protobuf - * compiler - */ -protobuf { - protoc { - artifact = deps.build.protoc - } + Deps.build.protobuf.forEach { api(it) } + Deps.test.junit5Api.forEach { api(it) } + Deps.test.truth.forEach { api(it) } + api(Deps.test.guavaTestlib) + api(Deps.test.hamcrest) + implementation(project(":base")) } diff --git a/tools/errorprone-checks/build.gradle b/tools/errorprone-checks/build.gradle.kts similarity index 50% rename from tools/errorprone-checks/build.gradle rename to tools/errorprone-checks/build.gradle.kts index e5d0cd2db3..605112dc95 100644 --- a/tools/errorprone-checks/build.gradle +++ b/tools/errorprone-checks/build.gradle.kts @@ -18,44 +18,42 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -group = 'io.spine.tools' +import io.spine.gradle.internal.Deps +import io.spine.gradle.internal.Repos +import java.net.URI + +group = "io.spine.tools" repositories { - maven { url = repos.sonatypeSnapshots } + maven { url = URI(Repos.sonatypeSnapshots) } } dependencies { - annotationProcessor deps.build.autoService.processor - compileOnly deps.build.autoService.annotations - - implementation project(':base') - implementation project(':plugin-base') - - implementation deps.build.errorProneCore - implementation deps.build.errorProneAnnotations - - testImplementation deps.build.errorProneTestHelpers + annotationProcessor(Deps.build.autoService.processor) + compileOnly(Deps.build.autoService.annotations) + implementation(project(":base")) + implementation(project(":plugin-base")) + implementation(Deps.build.errorProneCore) + Deps.build.errorProneAnnotations.forEach { implementation(it) } + testImplementation(Deps.build.errorProneTestHelpers) } -def getResolvedArtifactFor(final dependency) { - final def resolvedTestClasspath = configurations.testRuntimeClasspath.resolvedConfiguration - final def javacDependency = resolvedTestClasspath.resolvedArtifacts.findAll { +fun getResolvedArtifactFor(dependency: String): String { + val resolvedTestClasspath = configurations.testRuntimeClasspath.get().resolvedConfiguration + val javacDependency = resolvedTestClasspath.resolvedArtifacts.filter { it.name == dependency } - if (javacDependency.empty) { - throw new MissingResourceException("The 'javac' dependency is not found among the " + + if (javacDependency.isEmpty()) { + throw MissingResourceException("The 'javac' dependency is not found among the " + "resolved artifacts") } - final def path = javacDependency[0].file.absolutePath - return path + return javacDependency[0].file.absolutePath } -test.dependsOn project(':base').getTasksByName('rebuildProtobuf', false) +val test: Test = tasks.test.get() +test.dependsOn(project(":base").getTasksByName("rebuildProtobuf", false)) afterEvaluate { - final def javacPath = getResolvedArtifactFor("javac") - - test { - jvmArgs "-Xbootclasspath/p:$javacPath" - } + val javacPath = getResolvedArtifactFor("javac") + test.jvmArgs("-Xbootclasspath/p:$javacPath") } diff --git a/tools/javadoc-filter/build.gradle b/tools/javadoc-filter/build.gradle.kts similarity index 67% rename from tools/javadoc-filter/build.gradle rename to tools/javadoc-filter/build.gradle.kts index 0d0dae4a08..cf446c5174 100644 --- a/tools/javadoc-filter/build.gradle +++ b/tools/javadoc-filter/build.gradle.kts @@ -18,26 +18,25 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -group = 'io.spine.tools' +import io.spine.gradle.internal.Deps -ext { - javaxAnnotationsVersion = '1.3.1' -} +group = "io.spine.tools" + +val javaxAnnotationsVersion = "1.3.1" dependencies { - implementation files("${System.properties['java.home']}/../lib/tools.jar") - implementation project(':base') - implementation "javax.annotation:javax.annotation-api:$javaxAnnotationsVersion" - implementation deps.grpc.grpcCore - - testImplementation project(':testlib') - testImplementation project(':mute-logging') + implementation(files("${System.getProperty("java.home")}/../lib/tools.jar")) + implementation(project(":base")) + implementation("javax.annotation:javax.annotation-api:$javaxAnnotationsVersion") + implementation(Deps.grpc.core) + testImplementation(project(":testlib")) + testImplementation(project(":mute-logging")) } // We need to include module dependencies to JAR. // In particular, we need @Internal Spine annotation. -jar { - from { - configurations.runtime.collect { it.isDirectory() ? it : zipTree(it) } - } +tasks.jar.configure { + from(configurations.runtime.get().map { + if(it.isDirectory()) it else zipTree(it) + }) } diff --git a/tools/javadoc-prettifier/build.gradle b/tools/javadoc-prettifier/build.gradle deleted file mode 100644 index 17973a87ad..0000000000 --- a/tools/javadoc-prettifier/build.gradle +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2020, TeamDev. All rights reserved. - * - * 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. - */ - -group = 'io.spine.tools' - -dependencies { - implementation deps.build.guava - - implementation project(':base') - implementation project(':plugin-base') - - testImplementation project(':plugin-testlib') - testImplementation gradleTestKit() -} - -test.dependsOn(publishToMavenLocal, - project(':base').publishToMavenLocal, - project(':tool-base').publishToMavenLocal, - project(':plugin-base').publishToMavenLocal) diff --git a/tools/proto-js-plugin/build.gradle b/tools/javadoc-prettifier/build.gradle.kts similarity index 68% rename from tools/proto-js-plugin/build.gradle rename to tools/javadoc-prettifier/build.gradle.kts index 68eb03b7f0..4192c96f96 100644 --- a/tools/proto-js-plugin/build.gradle +++ b/tools/javadoc-prettifier/build.gradle.kts @@ -18,24 +18,21 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -group = 'io.spine.tools' +import io.spine.gradle.internal.Deps -dependencies { - implementation project(':base') - implementation project(':plugin-base') - - testProtobuf project(':base') - testImplementation project(':testlib') - testImplementation project(':plugin-testlib') - testImplementation gradleTestKit() +group = "io.spine.tools" - testImplementation deps.test.junit5Api - testImplementation deps.test.junit5Runner +dependencies { + implementation(Deps.build.guava) + implementation(project(":base")) + implementation(project(":plugin-base")) + testImplementation(project(":plugin-testlib")) + testImplementation(gradleTestKit()) } -protobuf { - generatedFilesBaseDir = generatedRootDir - protoc { - artifact = deps.build.protoc - } +tasks.test.configure { + dependsOn("publishToMavenLocal", + ":base:publishToMavenLocal", + ":tool-base:publishToMavenLocal", + ":plugin-base:publishToMavenLocal") } diff --git a/tools/javadoc-prettifier/src/test/resources/build.gradle b/tools/javadoc-prettifier/src/test/resources/build.gradle index 20d79ce57f..0622af5297 100644 --- a/tools/javadoc-prettifier/src/test/resources/build.gradle +++ b/tools/javadoc-prettifier/src/test/resources/build.gradle @@ -24,7 +24,7 @@ buildscript { apply from: "$rootDir/test-env.gradle" apply from: "$enclosingRootDir/config/gradle/dependencies.gradle" - apply from: "$enclosingRootDir/version.gradle" + apply from: "$enclosingRootDir/version.gradle.kts" repositories { mavenLocal() diff --git a/tools/model-compiler/build.gradle b/tools/model-compiler/build.gradle deleted file mode 100644 index 676db92608..0000000000 --- a/tools/model-compiler/build.gradle +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright 2020, TeamDev. All rights reserved. - * - * 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. - */ - -import java.nio.file.Files -import java.nio.file.StandardCopyOption - -ext { - spineFolder = "${project.projectDir}/.spine" as File - protocPluginDependency = null -} - -group = 'io.spine.tools' - -dependencies { - implementation project(':plugin-base') - implementation project(':protoc-api') - - implementation deps.gen.javaPoet - - // A library for parsing Java sources. - // Used for parsing Java sources generated from Protobuf files - // to make their annotation more convenient. - implementation(deps.build.roasterApi) { - exclude group: 'com.google.guava' - } - - implementation(deps.build.roasterJdt) { - exclude group: 'com.google.guava' - } - - implementation deps.build.gradlePlugins.protobuf - - testImplementation project(':testlib') - testImplementation deps.test.junitPioneer - testImplementation gradleTestKit() - testImplementation project(':plugin-testlib') - - // The freshest version of the plugin required for tests - protocPluginDependency = testCompileOnly "io.spine.tools:spine-protoc-plugin:$spineVersion@jar" -} - -protobuf { - generatedFilesBaseDir = generatedRootDir - - protoc { - artifact = deps.build.protoc - } - - generateProtoTasks { - all().each { final task -> - final def scope = task.sourceSet.name - task.generateDescriptorSet = true - task.descriptorSetOptions.path = "$buildDir/descriptors/${scope}/io.spine.tools.spine-model-compiler-${scope}.desc" - task.descriptorSetOptions.includeImports = true - task.descriptorSetOptions.includeSourceInfo = true - } - } -} - -sourceSets { - main { - java.srcDirs += "$projectDir/generated/main/spine" - resources.srcDirs += "$projectDir/generated/main/resources" - resources.srcDirs += "$buildDir/descriptors/main" - } - test { - java.srcDirs += "$projectDir/generated/test/spine" - resources.srcDirs += "$buildDir/descriptors/test" - } -} - -final def copyPluginJarAction = { - final def from = configurations.testCompileClasspath.fileCollection(protocPluginDependency).singleFile - final def srcPath = from.toPath() - final def dest = project.spineFolder.toPath().resolve(from.name) - dest.toFile().mkdirs() - Files.copy(srcPath, dest, StandardCopyOption.REPLACE_EXISTING) -} - -// We cannot use standard Copy task here as it resolves the `from` property not lazily. -// Since we use use a dependency in the `from`, it may cause some issues with the Maven plugin -// See https://discuss.gradle.org/t/right-way-to-copy-contents-from-dependency-archives/7449 -task copyProtocPluginTestArtifact { - description = "Spawns the Spine Protoc plugin artifact in the project directory for tests" -} - -copyProtocPluginTestArtifact.doLast(copyPluginJarAction) -copyProtocPluginTestArtifact.dependsOn project.project(':protoc-plugin').publishToMavenLocal - -// Tests use the Protobuf plugin. -compileTestJava.dependsOn copyProtocPluginTestArtifact - -test.dependsOn project(':errorprone-checks').publishToMavenLocal diff --git a/tools/model-compiler/build.gradle.kts b/tools/model-compiler/build.gradle.kts new file mode 100644 index 0000000000..15a893b713 --- /dev/null +++ b/tools/model-compiler/build.gradle.kts @@ -0,0 +1,105 @@ +/* + * Copyright 2020, TeamDev. All rights reserved. + * + * 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. + */ + +import com.google.protobuf.gradle.ProtobufConfigurator.JavaGenerateProtoTaskCollection +import groovy.lang.Closure +import groovy.lang.GString +import io.spine.gradle.internal.Deps +import java.nio.file.Files +import java.nio.file.StandardCopyOption + +group = "io.spine.tools" + +var protocPluginDependency: Dependency? = null +val spineVersion: String by extra + +dependencies { + implementation(project(":plugin-base")) + implementation(project(":protoc-api")) + implementation(Deps.gen.javaPoet) + + // A library for parsing Java sources. + // Used for parsing Java sources generated from Protobuf files + // to make their annotation more convenient. + implementation(Deps.build.roasterApi) { + exclude(group = "com.google.guava") + } + implementation(Deps.build.roasterJdt) { + exclude(group = "com.google.guava") + } + implementation(Deps.build.gradlePlugins.protobuf) + testImplementation(project(":testlib")) + testImplementation(Deps.test.junitPioneer) + testImplementation(gradleTestKit()) + testImplementation(project(":plugin-testlib")) + // The freshest version of the plugin required for tests + protocPluginDependency = testCompileOnly("io.spine.tools:spine-protoc-plugin:$spineVersion@jar") +} + +protobuf { + protobuf.generateProtoTasks( + object : Closure(this) { + private fun doCall(tasks: JavaGenerateProtoTaskCollection) { + tasks.all().forEach { task -> + val scope = task.sourceSet.name + task.generateDescriptorSet = true + task.descriptorSetOptions.path = GString.EMPTY.plus("$buildDir/descriptors/${scope}/io.spine.tools.spine-model-compiler-${scope}.desc") + task.descriptorSetOptions.includeImports = true + task.descriptorSetOptions.includeSourceInfo = true + } + } + } + ) +} + +sourceSets { + main { + java.srcDir("$projectDir/generated/main/spine") + resources.srcDir("$projectDir/generated/main/resources") + resources.srcDir("$buildDir/descriptors/main") + } + test { + java.srcDir("$projectDir/generated/test/spine") + resources.srcDir("$buildDir/descriptors/test") + } +} + +val spineFolder = file(".spine") + +// We cannot use standard Copy task here as it resolves the `from` property not lazily. +// Since we use use a dependency in the `from`, it may cause some issues with the Maven plugin +// See https://discuss.gradle.org/t/right-way-to-copy-contents-from-dependency-archives/7449 +val copyProtocPluginTestArtifact by tasks.registering { + description = "Spawns the Spine Protoc plugin artifact in the project directory for tests" + dependsOn(":protoc-plugin:publishToMavenLocal") + + doLast { + val from = configurations.testCompileClasspath.get().fileCollection(protocPluginDependency).singleFile + val srcPath = from.toPath() + val dest = spineFolder.toPath().resolve(from.name) + dest.toFile().mkdirs() + Files.copy(srcPath, dest, StandardCopyOption.REPLACE_EXISTING) + } + +} + +// Tests use the Protobuf plugin. +tasks.compileTestJava.configure { dependsOn(copyProtocPluginTestArtifact) } +tasks.test.configure { dependsOn(":errorprone-checks:publishToMavenLocal") } diff --git a/tools/model-compiler/src/test/resources/build.gradle b/tools/model-compiler/src/test/resources/build.gradle index 156bd81b1a..977e4c973c 100644 --- a/tools/model-compiler/src/test/resources/build.gradle +++ b/tools/model-compiler/src/test/resources/build.gradle @@ -26,7 +26,7 @@ buildscript { apply from: "$rootDir/test-env.gradle" apply from: "$enclosingRootDir/config/gradle/dependencies.gradle" - apply from: "$enclosingRootDir/version.gradle" + apply from: "$enclosingRootDir/version.gradle.kts" repositories { mavenLocal() diff --git a/tools/mute-logging/build.gradle.kts b/tools/mute-logging/build.gradle.kts new file mode 100644 index 0000000000..45210681a9 --- /dev/null +++ b/tools/mute-logging/build.gradle.kts @@ -0,0 +1,29 @@ +/* + * Copyright 2020, TeamDev. All rights reserved. + * + * 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. + */ + +import io.spine.gradle.internal.Deps + +group = "io.spine.tools" + +dependencies { + implementation(project(":base")) + implementation(project(":testlib")) + Deps.test.junit5Api.forEach { implementation(it) } +} diff --git a/tools/plugin-base/build.gradle b/tools/plugin-base/build.gradle deleted file mode 100644 index a72013dab0..0000000000 --- a/tools/plugin-base/build.gradle +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright 2020, TeamDev. All rights reserved. - * - * 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. - */ - -import static com.google.common.io.Files.createParentDirs - -group = 'io.spine.tools' - -dependencies { - api gradleApi() - api deps.build.gradlePlugins.protobuf - api project(':tool-base') - - testImplementation project(':testlib') - testImplementation project(':plugin-testlib') -} - -protobuf { - generatedFilesBaseDir = generatedRootDir - - protoc { - artifact = deps.build.protoc - } - - generateProtoTasks { - all().each { final task -> - task.generateDescriptorSet = true - task.descriptorSetOptions.path = "$buildDir/descriptors/${task.sourceSet.name}/known_types.desc" - } - } -} - -/** - * Prepares the `versions.properties` file and puts it into the resources of this project. - * - *

The file contains versions of dependencies which are configured by - * the `ProtocConfigurationPlugin`. - */ -task prepareProtocConfigVersions { - description = "Prepares the versions.properties file." - - final def file = file("$projectDir/generated/main/resources/versions.properties") - - outputs.file(file) - - final Properties versions = new Properties() - versions.setProperty("baseVersion", spineBaseVersion) - versions.setProperty("protobufVersion", deps.versions.protobuf) - versions.setProperty("gRPCVersion", deps.versions.grpc) - - doLast { - createParentDirs(file) - file.createNewFile() - file.withOutputStream { final stream -> - versions.store(stream, "Versions of dependencies of the Model Compiler plugin and the Spine Protoc plugin.") - } - } -} - -processResources.dependsOn prepareProtocConfigVersions - -sourceSets { - test { - resources.srcDirs += "$sourcesRootDir/test/resources" - } -} diff --git a/tools/plugin-base/build.gradle.kts b/tools/plugin-base/build.gradle.kts new file mode 100644 index 0000000000..a7d89c0f41 --- /dev/null +++ b/tools/plugin-base/build.gradle.kts @@ -0,0 +1,80 @@ +/* + * Copyright 2020, TeamDev. All rights reserved. + * + * 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. + */ + +import com.google.common.io.Files +import com.google.protobuf.gradle.ProtobufConfigurator.JavaGenerateProtoTaskCollection +import groovy.lang.Closure +import groovy.lang.GString +import io.spine.gradle.internal.Deps +import java.util.* +import kotlin.collections.HashMap + +group = "io.spine.tools" + +dependencies { + api(gradleApi()) + api(Deps.build.gradlePlugins.protobuf) + api(project(":tool-base")) + + testImplementation(project(":testlib")) + testImplementation(project(":plugin-testlib")) +} + +protobuf { + protobuf.generateProtoTasks(object : Closure(this) { + private fun doCall(tasks: JavaGenerateProtoTaskCollection) { + for (task in tasks.all()) { + task.generateDescriptorSet = true + task.descriptorSetOptions.path = GString.EMPTY.plus("$buildDir/descriptors/${task.sourceSet.name}/known_types.desc") + } + } + }) +} + +val spineBaseVersion: String by extra + +val prepareProtocConfigVersions by tasks.registering { + description = "Prepares the versions.properties file." + + val file = file("$projectDir/generated/main/resources/versions.properties") + outputs.file(file) + + val versions = Properties() + versions.setProperty("baseVersion", spineBaseVersion) + versions.setProperty("protobufVersion", Deps.versions.protobuf) + versions.setProperty("gRPCVersion", Deps.versions.grpc) + + @Suppress("UNCHECKED_CAST") + inputs.properties(HashMap(versions) as MutableMap) + + doLast { + Files.createParentDirs(file) + file.createNewFile() + file.outputStream().use { + versions.store(it, "Versions of dependencies of the Model Compiler plugin and the Spine Protoc plugin.") + } + } +} + +tasks.processResources.get().dependsOn(prepareProtocConfigVersions) + +sourceSets.test { + resources.srcDir("$projectDir/src/test/resources") +} diff --git a/tools/plugin-base/src/main/java/io/spine/tools/gradle/GradleTask.java b/tools/plugin-base/src/main/java/io/spine/tools/gradle/GradleTask.java index 8c9a48da9a..f37f92d4b6 100644 --- a/tools/plugin-base/src/main/java/io/spine/tools/gradle/GradleTask.java +++ b/tools/plugin-base/src/main/java/io/spine/tools/gradle/GradleTask.java @@ -22,18 +22,19 @@ import com.google.common.base.MoreObjects; import com.google.errorprone.annotations.CanIgnoreReturnValue; -import org.checkerframework.checker.nullness.qual.MonotonicNonNull; import org.checkerframework.checker.nullness.qual.Nullable; import org.gradle.api.Action; import org.gradle.api.Project; import org.gradle.api.Task; import org.gradle.api.file.FileCollection; -import org.gradle.api.internal.file.UnionFileCollection; import org.gradle.api.tasks.TaskContainer; +import java.io.File; import java.io.Serializable; +import java.util.HashSet; import java.util.Map; import java.util.Objects; +import java.util.Set; import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkState; @@ -99,9 +100,11 @@ public static final class Builder { private boolean allowNoDependencies; - private @MonotonicNonNull UnionFileCollection inputs; + private boolean hasInputFiles = false; + private final Set inputs = new HashSet<>(); private Map inputProperties; - private @MonotonicNonNull UnionFileCollection outputs; + private boolean hasOutputFiles = false; + private final Set outputs = new HashSet<>(); Builder(TaskName name, Action action) { this.name = name; @@ -203,10 +206,8 @@ public Builder allowNoDependencies() { */ public Builder withInputFiles(FileCollection inputs) { checkNotNull(inputs, "Task inputs"); - if (this.inputs == null) { - this.inputs = new UnionFileCollection(); - } - this.inputs.addToUnion(inputs); + this.inputs.addAll(inputs.getFiles()); + hasInputFiles = true; return this; } @@ -247,10 +248,8 @@ public Builder withInputProperty(String propertyName, @Nullable Serializable val */ public Builder withOutputFiles(FileCollection outputs) { checkNotNull(outputs, "Task outputs"); - if (this.outputs == null) { - this.outputs = new UnionFileCollection(); - } - this.outputs.addToUnion(outputs); + this.outputs.addAll(outputs.getFiles()); + hasOutputFiles = true; return this; } @@ -317,7 +316,7 @@ private void dependTaskOnAllProjects(Task task, Project rootProject) { } private void addTaskIO(Task task) { - if (inputs != null) { + if (hasInputFiles) { task.getInputs() .files(inputs) .skipWhenEmpty() @@ -327,7 +326,7 @@ private void addTaskIO(Task task) { task.getInputs() .properties(inputProperties); } - if (outputs != null) { + if (hasOutputFiles) { task.getOutputs() .files(outputs) .optional(); diff --git a/tools/plugin-testlib/build.gradle b/tools/plugin-testlib/build.gradle.kts similarity index 85% rename from tools/plugin-testlib/build.gradle rename to tools/plugin-testlib/build.gradle.kts index ebcf42a55e..1a215c39ac 100644 --- a/tools/plugin-testlib/build.gradle +++ b/tools/plugin-testlib/build.gradle.kts @@ -18,11 +18,11 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -group = 'io.spine.tools' +group = "io.spine.tools" dependencies { - implementation project(':plugin-base') - implementation project(':testlib') - implementation gradleApi() - implementation gradleTestKit() + implementation(project(":plugin-base")) + implementation(project(":testlib")) + implementation(gradleApi()) + implementation(gradleTestKit()) } diff --git a/tools/plugin-testlib/src/main/java/io/spine/tools/gradle/testing/ProjectRoot.java b/tools/plugin-testlib/src/main/java/io/spine/tools/gradle/testing/ProjectRoot.java index 8e58121c32..2126da6c60 100644 --- a/tools/plugin-testlib/src/main/java/io/spine/tools/gradle/testing/ProjectRoot.java +++ b/tools/plugin-testlib/src/main/java/io/spine/tools/gradle/testing/ProjectRoot.java @@ -28,17 +28,18 @@ import static java.nio.file.Files.exists; /** - * Finds a root of a project by presence of the {@link #VERSION_GRADLE_NAME version.gradle} file. + * Finds a root of a project by presence of the {@link #VERSION_GRADLE_NAME version.gradle.kts} + * file. * *

Starts from the current directory, climbing up, until the file is found. By convention - * a project should have only one {@link #VERSION_GRADLE_NAME version.gradle} file, which is + * a project should have only one {@link #VERSION_GRADLE_NAME version.gradle.kts} file, which is * placed in the root directory of the project. */ enum ProjectRoot { INSTANCE; - private static final String VERSION_GRADLE_NAME = "version.gradle"; + private static final String VERSION_GRADLE_NAME = "version.gradle.kts"; static ProjectRoot instance() { return INSTANCE; @@ -48,7 +49,7 @@ static ProjectRoot instance() { * Obtains a root directory of the project. * * @throws IllegalStateException - * if the {@link #VERSION_GRADLE_NAME version.gradle} file is not found + * if the {@link #VERSION_GRADLE_NAME version.gradle.kts} file is not found */ Path toPath() { Path workingFolderPath = Paths.get(".") @@ -69,7 +70,7 @@ Path toPath() { * Obtains root directory of the project. * * @throws IllegalStateException - * if the {@link #VERSION_GRADLE_NAME version.gradle} file is not found + * if the {@link #VERSION_GRADLE_NAME version.gradle.kts} file is not found * @see #toPath() */ File toFile() { diff --git a/tools/plugin-testlib/src/test/resources/build.gradle b/tools/plugin-testlib/src/test/resources/build.gradle index 21cab52cdc..8c46ee78b8 100644 --- a/tools/plugin-testlib/src/test/resources/build.gradle +++ b/tools/plugin-testlib/src/test/resources/build.gradle @@ -23,4 +23,4 @@ apply plugin: 'java' // NOTE: this file is copied from the root project in the test setup. apply from: "$rootDir/test-env.gradle" -apply from: "$enclosingRootDir/version.gradle" +apply from: "$enclosingRootDir/version.gradle.kts" diff --git a/tools/proto-dart-plugin/build.gradle b/tools/proto-dart-plugin/build.gradle.kts similarity index 90% rename from tools/proto-dart-plugin/build.gradle rename to tools/proto-dart-plugin/build.gradle.kts index 9bb2d36599..e296f20353 100644 --- a/tools/proto-dart-plugin/build.gradle +++ b/tools/proto-dart-plugin/build.gradle.kts @@ -18,9 +18,9 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -group = 'io.spine.tools' +group = "io.spine.tools" dependencies { - implementation project(':plugin-base') - testImplementation project(':testlib') + implementation(project(":plugin-base")) + testImplementation(project(":testlib")) } diff --git a/tools/protoc-api/build.gradle b/tools/proto-js-plugin/build.gradle.kts similarity index 71% rename from tools/protoc-api/build.gradle rename to tools/proto-js-plugin/build.gradle.kts index cdd881b1ad..df887a3303 100644 --- a/tools/protoc-api/build.gradle +++ b/tools/proto-js-plugin/build.gradle.kts @@ -18,22 +18,17 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -group = 'io.spine.tools' +import io.spine.gradle.internal.Deps -dependencies { - implementation project(':base') - - testImplementation project(':testlib') -} +group = "io.spine.tools" -sourceSets.main { - java.srcDir "$projectDir/generated/main/java" - proto.srcDir "$projectDir/src/main/proto" -} - -protobuf { - generatedFilesBaseDir = "$projectDir/generated" - protoc { - artifact = deps.build.protoc - } +dependencies { + implementation(project(":base")) + implementation(project(":plugin-base")) + testProtobuf(project(":base")) + testImplementation(project(":testlib")) + testImplementation(project(":plugin-testlib")) + testImplementation(gradleTestKit()) + Deps.test.junit5Api.forEach { testImplementation(it) } + testImplementation(Deps.test.junit5Runner) } diff --git a/tools/proto-js-plugin/src/test/resources/build.gradle b/tools/proto-js-plugin/src/test/resources/build.gradle index 313f62a4c4..b26a4c8d17 100644 --- a/tools/proto-js-plugin/src/test/resources/build.gradle +++ b/tools/proto-js-plugin/src/test/resources/build.gradle @@ -24,7 +24,7 @@ buildscript { apply from: "$rootDir/test-env.gradle" apply from: "$enclosingRootDir/config/gradle/dependencies.gradle" - apply from: "$enclosingRootDir/version.gradle" + apply from: "$enclosingRootDir/version.gradle.kts" repositories { mavenLocal() diff --git a/tools/protoc-api/build.gradle.kts b/tools/protoc-api/build.gradle.kts new file mode 100644 index 0000000000..dc714defa3 --- /dev/null +++ b/tools/protoc-api/build.gradle.kts @@ -0,0 +1,31 @@ +/* + * Copyright 2020, TeamDev. All rights reserved. + * + * 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. + */ + +group = "io.spine.tools" + +dependencies { + implementation(project(":base")) + testImplementation(project(":testlib")) +} + +sourceSets.main { + java.srcDir("$projectDir/generated/main/java") + proto.srcDir("$projectDir/src/main/proto") +} diff --git a/tools/protoc-plugin/build.gradle b/tools/protoc-plugin/build.gradle.kts similarity index 57% rename from tools/protoc-plugin/build.gradle rename to tools/protoc-plugin/build.gradle.kts index 3d7c86e92b..22eb518519 100644 --- a/tools/protoc-plugin/build.gradle +++ b/tools/protoc-plugin/build.gradle.kts @@ -18,58 +18,49 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +import io.spine.gradle.internal.Deps import java.nio.file.Files -group = 'io.spine.tools' +group = "io.spine.tools" dependencies { - implementation( - project(':tool-base'), - project(':protoc-api'), - project(':validation-generator'), - deps.gen.javaPoet - ) + implementation(project(":tool-base")) + implementation(project(":protoc-api")) + implementation(project(":validation-generator")) + implementation(Deps.gen.javaPoet) - testImplementation project(':base') - testImplementation( - project(':testlib'), - project(':mute-logging'), - deps.test.truth - ) + testImplementation(project(":base")) + testImplementation(project(":testlib")) + testImplementation(project(":mute-logging")) + Deps.test.truth.forEach { testImplementation(it) } } -protobuf { - generatedFilesBaseDir = generatedRootDir - protoc { - artifact = deps.build.protoc - } -} - -jar { - dependsOn( - project(':protoc-api').jar, - project(':tool-base').jar, - project(':validation-generator').jar - ) +tasks.jar { + dependsOn(":protoc-api:jar", + ":tool-base:jar", + ":validation-generator:jar") manifest { - attributes 'Main-Class': 'io.spine.tools.protoc.Plugin' + attributes(mapOf("Main-Class" to "io.spine.tools.protoc.Plugin")) } // Assemble "Fat-JAR" artifact containing all the dependencies. - from { - configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } - } + from(configurations.runtimeClasspath.get().map { + when { + it.isDirectory() -> it + else -> zipTree(it) + } + }) } -final def shellRunner = injectVersion(file('plugin_runner.sh')) -final def batchRunner = injectVersion(file('plugin_runner.bat')) +val shellRunner = injectVersion(file("plugin_runner.sh")) +val batchRunner = injectVersion(file("plugin_runner.bat")) artifacts { archives(shellRunner) { - classifier "script" + classifier = "script" } archives(batchRunner) { - classifier "script" + classifier = "script" } } @@ -87,11 +78,14 @@ artifacts { * @param scriptFile the script file to modify * @return the new script file to publish */ -def injectVersion(final File scriptFile) { - def text = scriptFile.text - text = text.replace("{version}", project.version) - final def tempFile = Files.createTempFile("build", scriptFile.name.endsWith(".sh") ? ".sh" : ".bat") - tempFile.text = text - final result = file(tempFile.toAbsolutePath()) - return result +fun injectVersion(scriptFile: File): File { + var text = scriptFile.readText() + text = text.replace("{version}", project.version as String) + val extension = when { + scriptFile.name.endsWith(".sh") -> ".sh" + else -> ".bat" + } + val tempFile = Files.createTempFile("build", extension) + tempFile.toFile().writeText(text) + return project.file(tempFile.toAbsolutePath()) } diff --git a/tools/smoke-tests/build.gradle b/tools/smoke-tests/build.gradle index 4098ded5bb..9802cec52a 100644 --- a/tools/smoke-tests/build.gradle +++ b/tools/smoke-tests/build.gradle @@ -20,7 +20,7 @@ buildscript { ext.baseRoot = "$rootDir/../.." - ext.versionGradle = "$baseRoot/version.gradle" + ext.versionGradle = "$baseRoot/version.gradle.kts" apply from: versionGradle diff --git a/tools/smoke-tests/gradle/wrapper/gradle-wrapper.jar b/tools/smoke-tests/gradle/wrapper/gradle-wrapper.jar index f3d88b1c2f..490fda8577 100644 Binary files a/tools/smoke-tests/gradle/wrapper/gradle-wrapper.jar and b/tools/smoke-tests/gradle/wrapper/gradle-wrapper.jar differ diff --git a/tools/smoke-tests/gradle/wrapper/gradle-wrapper.properties b/tools/smoke-tests/gradle/wrapper/gradle-wrapper.properties index a4b4429748..4c5803d13c 100644 --- a/tools/smoke-tests/gradle/wrapper/gradle-wrapper.properties +++ b/tools/smoke-tests/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.3-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.4-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/tools/mute-logging/build.gradle b/tools/tool-base/build.gradle.kts similarity index 85% rename from tools/mute-logging/build.gradle rename to tools/tool-base/build.gradle.kts index a3bdcbc0e8..054400491f 100644 --- a/tools/mute-logging/build.gradle +++ b/tools/tool-base/build.gradle.kts @@ -18,10 +18,13 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -group = 'io.spine.tools' +import io.spine.gradle.internal.Deps + +group = "io.spine.tools" dependencies { - implementation project(':base') - implementation project(':testlib') - implementation deps.test.junit5Api + api(project(":base")) + implementation(Deps.gen.javaPoet) + + testImplementation(project(":testlib")) } diff --git a/version.gradle b/version.gradle.kts similarity index 84% rename from version.gradle rename to version.gradle.kts index 0d6aa31763..d307d56558 100644 --- a/version.gradle +++ b/version.gradle.kts @@ -25,11 +25,10 @@ * as we want to manage the versions in a single source. */ -final def SPINE_VERSION = '1.5.11' +val SPINE_VERSION = "1.5.11" -ext { - spineVersion = SPINE_VERSION - spineBaseVersion = SPINE_VERSION // Used by `filter-internal-javadoc.gradle`. - - versionToPublish = SPINE_VERSION +project.extra.apply { + this["spineVersion"] = SPINE_VERSION + this["spineBaseVersion"] = SPINE_VERSION // Used by `filter-internal-javadoc.gradle`. + this["versionToPublish"] = SPINE_VERSION }