Add enforcement to android_binary to require *.pgcfg extension for ProGuard configuration files, guarded by option "--enforce_proguard_file_extension". RELNOTES: None PiperOrigin-RevId: 248000326
diff --git a/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java b/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java index 97fffd3..b476a58 100644 --- a/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java +++ b/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java
@@ -134,6 +134,7 @@ Functions.<Set<String>>constant(ImmutableSet.<String>of()); public static final PathFragment THIRD_PARTY_PREFIX = PathFragment.create("third_party"); + public static final PathFragment EXPERIMENTAL_PREFIX = PathFragment.create("experimental"); public static final String EXEC_COMPATIBLE_WITH_ATTR = "exec_compatible_with"; /**
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinary.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinary.java index 4163b1b..d3b5ba0 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinary.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinary.java
@@ -59,6 +59,7 @@ import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable; import com.google.devtools.build.lib.packages.BuildType; +import com.google.devtools.build.lib.packages.RuleClass; import com.google.devtools.build.lib.packages.RuleErrorConsumer; import com.google.devtools.build.lib.packages.TriState; import com.google.devtools.build.lib.rules.android.AndroidBinaryMobileInstall.MobileInstallResourceApks; @@ -155,6 +156,34 @@ ruleContext.throwWithAttributeError( "multidex", "Support for Java 8 libraries on legacy devices requires multidex"); } + + if (ruleContext.getFragment(JavaConfiguration.class).enforceProguardFileExtension() + && ruleContext.attributes().has(ProguardHelper.PROGUARD_SPECS)) { + List<PathFragment> pathsWithUnexpectedExtension = + ruleContext + .getPrerequisiteArtifacts(ProguardHelper.PROGUARD_SPECS, Mode.TARGET) + .list() + .stream() + .filter(Artifact::isSourceArtifact) + .map(Artifact::getRootRelativePath) + .filter( + // This checks the filename directly instead of using FileType because we want to + // exclude third_party/, but FileType is generally only given the basename. + // + // See e.g. RuleContext#validateDirectPrerequisiteType and + // PrerequisiteArtifacts#filter. + path -> + !path.getFileExtension().equals("pgcfg") + && !path.startsWith(RuleClass.THIRD_PARTY_PREFIX) + && !path.startsWith(RuleClass.EXPERIMENTAL_PREFIX)) + .collect(toImmutableList()); + if (!pathsWithUnexpectedExtension.isEmpty()) { + ruleContext.throwWithAttributeError( + ProguardHelper.PROGUARD_SPECS, + "Proguard spec files must use the .pgcfg extension. These files do not end in .pgcfg: " + + pathsWithUnexpectedExtension); + } + } } private static RuleConfiguredTargetBuilder init(
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaConfiguration.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaConfiguration.java index 0d8f49f..6fac9a7 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaConfiguration.java +++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaConfiguration.java
@@ -168,6 +168,7 @@ private final ImmutableList<Label> translationTargets; private final JavaOptimizationMode javaOptimizationMode; private final ImmutableMap<String, Optional<Label>> bytecodeOptimizers; + private final boolean enforceProguardFileExtension; private final Label toolchainLabel; private final Label runtimeLabel; private final boolean explicitJavaTestDeps; @@ -199,6 +200,7 @@ this.fixDepsTool = javaOptions.fixDepsTool; this.proguardBinary = javaOptions.proguard; this.extraProguardSpecs = ImmutableList.copyOf(javaOptions.extraProguardSpecs); + this.enforceProguardFileExtension = javaOptions.enforceProguardFileExtension; this.bundleTranslations = javaOptions.bundleTranslations; this.toolchainLabel = javaOptions.javaToolchain; this.runtimeLabel = javaOptions.javaBase; @@ -369,6 +371,11 @@ return extraProguardSpecs; } + /** Returns whether ProGuard configuration files are required to use a *.pgcfg extension. */ + public boolean enforceProguardFileExtension() { + return enforceProguardFileExtension; + } + /** Returns the raw translation targets. */ public ImmutableList<Label> getTranslationTargets() { return translationTargets;
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaOptions.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaOptions.java index ebd0156..998e954 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaOptions.java +++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaOptions.java
@@ -419,6 +419,16 @@ public Map<String, Label> bytecodeOptimizers; @Option( + name = "enforce_proguard_file_extension", + defaultValue = "false", + documentationCategory = OptionDocumentationCategory.UNDOCUMENTED, + effectTags = {OptionEffectTag.EAGERNESS_TO_EXIT}, + help = + "If enabled, requires that ProGuard configuration files outside of third_party/ use the" + + " *.pgcfg file extension.") + public boolean enforceProguardFileExtension; + + @Option( name = "translations", defaultValue = "auto", documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,