Automated rollback of commit 78fdb7d62da15f7048cc3c170ca4fc03ff8f9bb2.
*** Reason for rollback ***
Throwing a NPE in users blaze integration tests
*** Original change description ***
Stop "query --output=proto" crashing on label-dict aspect attributes.
It's unfortunately complicated to properly support these attributes (we need
to define the proto spec more finely). This change just reports a proper error
vs. crashing Blaze. See the new comments in ProtoOutputFormatter for details.
PiperOrigin-RevId: 300096191
diff --git a/src/main/java/com/google/devtools/build/lib/packages/PackageFactory.java b/src/main/java/com/google/devtools/build/lib/packages/PackageFactory.java
index 9ed0d21..4a90723 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/PackageFactory.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/PackageFactory.java
@@ -30,7 +30,6 @@
import com.google.devtools.build.lib.events.ExtendedEventHandler;
import com.google.devtools.build.lib.events.ExtendedEventHandler.Postable;
import com.google.devtools.build.lib.events.Location;
-import com.google.devtools.build.lib.events.Reporter;
import com.google.devtools.build.lib.events.StoredEventHandler;
import com.google.devtools.build.lib.packages.Globber.BadGlobException;
import com.google.devtools.build.lib.packages.PackageValidator.InvalidPackageException;
@@ -137,7 +136,6 @@
protected Iterable<EnvironmentExtension> environmentExtensions = ImmutableList.of();
protected PackageValidator packageValidator = PackageValidator.NOOP_VALIDATOR;
protected boolean doChecksForTesting = true;
- protected Reporter reporter;
public BuilderForTesting setEnvironmentExtensions(
Iterable<EnvironmentExtension> environmentExtensions) {
@@ -155,11 +153,6 @@
return this;
}
- public BuilderForTesting setReporter(Reporter reporter) {
- this.reporter = reporter;
- return this;
- }
-
public abstract PackageFactory build(RuleClassProvider ruleClassProvider, FileSystem fs);
}
diff --git a/src/main/java/com/google/devtools/build/lib/query2/engine/OutputFormatterCallback.java b/src/main/java/com/google/devtools/build/lib/query2/engine/OutputFormatterCallback.java
index c66eefe..50708d6 100644
--- a/src/main/java/com/google/devtools/build/lib/query2/engine/OutputFormatterCallback.java
+++ b/src/main/java/com/google/devtools/build/lib/query2/engine/OutputFormatterCallback.java
@@ -67,11 +67,11 @@
* Use an {@code OutputFormatterCallback} with an already computed set of targets. Note that this
* does not work in stream mode, as the {@code targets} would already be computed.
*
- * <p>The intended usage of this method is to use {@code StreamedFormatter} formatters in non
+ * <p>The intended usage of this method is to use {@code StreamedFormatter} formaters in non
* streaming contexts.
*/
- public static <T> void processAllTargets(OutputFormatterCallback<T> callback, Iterable<T> targets)
- throws IOException, InterruptedException {
+ public static <T> void processAllTargets(OutputFormatterCallback<T> callback,
+ Iterable<T> targets) throws IOException, InterruptedException {
boolean failFast = true;
try {
callback.start();
diff --git a/src/main/java/com/google/devtools/build/lib/query2/query/output/AbstractUnorderedFormatter.java b/src/main/java/com/google/devtools/build/lib/query2/query/output/AbstractUnorderedFormatter.java
index 336849b..6a6917a 100644
--- a/src/main/java/com/google/devtools/build/lib/query2/query/output/AbstractUnorderedFormatter.java
+++ b/src/main/java/com/google/devtools/build/lib/query2/query/output/AbstractUnorderedFormatter.java
@@ -15,7 +15,6 @@
package com.google.devtools.build.lib.query2.query.output;
import com.google.common.collect.Iterables;
-import com.google.devtools.build.lib.events.EventHandler;
import com.google.devtools.build.lib.graph.Digraph;
import com.google.devtools.build.lib.graph.Node;
import com.google.devtools.build.lib.packages.Target;
@@ -31,19 +30,11 @@
@Override
public void setOptions(CommonQueryOptions options, AspectResolver aspectResolver) {}
- /** Sets a handler for reporting status output / errors. */
- public void setEventHandler(EventHandler eventHandler) {}
-
@Override
public void output(
- QueryOptions options,
- Digraph<Target> result,
- OutputStream out,
- AspectResolver aspectResolver,
- EventHandler eventHandler)
+ QueryOptions options, Digraph<Target> result, OutputStream out, AspectResolver aspectResolver)
throws IOException, InterruptedException {
setOptions(options, aspectResolver);
- setEventHandler(eventHandler);
OutputFormatterCallback.processAllTargets(
createPostFactoStreamCallback(out, options), getOrderedTargets(result, options));
}
diff --git a/src/main/java/com/google/devtools/build/lib/query2/query/output/GraphOutputFormatter.java b/src/main/java/com/google/devtools/build/lib/query2/query/output/GraphOutputFormatter.java
index 3d71a0f..7e9f377 100644
--- a/src/main/java/com/google/devtools/build/lib/query2/query/output/GraphOutputFormatter.java
+++ b/src/main/java/com/google/devtools/build/lib/query2/query/output/GraphOutputFormatter.java
@@ -19,7 +19,6 @@
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.collect.CollectionUtils;
import com.google.devtools.build.lib.collect.EquivalenceRelation;
-import com.google.devtools.build.lib.events.EventHandler;
import com.google.devtools.build.lib.graph.Digraph;
import com.google.devtools.build.lib.graph.DotOutputVisitor;
import com.google.devtools.build.lib.graph.LabelSerializer;
@@ -59,8 +58,7 @@
QueryOptions options,
Digraph<Target> result,
OutputStream out,
- AspectResolver aspectProvider,
- EventHandler eventHandler) {
+ AspectResolver aspectProvider) {
this.graphNodeStringLimit = options.graphNodeStringLimit;
this.graphConditionalEdgesLimit = options.graphConditionalEdgesLimit;
diff --git a/src/main/java/com/google/devtools/build/lib/query2/query/output/MaxrankOutputFormatter.java b/src/main/java/com/google/devtools/build/lib/query2/query/output/MaxrankOutputFormatter.java
index 777cc3d..83dba1a 100644
--- a/src/main/java/com/google/devtools/build/lib/query2/query/output/MaxrankOutputFormatter.java
+++ b/src/main/java/com/google/devtools/build/lib/query2/query/output/MaxrankOutputFormatter.java
@@ -16,7 +16,6 @@
import static java.util.Comparator.comparingInt;
-import com.google.devtools.build.lib.events.EventHandler;
import com.google.devtools.build.lib.graph.Digraph;
import com.google.devtools.build.lib.graph.Node;
import com.google.devtools.build.lib.packages.Target;
@@ -52,11 +51,7 @@
@Override
public void output(
- QueryOptions options,
- Digraph<Target> result,
- OutputStream out,
- AspectResolver aspectResolver,
- EventHandler eventHandler)
+ QueryOptions options, Digraph<Target> result, OutputStream out, AspectResolver aspectResolver)
throws IOException {
// 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
diff --git a/src/main/java/com/google/devtools/build/lib/query2/query/output/MinrankOutputFormatter.java b/src/main/java/com/google/devtools/build/lib/query2/query/output/MinrankOutputFormatter.java
index 8e020cd..efc5cb6 100644
--- a/src/main/java/com/google/devtools/build/lib/query2/query/output/MinrankOutputFormatter.java
+++ b/src/main/java/com/google/devtools/build/lib/query2/query/output/MinrankOutputFormatter.java
@@ -15,7 +15,6 @@
package com.google.devtools.build.lib.query2.query.output;
import com.google.devtools.build.lib.cmdline.Label;
-import com.google.devtools.build.lib.events.EventHandler;
import com.google.devtools.build.lib.graph.Digraph;
import com.google.devtools.build.lib.graph.Node;
import com.google.devtools.build.lib.packages.Target;
@@ -64,11 +63,7 @@
@Override
public void output(
- QueryOptions options,
- Digraph<Target> result,
- OutputStream out,
- AspectResolver aspectResolver,
- EventHandler eventHandler)
+ QueryOptions options, Digraph<Target> result, OutputStream out, AspectResolver aspectResolver)
throws IOException {
PrintStream printStream = new PrintStream(out);
// getRoots() isn't defined for cyclic graphs, so in order to handle
diff --git a/src/main/java/com/google/devtools/build/lib/query2/query/output/OutputFormatter.java b/src/main/java/com/google/devtools/build/lib/query2/query/output/OutputFormatter.java
index a3e8314..77770fc 100644
--- a/src/main/java/com/google/devtools/build/lib/query2/query/output/OutputFormatter.java
+++ b/src/main/java/com/google/devtools/build/lib/query2/query/output/OutputFormatter.java
@@ -13,7 +13,6 @@
// limitations under the License.
package com.google.devtools.build.lib.query2.query.output;
-import com.google.devtools.build.lib.events.EventHandler;
import com.google.devtools.build.lib.graph.Digraph;
import com.google.devtools.build.lib.packages.Target;
import com.google.devtools.build.lib.query2.engine.QueryEnvironment;
@@ -55,10 +54,6 @@
* by the QueryEnvironment), and print it to "out".
*/
public abstract void output(
- QueryOptions options,
- Digraph<Target> result,
- OutputStream out,
- AspectResolver aspectProvider,
- EventHandler eventHandler)
+ QueryOptions options, Digraph<Target> result, OutputStream out, AspectResolver aspectProvider)
throws IOException, InterruptedException;
}
diff --git a/src/main/java/com/google/devtools/build/lib/query2/query/output/ProtoOutputFormatter.java b/src/main/java/com/google/devtools/build/lib/query2/query/output/ProtoOutputFormatter.java
index e0b580b..23db2a6 100644
--- a/src/main/java/com/google/devtools/build/lib/query2/query/output/ProtoOutputFormatter.java
+++ b/src/main/java/com/google/devtools/build/lib/query2/query/output/ProtoOutputFormatter.java
@@ -24,14 +24,11 @@
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;
import com.google.devtools.build.lib.cmdline.Label;
-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.graph.Node;
import com.google.devtools.build.lib.packages.AggregatingAttributeMapper;
@@ -101,8 +98,6 @@
private boolean includeLocations = true;
private boolean includeRuleInputsAndOutputs = true;
- private EventHandler eventHandler;
-
@Override
public String getName() {
return "proto";
@@ -121,11 +116,6 @@
this.includeRuleInputsAndOutputs = options.protoIncludeRuleInputsAndOutputs;
}
- @Override
- public void setEventHandler(EventHandler eventHandler) {
- this.eventHandler = eventHandler;
- }
-
private static Predicate<String> newAttributePredicate(List<String> outputAttributes) {
if (outputAttributes.equals(ImmutableList.of("all"))) {
return Predicates.alwaysTrue();
@@ -208,7 +198,7 @@
if (!includeAspectAttribute(attribute, labels)) {
continue;
}
- Object attributeValue = getAspectAttributeValue(target, attribute, labels);
+ Object attributeValue = getAspectAttributeValue(attribute, labels);
Build.Attribute serializedAttribute =
AttributeFormatter.getAttributeProto(
attribute,
@@ -379,29 +369,11 @@
&& ruleAttributePredicate.apply(attr.getName());
}
- private Object getAspectAttributeValue(
- Target target, Attribute attribute, Collection<Label> labels) {
+ private static Object getAspectAttributeValue(Attribute attribute, Collection<Label> labels) {
Type<?> attributeType = attribute.getType();
if (attributeType.equals(BuildType.LABEL)) {
Preconditions.checkState(labels.size() == 1, "attribute=%s, labels=%s", attribute, labels);
return Iterables.getOnlyElement(labels);
- } else if (attributeType.equals(BuildType.LABEL_KEYED_STRING_DICT)) {
- // Ideally we'd support LABEL_KEYED_STRING_DICT by getting the value directly from the aspect
- // definition vs. trying to reverse-construct it from the flattened labels as this method
- // does. Unfortunately any proper support surfaces a latent bug between --output=proto and
- // aspect attributes: "{@code labels} isn't the set of labels for a single attribute value but
- // for all values of all attributes with the same name. We can have multiple attributes with
- // the same name because multiple aspects may attach to a rule, and nothing is stopping them
- // from defining the same attribute names. That means the "Attribute" proto message doesn't
- // really represent a single attribute, in spite of its documented purpose. This all calls for
- // an API design upgrade to properly consider these relationships. Details at b/149982967.
- eventHandler.handle(
- Event.error(
- String.format(
- "Target \"%s\", aspect attribute \"%s\": type \"%s\" not yet supported with"
- + " --output=proto. See b/149982967",
- target.getLabel(), attribute.getName(), BuildType.LABEL_KEYED_STRING_DICT)));
- return ImmutableMap.of();
} else {
Preconditions.checkState(
attributeType.equals(BuildType.LABEL_LIST),
diff --git a/src/main/java/com/google/devtools/build/lib/query2/query/output/QueryOutputUtils.java b/src/main/java/com/google/devtools/build/lib/query2/query/output/QueryOutputUtils.java
index 5e6506f..89bf13f 100644
--- a/src/main/java/com/google/devtools/build/lib/query2/query/output/QueryOutputUtils.java
+++ b/src/main/java/com/google/devtools/build/lib/query2/query/output/QueryOutputUtils.java
@@ -13,7 +13,6 @@
// limitations under the License.
package com.google.devtools.build.lib.query2.query.output;
-import com.google.devtools.build.lib.events.EventHandler;
import com.google.devtools.build.lib.graph.Digraph;
import com.google.devtools.build.lib.packages.Target;
import com.google.devtools.build.lib.profiler.Profiler;
@@ -38,14 +37,9 @@
&& formatter instanceof StreamedFormatter;
}
- public static void output(
- QueryOptions queryOptions,
- QueryEvalResult result,
- Set<Target> targetsResult,
- OutputFormatter formatter,
- OutputStream outputStream,
- AspectResolver aspectResolver,
- EventHandler eventHandler)
+ public static void output(QueryOptions queryOptions, QueryEvalResult result,
+ Set<Target> targetsResult, OutputFormatter formatter, OutputStream outputStream,
+ AspectResolver aspectResolver)
throws IOException, InterruptedException {
/*
* This is not really streaming, but we are using the streaming interface for writing into the
@@ -69,7 +63,7 @@
}
try (SilentCloseable closeable = Profiler.instance().profile("formatter.output")) {
- formatter.output(queryOptions, subgraph, outputStream, aspectResolver, eventHandler);
+ formatter.output(queryOptions, subgraph, outputStream, aspectResolver);
}
}
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/genquery/GenQuery.java b/src/main/java/com/google/devtools/build/lib/rules/genquery/GenQuery.java
index 252e1e2..fbbc6bb 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/genquery/GenQuery.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/genquery/GenQuery.java
@@ -404,8 +404,7 @@
result,
formatter,
outputStream,
- queryOptions.aspectDeps.createResolver(packageProvider, getEventHandler(ruleContext)),
- getEventHandler(ruleContext));
+ queryOptions.aspectDeps.createResolver(packageProvider, getEventHandler(ruleContext)));
outputStream.close();
} catch (ClosedByInterruptException e) {
throw new InterruptedException(e.getMessage());
diff --git a/src/main/java/com/google/devtools/build/lib/runtime/commands/QueryCommand.java b/src/main/java/com/google/devtools/build/lib/runtime/commands/QueryCommand.java
index 66964a7..c0ced79 100644
--- a/src/main/java/com/google/devtools/build/lib/runtime/commands/QueryCommand.java
+++ b/src/main/java/com/google/devtools/build/lib/runtime/commands/QueryCommand.java
@@ -158,8 +158,7 @@
targets,
formatter,
out,
- queryOptions.aspectDeps.createResolver(env.getPackageManager(), env.getReporter()),
- env.getReporter());
+ queryOptions.aspectDeps.createResolver(env.getPackageManager(), env.getReporter()));
} catch (ClosedByInterruptException | InterruptedException e) {
env.getReporter().handle(Event.error("query interrupted"));
return Either.ofLeft(BlazeCommandResult.exitCode(ExitCode.INTERRUPTED));
diff --git a/src/test/java/com/google/devtools/build/lib/buildtool/QueryIntegrationTest.java b/src/test/java/com/google/devtools/build/lib/buildtool/QueryIntegrationTest.java
index 8d4952a..f3840da 100644
--- a/src/test/java/com/google/devtools/build/lib/buildtool/QueryIntegrationTest.java
+++ b/src/test/java/com/google/devtools/build/lib/buildtool/QueryIntegrationTest.java
@@ -303,15 +303,13 @@
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
- Reporter reporter = new Reporter(new EventBus(), events.collector());
QueryOutputUtils.output(
- queryOptions,
- result,
- callback.getResult(),
- formatter,
+ queryOptions, result,
+ callback.getResult(), formatter,
outputStream,
- queryOptions.aspectDeps.createResolver(env.getPackageManager(), reporter),
- reporter);
+ queryOptions.aspectDeps.createResolver(
+ env.getPackageManager(),
+ new Reporter(new EventBus(), events.collector())));
return outputStream.toByteArray();
}
diff --git a/src/test/java/com/google/devtools/build/lib/packages/util/PackageLoadingTestCase.java b/src/test/java/com/google/devtools/build/lib/packages/util/PackageLoadingTestCase.java
index 56e9db9..7fea1b1 100644
--- a/src/test/java/com/google/devtools/build/lib/packages/util/PackageLoadingTestCase.java
+++ b/src/test/java/com/google/devtools/build/lib/packages/util/PackageLoadingTestCase.java
@@ -100,7 +100,6 @@
loadingMock
.getPackageFactoryBuilderForTesting(directories)
.setEnvironmentExtensions(getEnvironmentExtensions())
- .setReporter(reporter)
.build(ruleClassProvider, fileSystem);
skyframeExecutor = createSkyframeExecutor();
setUpSkyframe();