From d73d784ee4904245be759df488a6cf3f2db21d2a Mon Sep 17 00:00:00 2001 From: Chengyuan Zhang Date: Thu, 12 Dec 2019 12:59:21 -0800 Subject: [PATCH 1/9] Bump gradle API version 5.6. --- gradle/wrapper/gradle-wrapper.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index e8289e81..086b56fe 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-5.6-bin.zip From 62b72c1b12935103758f625ef36a5cbaae33cecc Mon Sep 17 00:00:00 2001 From: Chengyuan Zhang Date: Thu, 12 Dec 2019 13:01:32 -0800 Subject: [PATCH 2/9] Add a new configuration set for holding resources from compilation dependencies. --- .../protobuf/gradle/ProtobufPlugin.groovy | 37 ++++++++++++------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/src/main/groovy/com/google/protobuf/gradle/ProtobufPlugin.groovy b/src/main/groovy/com/google/protobuf/gradle/ProtobufPlugin.groovy index 036eedd1..e7220cb7 100644 --- a/src/main/groovy/com/google/protobuf/gradle/ProtobufPlugin.groovy +++ b/src/main/groovy/com/google/protobuf/gradle/ProtobufPlugin.groovy @@ -36,6 +36,7 @@ import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.api.Task import org.gradle.api.attributes.Attribute +import org.gradle.api.attributes.LibraryElements import org.gradle.api.file.FileCollection import org.gradle.api.file.SourceDirectorySet import org.gradle.api.internal.file.DefaultSourceDirectorySet @@ -135,7 +136,7 @@ class ProtobufPlugin implements Plugin { addSourceSetExtensions() getSourceSets().all { sourceSet -> - createConfiguration(sourceSet.name) + createConfigurations(sourceSet.name) } project.afterEvaluate { // The Android variants are only available at this point. @@ -158,18 +159,34 @@ class ProtobufPlugin implements Plugin { } /** - * Creates a configuration if necessary for a source set so that the build + * Creates configurations if necessary for a source set so that the build * author can configure dependencies for it. */ - private void createConfiguration(String sourceSetName) { - String configName = Utils.getConfigName(sourceSetName, 'protobuf') - if (project.configurations.findByName(configName) == null) { - project.configurations.create(configName) { + private void createConfigurations(String sourceSetName) { + String protobufConfigName = Utils.getConfigName(sourceSetName, 'protobuf') + if (project.configurations.findByName(protobufConfigName) == null) { + project.configurations.create(protobufConfigName) { visible = false transitive = true extendsFrom = [] } } + + // Create a 'compileProto' configuration as a bucket of dependencies that contains resources + // attribute for compileClasspath dependencies. This works around 'java-library' plugin + // not exposing resources to consumers for compilation. + String compileProtoConfigName = Utils.getConfigName(sourceSetName, 'compileProto') + String compileClasspathConfigName = Utils.getConfigName(sourceSetName, 'compileClasspath') + if (project.configurations.findByName(compileProtoConfigName) == null) { + project.configurations.create(compileProtoConfigName) { + visible = false + transitive = true + extendsFrom = [project.configurations.findByName(compileClasspathConfigName)] + canBeConsumed = false + }.getAttributes().attribute( + LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, + project.getObjects().named(LibraryElements, LibraryElements.RESOURCES)) + } } /** @@ -364,7 +381,7 @@ class ProtobufPlugin implements Plugin { description = "Extracts proto files from compile dependencies for includes" destDir = getExtractedIncludeProtosDir(sourceSetOrVariantName) as File inputFiles.from(compileClasspathConfiguration - ?: project.configurations[Utils.getConfigName(sourceSetOrVariantName, 'compile')]) + ?: project.configurations[Utils.getConfigName(sourceSetOrVariantName, 'compileProto')]) // TL; DR: Make protos in 'test' sourceSet able to import protos from the 'main' // sourceSet. Sub-configurations, e.g., 'testCompile' that extends 'compile', don't @@ -380,12 +397,6 @@ class ProtobufPlugin implements Plugin { inputFiles.from getSourceSets()['main'].proto inputFiles.from testedCompileClasspathConfiguration ?: project.configurations['compile'] } - } else { - // In Java projects, the compileClasspath of the 'test' sourceSet includes all the - // 'resources' of the output of 'main', in which the source protos are placed. This is - // nicer than the ad-hoc solution that Android has, because it works for any extended - // configuration, not just 'testCompile'. - inputFiles.from getSourceSets()[sourceSetOrVariantName].compileClasspath } isTest = Utils.isTest(sourceSetOrVariantName) } From 1c15a3e299a238c8c57b83520090447ea2608a0d Mon Sep 17 00:00:00 2001 From: Chengyuan Zhang Date: Thu, 12 Dec 2019 13:05:04 -0800 Subject: [PATCH 3/9] Add test for a lib-app project, in which :app depends on :lib and :lib uses java-library plugin. --- .../gradle/ProtobufJavaPluginTest.groovy | 54 +++++++++++++++++++ testProjectDependentApp/build.gradle | 31 +++++++++++ testProjectDependentApp/settings.gradle | 1 + .../src/main/proto/dependent.proto | 14 +++++ .../src/test/java/DependentTest.java | 19 +++++++ .../src/test/proto/dependent2.proto | 8 +++ testProjectJavaLibrary/build.gradle | 5 ++ testProjectJavaLibrary/settings.gradle | 1 + testProjectJavaLibrary/src/main/java/Foo.java | 30 +++++++++++ .../src/test/java/FooTest.java | 25 +++++++++ 10 files changed, 188 insertions(+) create mode 100644 testProjectDependentApp/build.gradle create mode 100644 testProjectDependentApp/settings.gradle create mode 100644 testProjectDependentApp/src/main/proto/dependent.proto create mode 100644 testProjectDependentApp/src/test/java/DependentTest.java create mode 100644 testProjectDependentApp/src/test/proto/dependent2.proto create mode 100644 testProjectJavaLibrary/build.gradle create mode 100644 testProjectJavaLibrary/settings.gradle create mode 100644 testProjectJavaLibrary/src/main/java/Foo.java create mode 100644 testProjectJavaLibrary/src/test/java/FooTest.java diff --git a/src/test/groovy/com/google/protobuf/gradle/ProtobufJavaPluginTest.groovy b/src/test/groovy/com/google/protobuf/gradle/ProtobufJavaPluginTest.groovy index 760b6c85..e455d1e0 100644 --- a/src/test/groovy/com/google/protobuf/gradle/ProtobufJavaPluginTest.groovy +++ b/src/test/groovy/com/google/protobuf/gradle/ProtobufJavaPluginTest.groovy @@ -193,6 +193,60 @@ class ProtobufJavaPluginTest extends Specification { gradleVersion << GRADLE_VERSIONS } + void "testProjectJavaLibrary should be successfully executed (java-only project as a library)"() { + given: "project from testProjectJavaLibrary" + File projectDir = ProtobufPluginTestHelper.projectBuilder('testProjectJavaLibrary') + .copyDirs('testProjectBase', 'testProjectJavaLibrary') + .build() + + when: "build is invoked" + BuildResult result = GradleRunner.create() + .withProjectDir(projectDir) + .withArguments('build', '--stacktrace') + .withGradleVersion(gradleVersion) + .forwardStdOutput(new OutputStreamWriter(System.out)) + .forwardStdError(new OutputStreamWriter(System.err)) + .withDebug(true) + .build() + + then: "it succeed" + result.task(":build").outcome == TaskOutcome.SUCCESS + ProtobufPluginTestHelper.verifyProjectDir(projectDir) + + where: + gradleVersion << GRADLE_VERSIONS + } + + void "testProjectDependentApp should be successfully executed"() { + given: "project from testProject & testProjectDependent" + File testProjectStaging = ProtobufPluginTestHelper.projectBuilder('testProjectJavaLibrary') + .copyDirs('testProjectBase', 'testProjectJavaLibrary') + .build() + File testProjectDependentStaging = ProtobufPluginTestHelper.projectBuilder('testProjectDependentApp') + .copyDirs('testProjectDependentApp') + .build() + + File mainProjectDir = ProtobufPluginTestHelper.projectBuilder('testProjectDependentAppMain') + .copySubProjects(testProjectStaging, testProjectDependentStaging) + .build() + + when: "build is invoked" + BuildResult result = GradleRunner.create() + .withProjectDir(mainProjectDir) + .withArguments('testProjectDependentApp:build', '--stacktrace') + .withGradleVersion(gradleVersion) + .forwardStdOutput(new OutputStreamWriter(System.out)) + .forwardStdError(new OutputStreamWriter(System.err)) + .withDebug(true) + .build() + + then: "it succeed" + result.task(":testProjectDependentApp:build").outcome == TaskOutcome.SUCCESS + + where: + gradleVersion << GRADLE_VERSIONS + } + void "testProjectCustomProtoDir should be successfully executed"() { given: "project from testProjectCustomProtoDir" File projectDir = ProtobufPluginTestHelper.projectBuilder('testProjectCustomProtoDir') diff --git a/testProjectDependentApp/build.gradle b/testProjectDependentApp/build.gradle new file mode 100644 index 00000000..0ea9434c --- /dev/null +++ b/testProjectDependentApp/build.gradle @@ -0,0 +1,31 @@ +// A project that depends on another project and a published artifact, both of +// which include proto files. The included proto files are added to the +// --proto_path argument of protoc, so that the protos from this project can +// import them. However, these imported proto files will not be compiled in +// this project, since they have already been compiled in their own projects. + +apply plugin: 'java' +apply plugin: 'com.google.protobuf' + +repositories { + maven { url "https://plugins.gradle.org/m2/" } +} + +dependencies { + implementation 'com.google.protobuf:protobuf-java:3.0.0' + implementation project(':testProjectJavaLibrary') + + testImplementation 'junit:junit:4.12' +} + +protobuf.protoc { + artifact = 'com.google.protobuf:protoc:3.0.0' +} + +test.doLast { + // This project has compiled only one proto file, despite that it imports + // other proto files from dependencies. + def generatedFiles = project.fileTree(protobuf.generatedFilesBaseDir + "/main") + File onlyGeneratedFile = generatedFiles.singleFile + assert 'Dependent.java' == onlyGeneratedFile.name +} diff --git a/testProjectDependentApp/settings.gradle b/testProjectDependentApp/settings.gradle new file mode 100644 index 00000000..55032de8 --- /dev/null +++ b/testProjectDependentApp/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'testProjectDependentApp' diff --git a/testProjectDependentApp/src/main/proto/dependent.proto b/testProjectDependentApp/src/main/proto/dependent.proto new file mode 100644 index 00000000..f6c6317f --- /dev/null +++ b/testProjectDependentApp/src/main/proto/dependent.proto @@ -0,0 +1,14 @@ +syntax = "proto3"; + +package dependent; + +// From testProject/src/main/proto +import "ws/antonov/protobuf/test/test.proto"; + +// From protobuf-java artifact +import "google/protobuf/any.proto"; + +message WrapperMessage { + ws.antonov.protobuf.test.Item item = 1; + google.protobuf.Any any = 2; +} diff --git a/testProjectDependentApp/src/test/java/DependentTest.java b/testProjectDependentApp/src/test/java/DependentTest.java new file mode 100644 index 00000000..5b45aad0 --- /dev/null +++ b/testProjectDependentApp/src/test/java/DependentTest.java @@ -0,0 +1,19 @@ +import static org.junit.Assert.assertSame; + +import org.junit.Test; + +public class DependentTest { + + @Test public void testProtos() { + dependent.Dependent.WrapperMessage message = + dependent.Dependent.WrapperMessage.newBuilder() + .setItem(ws.antonov.protobuf.test.Test.Item.getDefaultInstance()) + .setAny(com.google.protobuf.Any.getDefaultInstance()) + .build(); + assertSame(ws.antonov.protobuf.test.Test.Item.getDefaultInstance(), + message.getItem()); + Dependent2.TestWrapperMessage testMessage = + Dependent2.TestWrapperMessage.newBuilder() + .setM(message).build(); + } +} diff --git a/testProjectDependentApp/src/test/proto/dependent2.proto b/testProjectDependentApp/src/test/proto/dependent2.proto new file mode 100644 index 00000000..4e19d4ba --- /dev/null +++ b/testProjectDependentApp/src/test/proto/dependent2.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +// From the 'main' sourceSet +import "dependent.proto"; + +message TestWrapperMessage { + dependent.WrapperMessage m = 1; +} \ No newline at end of file diff --git a/testProjectJavaLibrary/build.gradle b/testProjectJavaLibrary/build.gradle new file mode 100644 index 00000000..d3cc0005 --- /dev/null +++ b/testProjectJavaLibrary/build.gradle @@ -0,0 +1,5 @@ +// This build is not a complete project, but is used to generate a project. +// See: ProtobufPluginTestHelper.groovy +apply plugin: 'java-library' +apply plugin: 'idea' +apply from: 'build_base.gradle' diff --git a/testProjectJavaLibrary/settings.gradle b/testProjectJavaLibrary/settings.gradle new file mode 100644 index 00000000..cd92cb49 --- /dev/null +++ b/testProjectJavaLibrary/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'testProjectJavaLibrary' diff --git a/testProjectJavaLibrary/src/main/java/Foo.java b/testProjectJavaLibrary/src/main/java/Foo.java new file mode 100644 index 00000000..3a7e2235 --- /dev/null +++ b/testProjectJavaLibrary/src/main/java/Foo.java @@ -0,0 +1,30 @@ +import com.google.protobuf.MessageLite; + +import java.util.ArrayList; +import java.util.List; + +public class Foo { + public static List getDefaultInstances() { + ArrayList list = new ArrayList(); + // from src/main/proto/test.proto + list.add(ws.antonov.protobuf.test.Test.TestMessage.getDefaultInstance()); + list.add(ws.antonov.protobuf.test.Test.AnotherMessage.getDefaultInstance()); + list.add(ws.antonov.protobuf.test.Test.Item.getDefaultInstance()); + list.add(ws.antonov.protobuf.test.Test.DataMap.getDefaultInstance()); + // from src/main/proto/sample.proto (java_multiple_files == true, thus no outter class) + list.add(com.example.tutorial.Msg.getDefaultInstance()); + list.add(com.example.tutorial.SecondMsg.getDefaultInstance()); + // from lib/protos.tar.gz/stuff.proto + list.add(Stuff.Blah.getDefaultInstance()); + // from ext/more.proto + list.add(More.MoreMsg.getDefaultInstance()); + list.add(More.Foo.getDefaultInstance()); + // from ext/test1.proto + list.add(test1.Test1.Test1Msg.getDefaultInstance()); + // from ext/ext1/test1.proto + list.add(ext1.Ext1Test1.Ext1Test1Msg.getDefaultInstance()); + // from ext/test2.proto + list.add(test2.Test2.Test2Msg.getDefaultInstance()); + return list; + } +} diff --git a/testProjectJavaLibrary/src/test/java/FooTest.java b/testProjectJavaLibrary/src/test/java/FooTest.java new file mode 100644 index 00000000..ec322869 --- /dev/null +++ b/testProjectJavaLibrary/src/test/java/FooTest.java @@ -0,0 +1,25 @@ +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class FooTest { + @org.junit.Test + public void testMainProtos() { + assertEquals(12, Foo.getDefaultInstances().size()); + } + + @org.junit.Test + public void testTestProtos() { + // from src/test/proto/test.proto + Test.MsgTest.getDefaultInstance(); + // from lib/protos-test.tar.gz + test.Stuff.BlahTest.getDefaultInstance(); + } + + @org.junit.Test + public void testGrpc() { + // from src/grpc/proto/ + assertTrue(com.google.protobuf.GeneratedMessageV3.class.isAssignableFrom( + io.grpc.testing.integration.Messages.SimpleRequest.class)); + assertTrue(Object.class.isAssignableFrom(io.grpc.testing.integration.TestServiceGrpc.class)); + } +} From e282d08eb01c73919fc672db40dfa279e08099c8 Mon Sep 17 00:00:00 2001 From: Chengyuan Zhang Date: Thu, 12 Dec 2019 14:07:07 -0800 Subject: [PATCH 4/9] Add back pulling dependencies from compileClasspath for test source set. --- .../groovy/com/google/protobuf/gradle/ProtobufPlugin.groovy | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/groovy/com/google/protobuf/gradle/ProtobufPlugin.groovy b/src/main/groovy/com/google/protobuf/gradle/ProtobufPlugin.groovy index e7220cb7..c8478625 100644 --- a/src/main/groovy/com/google/protobuf/gradle/ProtobufPlugin.groovy +++ b/src/main/groovy/com/google/protobuf/gradle/ProtobufPlugin.groovy @@ -397,6 +397,12 @@ class ProtobufPlugin implements Plugin { inputFiles.from getSourceSets()['main'].proto inputFiles.from testedCompileClasspathConfiguration ?: project.configurations['compile'] } + } else { + // In Java projects, the compileClasspath of the 'test' sourceSet includes all the + // 'resources' of the output of 'main', in which the source protos are placed. This is + // nicer than the ad-hoc solution that Android has, because it works for any extended + // configuration, not just 'testCompile'. + inputFiles.from getSourceSets()[sourceSetOrVariantName].compileClasspath } isTest = Utils.isTest(sourceSetOrVariantName) } From 7f765950493072cf2714d0544b9ec69744951fb6 Mon Sep 17 00:00:00 2001 From: Chengyuan Zhang Date: Thu, 12 Dec 2019 16:25:11 -0800 Subject: [PATCH 5/9] Only create compileProto configuration for sources with compileClasspath, work around for Android. --- .../groovy/com/google/protobuf/gradle/ProtobufPlugin.groovy | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/groovy/com/google/protobuf/gradle/ProtobufPlugin.groovy b/src/main/groovy/com/google/protobuf/gradle/ProtobufPlugin.groovy index c8478625..19ba6a16 100644 --- a/src/main/groovy/com/google/protobuf/gradle/ProtobufPlugin.groovy +++ b/src/main/groovy/com/google/protobuf/gradle/ProtobufPlugin.groovy @@ -175,9 +175,12 @@ class ProtobufPlugin implements Plugin { // Create a 'compileProto' configuration as a bucket of dependencies that contains resources // attribute for compileClasspath dependencies. This works around 'java-library' plugin // not exposing resources to consumers for compilation. + // Some Android sourceSet does not have 'compileClasspath' configuration, not even + // 'compile' or 'implementation'. String compileProtoConfigName = Utils.getConfigName(sourceSetName, 'compileProto') String compileClasspathConfigName = Utils.getConfigName(sourceSetName, 'compileClasspath') - if (project.configurations.findByName(compileProtoConfigName) == null) { + if (project.configurations.findByName(compileClasspathConfigName) && + project.configurations.findByName(compileProtoConfigName) == null) { project.configurations.create(compileProtoConfigName) { visible = false transitive = true From c47df5ef8c12eb12ad92bd5586d9057e9c6aded7 Mon Sep 17 00:00:00 2001 From: Chengyuan Zhang Date: Fri, 13 Dec 2019 00:20:09 -0800 Subject: [PATCH 6/9] Add java-library into the options of pre-applied plugins. --- src/main/groovy/com/google/protobuf/gradle/ProtobufPlugin.groovy | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/groovy/com/google/protobuf/gradle/ProtobufPlugin.groovy b/src/main/groovy/com/google/protobuf/gradle/ProtobufPlugin.groovy index 19ba6a16..a13ae900 100644 --- a/src/main/groovy/com/google/protobuf/gradle/ProtobufPlugin.groovy +++ b/src/main/groovy/com/google/protobuf/gradle/ProtobufPlugin.groovy @@ -55,6 +55,7 @@ class ProtobufPlugin implements Plugin { // any one of these plugins should be sufficient to proceed with applying this plugin private static final List PREREQ_PLUGIN_OPTIONS = [ 'java', + 'java-library', 'com.android.application', 'com.android.feature', 'com.android.library', From 79279595ffe588a7f97773bd381caf892e03063e Mon Sep 17 00:00:00 2001 From: Chengyuan Zhang Date: Fri, 13 Dec 2019 09:54:37 -0800 Subject: [PATCH 7/9] Fix line length style. --- .../com/google/protobuf/gradle/ProtobufJavaPluginTest.groovy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/groovy/com/google/protobuf/gradle/ProtobufJavaPluginTest.groovy b/src/test/groovy/com/google/protobuf/gradle/ProtobufJavaPluginTest.groovy index fce515a7..bf7127b7 100644 --- a/src/test/groovy/com/google/protobuf/gradle/ProtobufJavaPluginTest.groovy +++ b/src/test/groovy/com/google/protobuf/gradle/ProtobufJavaPluginTest.groovy @@ -201,7 +201,7 @@ class ProtobufJavaPluginTest extends Specification { } @Unroll - void "testProjectJavaLibrary should be successfully executed (java-only project as a library) [gradle #gradleVersion]"() { + void "testProjectJavaLibrary should be successfully executed (java-only as a library) [gradle #gradleVersion]"() { given: "project from testProjectJavaLibrary" File projectDir = ProtobufPluginTestHelper.projectBuilder('testProjectJavaLibrary') .copyDirs('testProjectBase', 'testProjectJavaLibrary') From 09a6f9c71db3ce3b978ea315a0176032733aab4f Mon Sep 17 00:00:00 2001 From: Chengyuan Zhang Date: Mon, 16 Dec 2019 17:31:32 -0800 Subject: [PATCH 8/9] Renamed configuration to compileProtoPath. --- .../com/google/protobuf/gradle/ProtobufPlugin.groovy | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/groovy/com/google/protobuf/gradle/ProtobufPlugin.groovy b/src/main/groovy/com/google/protobuf/gradle/ProtobufPlugin.groovy index a13ae900..1705ca4b 100644 --- a/src/main/groovy/com/google/protobuf/gradle/ProtobufPlugin.groovy +++ b/src/main/groovy/com/google/protobuf/gradle/ProtobufPlugin.groovy @@ -173,12 +173,12 @@ class ProtobufPlugin implements Plugin { } } - // Create a 'compileProto' configuration as a bucket of dependencies that contains resources - // attribute for compileClasspath dependencies. This works around 'java-library' plugin - // not exposing resources to consumers for compilation. + // Create a 'compileProtoPath' configuration as a bucket of dependencies that contains + // resources attribute for compileClasspath dependencies. This works around 'java-library' + // plugin not exposing resources to consumers for compilation. // Some Android sourceSet does not have 'compileClasspath' configuration, not even // 'compile' or 'implementation'. - String compileProtoConfigName = Utils.getConfigName(sourceSetName, 'compileProto') + String compileProtoConfigName = Utils.getConfigName(sourceSetName, 'compileProtoPath') String compileClasspathConfigName = Utils.getConfigName(sourceSetName, 'compileClasspath') if (project.configurations.findByName(compileClasspathConfigName) && project.configurations.findByName(compileProtoConfigName) == null) { @@ -385,7 +385,7 @@ class ProtobufPlugin implements Plugin { description = "Extracts proto files from compile dependencies for includes" destDir = getExtractedIncludeProtosDir(sourceSetOrVariantName) as File inputFiles.from(compileClasspathConfiguration - ?: project.configurations[Utils.getConfigName(sourceSetOrVariantName, 'compileProto')]) + ?: project.configurations[Utils.getConfigName(sourceSetOrVariantName, 'compileProtoPath')]) // TL; DR: Make protos in 'test' sourceSet able to import protos from the 'main' // sourceSet. Sub-configurations, e.g., 'testCompile' that extends 'compile', don't From 016321166a4736e4f61c6f838ce9d1e538bf0f24 Mon Sep 17 00:00:00 2001 From: Chengyuan Zhang Date: Mon, 16 Dec 2019 18:07:13 -0800 Subject: [PATCH 9/9] Make the compileProtoPath configuration extend from compileOnly and implementation. --- .../protobuf/gradle/ProtobufPlugin.groovy | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/main/groovy/com/google/protobuf/gradle/ProtobufPlugin.groovy b/src/main/groovy/com/google/protobuf/gradle/ProtobufPlugin.groovy index 1705ca4b..c07b62bf 100644 --- a/src/main/groovy/com/google/protobuf/gradle/ProtobufPlugin.groovy +++ b/src/main/groovy/com/google/protobuf/gradle/ProtobufPlugin.groovy @@ -35,6 +35,7 @@ import org.gradle.api.GradleException import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.api.Task +import org.gradle.api.artifacts.Configuration import org.gradle.api.attributes.Attribute import org.gradle.api.attributes.LibraryElements import org.gradle.api.file.FileCollection @@ -173,19 +174,23 @@ class ProtobufPlugin implements Plugin { } } - // Create a 'compileProtoPath' configuration as a bucket of dependencies that contains - // resources attribute for compileClasspath dependencies. This works around 'java-library' + // Create a 'compileProtoPath' configuration that extends compilation configurations + // as a bucket of dependencies with resources attribute. This works around 'java-library' // plugin not exposing resources to consumers for compilation. - // Some Android sourceSet does not have 'compileClasspath' configuration, not even - // 'compile' or 'implementation'. + // Some Android sourceSets (more precisely, variants) do not have compilation configurations, + // they do not contain compilation dependencies, so they would not depend on any upstream + // proto files. String compileProtoConfigName = Utils.getConfigName(sourceSetName, 'compileProtoPath') - String compileClasspathConfigName = Utils.getConfigName(sourceSetName, 'compileClasspath') - if (project.configurations.findByName(compileClasspathConfigName) && + Configuration compileConfig = + project.configurations.findByName(Utils.getConfigName(sourceSetName, 'compileOnly')) + Configuration implementationConfig = + project.configurations.findByName(Utils.getConfigName(sourceSetName, 'implementation')) + if (compileConfig && implementationConfig && project.configurations.findByName(compileProtoConfigName) == null) { project.configurations.create(compileProtoConfigName) { visible = false transitive = true - extendsFrom = [project.configurations.findByName(compileClasspathConfigName)] + extendsFrom = [compileConfig, implementationConfig] canBeConsumed = false }.getAttributes().attribute( LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE,