Fix private visibility for aliased targets.
Also a drive-by improvement on some related error messages.
RELNOTES[INC]: Only targets with public visibility can be bound to something in //external: .
--
PiperOrigin-RevId: 141178039
MOS_MIGRATED_REVID=141178039
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java b/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java
index 1b45009..fad548a 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java
@@ -1649,13 +1649,12 @@
String msgReason = reason != null ? " (" + reason + ")" : "";
if (isWarning) {
return String.format(
- "%s'%s'%s is unexpected here%s; continuing anyway",
- msgPrefix, prerequisite.getLabel(), AliasProvider.printVisibilityChain(prerequisite),
+ "%s%s is unexpected here%s; continuing anyway",
+ msgPrefix, AliasProvider.printLabelWithAliasChain(prerequisite),
msgReason);
}
- return String.format(
- "%s'%s'%s is misplaced here%s", msgPrefix, prerequisite.getLabel(),
- AliasProvider.printVisibilityChain(prerequisite), msgReason);
+ return String.format("%s%s is misplaced here%s",
+ msgPrefix, AliasProvider.printLabelWithAliasChain(prerequisite), msgReason);
}
private void reportBadPrerequisite(Attribute attribute, String targetKind,
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java
index 508de47..ef82170 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java
@@ -195,29 +195,22 @@
private void validateDirectPrerequisiteVisibility(
RuleContext.Builder context, ConfiguredTarget prerequisite, String attrName) {
Rule rule = context.getRule();
- if (rule.getLabel().getPackageFragment().equals(Label.EXTERNAL_PACKAGE_NAME)) {
- // //external: labels are special. They have access to everything and visibility is checked
- // at the edge that points to the //external: label.
- return;
- }
Target prerequisiteTarget = prerequisite.getTarget();
- Label prerequisiteLabel = prerequisiteTarget.getLabel();
if (!context.getRule().getLabel().getPackageIdentifier().equals(
- prerequisite.getTarget().getLabel().getPackageIdentifier())
+ AliasProvider.getDependencyLabel(prerequisite).getPackageIdentifier())
&& !context.isVisible(prerequisite)) {
if (!context.getConfiguration().checkVisibility()) {
context.ruleWarning(String.format("Target '%s' violates visibility of target "
- + "'%s'. Continuing because --nocheck_visibility is active",
- rule.getLabel(), prerequisiteLabel));
+ + "%s. Continuing because --nocheck_visibility is active",
+ rule.getLabel(), AliasProvider.printLabelWithAliasChain(prerequisite)));
} else {
// Oddly enough, we use reportError rather than ruleError here.
context.reportError(rule.getLocation(),
- String.format("Target '%s' is not visible from target '%s'%s. Check "
+ String.format("Target %s is not visible from target '%s'. Check "
+ "the visibility declaration of the former target if you think "
+ "the dependency is legitimate",
- prerequisiteLabel,
- rule.getLabel(),
- AliasProvider.printVisibilityChain(prerequisite)));
+ AliasProvider.printLabelWithAliasChain(prerequisite),
+ rule.getLabel()));
}
}
@@ -230,9 +223,9 @@
+ rule.getRuleClass()
+ " rule "
+ rule.getLabel()
- + ": package group '"
- + prerequisiteLabel
- + "' is misplaced here "
+ + ": package group "
+ + AliasProvider.printLabelWithAliasChain(prerequisite)
+ + " is misplaced here "
+ "(they are only allowed in the visibility attribute)");
}
}
@@ -248,12 +241,11 @@
}
Target prerequisiteTarget = prerequisite.getTarget();
- Label prerequisiteLabel = prerequisiteTarget.getLabel();
String thisPackage = rule.getLabel().getPackageName();
if (isTestOnlyRule(prerequisiteTarget) && !isTestOnlyRule(rule)) {
- String message = "non-test target '" + rule.getLabel() + "' depends on testonly target '"
- + prerequisiteLabel + "'" + AliasProvider.printVisibilityChain(prerequisite)
+ String message = "non-test target '" + rule.getLabel() + "' depends on testonly target "
+ + AliasProvider.printLabelWithAliasChain(prerequisite)
+ " and doesn't have testonly attribute set";
if (thisPackage.startsWith("experimental/")) {
context.ruleWarning(message);
diff --git a/src/main/java/com/google/devtools/build/lib/rules/AliasProvider.java b/src/main/java/com/google/devtools/build/lib/rules/AliasProvider.java
index a6950b2..e3300cb 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/AliasProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/AliasProvider.java
@@ -68,12 +68,12 @@
return aliasChain;
}
- public static String printVisibilityChain(ConfiguredTarget target) {
+ public static String printLabelWithAliasChain(ConfiguredTarget target) {
AliasProvider aliasProvider = target.getProvider(AliasProvider.class);
- if (aliasProvider == null) {
- return "";
- }
+ String suffix = aliasProvider == null
+ ? ""
+ : " (aliased through '" + Joiner.on("' -> '").join(aliasProvider.getAliasChain()) + "')";
- return " (aliased through '" + Joiner.on("' -> '").join(aliasProvider.getAliasChain()) + "')";
+ return "'" + target.getLabel() + "'" + suffix;
}
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/repository/Bind.java b/src/main/java/com/google/devtools/build/lib/rules/repository/Bind.java
index 1b89ced..9f199a1 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/repository/Bind.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/repository/Bind.java
@@ -19,7 +19,11 @@
import com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode;
import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.analysis.TransitiveInfoProvider;
-import com.google.devtools.build.lib.packages.RuleClass.ConfiguredTargetFactory.RuleErrorException;
+import com.google.devtools.build.lib.analysis.VisibilityProvider;
+import com.google.devtools.build.lib.analysis.VisibilityProviderImpl;
+import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
+import com.google.devtools.build.lib.collect.nestedset.Order;
+import com.google.devtools.build.lib.packages.PackageSpecification;
import com.google.devtools.build.lib.rules.AliasConfiguredTarget;
import com.google.devtools.build.lib.rules.AliasProvider;
import com.google.devtools.build.lib.rules.RuleConfiguredTargetFactory;
@@ -43,6 +47,9 @@
ruleContext.getConfiguration(),
actual,
ImmutableMap.<Class<? extends TransitiveInfoProvider>, TransitiveInfoProvider>of(
- AliasProvider.class, AliasProvider.fromAliasRule(ruleContext.getLabel(), actual)));
+ AliasProvider.class, AliasProvider.fromAliasRule(ruleContext.getLabel(), actual),
+ VisibilityProvider.class, new VisibilityProviderImpl(
+ NestedSetBuilder.create(Order.STABLE_ORDER, PackageSpecification.everything()))));
+
}
}
diff --git a/src/test/java/com/google/devtools/build/lib/rules/AliasTest.java b/src/test/java/com/google/devtools/build/lib/rules/AliasTest.java
index 17d3ea1..4b456a3 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/AliasTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/AliasTest.java
@@ -79,7 +79,7 @@
reporter.removeHandler(failFastHandler);
getConfiguredTarget("//c:c");
assertContainsEvent(
- "Target '//a:a' is not visible from target '//c:c' (aliased through '//b:b')");
+ "Target '//a:a' (aliased through '//b:b') is not visible from target '//c:c'");
}
@Test
@@ -96,7 +96,18 @@
reporter.removeHandler(failFastHandler);
getConfiguredTarget("//d:d");
assertContainsEvent(
- "Target '//a:a' is not visible from target '//d:d' (aliased through '//c:c' -> '//b:b')");
+ "Target '//a:a' (aliased through '//c:c' -> '//b:b') is not visible from target '//d:d'");
+ }
+
+ @Test
+ public void testAliasWithPrivateVisibilityAccessibleFromSamePackage() throws Exception {
+ scratch.file("a/BUILD", "exports_files(['af'])");
+ scratch.file("b/BUILD",
+ "package(default_visibility=['//visibility:private'])",
+ "alias(name='al', actual='//a:af')",
+ "filegroup(name='ta', srcs=[':al'])");
+
+ getConfiguredTarget("//b:tf");
}
@Test
diff --git a/src/test/shell/bazel/external_skylark_load_test.sh b/src/test/shell/bazel/external_skylark_load_test.sh
index 49c603e..6c503f1 100755
--- a/src/test/shell/bazel/external_skylark_load_test.sh
+++ b/src/test/shell/bazel/external_skylark_load_test.sh
@@ -247,8 +247,8 @@
cat > BUILD <<EOF
load("//:rule.bzl", "test_rule")
-filegroup(name = "x1")
-filegroup(name = "x2")
+filegroup(name = "x1", visibility = ["//visibility:public"])
+filegroup(name = "x2", visibility = ["//visibility:public"])
test_rule(
name = "tr",
deps = ["//external:x1", "//external:x2"],
diff --git a/src/test/shell/bazel/local_repository_test.sh b/src/test/shell/bazel/local_repository_test.sh
index 4145267..851911c 100755
--- a/src/test/shell/bazel/local_repository_test.sh
+++ b/src/test/shell/bazel/local_repository_test.sh
@@ -842,7 +842,7 @@
bazel build @r//:public >& $TEST_log || fail "failed to build public target"
bazel build @r//:private >& $TEST_log && fail "could build private target"
- expect_log "Target '//:private' is not visible from target '@r//:private'"
+ expect_log "Target '//:private' is not visible from target '//external:private'"
}
function test_load_in_remote_repository() {