config_setting never declares licenses.
This overrides whatever config_setting(licenses = ...) or
package(licenses = ...) says.
This also provides the logic to opt any other rule out
of licenses.
This extends the work of https://github.com/bazelbuild/bazel/commit/fdb17eb11a9cef758544844add21decfd1d32b65.
PiperOrigin-RevId: 242883022
diff --git a/src/main/java/com/google/devtools/build/lib/packages/Rule.java b/src/main/java/com/google/devtools/build/lib/packages/Rule.java
index aeb5c33..bf3ceaf 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/Rule.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/Rule.java
@@ -666,7 +666,7 @@
if (isAttrDefined("licenses", BuildType.LICENSE)
&& isAttributeValueExplicitlySpecified("licenses")) {
return NonconfigurableAttributeMapper.of(this).get("licenses", BuildType.LICENSE);
- } else if (getRuleClassObject().ignorePackageLicenses()) {
+ } else if (getRuleClassObject().ignoreLicenses()) {
return License.NO_LICENSE;
} else {
return getPackage().getDefaultLicense();
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 4bdf988..4b3eb4f 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
@@ -661,7 +661,7 @@
private boolean hasAnalysisTestTransition = false;
private boolean hasFunctionTransitionWhitelist = false;
private boolean hasStarlarkRuleTransition = false;
- private boolean ignorePackageLicenses = false;
+ private boolean ignoreLicenses = false;
private ImplicitOutputsFunction implicitOutputsFunction = ImplicitOutputsFunction.NONE;
private TransitionFactory<Rule> transitionFactory;
private ConfiguredTargetFactory<?, ?, ?> configuredTargetFactory = null;
@@ -852,7 +852,7 @@
isAnalysisTest,
hasAnalysisTestTransition,
hasFunctionTransitionWhitelist,
- ignorePackageLicenses,
+ ignoreLicenses,
implicitOutputsFunction,
transitionFactory,
configuredTargetFactory,
@@ -1260,10 +1260,6 @@
return this;
}
- public boolean hasAnalysisTestTransition() {
- return this.hasAnalysisTestTransition;
- }
-
/**
* This rule class has the _whitelist_function_transition attribute. Intended only for Skylark
* rules.
@@ -1273,16 +1269,16 @@
return this;
}
- /** This rule class ignores package-level licenses. */
- public Builder setIgnorePackageLicenses() {
- this.ignorePackageLicenses = true;
+ /**
+ * This rule class never declares a license regardless of what the rule's or package's <code>
+ * licenses</code> attribute says.
+ */
+ // TODO(b/130286108): remove the licenses attribute completely from such rules.
+ public Builder setIgnoreLicenses() {
+ this.ignoreLicenses = true;
return this;
}
- public boolean ignorePackageLicenses() {
- return this.ignorePackageLicenses;
- }
-
public RuleClassType getType() {
return this.type;
}
@@ -1451,7 +1447,7 @@
private final boolean isAnalysisTest;
private final boolean hasAnalysisTestTransition;
private final boolean hasFunctionTransitionWhitelist;
- private final boolean ignorePackageLicenses;
+ private final boolean ignoreLicenses;
/**
* A (unordered) mapping from attribute names to small integers indexing into
@@ -1582,7 +1578,7 @@
boolean isAnalysisTest,
boolean hasAnalysisTestTransition,
boolean hasFunctionTransitionWhitelist,
- boolean ignorePackageLicenses,
+ boolean ignoreLicenses,
ImplicitOutputsFunction implicitOutputsFunction,
TransitionFactory<Rule> transitionFactory,
ConfiguredTargetFactory<?, ?, ?> configuredTargetFactory,
@@ -1632,7 +1628,7 @@
this.isAnalysisTest = isAnalysisTest;
this.hasAnalysisTestTransition = hasAnalysisTestTransition;
this.hasFunctionTransitionWhitelist = hasFunctionTransitionWhitelist;
- this.ignorePackageLicenses = ignorePackageLicenses;
+ this.ignoreLicenses = ignoreLicenses;
this.configurationFragmentPolicy = configurationFragmentPolicy;
this.supportsConstraintChecking = supportsConstraintChecking;
this.thirdPartyLicenseExistencePolicy = thirdPartyLicenseExistencePolicy;
@@ -1977,6 +1973,12 @@
}
Attribute attr = getAttribute(attrIndex);
+ if (attributeName.equals("licenses") && ignoreLicenses) {
+ setRuleAttributeValue(rule, eventHandler, attr, License.NO_LICENSE, /*explicit=*/ false);
+ definedAttrIndices.set(attrIndex);
+ continue;
+ }
+
// Convert the build-lang value to a native value, if necessary.
Object nativeAttributeValue;
if (attributeValues.valuesAreBuildLanguageTyped()) {
@@ -2041,7 +2043,9 @@
eventHandler);
}
- if (attr.hasComputedDefault()) {
+ if (attr.getName().equals("licenses") && ignoreLicenses) {
+ rule.setAttributeValue(attr, License.NO_LICENSE, /*explicit=*/ false);
+ } else if (attr.hasComputedDefault()) {
// Note that it is necessary to set all non-computed default values before calling
// Attribute#getDefaultValue for computed default attributes. Computed default attributes
// may have a condition predicate (i.e. the predicate returned by Attribute#getCondition)
@@ -2154,7 +2158,7 @@
*/
private static void checkThirdPartyRuleHasLicense(Rule rule,
Package.Builder pkgBuilder, EventHandler eventHandler) {
- if (rule.getRuleClassObject().ignorePackageLicenses()) {
+ if (rule.getRuleClassObject().ignoreLicenses()) {
// A package license is sufficient; ignore rules that don't include it.
return;
}
@@ -2516,9 +2520,14 @@
return hasFunctionTransitionWhitelist;
}
- /** Returns true if this rule class should ignore package-level licenses. */
- public boolean ignorePackageLicenses() {
- return ignorePackageLicenses;
+ /**
+ * If true, no rule of this class ever declares a license regardless of what the rule's or
+ * package's <code>licenses</code> attribute says.
+ *
+ * <p>This is useful for rule types that don't make sense for license checking.
+ */
+ public boolean ignoreLicenses() {
+ return ignoreLicenses;
}
public ImmutableSet<Label> getRequiredToolchains() {
diff --git a/src/main/java/com/google/devtools/build/lib/rules/config/ConfigRuleClasses.java b/src/main/java/com/google/devtools/build/lib/rules/config/ConfigRuleClasses.java
index eeaec37..2ce0e7b 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/config/ConfigRuleClasses.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/config/ConfigRuleClasses.java
@@ -139,7 +139,7 @@
@Override
public RuleClass build(RuleClass.Builder builder, RuleDefinitionEnvironment env) {
return builder
- .setIgnorePackageLicenses()
+ .setIgnoreLicenses()
.requiresConfigurationFragments(PlatformConfiguration.class)
.add(
attr(TOOLS_REPOSITORY_ATTRIBUTE, STRING)
diff --git a/src/test/java/com/google/devtools/build/lib/packages/RuleClassTest.java b/src/test/java/com/google/devtools/build/lib/packages/RuleClassTest.java
index 3db997a..0164f0c 100644
--- a/src/test/java/com/google/devtools/build/lib/packages/RuleClassTest.java
+++ b/src/test/java/com/google/devtools/build/lib/packages/RuleClassTest.java
@@ -898,7 +898,7 @@
isAnalysisTest,
/* hasAnalysisTestTransition=*/ false,
/* hasFunctionTransitionWhitelist=*/ false,
- /* ignorePackageLicenses=*/ false,
+ /* ignoreLicenses=*/ false,
implicitOutputsFunction,
transitionFactory,
configuredTargetFactory,
diff --git a/src/test/java/com/google/devtools/build/lib/rules/config/ConfigSettingTest.java b/src/test/java/com/google/devtools/build/lib/rules/config/ConfigSettingTest.java
index b7e3ddc..0e018c4 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/config/ConfigSettingTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/config/ConfigSettingTest.java
@@ -26,7 +26,9 @@
import com.google.devtools.build.lib.analysis.util.BuildViewTestCase;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.cmdline.RepositoryName;
+import com.google.devtools.build.lib.packages.BuildType;
import com.google.devtools.build.lib.packages.License.LicenseType;
+import com.google.devtools.build.lib.packages.RawAttributeMapper;
import com.google.devtools.build.lib.packages.Rule;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import com.google.devtools.build.lib.testutil.TestConstants;
@@ -1447,7 +1449,15 @@
}
private Set<LicenseType> getLicenses(String label) throws Exception {
- return getTarget(label).getLicense().getLicenseTypes();
+ Rule rule = (Rule) getTarget(label);
+ // There are two interfaces for retrieving a rule's license: from the Rule object and by
+ // directly reading the "licenses" attribute. For config_setting both of these should always
+ // be NONE. This method checks consistency between them.
+ Set<LicenseType> fromRule = rule.getLicense().getLicenseTypes();
+ Set<LicenseType> fromAttribute =
+ RawAttributeMapper.of(rule).get("licenses", BuildType.LICENSE).getLicenseTypes();
+ assertThat(fromRule).containsExactlyElementsIn(fromAttribute);
+ return fromRule;
}
/** Tests that default license behavior is unaffected. */
@@ -1496,7 +1506,7 @@
assertThat(getLicenses("//test:match")).containsExactly(LicenseType.NONE);
}
- /** Tests that rule-specific licenses are still used by config_setting. */
+ /** Tests that rule-specific licenses are ignored by config_setting. */
@Test
public void ruleLicensesUsed() throws Exception {
scratch.file(
@@ -1509,6 +1519,6 @@
" })");
useConfiguration("--copt", "-Dfoo");
- assertThat(getLicenses("//test:match")).containsExactly(LicenseType.RESTRICTED);
+ assertThat(getLicenses("//test:match")).containsExactly(LicenseType.NONE);
}
}