aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib/skyframe/ConfiguredTargetFunction.java
diff options
context:
space:
mode:
authorGravatar ulfjack <ulfjack@google.com>2018-05-29 05:17:35 -0700
committerGravatar Copybara-Service <copybara-piper@google.com>2018-05-29 05:18:35 -0700
commit904a8d63833301f54c7df85bccc56ff67156afc5 (patch)
tree3e272496bee7dee8f2d9c4690128e4f13cb323fe /src/main/java/com/google/devtools/build/lib/skyframe/ConfiguredTargetFunction.java
parentab2431e1ef62d91230fdef49b2556bbe60c9de56 (diff)
Refactor root cause reporting in ConfiguredTargetFunction
We now track Causes instead of plain Labels, which will allow us to do better reporting in the future. Add basic tests. PiperOrigin-RevId: 198380468
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/skyframe/ConfiguredTargetFunction.java')
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/ConfiguredTargetFunction.java156
1 files changed, 80 insertions, 76 deletions
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() {