Extend cquery's deps function to traverse aspects.
RELNOTES: None.
PiperOrigin-RevId: 314773050
diff --git a/src/main/java/com/google/devtools/build/lib/query2/PostAnalysisQueryEnvironment.java b/src/main/java/com/google/devtools/build/lib/query2/PostAnalysisQueryEnvironment.java
index 1a3749e..f2fd28f 100644
--- a/src/main/java/com/google/devtools/build/lib/query2/PostAnalysisQueryEnvironment.java
+++ b/src/main/java/com/google/devtools/build/lib/query2/PostAnalysisQueryEnvironment.java
@@ -391,7 +391,8 @@
.setConfiguration(getConfiguration(dependency))
.build());
values.add(new ClassifiedDependency<>(dependency, implicit));
- } else if (key.functionName().equals(SkyFunctions.TOOLCHAIN_RESOLUTION)) {
+ } else if (key.functionName().equals(SkyFunctions.TOOLCHAIN_RESOLUTION)
+ || key.functionName().equals(SkyFunctions.ASPECT)) {
// Also fetch these dependencies.
values.addAll(targetifyValues(null, graph.getDirectDeps(key)));
}
diff --git a/src/test/java/com/google/devtools/build/lib/query2/testutil/AbstractQueryTest.java b/src/test/java/com/google/devtools/build/lib/query2/testutil/AbstractQueryTest.java
index 6cb55f1..0463edf 100644
--- a/src/test/java/com/google/devtools/build/lib/query2/testutil/AbstractQueryTest.java
+++ b/src/test/java/com/google/devtools/build/lib/query2/testutil/AbstractQueryTest.java
@@ -124,6 +124,20 @@
helper.overwriteFile(pathName, lines);
}
+ protected final void overwriteFile(String pathName, ImmutableList<String> lines)
+ throws IOException {
+ helper.overwriteFile(pathName, lines.toArray(new String[lines.size()]));
+ }
+
+ protected final void appendToWorkspace(String... lines) throws IOException {
+ overwriteFile(
+ "WORKSPACE",
+ new ImmutableList.Builder<String>()
+ .addAll(analysisMock.getWorkspaceContents(mockToolsConfig))
+ .add(lines)
+ .build());
+ }
+
protected void assertContainsEvent(String expectedMessage) {
helper.assertContainsEvent(expectedMessage);
}
@@ -576,6 +590,122 @@
.containsNoneOf("//deps:BUILD", "//deps:build_def", "//deps:skylark.bzl", "//s:BUILD");
}
+ protected void writeAspectDefinition(String aspectAttrs) throws Exception {
+ writeFile(
+ "test/aspect.bzl",
+ "def _aspect_impl(target, ctx):",
+ " return struct()",
+ "def _rule_impl(ctx):",
+ " return struct()",
+ "",
+ "MyAspect = aspect(",
+ " implementation=_aspect_impl,",
+ " attr_aspects=['deps'],",
+ " attrs = ",
+ aspectAttrs,
+ ")",
+ "aspect_rule = rule(",
+ " implementation=_rule_impl,",
+ " attrs = { 'attr' : ",
+ " attr.label_list(mandatory=True, allow_files=True, aspects = [MyAspect]),",
+ " 'param' : attr.string(),",
+ " },",
+ ")",
+ "plain_rule = rule(",
+ " implementation=_rule_impl,",
+ " attrs = { 'attr' : ",
+ " attr.label_list(mandatory=False, allow_files=True) ",
+ " },",
+ ")");
+ writeFile(
+ "prod/BUILD",
+ "load('//test:aspect.bzl', 'plain_rule')",
+ "plain_rule(",
+ " name = 'zzz'",
+ ")");
+ }
+
+ @Test
+ public void testAspectOnRuleWithoutDeclaredProviders() throws Exception {
+ writeAspectDefinition("{'_extra_deps' : attr.label(default = Label('//test:z'))}");
+ writeFile(
+ "test/BUILD",
+ "load('//test:aspect.bzl', 'aspect_rule', 'plain_rule')",
+ "aspect_rule(name='a', attr=[':b'])",
+ "plain_rule(name='b')",
+ "plain_rule(name='z')");
+
+ assertThat(eval("deps(//test:a)")).containsAtLeastElementsIn(eval("//test:b + //test:z"));
+ }
+
+ @Test
+ public void testQueryStarlarkAspects() throws Exception {
+ writeAspectDefinition("{'_extra_deps' : attr.label(default = Label('//prod:zzz'))}");
+ writeFile(
+ "test/BUILD",
+ "load('//test:aspect.bzl', 'aspect_rule', 'plain_rule')",
+ "plain_rule(",
+ " name = 'yyy',",
+ ")",
+ "aspect_rule(",
+ " name = 'xxx',",
+ " attr = [':yyy'],",
+ ")",
+ "aspect_rule(",
+ " name = 'qqq',",
+ " attr = ['//external:yyy'],",
+ ")");
+ appendToWorkspace("bind(name = 'yyy', actual = '//test:yyy')");
+
+ assertThat(eval("deps(//test:xxx)")).containsAtLeastElementsIn(eval("//prod:zzz + //test:yyy"));
+ assertThat(eval("deps(//test:qqq)")).containsAtLeastElementsIn(eval("//prod:zzz + //test:yyy"));
+ }
+
+ @Test
+ public void testQueryStarlarkAspectWithParameters() throws Exception {
+ writeAspectDefinition(
+ "{'_extra_deps' : attr.label(default = Label('//prod:zzz')),"
+ + "'param' : attr.string(values=['a', 'b']) }");
+ writeFile(
+ "test/BUILD",
+ "load('//test:aspect.bzl', 'aspect_rule', 'plain_rule')",
+ "plain_rule(",
+ " name = 'yyy',",
+ ")",
+ "aspect_rule(",
+ " name = 'xxx',",
+ " attr = [':yyy'],",
+ " param = 'a',",
+ ")",
+ "aspect_rule(",
+ " name = 'qqq',",
+ " attr = ['//external:yyy'],",
+ " param = 'b',",
+ ")");
+ appendToWorkspace("bind(name = 'yyy', actual = '//test:yyy')");
+
+ assertThat(eval("deps(//test:xxx)")).containsAtLeastElementsIn(eval("//prod:zzz + //test:yyy"));
+ assertThat(eval("deps(//test:qqq)")).containsAtLeastElementsIn(eval("//prod:zzz + //test:yyy"));
+ }
+
+ @Test
+ public void testQueryStarlarkAspectsNoImplicitDeps() throws Exception {
+ writeAspectDefinition("{'_extra_deps':attr.label(default = Label('//prod:zzz'))}");
+ writeFile(
+ "test/BUILD",
+ "load('//test:aspect.bzl', 'aspect_rule', 'plain_rule')",
+ "plain_rule(",
+ " name = 'yyy',",
+ ")",
+ "aspect_rule(",
+ " name = 'xxx',",
+ " attr = [':yyy'],",
+ ")");
+ helper.setQuerySettings(Setting.NO_IMPLICIT_DEPS);
+
+ assertThat(eval("deps(//test:xxx)")).containsNoneIn(eval("//prod:zzz"));
+ }
+
@Test
public void testStarlarkDiamondEquality() throws Exception {
writeFile(