aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib/query2
diff options
context:
space:
mode:
authorGravatar Lukacs Berki <lberki@google.com>2015-06-05 07:20:55 +0000
committerGravatar Florian Weikert <fwe@google.com>2015-06-05 09:39:01 +0000
commit14d905b5cce9a1bbc2911331809b03679b23dad1 (patch)
treeeb97900e7011cf90503e8898297a69066029d977 /src/main/java/com/google/devtools/build/lib/query2
parent8bc4352deaeb8d8b8afeaa68bd1a015d7731e0e0 (diff)
Add --with_aspect_deps flag to blaze query. This flag should produce additional information about aspect dependencies when --output is set to {xml, proto}.
One quirk of this CL is that if BUILD files of direct dependencies are added both under <subinclude> and <load>. Any better ideas are appreciated. As a drive-by fix, if for some reason a package reports the same label as a both subinclude and a Skylark dependency, it will only be reported once in the proto output. RELNOTES[NEW]: added --with_aspect_deps to blaze query, that prints additional information about aspects of target when --output is set to {xml, proto, record}. -- MOS_MIGRATED_REVID=95272042
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/query2')
-rw-r--r--src/main/java/com/google/devtools/build/lib/query2/output/AspectResolver.java158
-rw-r--r--src/main/java/com/google/devtools/build/lib/query2/output/GraphOutputFormatter.java3
-rw-r--r--src/main/java/com/google/devtools/build/lib/query2/output/OutputFormatter.java46
-rw-r--r--src/main/java/com/google/devtools/build/lib/query2/output/ProtoOutputFormatter.java60
-rw-r--r--src/main/java/com/google/devtools/build/lib/query2/output/QueryOptions.java7
-rw-r--r--src/main/java/com/google/devtools/build/lib/query2/output/QueryOutputUtils.java8
-rw-r--r--src/main/java/com/google/devtools/build/lib/query2/output/XmlOutputFormatter.java44
7 files changed, 281 insertions, 45 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/query2/output/AspectResolver.java b/src/main/java/com/google/devtools/build/lib/query2/output/AspectResolver.java
new file mode 100644
index 0000000000..7a560e886a
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/query2/output/AspectResolver.java
@@ -0,0 +1,158 @@
+// Copyright 2014 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+package com.google.devtools.build.lib.query2.output;
+
+import com.google.common.collect.Multimap;
+import com.google.common.collect.Multimaps;
+import com.google.devtools.build.lib.events.EventHandler;
+import com.google.devtools.build.lib.packages.AspectDefinition;
+import com.google.devtools.build.lib.packages.Attribute;
+import com.google.devtools.build.lib.packages.NoSuchPackageException;
+import com.google.devtools.build.lib.packages.NoSuchThingException;
+import com.google.devtools.build.lib.packages.Package;
+import com.google.devtools.build.lib.packages.PackageIdentifier;
+import com.google.devtools.build.lib.packages.Rule;
+import com.google.devtools.build.lib.packages.Target;
+import com.google.devtools.build.lib.pkgcache.PackageProvider;
+import com.google.devtools.build.lib.syntax.Label;
+import com.google.devtools.build.lib.util.BinaryPredicate;
+
+import java.util.Collection;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import javax.annotation.Nullable;
+
+/** Utility class that determines additional dependencies of a target from its aspects. */
+public class AspectResolver {
+ private final PackageProvider packageProvider;
+ private final EventHandler eventHandler;
+
+ public AspectResolver(PackageProvider packageProvider, EventHandler eventHandler) {
+ this.packageProvider = packageProvider;
+ this.eventHandler = eventHandler;
+ }
+
+ /**
+ * Compute additional dependencies of target from aspects. This method is going to load direct
+ * deps of target to determine their types. Returns map of attributes and corresponding label
+ * values.
+ */
+ Map<Attribute, Collection<Label>> computeAspectDependenciesWithAttributes(Target target)
+ throws InterruptedException {
+ Map<Attribute, Collection<Label>> aspectDependencies = new LinkedHashMap<>();
+ if (target instanceof Rule) {
+ Multimap<Attribute, Label> transitions =
+ ((Rule) target).getTransitions(Rule.NO_NODEP_ATTRIBUTES);
+ for (Entry<Attribute, Label> entry : transitions.entries()) {
+ Target toTarget;
+ try {
+ toTarget = packageProvider.getTarget(eventHandler, entry.getValue());
+ Map<Attribute, Collection<Label>> deps = Multimaps.asMap(
+ AspectDefinition.visitAspectsIfRequired(target, entry.getKey(), toTarget));
+ aspectDependencies.putAll(deps);
+ } catch (NoSuchThingException e) {
+ // Do nothing. One of target direct deps has an error. The dependency on the BUILD file
+ // (or one of the files included in it) will be reported in the query result of :BUILD.
+ }
+ }
+ }
+ return aspectDependencies;
+ }
+
+ /**
+ * Compute additional dependencies of target from aspects. This method is going to load direct
+ * deps of target to determine their types. Returns set of labels.
+ */
+ Set<Label> computeAspectDependencies(Target target) throws InterruptedException {
+ Set<Label> labels = new LinkedHashSet<Label>();
+ for (Collection<Label> labelCollection :
+ computeAspectDependenciesWithAttributes(target).values()) {
+ labels.addAll(labelCollection);
+ }
+ return labels;
+ }
+
+ /** The way aspect dependencies for a BUILD file are calculated. */
+ enum BuildFileDependencyMode {
+
+ /** Return all the subincluded files that may affect the package. */
+ SUBINCLUDE {
+ @Override
+ protected Collection<Label> getDependencies(Package pkg) {
+ return pkg.getSubincludeLabels();
+ }
+ },
+
+ /** Return all Skylark files that may affect the package. */
+ SKYLARK {
+ @Override
+ protected Collection<Label> getDependencies(Package pkg) {
+ return pkg.getSkylarkFileDependencies();
+ }
+ };
+
+ protected abstract Collection<Label> getDependencies(Package pkg);
+ };
+
+ Set<Label> computeBuildFileDependencies(Package pkg, BuildFileDependencyMode mode)
+ throws InterruptedException {
+ Set<Label> result = new LinkedHashSet<>();
+ result.addAll(mode.getDependencies(pkg));
+
+ Set<PackageIdentifier> dependentPackages = new LinkedHashSet<>();
+ // First compute with packages can possibly affect the aspect attributes of this package:
+ // Iterate over all rules...
+ for (Target target : pkg.getTargets()) {
+
+ if (!(target instanceof Rule)) {
+ continue;
+ }
+
+ // ...figure out which direct dependencies can possibly have aspects attached to them...
+ Multimap<Attribute, Label> depsWithPossibleAspects = ((Rule) target).getTransitions(
+ new BinaryPredicate<Rule, Attribute>() {
+ @Override
+ public boolean apply(@Nullable Rule rule, @Nullable Attribute attribute) {
+ return !attribute.getAspects().isEmpty();
+ }
+ });
+
+ // ...and add the package of the aspect.
+ for (Label depLabel : depsWithPossibleAspects.values()) {
+ dependentPackages.add(depLabel.getPackageIdentifier());
+ }
+ }
+
+ // Then add all the subinclude labels of the packages thus found to the result.
+ for (PackageIdentifier packageIdentifier : dependentPackages) {
+ try {
+ result.add(Label.create(packageIdentifier, "BUILD"));
+ Package dependentPackage = packageProvider.getPackage(eventHandler, packageIdentifier);
+ result.addAll(mode.getDependencies(dependentPackage));
+ } catch (NoSuchPackageException e) {
+ // If the package is not found, just add its BUILD file, which is already done above.
+ // Hopefully this error is not raised when there is a syntax error in a subincluded file
+ // or something.
+ } catch (Label.SyntaxException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ return result;
+ }
+}
diff --git a/src/main/java/com/google/devtools/build/lib/query2/output/GraphOutputFormatter.java b/src/main/java/com/google/devtools/build/lib/query2/output/GraphOutputFormatter.java
index c51fc81e90..0cfcceac5b 100644
--- a/src/main/java/com/google/devtools/build/lib/query2/output/GraphOutputFormatter.java
+++ b/src/main/java/com/google/devtools/build/lib/query2/output/GraphOutputFormatter.java
@@ -42,7 +42,8 @@ class GraphOutputFormatter extends OutputFormatter {
}
@Override
- public void output(QueryOptions options, Digraph<Target> result, PrintStream out) {
+ public void output(QueryOptions options, Digraph<Target> result, PrintStream out,
+ AspectResolver aspectProvider) {
this.graphNodeStringLimit = options.graphNodeStringLimit;
this.graphFactored = options.graphFactored;
diff --git a/src/main/java/com/google/devtools/build/lib/query2/output/OutputFormatter.java b/src/main/java/com/google/devtools/build/lib/query2/output/OutputFormatter.java
index e8247c540a..e47fcb70da 100644
--- a/src/main/java/com/google/devtools/build/lib/query2/output/OutputFormatter.java
+++ b/src/main/java/com/google/devtools/build/lib/query2/output/OutputFormatter.java
@@ -144,8 +144,8 @@ public abstract class OutputFormatter implements Serializable {
* Format the result (a set of target nodes implicitly ordered according to
* the graph maintained by the QueryEnvironment), and print it to "out".
*/
- public abstract void output(QueryOptions options, Digraph<Target> result, PrintStream out)
- throws IOException;
+ public abstract void output(QueryOptions options, Digraph<Target> result, PrintStream out,
+ AspectResolver aspectProvider) throws IOException, InterruptedException;
/**
* Unordered output formatter (wrt. dependency ordering).
@@ -157,8 +157,8 @@ public abstract class OutputFormatter implements Serializable {
* subgraph extraction step before presenting the query results.
*/
public interface UnorderedFormatter {
- void outputUnordered(QueryOptions options, Iterable<Target> result, PrintStream out)
- throws IOException;
+ void outputUnordered(QueryOptions options, Iterable<Target> result, PrintStream out,
+ AspectResolver aspectResolver) throws IOException, InterruptedException;
}
/**
@@ -184,7 +184,8 @@ public abstract class OutputFormatter implements Serializable {
}
@Override
- public void outputUnordered(QueryOptions options, Iterable<Target> result, PrintStream out) {
+ public void outputUnordered(QueryOptions options, Iterable<Target> result, PrintStream out,
+ AspectResolver aspectResolver) {
for (Target target : result) {
if (showKind) {
out.print(target.getTargetKind());
@@ -195,10 +196,11 @@ public abstract class OutputFormatter implements Serializable {
}
@Override
- public void output(QueryOptions options, Digraph<Target> result, PrintStream out) {
+ public void output(QueryOptions options, Digraph<Target> result, PrintStream out,
+ AspectResolver aspectResolver) {
Iterable<Target> ordered = Iterables.transform(
result.getTopologicalOrder(new TargetOrdering()), EXTRACT_NODE_LABEL);
- outputUnordered(options, ordered, out);
+ outputUnordered(options, ordered, out, aspectResolver);
}
}
@@ -224,7 +226,8 @@ public abstract class OutputFormatter implements Serializable {
}
@Override
- public void outputUnordered(QueryOptions options, Iterable<Target> result, PrintStream out) {
+ public void outputUnordered(QueryOptions options, Iterable<Target> result, PrintStream out,
+ AspectResolver aspectResolver) {
Set<String> packageNames = Sets.newTreeSet();
for (Target target : result) {
packageNames.add(target.getLabel().getPackageName());
@@ -235,10 +238,11 @@ public abstract class OutputFormatter implements Serializable {
}
@Override
- public void output(QueryOptions options, Digraph<Target> result, PrintStream out) {
+ public void output(QueryOptions options, Digraph<Target> result, PrintStream out,
+ AspectResolver aspectResolver) {
Iterable<Target> ordered = Iterables.transform(
result.getTopologicalOrder(new TargetOrdering()), EXTRACT_NODE_LABEL);
- outputUnordered(options, ordered, out);
+ outputUnordered(options, ordered, out, aspectResolver);
}
}
@@ -256,7 +260,8 @@ public abstract class OutputFormatter implements Serializable {
}
@Override
- public void outputUnordered(QueryOptions options, Iterable<Target> result, PrintStream out) {
+ public void outputUnordered(QueryOptions options, Iterable<Target> result, PrintStream out,
+ AspectResolver aspectResolver) {
for (Target target : result) {
Location location = target.getLocation();
out.println(location.print() + ": " + target.getTargetKind() + " " + target.getLabel());
@@ -264,10 +269,11 @@ public abstract class OutputFormatter implements Serializable {
}
@Override
- public void output(QueryOptions options, Digraph<Target> result, PrintStream out) {
+ public void output(QueryOptions options, Digraph<Target> result, PrintStream out,
+ AspectResolver aspectResolver) {
Iterable<Target> ordered = Iterables.transform(
result.getTopologicalOrder(new TargetOrdering()), EXTRACT_NODE_LABEL);
- outputUnordered(options, ordered, out);
+ outputUnordered(options, ordered, out, aspectResolver);
}
}
@@ -310,7 +316,8 @@ public abstract class OutputFormatter implements Serializable {
}
@Override
- public void outputUnordered(QueryOptions options, Iterable<Target> result, PrintStream out) {
+ public void outputUnordered(QueryOptions options, Iterable<Target> result, PrintStream out,
+ AspectResolver aspectResolver) {
Set<Label> printed = new HashSet<>();
for (Target target : result) {
Rule rule = target.getAssociatedRule();
@@ -323,10 +330,11 @@ public abstract class OutputFormatter implements Serializable {
}
@Override
- public void output(QueryOptions options, Digraph<Target> result, PrintStream out) {
+ public void output(QueryOptions options, Digraph<Target> result, PrintStream out,
+ AspectResolver aspectResolver) {
Iterable<Target> ordered = Iterables.transform(
result.getTopologicalOrder(new TargetOrdering()), EXTRACT_NODE_LABEL);
- outputUnordered(options, ordered, out);
+ outputUnordered(options, ordered, out, aspectResolver);
}
}
@@ -347,7 +355,8 @@ public abstract class OutputFormatter implements Serializable {
}
@Override
- public void output(QueryOptions options, Digraph<Target> result, PrintStream out) {
+ public void output(QueryOptions options, Digraph<Target> result, PrintStream out,
+ AspectResolver aspectResolver) {
// getRoots() isn't defined for cyclic graphs, so in order to handle
// cycles correctly, we need work on the strong component graph, as
// cycles should be treated a "clump" of nodes all on the same rank.
@@ -397,7 +406,8 @@ public abstract class OutputFormatter implements Serializable {
}
@Override
- public void output(QueryOptions options, Digraph<Target> result, PrintStream out) {
+ public void output(QueryOptions options, Digraph<Target> result, PrintStream out,
+ AspectResolver aspectResolver) {
// In order to handle cycles correctly, we need work on the strong
// component graph, as cycles should be treated a "clump" of nodes all on
// the same rank. Graphs may contain cycles because there are errors in BUILD files.
diff --git a/src/main/java/com/google/devtools/build/lib/query2/output/ProtoOutputFormatter.java b/src/main/java/com/google/devtools/build/lib/query2/output/ProtoOutputFormatter.java
index e7d9d21aef..77761efbea 100644
--- a/src/main/java/com/google/devtools/build/lib/query2/output/ProtoOutputFormatter.java
+++ b/src/main/java/com/google/devtools/build/lib/query2/output/ProtoOutputFormatter.java
@@ -19,6 +19,7 @@ import static com.google.devtools.build.lib.query2.proto.proto2api.Build.Target.
import static com.google.devtools.build.lib.query2.proto.proto2api.Build.Target.Discriminator.RULE;
import static com.google.devtools.build.lib.query2.proto.proto2api.Build.Target.Discriminator.SOURCE_FILE;
+import com.google.common.collect.Lists;
import com.google.devtools.build.lib.graph.Digraph;
import com.google.devtools.build.lib.packages.Attribute;
import com.google.devtools.build.lib.packages.EnvironmentGroup;
@@ -30,6 +31,7 @@ import com.google.devtools.build.lib.packages.ProtoUtils;
import com.google.devtools.build.lib.packages.Rule;
import com.google.devtools.build.lib.packages.Target;
import com.google.devtools.build.lib.query2.FakeSubincludeTarget;
+import com.google.devtools.build.lib.query2.output.AspectResolver.BuildFileDependencyMode;
import com.google.devtools.build.lib.query2.output.OutputFormatter.UnorderedFormatter;
import com.google.devtools.build.lib.query2.proto.proto2api.Build;
import com.google.devtools.build.lib.syntax.Label;
@@ -38,6 +40,13 @@ import com.google.devtools.build.lib.util.BinaryPredicate;
import java.io.IOException;
import java.io.PrintStream;
+import java.util.Collection;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import javax.annotation.Nullable;
/**
* An output formatter that outputs a protocol buffer representation
@@ -54,6 +63,7 @@ public class ProtoOutputFormatter extends OutputFormatter implements UnorderedFo
private BinaryPredicate<Rule, Attribute> dependencyFilter;
private boolean relativeLocations = false;
+ @Nullable protected AspectResolver aspectResolver = null; // null if aspect deps are not required
protected void setDependencyFilter(QueryOptions options) {
this.dependencyFilter = OutputFormatter.getDependencyFilter(options);
@@ -65,10 +75,10 @@ public class ProtoOutputFormatter extends OutputFormatter implements UnorderedFo
}
@Override
- public void outputUnordered(QueryOptions options, Iterable<Target> result, PrintStream out)
- throws IOException {
+ public void outputUnordered(QueryOptions options, Iterable<Target> result, PrintStream out,
+ AspectResolver aspectResolver) throws IOException, InterruptedException {
relativeLocations = options.relativeLocations;
-
+ this.aspectResolver = aspectResolver;
setDependencyFilter(options);
Build.QueryResult.Builder queryResult = Build.QueryResult.newBuilder();
@@ -80,9 +90,9 @@ public class ProtoOutputFormatter extends OutputFormatter implements UnorderedFo
}
@Override
- public void output(QueryOptions options, Digraph<Target> result, PrintStream out)
- throws IOException {
- outputUnordered(options, result.getLabels(), out);
+ public void output(QueryOptions options, Digraph<Target> result, PrintStream out,
+ AspectResolver aspectResolver) throws IOException, InterruptedException {
+ outputUnordered(options, result.getLabels(), out, aspectResolver);
}
/**
@@ -91,14 +101,16 @@ public class ProtoOutputFormatter extends OutputFormatter implements UnorderedFo
* output targets.
* @param target The query target being converted to a protocol buffer.
*/
- private void addTarget(Build.QueryResult.Builder queryResult, Target target) {
+ private void addTarget(Build.QueryResult.Builder queryResult, Target target)
+ throws InterruptedException {
queryResult.addTarget(toTargetProtoBuffer(target));
}
/**
* Converts a logical Target object into a Target protobuffer.
*/
- protected Build.Target toTargetProtoBuffer(Target target) {
+ protected Build.Target toTargetProtoBuffer(Target target)
+ throws InterruptedException {
Build.Target.Builder targetPb = Build.Target.newBuilder();
String location = getLocation(target, relativeLocations);
@@ -127,6 +139,22 @@ public class ProtoOutputFormatter extends OutputFormatter implements UnorderedFo
.setStringValue(env.getTransitiveFileContentHashCode()));
}
+ if (aspectResolver != null) {
+ Map<Attribute, Collection<Label>> aspectsDependencies =
+ aspectResolver.computeAspectDependenciesWithAttributes(target);
+ // Add information about additional attributes from aspects.
+ for (Entry<Attribute, Collection<Label>> entry : aspectsDependencies.entrySet()) {
+ PackageSerializer.addAttributeToProto(rulePb, entry.getKey(),
+ Lists.<Object>newArrayList(entry.getValue()), null, false, false);
+ }
+ // Add all deps from aspects as rule inputs of current target.
+ for (Collection<Label> labelCollection : aspectsDependencies.values()) {
+ for (Label label : labelCollection) {
+ rulePb.addRuleInput(label.toString());
+ }
+ }
+ }
+
// Include explicit elements for all direct inputs and outputs of a rule;
// this goes beyond what is available from the attributes above, since it
// may also (depending on options) include implicit outputs,
@@ -166,11 +194,17 @@ public class ProtoOutputFormatter extends OutputFormatter implements UnorderedFo
.setName(label.toString());
if (inputFile.getName().equals("BUILD")) {
- for (Label subinclude : inputFile.getPackage().getSubincludeLabels()) {
- input.addSubinclude(subinclude.toString());
- }
-
- for (Label skylarkFileDep : inputFile.getPackage().getSkylarkFileDependencies()) {
+ Set<Label> subincludeLabels = new LinkedHashSet<>();
+ subincludeLabels.addAll(aspectResolver == null
+ ? inputFile.getPackage().getSubincludeLabels()
+ : aspectResolver.computeBuildFileDependencies(
+ inputFile.getPackage(), BuildFileDependencyMode.SUBINCLUDE));
+ subincludeLabels.addAll(aspectResolver == null
+ ? inputFile.getPackage().getSkylarkFileDependencies()
+ : aspectResolver.computeBuildFileDependencies(
+ inputFile.getPackage(), BuildFileDependencyMode.SKYLARK));
+
+ for (Label skylarkFileDep : subincludeLabels) {
input.addSubinclude(skylarkFileDep.toString());
}
diff --git a/src/main/java/com/google/devtools/build/lib/query2/output/QueryOptions.java b/src/main/java/com/google/devtools/build/lib/query2/output/QueryOptions.java
index 52d897ea69..417981ec2e 100644
--- a/src/main/java/com/google/devtools/build/lib/query2/output/QueryOptions.java
+++ b/src/main/java/com/google/devtools/build/lib/query2/output/QueryOptions.java
@@ -137,6 +137,13 @@ public class QueryOptions extends OptionsBase {
+ "across machines.")
public boolean relativeLocations;
+ @Option(name = "aspect_deps",
+ defaultValue = "false",
+ category = "query",
+ help = "If true, the dependencies from aspects should be added to targets. By default, this "
+ + "information about aspects is missing when --output is set to xml, proto or record.")
+ public boolean withAspectDeps;
+
/**
* Return the current options as a set of QueryEnvironment settings.
*/
diff --git a/src/main/java/com/google/devtools/build/lib/query2/output/QueryOutputUtils.java b/src/main/java/com/google/devtools/build/lib/query2/output/QueryOutputUtils.java
index 6443ee4687..078b937a55 100644
--- a/src/main/java/com/google/devtools/build/lib/query2/output/QueryOutputUtils.java
+++ b/src/main/java/com/google/devtools/build/lib/query2/output/QueryOutputUtils.java
@@ -31,14 +31,14 @@ public class QueryOutputUtils {
}
public static void output(QueryOptions queryOptions, QueryEvalResult<Target> result,
- OutputFormatter formatter, PrintStream outputStream)
- throws IOException {
+ OutputFormatter formatter, PrintStream outputStream, AspectResolver aspectResolver)
+ throws IOException, InterruptedException {
if (orderResults(queryOptions, formatter)) {
formatter.output(queryOptions, ((BlazeQueryEvalResult<Target>) result).getResultGraph(),
- outputStream);
+ outputStream, aspectResolver);
} else {
((UnorderedFormatter) formatter).outputUnordered(queryOptions, result.getResultSet(),
- outputStream);
+ outputStream, aspectResolver);
}
}
}
diff --git a/src/main/java/com/google/devtools/build/lib/query2/output/XmlOutputFormatter.java b/src/main/java/com/google/devtools/build/lib/query2/output/XmlOutputFormatter.java
index 68eaefd4d2..4d3dca8c8a 100644
--- a/src/main/java/com/google/devtools/build/lib/query2/output/XmlOutputFormatter.java
+++ b/src/main/java/com/google/devtools/build/lib/query2/output/XmlOutputFormatter.java
@@ -25,6 +25,7 @@ import com.google.devtools.build.lib.packages.PackageGroup;
import com.google.devtools.build.lib.packages.Rule;
import com.google.devtools.build.lib.packages.Target;
import com.google.devtools.build.lib.query2.FakeSubincludeTarget;
+import com.google.devtools.build.lib.query2.output.AspectResolver.BuildFileDependencyMode;
import com.google.devtools.build.lib.syntax.FilesetEntry;
import com.google.devtools.build.lib.syntax.Label;
import com.google.devtools.build.lib.util.BinaryPredicate;
@@ -40,6 +41,7 @@ import java.util.HashSet;
import java.util.Map;
import java.util.Set;
+import javax.annotation.Nullable;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
@@ -58,6 +60,7 @@ class XmlOutputFormatter extends OutputFormatter implements OutputFormatter.Unor
private boolean xmlLineNumbers;
private boolean showDefaultValues;
private boolean relativeLocations;
+ @Nullable private AspectResolver aspectResolver; // Null if aspect dependencies are not needed
private BinaryPredicate<Rule, Attribute> dependencyFilter;
@Override
@@ -66,12 +69,13 @@ class XmlOutputFormatter extends OutputFormatter implements OutputFormatter.Unor
}
@Override
- public void outputUnordered(QueryOptions options, Iterable<Target> result, PrintStream out) {
+ public void outputUnordered(QueryOptions options, Iterable<Target> result, PrintStream out,
+ AspectResolver aspectResolver) throws InterruptedException {
this.xmlLineNumbers = options.xmlLineNumbers;
this.showDefaultValues = options.xmlShowDefaultValues;
this.relativeLocations = options.relativeLocations;
this.dependencyFilter = OutputFormatter.getDependencyFilter(options);
-
+ this.aspectResolver = aspectResolver;
Document doc;
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
@@ -98,10 +102,11 @@ class XmlOutputFormatter extends OutputFormatter implements OutputFormatter.Unor
}
@Override
- public void output(QueryOptions options, Digraph<Target> result, PrintStream out) {
+ public void output(QueryOptions options, Digraph<Target> result, PrintStream out,
+ AspectResolver aspectResolver) throws InterruptedException {
Iterable<Target> ordered = Iterables.transform(
result.getTopologicalOrder(new TargetOrdering()), OutputFormatter.EXTRACT_NODE_LABEL);
- outputUnordered(options, ordered, out);
+ outputUnordered(options, ordered, out, aspectResolver);
}
/**
@@ -114,8 +119,10 @@ class XmlOutputFormatter extends OutputFormatter implements OutputFormatter.Unor
* - 'name' attribute is target's label.
* - 'location' attribute is consistent with output of --output location.
* - rule attributes are represented in the DOM structure.
+ * @throws InterruptedException
*/
- private Element createTargetElement(Document doc, Target target) {
+ private Element createTargetElement(Document doc, Target target)
+ throws InterruptedException {
Element elem;
if (target instanceof Rule) {
Rule rule = (Rule) target;
@@ -139,6 +146,13 @@ class XmlOutputFormatter extends OutputFormatter implements OutputFormatter.Unor
inputElem.setAttribute("name", label.toString());
elem.appendChild(inputElem);
}
+ if (aspectResolver != null) {
+ for (Label label : aspectResolver.computeAspectDependencies(target)) {
+ Element inputElem = doc.createElement("rule-input");
+ inputElem.setAttribute("name", label.toString());
+ elem.appendChild(inputElem);
+ }
+ }
for (OutputFile outputFile: rule.getOutputFiles()) {
Element outputElem = doc.createElement("rule-output");
outputElem.setAttribute("name", outputFile.getLabel().toString());
@@ -233,16 +247,28 @@ class XmlOutputFormatter extends OutputFormatter implements OutputFormatter.Unor
}
}
- private void addSubincludedFilesToElement(Document doc, Element parent, InputFile inputFile) {
- for (Label subinclude : inputFile.getPackage().getSubincludeLabels()) {
+ private void addSubincludedFilesToElement(Document doc, Element parent, InputFile inputFile)
+ throws InterruptedException {
+ Iterable<Label> dependencies = aspectResolver == null
+ ? inputFile.getPackage().getSubincludeLabels()
+ : aspectResolver.computeBuildFileDependencies(
+ inputFile.getPackage(), BuildFileDependencyMode.SUBINCLUDE);
+
+ for (Label subinclude : dependencies) {
Element elem = doc.createElement("subinclude");
elem.setAttribute("name", subinclude.toString());
parent.appendChild(elem);
}
}
- private void addSkylarkFilesToElement(Document doc, Element parent, InputFile inputFile) {
- for (Label skylarkFileDep : inputFile.getPackage().getSkylarkFileDependencies()) {
+ private void addSkylarkFilesToElement(Document doc, Element parent, InputFile inputFile)
+ throws InterruptedException {
+ Iterable<Label> dependencies = aspectResolver == null
+ ? inputFile.getPackage().getSkylarkFileDependencies()
+ : aspectResolver.computeBuildFileDependencies(
+ inputFile.getPackage(), BuildFileDependencyMode.SKYLARK);
+
+ for (Label skylarkFileDep : dependencies) {
Element elem = doc.createElement("load");
elem.setAttribute("name", skylarkFileDep.toString());
parent.appendChild(elem);