Skip to content

Commit

Permalink
[7.1.0] Implicit dependencies should be visible to rule/aspect defini…
Browse files Browse the repository at this point in the history
…tions in `.bzl` files in the same package (#21577)

Fixes: []
Commit
f4c9c88

PiperOrigin-RevId: 612579829
Change-Id: I429ca24931482cc94543692532ea4c08692020e3

---------

Co-authored-by: Googler <messa@google.com>
Co-authored-by: iancha1992 <heec@google.com>
  • Loading branch information
3 people authored Mar 5, 2024
1 parent bd4bddf commit 3c4bb77
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 49 deletions.
1 change: 1 addition & 0 deletions src/main/java/com/google/devtools/build/lib/analysis/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -657,6 +657,7 @@ java_library(
deps = [
":analysis_cluster",
":rule_error_consumer",
":visibility_provider",
"//src/main/java/com/google/devtools/build/lib/cmdline",
"//src/main/java/com/google/devtools/build/lib/packages",
"//src/main/java/com/google/devtools/build/lib/packages/semantics",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import com.google.devtools.build.lib.packages.FunctionSplitTransitionAllowlist;
import com.google.devtools.build.lib.packages.InputFile;
import com.google.devtools.build.lib.packages.NonconfigurableAttributeMapper;
import com.google.devtools.build.lib.packages.PackageSpecification.PackageGroupContents;
import com.google.devtools.build.lib.packages.RawAttributeMapper;
import com.google.devtools.build.lib.packages.Rule;
import com.google.devtools.build.lib.packages.RuleClass;
Expand Down Expand Up @@ -80,13 +81,6 @@ private void validateDirectPrerequisiteVisibility(

checkVisibilityAttributeContents(context, prerequisite, attribute, attrName, rule);

if (isSameLogicalPackage(
rule.getLabel().getPackageIdentifier(),
AliasProvider.getDependencyLabel(prerequisite.getConfiguredTarget())
.getPackageIdentifier())) {
return;
}

// We don't check the visibility of late-bound attributes, because it would break some
// features.
if (Attribute.isLateBound(attrName)) {
Expand Down Expand Up @@ -121,7 +115,7 @@ private void validateDirectPrerequisiteVisibility(
|| attribute.getName().equals(RuleClass.CONFIG_SETTING_DEPS_ATTRIBUTE)
|| !context.isStarlarkRuleOrAspect()) {
// Default check: The attribute must be visible from the target.
if (!context.isVisible(prerequisite.getConfiguredTarget())) {
if (!isVisible(rule.getLabel(), prerequisite)) {
handleVisibilityConflict(context, prerequisite, rule.getLabel());
}
} else {
Expand All @@ -142,15 +136,37 @@ private void validateDirectPrerequisiteVisibility(
// prerequisite is visible from the target so that adopting this new style of checking
// visibility is not a breaking change.
if (implicitDefinition != null
&& !RuleContext.isVisible(implicitDefinition, prerequisite.getConfiguredTarget())
&& !context.isVisible(prerequisite.getConfiguredTarget())) {
&& !isVisible(implicitDefinition, prerequisite)
&& !isVisible(rule.getLabel(), prerequisite)) {
// In the error message, always suggest making the prerequisite visible from the definition,
// not the target.
handleVisibilityConflict(context, prerequisite, implicitDefinition);
}
}
}

private boolean isVisible(Label target, ConfiguredTargetAndData prerequisite) {
if (isSameLogicalPackage(
target.getPackageIdentifier(),
AliasProvider.getDependencyLabel(prerequisite.getConfiguredTarget())
.getPackageIdentifier())) {
return true;
}
// Check visibility attribute
for (PackageGroupContents specification :
prerequisite
.getConfiguredTarget()
.getProvider(VisibilityProvider.class)
.getVisibility()
.toList()) {
if (specification.containsPackage(target.getPackageIdentifier())) {
return true;
}
}

return false;
}

private void checkVisibilityAttributeContents(
RuleContext.Builder context,
ConfiguredTargetAndData prerequisite,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1526,34 +1526,6 @@ public boolean isExecutedOnWindows() {
.hasConstraintValue(OS_TO_CONSTRAINTS.get(OS.WINDOWS));
}

/**
* Returns true if {@code label} is visible from {@code prerequisite}.
*
* <p>This only computes the logic as implemented by the visibility system. The final decision
* whether a dependency is allowed is made by {@link PrerequisiteValidator}.
*/
public static boolean isVisible(Label label, TransitiveInfoCollection prerequisite) {
// Check visibility attribute
for (PackageGroupContents specification :
prerequisite.getProvider(VisibilityProvider.class).getVisibility().toList()) {
if (specification.containsPackage(label.getPackageIdentifier())) {
return true;
}
}

return false;
}

/**
* Returns true if {@code rule} is visible from {@code prerequisite}.
*
* <p>This only computes the logic as implemented by the visibility system. The final decision
* whether a dependency is allowed is made by {@link PrerequisiteValidator}.
*/
public static boolean isVisible(Rule rule, TransitiveInfoCollection prerequisite) {
return isVisible(rule.getLabel(), prerequisite);
}

/**
* @return the set of features applicable for the current rule.
*/
Expand Down Expand Up @@ -1977,17 +1949,6 @@ public BuildConfigurationValue getConfiguration() {
return configuration;
}

/**
* @return true if {@code rule} is visible from {@code prerequisite}.
* <p>This only computes the logic as implemented by the visibility system. The final
* decision whether a dependency is allowed is made by {@link PrerequisiteValidator}, who is
* supposed to call this method to determine whether a dependency is allowed as per
* visibility rules.
*/
public boolean isVisible(TransitiveInfoCollection prerequisite) {
return RuleContext.isVisible(target.getAssociatedRule(), prerequisite);
}

@Nullable
Aspect getMainAspect() {
return Streams.findLast(aspects.stream()).orElse(null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,54 @@ public void testConfigSettingVisibilityAlwaysCheckedAtUse() throws Exception {
assertThat(hasErrors(getConfiguredTarget("//:my_target"))).isFalse();
}

@Test
public void testImplicitDependency_samePackageAsDefinition_visible() throws Exception {
scratch.file(
"aspect_def/BUILD",
"sh_binary(",
" name = 'aspect_tool',",
" srcs = ['a.sh'],",
" visibility = ['//visibility:private'])");
scratch.file(
"aspect_def/lib.bzl",
"def _impl_my_aspect(ctx, target):",
" return []",
"my_aspect = aspect(",
" _impl_my_aspect,",
" attrs = { '_aspect_tool': attr.label(default = '//aspect_def:aspect_tool') },",
")");
scratch.file(
"rule_def/BUILD",
"sh_binary(",
" name = 'rule_tool',",
" srcs = ['a.sh'],",
" visibility = ['//visibility:private'])");
scratch.file(
"rule_def/lib.bzl",
"load('//aspect_def:lib.bzl', 'my_aspect')",
"def _impl(ctx):",
" pass",
"my_rule = rule(",
" _impl,",
" attrs = {",
" 'dep': attr.label(aspects = [my_aspect]),",
" '_rule_tool': attr.label(default = '//rule_def:rule_tool'),",
" },",
")",
"simple_starlark_rule = rule(",
" _impl,",
")");
scratch.file(
"foo/BUILD",
"load('//rule_def:lib.bzl','my_rule', 'simple_starlark_rule')",
"simple_starlark_rule(name = 'simple_dep')",
"my_rule(name = 'my_target', dep = ':simple_dep')");

update("//foo:my_target");

assertThat(hasErrors(getConfiguredTarget("//foo:my_target"))).isFalse();
}

@Test
public void testAspectImplicitDependencyCheckedAtDefinition_visible() throws Exception {
scratch.file("inner_aspect/BUILD");
Expand Down

0 comments on commit 3c4bb77

Please sign in to comment.