From a74e97d83de9320426f9e2c3ace853c0ac1d23c7 Mon Sep 17 00:00:00 2001 From: rougsig Date: Sun, 17 Jul 2022 23:25:57 +0300 Subject: [PATCH 1/2] Remove generate proto task link to compile on Now: Java/kotlin: compile task implicit depends on generate proto task via source sets Android: compile tasks depends on generate proto task via registerJavaGeneratingTask --- .../protobuf/gradle/GenerateProtoTask.groovy | 27 +--------- .../protobuf/gradle/ProtobufPlugin.groovy | 52 +++---------------- .../com/google/protobuf/gradle/Utils.groovy | 22 ++++++++ 3 files changed, 30 insertions(+), 71 deletions(-) diff --git a/src/main/groovy/com/google/protobuf/gradle/GenerateProtoTask.groovy b/src/main/groovy/com/google/protobuf/gradle/GenerateProtoTask.groovy index 04f9c495..433a67ac 100644 --- a/src/main/groovy/com/google/protobuf/gradle/GenerateProtoTask.groovy +++ b/src/main/groovy/com/google/protobuf/gradle/GenerateProtoTask.groovy @@ -34,7 +34,6 @@ import static java.nio.charset.StandardCharsets.US_ASCII import com.google.common.base.Preconditions import com.google.common.collect.ImmutableList import groovy.transform.CompileStatic -import groovy.transform.PackageScope import groovy.transform.TypeChecked import groovy.transform.TypeCheckingMode import org.gradle.api.Action @@ -45,7 +44,6 @@ import org.gradle.api.NamedDomainObjectContainer import org.gradle.api.file.ConfigurableFileCollection import org.gradle.api.file.FileCollection import org.gradle.api.file.ProjectLayout -import org.gradle.api.file.SourceDirectorySet import org.gradle.api.internal.file.FileResolver import org.gradle.api.logging.LogLevel import org.gradle.api.model.ObjectFactory @@ -60,13 +58,13 @@ import org.gradle.api.tasks.InputFiles import org.gradle.api.tasks.Internal import org.gradle.api.tasks.Nested import org.gradle.api.tasks.Optional -import org.gradle.api.tasks.OutputDirectory import org.gradle.api.tasks.OutputFile import org.gradle.api.tasks.PathSensitive import org.gradle.api.tasks.PathSensitivity import org.gradle.api.tasks.SkipWhenEmpty import org.gradle.api.tasks.SourceSet import org.gradle.api.tasks.TaskAction +import org.gradle.api.tasks.OutputDirectories import javax.annotation.Nullable import javax.inject.Inject @@ -258,11 +256,6 @@ public abstract class GenerateProtoTask extends DefaultTask { this.outputBaseDir = outputBaseDir } - @OutputDirectory - String getOutputBaseDir() { - return outputBaseDir.get() - } - void setSourceSet(SourceSet sourceSet) { checkInitializing() Preconditions.checkState(!isAndroidProject.get(), @@ -593,23 +586,7 @@ public abstract class GenerateProtoTask extends DefaultTask { return "${outputBaseDir.get()}/${plugin.outputSubDir}" } - /** - * Returns a {@code SourceDirectorySet} representing the generated source - * directories. - */ - @Internal - SourceDirectorySet getOutputSourceDirectorySet() { - String srcSetName = "generate-proto-" + name - SourceDirectorySet srcSet - srcSet = objectFactory.sourceDirectorySet(srcSetName, srcSetName) - srcSet.srcDirs providerFactory.provider { - getOutputSourceDirectories() - } - return srcSet - } - - @Internal - @PackageScope + @OutputDirectories Collection getOutputSourceDirectories() { Collection srcDirs = [] builtins.each { builtin -> diff --git a/src/main/groovy/com/google/protobuf/gradle/ProtobufPlugin.groovy b/src/main/groovy/com/google/protobuf/gradle/ProtobufPlugin.groovy index 45cf9ca8..b3f3dae5 100644 --- a/src/main/groovy/com/google/protobuf/gradle/ProtobufPlugin.groovy +++ b/src/main/groovy/com/google/protobuf/gradle/ProtobufPlugin.groovy @@ -66,11 +66,6 @@ class ProtobufPlugin implements Plugin { 'android-library', ] - private static final List SUPPORTED_LANGUAGES = [ - 'java', - 'kotlin', - ] - private final FileResolver fileResolver private Project project private ProtobufExtension protobufExtension @@ -122,11 +117,6 @@ class ProtobufPlugin implements Plugin { } } - private static void linkGenerateProtoTasksToTask(Task task, GenerateProtoTask genProtoTask) { - task.dependsOn(genProtoTask) - task.source genProtoTask.getOutputSourceDirectorySet().include("**/*.java", "**/*.kt") - } - private void doApply() { boolean isAndroid = Utils.isAndroidProject(project) // Java projects will extract included protos from a 'compileProtoPath' @@ -249,7 +239,8 @@ class ProtobufPlugin implements Plugin { * Creates Protobuf tasks for a sourceSet in a Java project. */ private void addTasksForSourceSet(final SourceSet sourceSet) { - Task generateProtoTask = addGenerateProtoTask(sourceSet.name, [sourceSet]) + GenerateProtoTask generateProtoTask = addGenerateProtoTask(sourceSet.name, [sourceSet]) + sourceSet.java.srcDirs(generateProtoTask) generateProtoTask.sourceSet = sourceSet generateProtoTask.doneInitializing() generateProtoTask.builtins { @@ -267,10 +258,6 @@ class ProtobufPlugin implements Plugin { include '**/*.proto' } processResourcesTask.dependsOn(extractTask) - - SUPPORTED_LANGUAGES.each { String lang -> - linkGenerateProtoTasksToTaskName(sourceSet.getCompileTaskName(lang), generateProtoTask) - } } /** @@ -278,7 +265,7 @@ class ProtobufPlugin implements Plugin { */ private void addTasksForVariant(final Object variant, boolean isTestVariant, Collection postConfigure) { // GenerateProto task, one per variant (compilation unit). - Task generateProtoTask = addGenerateProtoTask(variant.name, variant.sourceSets) + GenerateProtoTask generateProtoTask = addGenerateProtoTask(variant.name, variant.sourceSets) generateProtoTask.setVariant(variant, isTestVariant) generateProtoTask.flavors = ImmutableList.copyOf(variant.productFlavors.collect { it.name } ) if (variant.hasProperty('buildType')) { @@ -320,21 +307,9 @@ class ProtobufPlugin implements Plugin { setupExtractProtosTask(generateProtoTask, it.name) } } - if (isTestVariant) { - // unit test variants do not implement registerJavaGeneratingTask - Task javaCompileTask = variant.javaCompileProvider.get() - if (javaCompileTask != null) { - linkGenerateProtoTasksToTask(javaCompileTask, generateProtoTask) - } - } else { - postConfigure.add { - // This cannot be called once task execution has started. - variant.registerJavaGeneratingTask(generateProtoTask, generateProtoTask.getOutputSourceDirectories()) - } - } postConfigure.add { - linkGenerateProtoTasksToTaskName( - Utils.getKotlinAndroidCompileTaskName(project, variant.name), generateProtoTask) + // This cannot be called once task execution has started. + variant.registerJavaGeneratingTask(generateProtoTask, generateProtoTask.getOutputSourceDirectories()) } } @@ -348,7 +323,7 @@ class ProtobufPlugin implements Plugin { * compiled. For Java it's the sourceSet that sourceSetOrVariantName stands * for; for Android it's the collection of sourceSets that the variant includes. */ - private Task addGenerateProtoTask(String sourceSetOrVariantName, Collection sourceSets) { + private GenerateProtoTask addGenerateProtoTask(String sourceSetOrVariantName, Collection sourceSets) { String generateProtoTaskName = 'generate' + Utils.getSourceSetSubstringForTaskNames(sourceSetOrVariantName) + 'Proto' Provider outDir = project.providers.provider { @@ -452,21 +427,6 @@ class ProtobufPlugin implements Plugin { generateTask.addIncludeDir(project.files(extractTask.destDir)) } - private void linkGenerateProtoTasksToTaskName(String compileTaskName, GenerateProtoTask genProtoTask) { - Task compileTask = project.tasks.findByName(compileTaskName) - if (compileTask != null) { - linkGenerateProtoTasksToTask(compileTask, genProtoTask) - } else { - // It is possible for a compile task to not exist yet. For example, if someone applied - // the proto plugin and then later applies the kotlin plugin. - project.tasks.configureEach { Task task -> - if (task.name == compileTaskName) { - linkGenerateProtoTasksToTask(task, genProtoTask) - } - } - } - } - private String getExtractedIncludeProtosDir(String sourceSetName) { return "${project.buildDir}/extracted-include-protos/${sourceSetName}" } diff --git a/src/main/groovy/com/google/protobuf/gradle/Utils.groovy b/src/main/groovy/com/google/protobuf/gradle/Utils.groovy index 2c6e1a3f..6d028cd8 100644 --- a/src/main/groovy/com/google/protobuf/gradle/Utils.groovy +++ b/src/main/groovy/com/google/protobuf/gradle/Utils.groovy @@ -147,6 +147,28 @@ class Utils { } } + /** + * For each variant, agp creates a unique source set. + * The variant does not have a property to get a unique source set. + * For that reason, map the variant name to the source set name to find a unique source set. + * + * Patterns (variant -> sourceSet): + * -> + * UnitTest -> test + * AndroidTest -> androidTest + * + * @param variantName + * @return + */ + public static String variantNameToSourceSetName(final String variantName) { + if (variantName.endsWith("UnitTest")) { + return "test${variantName.replace("UnitTest", "").capitalize()}" + } else if (variantName.endsWith("AndroidTest")) { + return "androidTest${variantName.replace("AndroidTest", "").capitalize()}" + } + return variantName + } + private static Matcher parseVersionString(String version) { Matcher matcher = version =~ "(\\d*)\\.(\\d*).*" if (!matcher || !matcher.matches()) { From e24e2f277b8cb25bff5014b2922145ebc32aa9c2 Mon Sep 17 00:00:00 2001 From: rougsig Date: Mon, 18 Jul 2022 00:43:21 +0300 Subject: [PATCH 2/2] Add kotlin compile depends on generate proto task --- .../protobuf/gradle/ProtobufPlugin.groovy | 44 +++++++++---------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/src/main/groovy/com/google/protobuf/gradle/ProtobufPlugin.groovy b/src/main/groovy/com/google/protobuf/gradle/ProtobufPlugin.groovy index b3f3dae5..856ad03b 100644 --- a/src/main/groovy/com/google/protobuf/gradle/ProtobufPlugin.groovy +++ b/src/main/groovy/com/google/protobuf/gradle/ProtobufPlugin.groovy @@ -308,8 +308,15 @@ class ProtobufPlugin implements Plugin { } } postConfigure.add { - // This cannot be called once task execution has started. + // This cannot be called once task execution has start variant.registerJavaGeneratingTask(generateProtoTask, generateProtoTask.getOutputSourceDirectories()) + + // registerJavaGeneratingTask do nothing with kotlin tasks. It's works only with java. + Task kotlinCompileTask = project.tasks.findByName("compile${variant.name.capitalize()}Kotlin") + if (kotlinCompileTask != null) { + kotlinCompileTask.dependsOn(generateProtoTask) + kotlinCompileTask.source(generateProtoTask.getOutputSourceDirectories()) + } } } @@ -442,28 +449,21 @@ class ProtobufPlugin implements Plugin { // The generated javalite sources have lint issues. This is fixed upstream but // there is still no release with the fix yet. // https://github.com/google/protobuf/pull/2823 - if (isAndroid) { - // variant.registerJavaGeneratingTask called earlier already registers the generated - // sources for normal variants, but unit test variants work differently and do not - // use registerJavaGeneratingTask. Let's call addJavaSourceFoldersToModel for all tasks - // to ensure all variants (including unit test variants) have sources registered. - project.tasks.withType(GenerateProtoTask).each { GenerateProtoTask generateProtoTask -> - generateProtoTask.variant.addJavaSourceFoldersToModel(generateProtoTask.getOutputSourceDirectories()) - } - // TODO(zpencer): add gen sources from cross project GenerateProtoTasks - // This is an uncommon project set up but it is possible. - // We must avoid using private android APIs to find subprojects that the variant depends - // on, such as by walking through - // variant.variantData.variantDependency.compileConfiguration.allDependencies - // Gradle.getTaskGraph().getDependencies() should allow us to walk the task graph, - // but unfortunately that API is @Incubating. We can revisit it when it becomes stable. - // https://docs.gradle.org/4.8/javadoc/org/gradle/api/execution/ - // TaskExecutionGraph.html#getDependencies-org.gradle.api.Task- - - // TODO(zpencer): find a way to make android studio aware of the .proto files - // Simply adding the .proto dirs via addJavaSourceFoldersToModel does not seem to work. - } else { + // TODO(zpencer): add gen sources from cross project GenerateProtoTasks + // This is an uncommon project set up but it is possible. + // We must avoid using private android APIs to find subprojects that the variant depends + // on, such as by walking through + // variant.variantData.variantDependency.compileConfiguration.allDependencies + // Gradle.getTaskGraph().getDependencies() should allow us to walk the task graph, + // but unfortunately that API is @Incubating. We can revisit it when it becomes stable. + // https://docs.gradle.org/4.8/javadoc/org/gradle/api/execution/ + // TaskExecutionGraph.html#getDependencies-org.gradle.api.Task- + + // TODO(zpencer): find a way to make android studio aware of the .proto files + // Simply adding the .proto dirs via addJavaSourceFoldersToModel does not seem to work. + + if (!isAndroid) { // Make the proto source dirs known to IDEs project.sourceSets.each { sourceSet -> SourceDirectorySet protoSrcDirSet = sourceSet.proto