Stop filtering out targets not in the graph in SkyQueryEnvironment. Instead, just warn if a target turns out to not be present. This means that queries may return unexpected results. For instance, if "query" means "bazel query --order_output=no ", then here are the results of two queries:
query --universe_scope=//foo/... //foo:output_file
//foo:output_file
query --universe_scope=//foo/... deps(//foo:output_file)
WARNING: Targets not in graph [//foo:output_file generated_file]
//foo:output_file
--
MOS_MIGRATED_REVID=112163475
diff --git a/src/main/java/com/google/devtools/build/lib/query2/SkyQueryEnvironment.java b/src/main/java/com/google/devtools/build/lib/query2/SkyQueryEnvironment.java
index 28431be..927b4ec 100644
--- a/src/main/java/com/google/devtools/build/lib/query2/SkyQueryEnvironment.java
+++ b/src/main/java/com/google/devtools/build/lib/query2/SkyQueryEnvironment.java
@@ -23,7 +23,6 @@
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSet.Builder;
import com.google.common.collect.Iterables;
-import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
import com.google.common.collect.Sets;
import com.google.devtools.build.lib.cmdline.Label;
@@ -32,6 +31,7 @@
import com.google.devtools.build.lib.cmdline.TargetParsingException;
import com.google.devtools.build.lib.cmdline.TargetPattern;
import com.google.devtools.build.lib.collect.CompactHashSet;
+import com.google.devtools.build.lib.events.Event;
import com.google.devtools.build.lib.events.EventHandler;
import com.google.devtools.build.lib.graph.Digraph;
import com.google.devtools.build.lib.packages.BuildFileContainsErrorsException;
@@ -231,10 +231,21 @@
});
}
+ /** Targets may not be in the graph because they are not in the universe or depend on cycles. */
+ private void warnIfMissingTargets(
+ Iterable<Target> targets, Set<Target> result) {
+ if (Iterables.size(targets) != result.size()) {
+ Set<Target> missingTargets = Sets.difference(ImmutableSet.copyOf(targets), result);
+ eventHandler.handle(Event.warn("Targets were missing from graph: " + missingTargets));
+ }
+ }
+
@Override
public Collection<Target> getFwdDeps(Iterable<Target> targets) {
Set<Target> result = new HashSet<>();
- for (Map.Entry<Target, Collection<Target>> entry : getRawFwdDeps(targets).entrySet()) {
+ Map<Target, Collection<Target>> rawFwdDeps = getRawFwdDeps(targets);
+ warnIfMissingTargets(targets, rawFwdDeps.keySet());
+ for (Map.Entry<Target, Collection<Target>> entry : rawFwdDeps.entrySet()) {
result.addAll(filterFwdDeps(entry.getKey(), entry.getValue()));
}
return result;
@@ -244,6 +255,7 @@
public Collection<Target> getReverseDeps(Iterable<Target> targets) {
Set<Target> result = CompactHashSet.create();
Map<Target, Collection<Target>> rawReverseDeps = getRawReverseDeps(targets);
+ warnIfMissingTargets(targets, rawReverseDeps.keySet());
CompactHashSet<Target> visited = CompactHashSet.create();
@@ -354,7 +366,7 @@
targets.add(target);
}
}
- batchStreamedCallback.process(filterTargetsNotInGraph(targets));
+ batchStreamedCallback.process(targets);
}
private void processLastPending() throws QueryException, InterruptedException {
@@ -547,9 +559,11 @@
graph.getMissingAndExceptions(unsuccessfulKeys).entrySet();
for (Map.Entry<SkyKey, Exception> entry : errorEntries) {
if (entry.getValue() == null) {
- throw new QueryException(entry.getKey().argument() + " does not exist in graph");
+ // Targets may be in the graph because they are not in the universe or depend on cycles.
+ eventHandler.handle(Event.warn(entry.getKey().argument() + " does not exist in graph"));
+ } else {
+ errorMessagesBuilder.add(entry.getValue().getMessage());
}
- errorMessagesBuilder.add(entry.getValue().getMessage());
}
// Lastly, report all found errors.
@@ -559,16 +573,6 @@
}
}
- private Set<Target> filterTargetsNotInGraph(Set<Target> targets) {
- Map<Target, SkyKey> map = Maps.toMap(targets, TARGET_TO_SKY_KEY);
- Set<SkyKey> present = graph.getSuccessfulValues(map.values()).keySet();
- if (present.size() == targets.size()) {
- // Optimize for case of all targets being in graph.
- return targets;
- }
- return Maps.filterValues(map, Predicates.in(present)).keySet();
- }
-
@Override
protected void preloadOrThrow(QueryExpression caller, Collection<String> patterns)
throws QueryException, TargetParsingException {