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,