diff --git a/.travis.yml b/.travis.yml index 32bdf0d1..65490e5c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -22,6 +22,7 @@ env: script: - ./gradlew clean assemble -x signArchives test --tests com.google.protobuf.gradle.ProtobufJavaPluginTest --stacktrace + - ./gradlew test --tests com.google.protobuf.gradle.ProtobufKotlinDslCopySpecTest --stacktrace - ./gradlew test --tests com.google.protobuf.gradle.ProtobufKotlinDslPluginTest --stacktrace - ./gradlew test --tests com.google.protobuf.gradle.ProtobufAndroidPluginTest --stacktrace - ./gradlew -stop diff --git a/src/main/groovy/com/google/protobuf/gradle/ProtobufExtract.groovy b/src/main/groovy/com/google/protobuf/gradle/ProtobufExtract.groovy index 100d87e1..fc65bba2 100644 --- a/src/main/groovy/com/google/protobuf/gradle/ProtobufExtract.groovy +++ b/src/main/groovy/com/google/protobuf/gradle/ProtobufExtract.groovy @@ -33,6 +33,7 @@ import com.google.common.base.Preconditions import groovy.transform.CompileDynamic import org.gradle.api.DefaultTask import org.gradle.api.file.ConfigurableFileCollection +import org.gradle.api.file.DuplicatesStrategy import org.gradle.api.file.FileCollection import org.gradle.api.file.FileSystemLocation import org.gradle.api.file.FileTree @@ -113,6 +114,8 @@ abstract class ProtobufExtract extends DefaultTask { spec.from(allProtoFiles) spec.include('**/*.proto') spec.into(destDir) + // gradle 7+ requires a duplicate strategy to be explicitly defined + spec.duplicatesStrategy = DuplicatesStrategy.INCLUDE } } diff --git a/src/test/groovy/com/google/protobuf/gradle/ProtobufKotlinDslCopySpecTest.groovy b/src/test/groovy/com/google/protobuf/gradle/ProtobufKotlinDslCopySpecTest.groovy new file mode 100644 index 00000000..84404fc9 --- /dev/null +++ b/src/test/groovy/com/google/protobuf/gradle/ProtobufKotlinDslCopySpecTest.groovy @@ -0,0 +1,55 @@ +package com.google.protobuf.gradle + +import groovy.transform.CompileDynamic +import org.gradle.testkit.runner.BuildResult +import org.gradle.testkit.runner.GradleRunner +import org.gradle.testkit.runner.TaskOutcome +import spock.lang.Specification +import spock.lang.Unroll + +/** + * Unit test confirming copy spec is explicitly defined for gradle7+ compliance. + */ +@CompileDynamic +class ProtobufKotlinDslCopySpecTest extends Specification { + private static final List GRADLE_VERSIONS = ["5.6", "6.0", "6.7.1", "7.0"] + + @Unroll + void "testProjectKotlinDslCopySpec should declare explicit copy spec [gradle #gradleVersion]"() { + given: "project from testProjectKotlinDslCopySpec" + File projectDir = ProtobufPluginTestHelper.projectBuilder('testProjectKotlinDslCopySpec') + .copyDirs('testProjectKotlinDslCopySpec') + .build() + + when: "build is invoked" + BuildResult result = GradleRunner.create() + .withProjectDir(projectDir) + .withArguments('test', 'build', '--stacktrace') + .withPluginClasspath() + .withGradleVersion(gradleVersion) + .forwardStdOutput(new OutputStreamWriter(System.out)) + .forwardStdError(new OutputStreamWriter(System.err)) + .build() + + then: "it succeed" + + result.task(":test").outcome == TaskOutcome.SUCCESS + + verifyProjectDir(projectDir) + + where: + gradleVersion << GRADLE_VERSIONS + } + + private static void verifyProjectDir(File projectDir) { + File generatedSrcDir = new File(projectDir.path, "build/generated/source/proto/main/java") + List fileList = [] + generatedSrcDir.eachFileRecurse { file -> + if (file.path.endsWith('.java')) { + fileList.add (file) + } + } + assert fileList.size > 0 + } + +} diff --git a/testProjectKotlinDslCopySpec/build.gradle.kts b/testProjectKotlinDslCopySpec/build.gradle.kts new file mode 100644 index 00000000..887598aa --- /dev/null +++ b/testProjectKotlinDslCopySpec/build.gradle.kts @@ -0,0 +1,56 @@ +import com.google.protobuf.gradle.generateProtoTasks +import com.google.protobuf.gradle.id +import com.google.protobuf.gradle.ofSourceSet +import com.google.protobuf.gradle.plugins +import com.google.protobuf.gradle.protobuf +import com.google.protobuf.gradle.protoc + +buildscript { + repositories { + gradlePluginPortal() + } +} + +plugins { + java + id("java-library") + id("com.google.protobuf") +} + +repositories { + mavenCentral() +} + +java { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 +} + +val protobufDepVersion = "3.0.0" +val grpcVersion = "1.37.0" + +dependencies { + implementation("io.grpc:grpc-protobuf:$grpcVersion") + implementation("io.grpc:grpc-stub:$grpcVersion") + implementation("com.google.protobuf:protobuf-java:$protobufDepVersion") + testImplementation("org.junit.jupiter:junit-jupiter-api:5.7.1") + testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.7.1") +} + +protobuf { + protoc { + artifact = "com.google.protobuf:protoc:$protobufDepVersion" + } + plugins { + id("grpc") { + artifact = "io.grpc:protoc-gen-grpc-java:$grpcVersion" + } + } +} + +tasks { + test { + useJUnitPlatform { + } + } +} diff --git a/testProjectKotlinDslCopySpec/settings.gradle.kts b/testProjectKotlinDslCopySpec/settings.gradle.kts new file mode 100644 index 00000000..cb566acf --- /dev/null +++ b/testProjectKotlinDslCopySpec/settings.gradle.kts @@ -0,0 +1 @@ +rootProject.name="testProjectKotlinDslCopySpec" diff --git a/testProjectKotlinDslCopySpec/src/main/proto/google/type/money.proto b/testProjectKotlinDslCopySpec/src/main/proto/google/type/money.proto new file mode 100644 index 00000000..2a3ea6fb --- /dev/null +++ b/testProjectKotlinDslCopySpec/src/main/proto/google/type/money.proto @@ -0,0 +1,42 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.type; + +option cc_enable_arenas = true; +option go_package = "google.golang.org/genproto/googleapis/type/money;money"; +option java_multiple_files = true; +option java_outer_classname = "MoneyProto"; +option java_package = "com.google.type"; +option objc_class_prefix = "GTP"; + +// Represents an amount of money with its currency type. +message Money { + // The three-letter currency code defined in ISO 4217. + string currency_code = 1; + + // The whole units of the amount. + // For example if `currencyCode` is `"USD"`, then 1 unit is one US dollar. + int64 units = 2; + + // Number of nano (10^-9) units of the amount. + // The value must be between -999,999,999 and +999,999,999 inclusive. + // If `units` is positive, `nanos` must be positive or zero. + // If `units` is zero, `nanos` can be positive, zero, or negative. + // If `units` is negative, `nanos` must be negative or zero. + // For example $-1.75 is represented as `units`=-1 and `nanos`=-750,000,000. + int32 nanos = 3; +} diff --git a/testProjectKotlinDslCopySpec/src/test/java/com/myapp/ExampleUnitTest.java b/testProjectKotlinDslCopySpec/src/test/java/com/myapp/ExampleUnitTest.java new file mode 100644 index 00000000..6a940aea --- /dev/null +++ b/testProjectKotlinDslCopySpec/src/test/java/com/myapp/ExampleUnitTest.java @@ -0,0 +1,12 @@ +package com.myapp; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class ExampleUnitTest { + + @Test + public void addition_isCorrect() { + Assertions.assertEquals(4, 2 + 2); + } +}