From aa107a8e22031d63d4cd26ae2a081d4c54a83b11 Mon Sep 17 00:00:00 2001 From: Clay Johnson Date: Wed, 27 Apr 2022 13:33:43 -0500 Subject: [PATCH] Improve caching of `proto` in `GenerateProtoTask` This change will remove the OS from the input properties of the `GenerateProtoTask`. The expectation is that same versions of `protoc` will produce same outputs regardless of the OS on which it was run. If a protoc `artifact` is defined with GAV parameters, the classifier and extension will not be considered part of the input. An exception is made for snapshots, which will always be considered uncacheable and be re-run. If a protoc `path` is defined, then the path will be exposed as a File Provider with absolute path normalization since there is no good way to tell the version of `protoc` without running `protoc --version`. See #457. --- .../protobuf/gradle/GenerateProtoTask.groovy | 36 +++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/src/main/groovy/com/google/protobuf/gradle/GenerateProtoTask.groovy b/src/main/groovy/com/google/protobuf/gradle/GenerateProtoTask.groovy index b51e6d6f..e0dee341 100644 --- a/src/main/groovy/com/google/protobuf/gradle/GenerateProtoTask.groovy +++ b/src/main/groovy/com/google/protobuf/gradle/GenerateProtoTask.groovy @@ -29,6 +29,8 @@ */ package com.google.protobuf.gradle +import org.gradle.api.tasks.InputFile + import static java.nio.charset.StandardCharsets.US_ASCII import com.google.common.base.Preconditions @@ -330,8 +332,38 @@ public abstract class GenerateProtoTask extends DefaultTask { @Internal("Input captured by getAlternativePaths(), this is used to query alternative path by locator name.") abstract MapProperty getLocatorToAlternativePathsMapping() - @InputFiles - @PathSensitive(PathSensitivity.NONE) + @Input + @Optional + Provider getProtocArtifact() { + // Ideally, this value could be mapped from the protocLocator property, but Provider#map cannot return null in + // Gradle < 6.2. See https://github.com/gradle/gradle/issues/11979 + return providerFactory.provider { + def protocArtifact = protocLocator.get().artifact + if (protocArtifact) { + def (groupId, artifact, version) = ToolsLocator.artifactParts(protocArtifact) + outputs.doNotCacheIf("protoc is a SNAPSHOT version", { + version.endsWith("-SNAPSHOT") + }) + "$groupId:$artifact:$version".toString() + } else { + null + } + } + } + + @InputFile + @PathSensitive(PathSensitivity.ABSOLUTE) + @Optional + Provider getProtocPath() { + // Ideally, this value could be mapped from the protocLocator property, but Provider#map cannot return null in + // Gradle < 6.2. See https://github.com/gradle/gradle/issues/11979 + return providerFactory.provider { + def path = getProtocLocator().get().path + path ? new File(path) : null + } + } + + @Internal ConfigurableFileCollection getAlternativePaths() { return objectFactory.fileCollection().from(getLocatorToAlternativePathsMapping().get().values()) }