aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/com')
-rw-r--r--src/main/java/com/google/devtools/build/lib/analysis/AnalysisFailureEvent.java24
-rw-r--r--src/main/java/com/google/devtools/build/lib/analysis/AspectResolver.java4
-rw-r--r--src/main/java/com/google/devtools/build/lib/analysis/BuildView.java3
-rw-r--r--src/main/java/com/google/devtools/build/lib/analysis/DependencyResolver.java19
-rw-r--r--src/main/java/com/google/devtools/build/lib/analysis/LegacyAnalysisFailureEvent.java40
-rw-r--r--src/main/java/com/google/devtools/build/lib/analysis/TargetConfiguredEvent.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/analysis/ToolchainContext.java6
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/rules/VisibilityErrorEvent.java7
-rw-r--r--src/main/java/com/google/devtools/build/lib/causes/ActionFailed.java9
-rw-r--r--src/main/java/com/google/devtools/build/lib/causes/AnalysisFailedCause.java94
-rw-r--r--src/main/java/com/google/devtools/build/lib/causes/LabelCause.java31
-rw-r--r--src/main/java/com/google/devtools/build/lib/causes/LoadingFailedCause.java27
-rw-r--r--src/main/java/com/google/devtools/build/lib/pkgcache/LoadingFailureEvent.java27
-rw-r--r--src/main/java/com/google/devtools/build/lib/query2/BUILD1
-rw-r--r--src/main/java/com/google/devtools/build/lib/query2/TransitionsOutputFormatterCallback.java3
-rw-r--r--src/main/java/com/google/devtools/build/lib/runtime/AggregatingTestListener.java4
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/ActionExecutionFunction.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/AspectFunction.java85
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/CompletionFunction.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/ConfiguredTargetFunction.java156
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/SkyframeBuildView.java40
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/SkyframeDependencyResolver.java10
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/ToplevelSkylarkAspectFunction.java8
23 files changed, 389 insertions, 215 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/AnalysisFailureEvent.java b/src/main/java/com/google/devtools/build/lib/analysis/AnalysisFailureEvent.java
index b39d826b19..cdc26efd30 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/AnalysisFailureEvent.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/AnalysisFailureEvent.java
@@ -23,8 +23,10 @@ import com.google.devtools.build.lib.buildeventstream.BuildEventStreamProtos;
import com.google.devtools.build.lib.buildeventstream.GenericBuildEvent;
import com.google.devtools.build.lib.buildeventstream.NullConfiguration;
import com.google.devtools.build.lib.causes.Cause;
+import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.skyframe.ConfiguredTargetKey;
import java.util.Collection;
+import javax.annotation.Nullable;
/**
* This event is fired during the build, when it becomes known that the analysis of a target cannot
@@ -33,23 +35,37 @@ import java.util.Collection;
public class AnalysisFailureEvent implements BuildEvent {
private final ConfiguredTargetKey failedTarget;
private final BuildEventId configuration;
- private final Iterable<Cause> causes;
+ private final Iterable<Cause> rootCauses;
public AnalysisFailureEvent(
- ConfiguredTargetKey failedTarget, BuildEventId configuration, Iterable<Cause> causes) {
+ ConfiguredTargetKey failedTarget, BuildEventId configuration, Iterable<Cause> rootCauses) {
this.failedTarget = failedTarget;
if (configuration != null) {
this.configuration = configuration;
} else {
this.configuration = NullConfiguration.INSTANCE.getEventId();
}
- this.causes = causes;
+ this.rootCauses = rootCauses;
}
public ConfiguredTargetKey getFailedTarget() {
return failedTarget;
}
+ /**
+ * Returns the label of a single root cause. Use {@link #getRootCauses} to report all root causes.
+ */
+ @Nullable public Label getLegacyFailureReason() {
+ if (!rootCauses.iterator().hasNext()) {
+ return null;
+ }
+ return rootCauses.iterator().next().getLabel();
+ }
+
+ public Iterable<Cause> getRootCauses() {
+ return rootCauses;
+ }
+
@Override
public BuildEventId getEventId() {
return BuildEventId.targetCompleted(failedTarget.getLabel(), configuration);
@@ -57,7 +73,7 @@ public class AnalysisFailureEvent implements BuildEvent {
@Override
public Collection<BuildEventId> getChildrenEvents() {
- return ImmutableList.copyOf(Iterables.transform(causes, BuildEventId::fromCause));
+ return ImmutableList.copyOf(Iterables.transform(rootCauses, BuildEventId::fromCause));
}
@Override
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/AspectResolver.java b/src/main/java/com/google/devtools/build/lib/analysis/AspectResolver.java
index da80785060..355fc21696 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/AspectResolver.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/AspectResolver.java
@@ -16,6 +16,7 @@ package com.google.devtools.build.lib.analysis;
import com.google.common.collect.ImmutableList;
import com.google.devtools.build.lib.analysis.configuredtargets.MergedConfiguredTarget;
+import com.google.devtools.build.lib.causes.LabelCause;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.packages.Aspect;
import com.google.devtools.build.lib.packages.AspectDescriptor;
@@ -81,7 +82,8 @@ public final class AspectResolver {
"Evaluation of aspect %s on %s failed: %s",
depAspect.getAspect().getAspectClass().getName(),
dep.getLabel(),
- e.toString()));
+ e.toString()),
+ new LabelCause(dep.getLabel(), e.getMessage()));
}
if (aspectValue == null) {
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/BuildView.java b/src/main/java/com/google/devtools/build/lib/analysis/BuildView.java
index ae3a500bd5..2651e65d82 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/BuildView.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/BuildView.java
@@ -52,6 +52,7 @@ import com.google.devtools.build.lib.analysis.constraints.TopLevelConstraintSema
import com.google.devtools.build.lib.analysis.test.CoverageReportActionFactory;
import com.google.devtools.build.lib.analysis.test.CoverageReportActionFactory.CoverageReportActionsWrapper;
import com.google.devtools.build.lib.analysis.test.InstrumentedFilesProvider;
+import com.google.devtools.build.lib.causes.Cause;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
@@ -1053,7 +1054,7 @@ public class BuildView {
}
@Override
- protected Target getTarget(Target from, Label label, NestedSetBuilder<Label> rootCauses)
+ protected Target getTarget(Target from, Label label, NestedSetBuilder<Cause> rootCauses)
throws InterruptedException {
try {
return skyframeExecutor.getPackageManager().getTarget(eventHandler, label);
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/DependencyResolver.java b/src/main/java/com/google/devtools/build/lib/analysis/DependencyResolver.java
index 4a35e373e7..9ad8ba8a16 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/DependencyResolver.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/DependencyResolver.java
@@ -30,6 +30,7 @@ import com.google.devtools.build.lib.analysis.config.transitions.ConfigurationTr
import com.google.devtools.build.lib.analysis.config.transitions.NullTransition;
import com.google.devtools.build.lib.analysis.config.transitions.PatchTransition;
import com.google.devtools.build.lib.analysis.config.transitions.SplitTransition;
+import com.google.devtools.build.lib.causes.Cause;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.events.Location;
@@ -108,7 +109,7 @@ public abstract class DependencyResolver {
@Nullable RuleTransitionFactory trimmingTransitionFactory)
throws EvalException, InvalidConfigurationException, InterruptedException,
InconsistentAspectOrderException {
- NestedSetBuilder<Label> rootCauses = NestedSetBuilder.<Label>stableOrder();
+ NestedSetBuilder<Cause> rootCauses = NestedSetBuilder.stableOrder();
OrderedSetMultimap<Attribute, Dependency> outgoingEdges =
dependentNodeMap(
node,
@@ -164,7 +165,7 @@ public abstract class DependencyResolver {
Iterable<Aspect> aspects,
ImmutableMap<Label, ConfigMatchingProvider> configConditions,
ImmutableSet<Label> toolchainLabels,
- NestedSetBuilder<Label> rootCauses,
+ NestedSetBuilder<Cause> rootCauses,
BuildOptions defaultBuildOptions,
@Nullable RuleTransitionFactory trimmingTransitionFactory)
throws EvalException, InvalidConfigurationException, InterruptedException,
@@ -207,7 +208,7 @@ public abstract class DependencyResolver {
Iterable<Aspect> aspects,
ImmutableMap<Label, ConfigMatchingProvider> configConditions,
ImmutableSet<Label> toolchainLabels,
- NestedSetBuilder<Label> rootCauses,
+ NestedSetBuilder<Cause> rootCauses,
OrderedSetMultimap<Attribute, Dependency> outgoingEdges,
BuildOptions defaultBuildOptions,
@Nullable RuleTransitionFactory trimmingTransitionFactory)
@@ -554,7 +555,7 @@ public abstract class DependencyResolver {
public final Collection<Dependency> resolveRuleLabels(
TargetAndConfiguration node,
OrderedSetMultimap<Attribute, Label> depLabels,
- NestedSetBuilder<Label> rootCauses,
+ NestedSetBuilder<Cause> rootCauses,
@Nullable RuleTransitionFactory trimmingTransitionFactory)
throws InterruptedException, InconsistentAspectOrderException {
Preconditions.checkArgument(node.getTarget() instanceof Rule);
@@ -581,7 +582,7 @@ public abstract class DependencyResolver {
private void visitPackageGroup(
TargetAndConfiguration node,
PackageGroup packageGroup,
- NestedSetBuilder<Label> rootCauses,
+ NestedSetBuilder<Cause> rootCauses,
Collection<Dependency> outgoingEdges)
throws InterruptedException {
for (Label label : packageGroup.getIncludes()) {
@@ -691,7 +692,7 @@ public abstract class DependencyResolver {
private final BuildConfiguration ruleConfig;
private final Iterable<Aspect> aspects;
private final ConfiguredAttributeMapper attributeMap;
- private final NestedSetBuilder<Label> rootCauses;
+ private final NestedSetBuilder<Cause> rootCauses;
private final OrderedSetMultimap<Attribute, Dependency> outgoingEdges;
@Nullable private final RuleTransitionFactory trimmingTransitionFactory;
private final List<AttributeAndOwner> attributes;
@@ -711,7 +712,7 @@ public abstract class DependencyResolver {
BuildConfiguration ruleConfig,
Iterable<Aspect> aspects,
ConfiguredAttributeMapper attributeMap,
- NestedSetBuilder<Label> rootCauses,
+ NestedSetBuilder<Cause> rootCauses,
OrderedSetMultimap<Attribute, Dependency> outgoingEdges,
@Nullable RuleTransitionFactory trimmingTransitionFactory) {
this.rule = rule;
@@ -839,7 +840,7 @@ public abstract class DependencyResolver {
private void visitTargetVisibility(
TargetAndConfiguration node,
- NestedSetBuilder<Label> rootCauses,
+ NestedSetBuilder<Cause> rootCauses,
Collection<Dependency> outgoingEdges)
throws InterruptedException {
Target target = node.getTarget();
@@ -899,7 +900,7 @@ public abstract class DependencyResolver {
* dependencies.
*/
@Nullable
- protected abstract Target getTarget(Target from, Label label, NestedSetBuilder<Label> rootCauses)
+ protected abstract Target getTarget(Target from, Label label, NestedSetBuilder<Cause> rootCauses)
throws InterruptedException;
/**
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/LegacyAnalysisFailureEvent.java b/src/main/java/com/google/devtools/build/lib/analysis/LegacyAnalysisFailureEvent.java
deleted file mode 100644
index 26c23e29c8..0000000000
--- a/src/main/java/com/google/devtools/build/lib/analysis/LegacyAnalysisFailureEvent.java
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2014 The Bazel Authors. 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.analysis;
-
-import com.google.devtools.build.lib.cmdline.Label;
-import com.google.devtools.build.lib.skyframe.ConfiguredTargetKey;
-
-/**
- * This event is fired during the build, when it becomes known that the analysis of a target cannot
- * be completed because of an error in one of its dependencies.
- */
-public class LegacyAnalysisFailureEvent {
- private final ConfiguredTargetKey failedTarget;
- private final Label failureReason;
-
- public LegacyAnalysisFailureEvent(ConfiguredTargetKey failedTarget, Label failureReason) {
- this.failedTarget = failedTarget;
- this.failureReason = failureReason;
- }
-
- public ConfiguredTargetKey getFailedTarget() {
- return failedTarget;
- }
-
- public Label getFailureReason() {
- return failureReason;
- }
-}
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/TargetConfiguredEvent.java b/src/main/java/com/google/devtools/build/lib/analysis/TargetConfiguredEvent.java
index dd015c7ad7..2dec44f617 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/TargetConfiguredEvent.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/TargetConfiguredEvent.java
@@ -60,7 +60,7 @@ public class TargetConfiguredEvent implements BuildEventWithConfiguration {
@Override
public Collection<BuildEventId> getChildrenEvents() {
- ImmutableList.Builder childrenBuilder = ImmutableList.builder();
+ ImmutableList.Builder<BuildEventId> childrenBuilder = ImmutableList.builder();
for (BuildConfiguration config : configurations) {
if (config != null) {
childrenBuilder.add(BuildEventId.targetCompleted(target.getLabel(), config.getEventId()));
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/ToolchainContext.java b/src/main/java/com/google/devtools/build/lib/analysis/ToolchainContext.java
index a2e63b9755..a53b79950e 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/ToolchainContext.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/ToolchainContext.java
@@ -42,6 +42,7 @@ import com.google.devtools.build.lib.syntax.SkylarkIndexable;
import com.google.devtools.build.lib.util.OrderedSetMultimap;
import java.util.Optional;
import java.util.Set;
+import java.util.stream.StreamSupport;
import javax.annotation.Nullable;
/** Contains toolchain-related information needed for a {@link RuleContext}. */
@@ -130,9 +131,8 @@ public class ToolchainContext {
}
/** Returns the {@link Label}s from the {@link NestedSet} that refer to toolchain dependencies. */
- public Set<Label> filterToolchainLabels(Set<Label> labels) {
- return labels
- .stream()
+ public Set<Label> filterToolchainLabels(Iterable<Label> labels) {
+ return StreamSupport.stream(labels.spliterator(), false)
.filter(label -> resolvedToolchainLabels.isToolchainDependency(label))
.collect(ImmutableSet.toImmutableSet());
}
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/VisibilityErrorEvent.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/VisibilityErrorEvent.java
index ebb0e4cc4f..9829ef459e 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/rules/VisibilityErrorEvent.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/VisibilityErrorEvent.java
@@ -39,8 +39,11 @@ public class VisibilityErrorEvent implements BuildEventWithConfiguration {
@Override
public BuildEventId getEventId() {
- // TODO(aehlig): track the configuration as well
- return BuildEventId.unconfiguredLabelId(label);
+ // This needs to match AnalysisFailedCause.
+ if (configuration == null) {
+ return BuildEventId.unconfiguredLabelId(label);
+ }
+ return BuildEventId.configuredLabelId(label, configuration.getEventId());
}
@Override
diff --git a/src/main/java/com/google/devtools/build/lib/causes/ActionFailed.java b/src/main/java/com/google/devtools/build/lib/causes/ActionFailed.java
index 9200c18d0f..cc59d3c262 100644
--- a/src/main/java/com/google/devtools/build/lib/causes/ActionFailed.java
+++ b/src/main/java/com/google/devtools/build/lib/causes/ActionFailed.java
@@ -13,6 +13,7 @@
// limitations under the License.
package com.google.devtools.build.lib.causes;
+import com.google.common.base.MoreObjects;
import com.google.devtools.build.lib.buildeventstream.BuildEventStreamProtos;
import com.google.devtools.build.lib.buildeventstream.BuildEventStreamProtos.BuildEventId;
import com.google.devtools.build.lib.buildeventstream.BuildEventStreamProtos.BuildEventId.ActionCompletedId;
@@ -23,7 +24,7 @@ import javax.annotation.Nullable;
/**
* Class describing a {@link Cause} that is associated with an action. It is uniquely determined by
- * the path to the primary output. For reference, a Label is attached as well.
+ * the path to the primary output. For reference, a Label is attached as well if available.
*/
public class ActionFailed implements Cause {
private final PathFragment execPath;
@@ -38,7 +39,11 @@ public class ActionFailed implements Cause {
@Override
public String toString() {
- return execPath.toString();
+ return MoreObjects.toStringHelper(this)
+ .add("execPath", execPath)
+ .add("label", label)
+ .add("configurationChecksum", configurationChecksum)
+ .toString();
}
@Override
diff --git a/src/main/java/com/google/devtools/build/lib/causes/AnalysisFailedCause.java b/src/main/java/com/google/devtools/build/lib/causes/AnalysisFailedCause.java
new file mode 100644
index 0000000000..9ff844cb10
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/causes/AnalysisFailedCause.java
@@ -0,0 +1,94 @@
+// Copyright 2018 The Bazel Authors. 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.causes;
+
+import com.google.common.base.MoreObjects;
+import com.google.devtools.build.lib.buildeventstream.BuildEventStreamProtos;
+import com.google.devtools.build.lib.buildeventstream.BuildEventStreamProtos.BuildEventId.ConfigurationId;
+import com.google.devtools.build.lib.cmdline.Label;
+import java.util.Objects;
+import javax.annotation.Nullable;
+
+/**
+ * Class describing a {@link Cause} that can uniquely be described by a {@link Label} and
+ * {@link com.google.devtools.build.lib.analysis.config.BuildConfiguration}. Note that the
+ * configuration may be null, in which case this generates an UnconfiguredLabel event.
+ */
+public class AnalysisFailedCause implements Cause {
+ private final Label label;
+ @Nullable private final ConfigurationId configuration;
+ private final String msg;
+
+ public AnalysisFailedCause(Label label, @Nullable ConfigurationId configuration, String msg) {
+ this.label = label;
+ this.configuration = configuration;
+ this.msg = msg;
+ }
+
+ public AnalysisFailedCause(Label label, @Nullable ConfigurationId configuration) {
+ this(label, configuration, null);
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this)
+ .add("label", label)
+ .add("configuration", configuration)
+ .add("msg", msg)
+ .toString();
+ }
+
+ @Override
+ public Label getLabel() {
+ return label;
+ }
+
+ @Override
+ public BuildEventStreamProtos.BuildEventId getIdProto() {
+ // This needs to match VisibilityErrorEvent.
+ if (configuration == null) {
+ return BuildEventStreamProtos.BuildEventId.newBuilder()
+ .setUnconfiguredLabel(
+ BuildEventStreamProtos.BuildEventId.UnconfiguredLabelId.newBuilder()
+ .setLabel(label.toString())
+ .build())
+ .build();
+ }
+ return BuildEventStreamProtos.BuildEventId.newBuilder()
+ .setConfiguredLabel(
+ BuildEventStreamProtos.BuildEventId.ConfiguredLabelId.newBuilder()
+ .setLabel(label.toString())
+ .setConfiguration(configuration)
+ .build())
+ .build();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ } else if (!(o instanceof AnalysisFailedCause)) {
+ return false;
+ }
+ AnalysisFailedCause a = (AnalysisFailedCause) o;
+ return Objects.equals(label, a.label)
+ && Objects.equals(configuration, a.configuration)
+ && Objects.equals(msg, a.msg);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(label, configuration, msg);
+ }
+}
diff --git a/src/main/java/com/google/devtools/build/lib/causes/LabelCause.java b/src/main/java/com/google/devtools/build/lib/causes/LabelCause.java
index b765c1516c..303f1ecd79 100644
--- a/src/main/java/com/google/devtools/build/lib/causes/LabelCause.java
+++ b/src/main/java/com/google/devtools/build/lib/causes/LabelCause.java
@@ -1,4 +1,4 @@
-// Copyright 2016 The Bazel Authors. All rights reserved.
+// Copyright 2018 The Bazel Authors. 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.
@@ -13,20 +13,27 @@
// limitations under the License.
package com.google.devtools.build.lib.causes;
+import com.google.common.base.MoreObjects;
import com.google.devtools.build.lib.buildeventstream.BuildEventStreamProtos;
import com.google.devtools.build.lib.cmdline.Label;
+import java.util.Objects;
-/** Class describing a {@link Cause} that can uniquely be described by a {@link Label}. */
+/** Failure due to something associated with a label; also adds a message. */
public class LabelCause implements Cause {
private final Label label;
+ private final String msg;
- public LabelCause(Label label) {
+ public LabelCause(Label label, String msg) {
this.label = label;
+ this.msg = msg;
}
@Override
public String toString() {
- return label.toString();
+ return MoreObjects.toStringHelper(this)
+ .add("label", label)
+ .add("msg", msg)
+ .toString();
}
@Override
@@ -43,4 +50,20 @@ public class LabelCause implements Cause {
.build())
.build();
}
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ } else if (!(o instanceof LabelCause)) {
+ return false;
+ }
+ LabelCause a = (LabelCause) o;
+ return label.equals(a.label) && msg.equals(a.msg);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(label, msg);
+ }
}
diff --git a/src/main/java/com/google/devtools/build/lib/causes/LoadingFailedCause.java b/src/main/java/com/google/devtools/build/lib/causes/LoadingFailedCause.java
new file mode 100644
index 0000000000..84dbf6b4e0
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/causes/LoadingFailedCause.java
@@ -0,0 +1,27 @@
+// Copyright 2018 The Bazel Authors. 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.causes;
+
+import com.google.devtools.build.lib.cmdline.Label;
+
+/**
+ * Failure due to something associated with a label; also adds a message. The difference between
+ * this class and {@link LabelCause} is that instances of this class get posted to the EventBus as
+ * {@link com.google.devtools.build.lib.pkgcache.LoadingFailureEvent}.
+ */
+public class LoadingFailedCause extends LabelCause {
+ public LoadingFailedCause(Label label, String msg) {
+ super(label, msg);
+ }
+}
diff --git a/src/main/java/com/google/devtools/build/lib/pkgcache/LoadingFailureEvent.java b/src/main/java/com/google/devtools/build/lib/pkgcache/LoadingFailureEvent.java
index 45305d2075..4ee722fcd4 100644
--- a/src/main/java/com/google/devtools/build/lib/pkgcache/LoadingFailureEvent.java
+++ b/src/main/java/com/google/devtools/build/lib/pkgcache/LoadingFailureEvent.java
@@ -13,7 +13,9 @@
// limitations under the License.
package com.google.devtools.build.lib.pkgcache;
+import com.google.common.base.MoreObjects;
import com.google.devtools.build.lib.cmdline.Label;
+import java.util.Objects;
/**
* This event is fired during the build, when it becomes known that the loading
@@ -29,6 +31,14 @@ public class LoadingFailureEvent {
this.failureReason = failureReason;
}
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this)
+ .add("failedTarget", failedTarget)
+ .add("failureReason", failureReason)
+ .toString();
+ }
+
public Label getFailedTarget() {
return failedTarget;
}
@@ -36,4 +46,21 @@ public class LoadingFailureEvent {
public Label getFailureReason() {
return failureReason;
}
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ } else if (!(o instanceof LoadingFailureEvent)) {
+ return false;
+ }
+ LoadingFailureEvent a = (LoadingFailureEvent) o;
+ return Objects.equals(failedTarget, a.failedTarget)
+ && Objects.equals(failureReason, a.failureReason);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(failedTarget, failureReason);
+ }
}
diff --git a/src/main/java/com/google/devtools/build/lib/query2/BUILD b/src/main/java/com/google/devtools/build/lib/query2/BUILD
index cb0dc139d8..b3ded139a2 100644
--- a/src/main/java/com/google/devtools/build/lib/query2/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/query2/BUILD
@@ -27,6 +27,7 @@ java_library(
"//src/main/java/com/google/devtools/build/lib:packages-internal",
"//src/main/java/com/google/devtools/build/lib:util",
"//src/main/java/com/google/devtools/build/lib/actions",
+ "//src/main/java/com/google/devtools/build/lib/causes",
"//src/main/java/com/google/devtools/build/lib/collect/compacthashset",
"//src/main/java/com/google/devtools/build/lib/collect/nestedset",
"//src/main/java/com/google/devtools/build/lib/concurrent",
diff --git a/src/main/java/com/google/devtools/build/lib/query2/TransitionsOutputFormatterCallback.java b/src/main/java/com/google/devtools/build/lib/query2/TransitionsOutputFormatterCallback.java
index 8da9e0f565..a84386b36a 100644
--- a/src/main/java/com/google/devtools/build/lib/query2/TransitionsOutputFormatterCallback.java
+++ b/src/main/java/com/google/devtools/build/lib/query2/TransitionsOutputFormatterCallback.java
@@ -35,6 +35,7 @@ import com.google.devtools.build.lib.analysis.config.InvalidConfigurationExcepti
import com.google.devtools.build.lib.analysis.config.transitions.ConfigurationTransition;
import com.google.devtools.build.lib.analysis.config.transitions.NoTransition;
import com.google.devtools.build.lib.analysis.configuredtargets.RuleConfiguredTarget;
+import com.google.devtools.build.lib.causes.Cause;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.events.Event;
@@ -240,7 +241,7 @@ public class TransitionsOutputFormatterCallback extends CqueryThreadsafeCallback
}
@Override
- protected Target getTarget(Target from, Label label, NestedSetBuilder<Label> rootCauses)
+ protected Target getTarget(Target from, Label label, NestedSetBuilder<Cause> rootCauses)
throws InterruptedException {
return partialResultMap.get(label);
}
diff --git a/src/main/java/com/google/devtools/build/lib/runtime/AggregatingTestListener.java b/src/main/java/com/google/devtools/build/lib/runtime/AggregatingTestListener.java
index 847ef2d457..e2a70d2afb 100644
--- a/src/main/java/com/google/devtools/build/lib/runtime/AggregatingTestListener.java
+++ b/src/main/java/com/google/devtools/build/lib/runtime/AggregatingTestListener.java
@@ -28,8 +28,8 @@ import com.google.common.eventbus.Subscribe;
import com.google.devtools.build.lib.actions.ActionOwner;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.analysis.AliasProvider;
+import com.google.devtools.build.lib.analysis.AnalysisFailureEvent;
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
-import com.google.devtools.build.lib.analysis.LegacyAnalysisFailureEvent;
import com.google.devtools.build.lib.analysis.TargetCompleteEvent;
import com.google.devtools.build.lib.analysis.test.TestProvider;
import com.google.devtools.build.lib.analysis.test.TestResult;
@@ -207,7 +207,7 @@ public class AggregatingTestListener {
}
@Subscribe
- public void analysisFailure(LegacyAnalysisFailureEvent event) {
+ public void analysisFailure(AnalysisFailureEvent event) {
targetFailure(event.getFailedTarget());
}
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/ActionExecutionFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/ActionExecutionFunction.java
index f099d7635c..64e9b29681 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/ActionExecutionFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/ActionExecutionFunction.java
@@ -703,7 +703,7 @@ public class ActionExecutionFunction implements SkyFunction, CompletionReceiver
} catch (MissingInputFileException e) {
missingCount++;
if (input.getOwner() != null) {
- rootCauses.add(new LabelCause(input.getOwner()));
+ rootCauses.add(new LabelCause(input.getOwner(), e.getMessage()));
}
} catch (ActionExecutionException e) {
actionFailures++;
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/AspectFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/AspectFunction.java
index 29ffee6abf..1e39c7693c 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/AspectFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/AspectFunction.java
@@ -38,10 +38,13 @@ import com.google.devtools.build.lib.analysis.config.ConfigMatchingProvider;
import com.google.devtools.build.lib.analysis.config.InvalidConfigurationException;
import com.google.devtools.build.lib.analysis.configuredtargets.MergedConfiguredTarget;
import com.google.devtools.build.lib.analysis.configuredtargets.MergedConfiguredTarget.DuplicateException;
+import com.google.devtools.build.lib.buildeventstream.BuildEventStreamProtos.BuildEventId.ConfigurationId;
+import com.google.devtools.build.lib.causes.AnalysisFailedCause;
+import com.google.devtools.build.lib.causes.Cause;
+import com.google.devtools.build.lib.causes.LabelCause;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
-import com.google.devtools.build.lib.collect.nestedset.Order;
import com.google.devtools.build.lib.events.Event;
import com.google.devtools.build.lib.events.StoredEventHandler;
import com.google.devtools.build.lib.packages.Aspect;
@@ -149,7 +152,8 @@ public final class AspectFunction implements SkyFunction {
throw new AspectCreationException(
String.format(
"%s from %s is not a skylark-defined aspect",
- skylarkValueName, extensionLabel.toString()));
+ skylarkValueName, extensionLabel.toString()),
+ extensionLabel);
} else {
return (SkylarkDefinedAspect) skylarkAspect;
}
@@ -202,7 +206,7 @@ public final class AspectFunction implements SkyFunction {
| ConversionException
| InconsistentFilesystemException e) {
env.getListener().handle(Event.error(e.getMessage()));
- throw new AspectCreationException(e.getMessage());
+ throw new AspectCreationException(e.getMessage(), extensionLabel);
}
}
@@ -211,7 +215,7 @@ public final class AspectFunction implements SkyFunction {
public SkyValue compute(SkyKey skyKey, Environment env)
throws AspectFunctionException, InterruptedException {
SkyframeBuildView view = buildViewProvider.getSkyframeBuildView();
- NestedSetBuilder<Label> transitiveRootCauses = NestedSetBuilder.stableOrder();
+ NestedSetBuilder<Cause> transitiveRootCauses = NestedSetBuilder.stableOrder();
AspectKey key = (AspectKey) skyKey.argument();
ConfiguredAspectFactory aspectFactory;
Aspect aspect;
@@ -274,7 +278,8 @@ public final class AspectFunction implements SkyFunction {
baseConfiguredTargetValue =
(ConfiguredTargetValue) baseAndAspectValues.get(key.getBaseConfiguredTargetKey()).get();
} catch (ConfiguredValueCreationException e) {
- throw new AspectFunctionException(new AspectCreationException(e.getRootCauses()));
+ throw new AspectFunctionException(
+ new AspectCreationException(e.getMessage(), e.getRootCauses()));
}
if (aspectHasConfiguration) {
@@ -364,7 +369,8 @@ public final class AspectFunction implements SkyFunction {
associatedConfiguredTargetAndData.getTarget().getLocation(), e.getMessage()));
throw new AspectFunctionException(
- new AspectCreationException(e.getMessage(), associatedTarget.getLabel()));
+ new AspectCreationException(
+ e.getMessage(), associatedTarget.getLabel(), aspectConfiguration));
}
}
associatedConfiguredTargetAndData =
@@ -416,7 +422,8 @@ public final class AspectFunction implements SkyFunction {
key.getAspectConfigurationKey());
} catch (ToolchainContextException e) {
// TODO(katre): better error handling
- throw new AspectCreationException(e.getMessage());
+ throw new AspectCreationException(
+ e.getMessage(), new LabelCause(key.getLabel(), e.getMessage()));
}
if (env.valuesMissing()) {
return null;
@@ -438,7 +445,7 @@ public final class AspectFunction implements SkyFunction {
transitiveRootCauses,
defaultBuildOptions);
} catch (ConfiguredTargetFunctionException e) {
- throw new AspectCreationException(e.getMessage());
+ throw new AspectCreationException(e.getMessage(), key.getLabel(), aspectConfiguration);
}
if (depValueMap == null) {
return null;
@@ -463,17 +470,18 @@ public final class AspectFunction implements SkyFunction {
} catch (DependencyEvaluationException e) {
if (e.getCause() instanceof ConfiguredValueCreationException) {
ConfiguredValueCreationException cause = (ConfiguredValueCreationException) e.getCause();
- throw new AspectFunctionException(new AspectCreationException(
- cause.getMessage(), cause.getAnalysisRootCause()));
+ throw new AspectFunctionException(
+ new AspectCreationException(cause.getMessage(), cause.getRootCauses()));
} else if (e.getCause() instanceof InconsistentAspectOrderException) {
InconsistentAspectOrderException cause = (InconsistentAspectOrderException) e.getCause();
- throw new AspectFunctionException(new AspectCreationException(
- cause.getMessage()));
+ throw new AspectFunctionException(
+ new AspectCreationException(cause.getMessage(), key.getLabel(), aspectConfiguration));
} else {
// Cast to InvalidConfigurationException as a consistency check. If you add any
// DependencyEvaluationException constructors, you may need to change this code, too.
InvalidConfigurationException cause = (InvalidConfigurationException) e.getCause();
- throw new AspectFunctionException(new AspectCreationException(cause.getMessage()));
+ throw new AspectFunctionException(
+ new AspectCreationException(cause.getMessage(), key.getLabel(), aspectConfiguration));
}
} catch (AspectCreationException e) {
throw new AspectFunctionException(e);
@@ -623,11 +631,11 @@ public final class AspectFunction implements SkyFunction {
events.replayOn(env.getListener());
if (events.hasErrors()) {
analysisEnvironment.disable(associatedTarget.getTarget());
+ String msg = "Analysis of target '"
+ + associatedTarget.getTarget().getLabel()
+ + "' failed; build aborted";
throw new AspectFunctionException(
- new AspectCreationException(
- "Analysis of target '"
- + associatedTarget.getTarget().getLabel()
- + "' failed; build aborted"));
+ new AspectCreationException(msg, key.getLabel(), aspectConfiguration));
}
Preconditions.checkState(!analysisEnvironment.hasErrors(),
"Analysis environment hasError() but no errors reported");
@@ -672,41 +680,36 @@ public final class AspectFunction implements SkyFunction {
* An exception indicating that there was a problem creating an aspect.
*/
public static final class AspectCreationException extends Exception {
- /** Targets in the transitive closure that failed to load. May be empty. */
- private final NestedSet<Label> loadingRootCauses;
-
- /**
- * The target for which analysis failed, if any. We can't represent aspects with labels, so if
- * the aspect analysis fails, this will be {@code null}.
- */
- @Nullable private final Label analysisRootCause;
-
- public AspectCreationException(String message, Label analysisRootCause) {
- super(message);
- this.loadingRootCauses = NestedSetBuilder.<Label>emptySet(Order.STABLE_ORDER);
- this.analysisRootCause = analysisRootCause;
+ private static ConfigurationId toId(BuildConfiguration config) {
+ return config == null ? null : config.getEventId().asStreamProto().getConfiguration();
}
- public AspectCreationException(String message, NestedSet<Label> loadingRootCauses) {
+ private final NestedSet<Cause> causes;
+
+ public AspectCreationException(String message, NestedSet<Cause> causes) {
super(message);
- this.loadingRootCauses = loadingRootCauses;
- this.analysisRootCause = null;
+ this.causes = causes;
}
- public AspectCreationException(NestedSet<Label> loadingRootCauses) {
- this("Loading failed", loadingRootCauses);
+ public AspectCreationException(
+ String message, Label currentTarget, @Nullable BuildConfiguration configuration) {
+ this(
+ message,
+ NestedSetBuilder.<Cause>stableOrder()
+ .add(new AnalysisFailedCause(currentTarget, toId(configuration), message))
+ .build());
}
- public AspectCreationException(String message) {
- this(message, (Label) null);
+ public AspectCreationException(String message, Label currentTarget) {
+ this(message, currentTarget, null);
}
- public NestedSet<Label> getRootCauses() {
- return loadingRootCauses;
+ public AspectCreationException(String message, Cause cause) {
+ this(message, NestedSetBuilder.<Cause>stableOrder().add(cause).build());
}
- @Nullable public Label getAnalysisRootCause() {
- return analysisRootCause;
+ public NestedSet<Cause> getCauses() {
+ return causes;
}
}
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/CompletionFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/CompletionFunction.java
index 05a4fbe1a3..83e879994f 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/CompletionFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/CompletionFunction.java
@@ -322,7 +322,7 @@ public final class CompletionFunction<TValue extends SkyValue, TResult extends S
missingCount++;
final Label inputOwner = input.getOwner();
if (inputOwner != null) {
- Cause cause = new LabelCause(inputOwner);
+ Cause cause = new LabelCause(inputOwner, e.getMessage());
rootCausesBuilder.add(cause);
env.getListener().handle(completor.getRootCauseError(value, cause, env));
}
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/ConfiguredTargetFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/ConfiguredTargetFunction.java
index 748451bbcb..a310fadf2b 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/ConfiguredTargetFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/ConfiguredTargetFunction.java
@@ -41,11 +41,16 @@ import com.google.devtools.build.lib.analysis.config.InvalidConfigurationExcepti
import com.google.devtools.build.lib.analysis.configuredtargets.MergedConfiguredTarget.DuplicateException;
import com.google.devtools.build.lib.analysis.configuredtargets.RuleConfiguredTarget;
import com.google.devtools.build.lib.buildeventstream.BuildEventId;
+import com.google.devtools.build.lib.buildeventstream.BuildEventStreamProtos.BuildEventId.ConfigurationId;
+import com.google.devtools.build.lib.causes.AnalysisFailedCause;
+import com.google.devtools.build.lib.causes.Cause;
+import com.google.devtools.build.lib.causes.LoadingFailedCause;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.collect.nestedset.Order;
import com.google.devtools.build.lib.events.Event;
+import com.google.devtools.build.lib.events.EventKind;
import com.google.devtools.build.lib.events.StoredEventHandler;
import com.google.devtools.build.lib.packages.Aspect;
import com.google.devtools.build.lib.packages.Attribute;
@@ -78,6 +83,7 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Semaphore;
+import java.util.stream.Collectors;
import javax.annotation.Nullable;
/**
@@ -161,7 +167,7 @@ public final class ConfiguredTargetFunction implements SkyFunction {
SkyframeBuildView view = buildViewProvider.getSkyframeBuildView();
NestedSetBuilder<Package> transitivePackagesForPackageRootResolution =
storeTransitivePackagesForPackageRootResolution ? NestedSetBuilder.stableOrder() : null;
- NestedSetBuilder<Label> transitiveLoadingRootCauses = NestedSetBuilder.stableOrder();
+ NestedSetBuilder<Cause> transitiveRootCauses = NestedSetBuilder.stableOrder();
ConfiguredTargetKey configuredTargetKey = (ConfiguredTargetKey) key.argument();
Label label = configuredTargetKey.getLabel();
@@ -197,7 +203,8 @@ public final class ConfiguredTargetFunction implements SkyFunction {
new ConfiguredValueCreationException(e.getMessage(), label, configuration));
}
if (pkg.containsErrors()) {
- transitiveLoadingRootCauses.add(label);
+ transitiveRootCauses.add(
+ new LoadingFailedCause(label, new NoSuchTargetException(target).getMessage()));
}
if (transitivePackagesForPackageRootResolution != null) {
transitivePackagesForPackageRootResolution.add(pkg);
@@ -241,7 +248,7 @@ public final class ConfiguredTargetFunction implements SkyFunction {
resolver,
ctgValue,
transitivePackagesForPackageRootResolution,
- transitiveLoadingRootCauses,
+ transitiveRootCauses,
((ConfiguredRuleClassProvider) ruleClassProvider).getTrimmingTransitionFactory());
if (env.valuesMissing()) {
return null;
@@ -253,9 +260,10 @@ public final class ConfiguredTargetFunction implements SkyFunction {
// more root causes during computeDependencies.
// Note that this doesn't apply to AspectFunction, because aspects can't have configurable
// attributes.
- if (!transitiveLoadingRootCauses.isEmpty() && configConditions != NO_CONFIG_CONDITIONS) {
+ if (!transitiveRootCauses.isEmpty() && configConditions != NO_CONFIG_CONDITIONS) {
throw new ConfiguredTargetFunctionException(
- new ConfiguredValueCreationException(transitiveLoadingRootCauses.build()));
+ new ConfiguredValueCreationException(
+ "Cannot compute config conditions", configuration, transitiveRootCauses.build()));
}
// Determine what toolchains are needed by this target.
@@ -288,14 +296,15 @@ public final class ConfiguredTargetFunction implements SkyFunction {
ruleClassProvider,
view.getHostConfiguration(configuration),
transitivePackagesForPackageRootResolution,
- transitiveLoadingRootCauses,
+ transitiveRootCauses,
defaultBuildOptions);
if (env.valuesMissing()) {
return null;
}
- if (!transitiveLoadingRootCauses.isEmpty()) {
+ if (!transitiveRootCauses.isEmpty()) {
throw new ConfiguredTargetFunctionException(
- new ConfiguredValueCreationException(transitiveLoadingRootCauses.build()));
+ new ConfiguredValueCreationException(
+ "Analysis failed", configuration, transitiveRootCauses.build()));
}
Preconditions.checkNotNull(depValueMap);
ConfiguredTargetValue ans =
@@ -315,21 +324,15 @@ public final class ConfiguredTargetFunction implements SkyFunction {
// Check if this is caused by an unresolved toolchain, and report it as such.
if (toolchainContext != null) {
- ImmutableSet.Builder<Label> causes = new ImmutableSet.Builder<Label>();
- if (cvce.getAnalysisRootCause() != null) {
- causes.add(cvce.getAnalysisRootCause());
- }
- if (!cvce.getRootCauses().isEmpty()) {
- causes.addAll(cvce.getRootCauses());
- }
Set<Label> toolchainDependencyErrors =
- toolchainContext.filterToolchainLabels(causes.build());
+ toolchainContext.filterToolchainLabels(
+ Iterables.transform(cvce.getRootCauses(), Cause::getLabel));
if (!toolchainDependencyErrors.isEmpty()) {
env.getListener()
.handle(
Event.error(
String.format(
- "While resolving toolchains for target %s: %s",
+ "XXX - While resolving toolchains for target %s: %s",
target.getLabel(), e.getCause().getMessage())));
}
}
@@ -352,13 +355,11 @@ public final class ConfiguredTargetFunction implements SkyFunction {
new ConfiguredValueCreationException(e.getMessage(), target.getLabel(), configuration));
}
} catch (AspectCreationException e) {
- // getAnalysisRootCause may be null if the analysis of the aspect itself failed.
- Label analysisRootCause = target.getLabel();
- if (e.getAnalysisRootCause() != null) {
- analysisRootCause = e.getAnalysisRootCause();
- }
throw new ConfiguredTargetFunctionException(
- new ConfiguredValueCreationException(e.getMessage(), analysisRootCause, configuration));
+ new ConfiguredValueCreationException(
+ e.getMessage(),
+ configuration,
+ e.getCauses()));
} catch (ToolchainContextException e) {
// We need to throw a ConfiguredValueCreationException, so either find one or make one.
ConfiguredValueCreationException cvce;
@@ -415,7 +416,7 @@ public final class ConfiguredTargetFunction implements SkyFunction {
RuleClassProvider ruleClassProvider,
BuildConfiguration hostConfiguration,
@Nullable NestedSetBuilder<Package> transitivePackagesForPackageRootResolution,
- NestedSetBuilder<Label> transitiveLoadingRootCauses,
+ NestedSetBuilder<Cause> transitiveRootCauses,
BuildOptions defaultBuildOptions)
throws DependencyEvaluationException, ConfiguredTargetFunctionException,
AspectCreationException, InterruptedException {
@@ -431,14 +432,15 @@ public final class ConfiguredTargetFunction implements SkyFunction {
toolchainContext == null
? ImmutableSet.of()
: toolchainContext.getResolvedToolchainLabels(),
- transitiveLoadingRootCauses,
+ transitiveRootCauses,
defaultBuildOptions,
((ConfiguredRuleClassProvider) ruleClassProvider).getTrimmingTransitionFactory());
} catch (EvalException e) {
// EvalException can only be thrown by computed Skylark attributes in the current rule.
env.getListener().handle(Event.error(e.getLocation(), e.getMessage()));
throw new DependencyEvaluationException(
- new ConfiguredValueCreationException(e.print(), ctgValue.getLabel()));
+ new ConfiguredValueCreationException(
+ e.print(), ctgValue.getLabel(), ctgValue.getConfiguration()));
} catch (InvalidConfigurationException e) {
throw new DependencyEvaluationException(e);
} catch (InconsistentAspectOrderException e) {
@@ -469,9 +471,10 @@ public final class ConfiguredTargetFunction implements SkyFunction {
Map<SkyKey, ConfiguredTargetAndData> depValues =
resolveConfiguredTargetDependencies(
env,
+ ctgValue,
depValueNames.values(),
transitivePackagesForPackageRootResolution,
- transitiveLoadingRootCauses);
+ transitiveRootCauses);
if (depValues == null) {
return null;
}
@@ -492,7 +495,8 @@ public final class ConfiguredTargetFunction implements SkyFunction {
Event.error(ctgValue.getTarget().getLocation(), e.getMessage()));
throw new ConfiguredTargetFunctionException(
- new ConfiguredValueCreationException(e.getMessage(), ctgValue.getLabel()));
+ new ConfiguredValueCreationException(
+ e.getMessage(), ctgValue.getLabel(), ctgValue.getConfiguration()));
}
}
@@ -510,7 +514,7 @@ public final class ConfiguredTargetFunction implements SkyFunction {
SkyframeDependencyResolver resolver,
TargetAndConfiguration ctgValue,
@Nullable NestedSetBuilder<Package> transitivePackagesForPackageRootResolution,
- NestedSetBuilder<Label> transitiveLoadingRootCauses,
+ NestedSetBuilder<Cause> transitiveRootCauses,
@Nullable RuleTransitionFactory trimmingTransitionFactory)
throws DependencyEvaluationException, InterruptedException {
if (!(target instanceof Rule)) {
@@ -538,7 +542,7 @@ public final class ConfiguredTargetFunction implements SkyFunction {
Collection<Dependency> configValueNames;
try {
configValueNames = resolver.resolveRuleLabels(
- ctgValue, configLabelMap, transitiveLoadingRootCauses, trimmingTransitionFactory);
+ ctgValue, configLabelMap, transitiveRootCauses, trimmingTransitionFactory);
} catch (InconsistentAspectOrderException e) {
throw new DependencyEvaluationException(e);
}
@@ -560,9 +564,10 @@ public final class ConfiguredTargetFunction implements SkyFunction {
Map<SkyKey, ConfiguredTargetAndData> configValues =
resolveConfiguredTargetDependencies(
env,
+ ctgValue,
configValueNames,
transitivePackagesForPackageRootResolution,
- transitiveLoadingRootCauses);
+ transitiveRootCauses);
if (configValues == null) {
return null;
}
@@ -580,8 +585,9 @@ public final class ConfiguredTargetFunction implements SkyFunction {
String message =
entry.getLabel() + " is not a valid configuration key for " + target.getLabel();
env.getListener().handle(Event.error(TargetUtils.getLocationMaybe(target), message));
- throw new DependencyEvaluationException(new ConfiguredValueCreationException(
- message, target.getLabel()));
+ throw new DependencyEvaluationException(
+ new ConfiguredValueCreationException(
+ message, ctgValue.getLabel(), ctgValue.getConfiguration()));
}
}
@@ -597,12 +603,13 @@ public final class ConfiguredTargetFunction implements SkyFunction {
@Nullable
private static Map<SkyKey, ConfiguredTargetAndData> resolveConfiguredTargetDependencies(
Environment env,
+ TargetAndConfiguration ctgValue,
Collection<Dependency> deps,
@Nullable NestedSetBuilder<Package> transitivePackagesForPackageRootResolution,
- NestedSetBuilder<Label> transitiveLoadingRootCauses)
+ NestedSetBuilder<Cause> transitiveRootCauses)
throws DependencyEvaluationException, InterruptedException {
boolean missedValues = env.valuesMissing();
- boolean failed = false;
+ String failWithMessage = null;
// Naively we would like to just fetch all requested ConfiguredTargets, together with their
// Packages. However, some ConfiguredTargets are AliasConfiguredTargets, which means that their
// associated Targets (and therefore associated Packages) don't correspond to their own Labels.
@@ -677,12 +684,8 @@ public final class ConfiguredTargetFunction implements SkyFunction {
}
}
} catch (ConfiguredValueCreationException e) {
- // TODO(ulfjack): If there is an analysis root cause, we drop all loading root causes.
- if (e.getAnalysisRootCause() != null) {
- throw new DependencyEvaluationException(e);
- }
- transitiveLoadingRootCauses.addTransitive(e.loadingRootCauses);
- failed = true;
+ transitiveRootCauses.addTransitive(e.rootCauses);
+ failWithMessage = e.getMessage();
}
}
if (aliasDepsToRedo.isEmpty()) {
@@ -693,9 +696,10 @@ public final class ConfiguredTargetFunction implements SkyFunction {
}
if (missedValues) {
return null;
- } else if (failed) {
+ } else if (failWithMessage != null) {
throw new DependencyEvaluationException(
- new ConfiguredValueCreationException(transitiveLoadingRootCauses.build()));
+ new ConfiguredValueCreationException(
+ failWithMessage, ctgValue.getConfiguration(), transitiveRootCauses.build()));
} else {
return result;
}
@@ -753,11 +757,21 @@ public final class ConfiguredTargetFunction implements SkyFunction {
events.replayOn(env.getListener());
if (events.hasErrors()) {
analysisEnvironment.disable(target);
+ NestedSet<Cause> rootCauses = NestedSetBuilder.wrap(
+ Order.STABLE_ORDER,
+ events.getEvents().stream()
+ .filter((event) -> event.getKind() == EventKind.ERROR)
+ .map((event) ->
+ new AnalysisFailedCause(
+ target.getLabel(),
+ ConfiguredValueCreationException.toId(configuration),
+ event.getMessage()))
+ .collect(Collectors.toList()));
throw new ConfiguredTargetFunctionException(
new ConfiguredValueCreationException(
"Analysis of target '" + target.getLabel() + "' failed; build aborted",
- target.getLabel(),
- configuration));
+ configuration,
+ rootCauses));
}
Preconditions.checkState(!analysisEnvironment.hasErrors(),
"Analysis environment hasError() but no errors reported");
@@ -804,51 +818,41 @@ public final class ConfiguredTargetFunction implements SkyFunction {
*/
@AutoCodec
public static final class ConfiguredValueCreationException extends Exception {
- private final NestedSet<Label> loadingRootCauses;
- // TODO(ulfjack): Collect all analysis root causes, not just the first one.
- @Nullable private final Label analysisRootCause;
- @Nullable private final BuildEventId configuration;
-
- private ConfiguredValueCreationException(
- String message, Label currentTarget, BuildConfiguration configuration) {
- this(
- message,
- Preconditions.checkNotNull(currentTarget),
- NestedSetBuilder.<Label>emptySet(Order.STABLE_ORDER),
- configuration == null ? null : configuration.getEventId());
+ private static ConfigurationId toId(BuildConfiguration config) {
+ return config == null ? null : config.getEventId().asStreamProto().getConfiguration();
}
+ @Nullable private final BuildEventId configuration;
+ private final NestedSet<Cause> rootCauses;
+
@AutoCodec.VisibleForSerialization
@AutoCodec.Instantiator
ConfiguredValueCreationException(
String message,
- Label analysisRootCause,
- NestedSet<Label> loadingRootCauses,
- BuildEventId configuration) {
+ @Nullable BuildEventId configuration,
+ NestedSet<Cause> rootCauses) {
super(message);
- this.loadingRootCauses = loadingRootCauses;
- this.analysisRootCause = analysisRootCause;
+ this.rootCauses = rootCauses;
this.configuration = configuration;
}
- private ConfiguredValueCreationException(String message, Label currentTarget) {
- this(message, currentTarget, /*configuration=*/ null);
- }
-
- private ConfiguredValueCreationException(String message, NestedSet<Label> rootCauses) {
- this(message, /*analysisRootCause=*/ null, rootCauses, /*configuration=*/ null);
- }
-
- private ConfiguredValueCreationException(NestedSet<Label> rootCauses) {
- this("Loading failed", rootCauses);
+ private ConfiguredValueCreationException(
+ String message, Label currentTarget, @Nullable BuildConfiguration configuration) {
+ this(
+ message,
+ configuration == null ? null : configuration.getEventId(),
+ NestedSetBuilder.<Cause>stableOrder()
+ .add(new AnalysisFailedCause(currentTarget, toId(configuration), message))
+ .build());
}
- public NestedSet<Label> getRootCauses() {
- return loadingRootCauses;
+ private ConfiguredValueCreationException(
+ String message, @Nullable BuildConfiguration configuration, NestedSet<Cause> rootCauses) {
+ this(message, configuration == null ? null : configuration.getEventId(), rootCauses);
}
- @Nullable public Label getAnalysisRootCause() {
- return analysisRootCause;
+ public NestedSet<Cause> getRootCauses() {
+ return rootCauses;
}
@Nullable public BuildEventId getConfiguration() {
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeBuildView.java b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeBuildView.java
index 9c36ba5daa..c4491ff6a0 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeBuildView.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeBuildView.java
@@ -34,12 +34,10 @@ import com.google.devtools.build.lib.actions.MutableActionGraph.ActionConflictEx
import com.google.devtools.build.lib.actions.PackageRoots;
import com.google.devtools.build.lib.analysis.AnalysisFailureEvent;
import com.google.devtools.build.lib.analysis.BlazeDirectories;
-import com.google.devtools.build.lib.analysis.BuildView;
import com.google.devtools.build.lib.analysis.CachingAnalysisEnvironment;
import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider;
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
import com.google.devtools.build.lib.analysis.ConfiguredTargetFactory;
-import com.google.devtools.build.lib.analysis.LegacyAnalysisFailureEvent;
import com.google.devtools.build.lib.analysis.ToolchainContext;
import com.google.devtools.build.lib.analysis.ViewCreationFailedException;
import com.google.devtools.build.lib.analysis.buildinfo.BuildInfoFactory;
@@ -51,6 +49,7 @@ import com.google.devtools.build.lib.analysis.config.FragmentClassSet;
import com.google.devtools.build.lib.buildeventstream.BuildEventId;
import com.google.devtools.build.lib.causes.Cause;
import com.google.devtools.build.lib.causes.LabelCause;
+import com.google.devtools.build.lib.causes.LoadingFailedCause;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.events.Event;
@@ -78,10 +77,10 @@ import com.google.devtools.build.skyframe.SkyFunction.Environment;
import com.google.devtools.build.skyframe.SkyKey;
import com.google.devtools.build.skyframe.SkyValue;
import java.util.Collection;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
-import java.util.logging.Logger;
import javax.annotation.Nullable;
/**
@@ -90,8 +89,6 @@ import javax.annotation.Nullable;
* <p>Covers enough functionality to work as a substitute for {@code BuildView#configureTargets}.
*/
public final class SkyframeBuildView {
- private static final Logger logger = Logger.getLogger(BuildView.class.getName());
-
private final ConfiguredTargetFactory factory;
private final ArtifactFactory artifactFactory;
private final SkyframeExecutor skyframeExecutor;
@@ -332,26 +329,34 @@ public final class SkyframeBuildView {
skyframeExecutor.getCyclesReporter().reportCycles(errorInfo.getCycleInfo(), errorKey,
eventHandler);
Exception cause = errorInfo.getException();
- Label analysisRootCause = null;
BuildEventId configuration = null;
Iterable<Cause> rootCauses;
if (cause instanceof ConfiguredValueCreationException) {
ConfiguredValueCreationException ctCause = (ConfiguredValueCreationException) cause;
- for (Label rootCause : ctCause.getRootCauses()) {
- hasLoadingError = true;
- eventBus.post(new LoadingFailureEvent(topLevelLabel, rootCause));
+ // Previously, the nested set was de-duplicating loading root cause labels. Now that we
+ // track Cause instances including a message, we get one event per label and message. In
+ // order to keep backwards compatibility, we de-duplicate root cause labels here.
+ // TODO(ulfjack): Remove this code once we've migrated to the BEP.
+ Set<Label> loadingRootCauses = new HashSet<>();
+ for (Cause rootCause : ctCause.getRootCauses()) {
+ if (rootCause instanceof LoadingFailedCause) {
+ hasLoadingError = true;
+ loadingRootCauses.add(rootCause.getLabel());
+ }
}
- analysisRootCause = ctCause.getAnalysisRootCause();
- rootCauses = analysisRootCause != null
- ? ImmutableList.of(new LabelCause(analysisRootCause))
- : ImmutableList.copyOf(Iterables.transform(ctCause.getRootCauses(), LabelCause::new));
+ for (Label loadingRootCause : loadingRootCauses) {
+ // This event is only for backwards compatibility with the old event protocol. Remove
+ // once we've migrated to the build event protocol.
+ eventBus.post(new LoadingFailureEvent(topLevelLabel, loadingRootCause));
+ }
+ rootCauses = ctCause.getRootCauses();
configuration = ctCause.getConfiguration();
} else if (!Iterables.isEmpty(errorInfo.getCycleInfo())) {
- analysisRootCause = maybeGetConfiguredTargetCycleCulprit(
+ Label analysisRootCause = maybeGetConfiguredTargetCycleCulprit(
topLevelLabel, errorInfo.getCycleInfo());
- // TODO(ulfjack): Report the dependency cycle.
rootCauses = analysisRootCause != null
- ? ImmutableList.of(new LabelCause(analysisRootCause))
+ ? ImmutableList.of(new LabelCause(analysisRootCause, "Dependency cycle"))
+ // TODO(ulfjack): We need to report the dependency cycle here. How?
: ImmutableList.of();
} else if (cause instanceof ActionConflictException) {
((ActionConflictException) cause).reportTo(eventHandler);
@@ -367,9 +372,6 @@ public final class SkyframeBuildView {
ConfiguredTargetKey configuredTargetKey =
ConfiguredTargetKey.of(
topLevelLabel, label.getConfigurationKey(), label.isHostConfiguration());
- if (analysisRootCause != null) {
- eventBus.post(new LegacyAnalysisFailureEvent(configuredTargetKey, analysisRootCause));
- }
eventBus.post(new AnalysisFailureEvent(configuredTargetKey, configuration, rootCauses));
}
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeDependencyResolver.java b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeDependencyResolver.java
index f4940066c8..4d1b86bed2 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeDependencyResolver.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeDependencyResolver.java
@@ -20,6 +20,8 @@ import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
import com.google.devtools.build.lib.analysis.config.BuildOptions;
import com.google.devtools.build.lib.analysis.config.FragmentClassSet;
import com.google.devtools.build.lib.analysis.config.InvalidConfigurationException;
+import com.google.devtools.build.lib.causes.Cause;
+import com.google.devtools.build.lib.causes.LoadingFailedCause;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.events.Event;
@@ -86,14 +88,14 @@ public final class SkyframeDependencyResolver extends DependencyResolver {
@Nullable
@Override
- protected Target getTarget(Target from, Label label, NestedSetBuilder<Label> rootCauses)
+ protected Target getTarget(Target from, Label label, NestedSetBuilder<Cause> rootCauses)
throws InterruptedException {
SkyKey key = PackageValue.key(label.getPackageIdentifier());
PackageValue packageValue;
try {
packageValue = (PackageValue) env.getValueOrThrow(key, NoSuchPackageException.class);
} catch (NoSuchPackageException e) {
- rootCauses.add(label);
+ rootCauses.add(new LoadingFailedCause(label, e.getMessage()));
missingEdgeHook(from, label, e);
return null;
}
@@ -107,7 +109,7 @@ public final class SkyframeDependencyResolver extends DependencyResolver {
NoSuchTargetException e = new NoSuchTargetException(target);
missingEdgeHook(from, label, e);
if (target != null) {
- rootCauses.add(label);
+ rootCauses.add(new LoadingFailedCause(label, e.getMessage()));
return target;
} else {
return null;
@@ -115,7 +117,7 @@ public final class SkyframeDependencyResolver extends DependencyResolver {
}
return target;
} catch (NoSuchTargetException e) {
- rootCauses.add(label);
+ rootCauses.add(new LoadingFailedCause(label, e.getMessage()));
missingEdgeHook(from, label, e);
return null;
}
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/ToplevelSkylarkAspectFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/ToplevelSkylarkAspectFunction.java
index d2ce04f08e..ee2a30c37a 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/ToplevelSkylarkAspectFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/ToplevelSkylarkAspectFunction.java
@@ -17,6 +17,7 @@ package com.google.devtools.build.lib.skyframe;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
+import com.google.devtools.build.lib.causes.LabelCause;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.events.Event;
import com.google.devtools.build.lib.packages.SkylarkAspect;
@@ -66,7 +67,7 @@ public class ToplevelSkylarkAspectFunction implements SkyFunction {
} catch (SkylarkImportFailedException e) {
env.getListener().handle(Event.error(e.getMessage()));
throw new LoadSkylarkAspectFunctionException(
- new AspectCreationException(e.getMessage()));
+ new AspectCreationException(e.getMessage(), Label.parseAbsoluteUnchecked("//:empty")));
}
if (labelLookupMap == null) {
return null;
@@ -82,8 +83,9 @@ public class ToplevelSkylarkAspectFunction implements SkyFunction {
return null;
}
if (!skylarkAspect.getParamAttributes().isEmpty()) {
- throw new AspectCreationException("Cannot instantiate parameterized aspect "
- + skylarkAspect.getName() + " at the top level.", extensionFileLabel);
+ String msg = "Cannot instantiate parameterized aspect " + skylarkAspect.getName()
+ + " at the top level.";
+ throw new AspectCreationException(msg, new LabelCause(extensionFileLabel, msg));
}
} catch (AspectCreationException e) {
throw new LoadSkylarkAspectFunctionException(e);