From 8df229f8dc8e4521882fbf69806ab91ba4d51d5e Mon Sep 17 00:00:00 2001 From: Clay Johnson Date: Thu, 28 Apr 2022 12:21:07 -0500 Subject: [PATCH] Ignore OS as an input to `GenerateProtoTask` This change will remove the OS from the input properties of the GenerateProtoTask when `protoc` or a plugin is defined as a resolvable artifact. The expectation is that same versions of `protoc` or plugins will produce same outputs regardless of the OS on which they are run. This is done by creating marking `alternativePaths` as Internal for backwards compatibility and creating two new properties: `releaseArtifacts` and `snapshotArtifacts`. `releaseArtifacts` will contain "$groupId:$artifact:$version" for each non-snapshot dependency, effectively ignoring OS for these dependencies. `snapshotArtifacts` will contain each snapshot artifact in a `FileCollection` since the snapshots cannot be matched solely by their maven coordinates. See #457. --- .../protobuf/gradle/GenerateProtoTask.groovy | 47 ++++++++++++++++++- .../protobuf/gradle/ToolsLocator.groovy | 1 + 2 files changed, 46 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..678e5cf1 100644 --- a/src/main/groovy/com/google/protobuf/gradle/GenerateProtoTask.groovy +++ b/src/main/groovy/com/google/protobuf/gradle/GenerateProtoTask.groovy @@ -330,12 +330,55 @@ 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) + @Internal + abstract MapProperty getLocatorToDependencyMapping() + + @Internal ConfigurableFileCollection getAlternativePaths() { return objectFactory.fileCollection().from(getLocatorToAlternativePathsMapping().get().values()) } + /** + * For each protoc and code gen plugin defined by an artifact specification, this list will contain a String with the + * group, artifact, and version, as long as the version is a stable release version. + * + * Giving this as an input to the task allows gradle to ignore the OS classifier and use cached outputs generated from + * different operating systems since the expectation is that different operating systems will produce the same + * generated code. + */ + @Input + Provider> getReleaseArtifacts() { + releaseDependenciesMapping.map { it.values().collect() } + } + + /** + * This file collection contains the file for each protoc and code gen plugin that is defined by an artifact + * specification that specifies a SNAPSHOT version. + * + * Since snapshots are expected to differ within the same version, this input allows Gradle to consider the file + * itself rather than the version number. + */ + @InputFiles + @PathSensitive(PathSensitivity.NONE) + FileCollection getSnapshotArtifacts() { + def snapshotArtifacts = locatorToAlternativePathsMapping.map { map -> + def releaseArtifactKeys = releaseDependenciesMapping.get().keySet() + map.findAll { entry -> + !releaseArtifactKeys.contains(entry.key) + }.values() + } + + objectFactory.fileCollection().from(snapshotArtifacts) + } + + @Internal + Provider> getReleaseDependenciesMapping() { + providerFactory.provider { + locatorToDependencyMapping.get() + .findAll { entry -> ! entry.value.endsWith ("-SNAPSHOT") } + } + } + @Internal("Input captured by getAlternativePaths()") abstract MapProperty getPluginsExecutableLocators() diff --git a/src/main/groovy/com/google/protobuf/gradle/ToolsLocator.groovy b/src/main/groovy/com/google/protobuf/gradle/ToolsLocator.groovy index 3b2e8b9f..d3113ed1 100644 --- a/src/main/groovy/com/google/protobuf/gradle/ToolsLocator.groovy +++ b/src/main/groovy/com/google/protobuf/gradle/ToolsLocator.groovy @@ -112,6 +112,7 @@ class ToolsLocator { for (GenerateProtoTask protoTask in protoTasks) { if (protoc.is(locator) || protoTask.hasPlugin(locator.name)) { protoTask.locatorToAlternativePathsMapping.put(locator.name, artifactFiles) + protoTask.locatorToDependencyMapping.put(locator.name, "$groupId:$artifact:$version".toString()) } } }