Don't crash when Starlark rules declare attributes named "licenses".
The specific use case that triggers this is writing a rule with
a non-LICENSE-typed attribute named "licenses", then creating
a BUILD instance that doesn't explicitly set its value. See the test
for an example.
Fixes #7194. Also fixes https://github.com/bazelbuild/bazel/issues/6420#issuecomment-450668017,
which blocks the --incompatible_no_attr_license migration.
RELNOTES: Starlark rules can safely declare attributes named "licenses"
PiperOrigin-RevId: 235919628
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 a71cdaa..fcf4ad5 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
@@ -2230,7 +2230,9 @@
*/
private static Object getAttributeNoncomputedDefaultValue(Attribute attr,
Package.Builder pkgBuilder) {
- if (attr.getName().equals("licenses")) {
+ // Starlark rules may define their own "licenses" attributes with different types -
+ // we shouldn't trigger the special "licenses" on those cases.
+ if (attr.getName().equals("licenses") && attr.getType() == BuildType.LICENSE) {
return pkgBuilder.getDefaultLicense();
}
if (attr.getName().equals("distribs")) {
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/LicensingTests.java b/src/test/java/com/google/devtools/build/lib/analysis/LicensingTests.java
index b70021a..6447099 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/LicensingTests.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/LicensingTests.java
@@ -32,7 +32,10 @@
import com.google.devtools.build.lib.packages.License;
import com.google.devtools.build.lib.packages.License.DistributionType;
import com.google.devtools.build.lib.packages.License.LicenseParsingException;
+import com.google.devtools.build.lib.packages.RawAttributeMapper;
+import com.google.devtools.build.lib.packages.Rule;
import com.google.devtools.build.lib.packages.util.MockCcSupport;
+import com.google.devtools.build.lib.syntax.Type;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.HashMap;
@@ -683,6 +686,28 @@
.testEquals();
}
+ /** Regression fix for https://github.com/bazelbuild/bazel/issues/7194. */
+ @Test
+ public void testStarlarkLicensesAttributeCanUseUseCustomDefault() throws Exception {
+ scratch.file(
+ "foo/rules.bzl",
+ "def _myrule_impl(ctx):",
+ " return []",
+ "",
+ "myrule = rule(",
+ " implementation = _myrule_impl,",
+ " attrs = {",
+ " 'licenses': attr.string(default = 'custom_licenses_default'),",
+ " }",
+ ")");
+
+ scratch.file("foo/BUILD", "load('//foo:rules.bzl', 'myrule')", "myrule(name = 'hi')");
+
+ assertThat(RawAttributeMapper.of((Rule) getTarget("//foo:hi")).get("licenses", Type.STRING))
+ .isEqualTo("custom_licenses_default");
+ assertNoEvents();
+ }
+
/**
* Gets the licenses of all targets that are in the transitive closure of a
* target. The result includes this target itself.