use of com.google.devtools.build.lib.causes.LabelCause in project bazel by bazelbuild.
the class ActionExecutionFunction method checkInputs.
/**
* Declare dependency on all known inputs of action. Throws exception if any are known to be
* missing. Some inputs may not yet be in the graph, in which case the builder should abort.
*/
private Pair<Map<Artifact, FileArtifactValue>, Map<Artifact, Collection<Artifact>>> checkInputs(Environment env, Action action, Map<SkyKey, ValueOrException2<MissingInputFileException, ActionExecutionException>> inputDeps) throws ActionExecutionException {
int missingCount = 0;
int actionFailures = 0;
boolean catastrophe = false;
// Only populate input data if we have the input values, otherwise they'll just go unused.
// We still want to loop through the inputs to collect missing deps errors. During the
// evaluator "error bubbling", we may get one last chance at reporting errors even though
// some deps are still missing.
boolean populateInputData = !env.valuesMissing();
NestedSetBuilder<Cause> rootCauses = NestedSetBuilder.stableOrder();
Map<Artifact, FileArtifactValue> inputArtifactData = new HashMap<>(populateInputData ? inputDeps.size() : 0);
Map<Artifact, Collection<Artifact>> expandedArtifacts = new HashMap<>(populateInputData ? 128 : 0);
ActionExecutionException firstActionExecutionException = null;
for (Map.Entry<SkyKey, ValueOrException2<MissingInputFileException, ActionExecutionException>> depsEntry : inputDeps.entrySet()) {
Artifact input = ArtifactSkyKey.artifact(depsEntry.getKey());
try {
SkyValue value = depsEntry.getValue().get();
if (populateInputData) {
if (value instanceof AggregatingArtifactValue) {
AggregatingArtifactValue aggregatingValue = (AggregatingArtifactValue) value;
for (Pair<Artifact, FileArtifactValue> entry : aggregatingValue.getInputs()) {
inputArtifactData.put(entry.first, entry.second);
}
// We have to cache the "digest" of the aggregating value itself,
// because the action cache checker may want it.
inputArtifactData.put(input, aggregatingValue.getSelfData());
ImmutableList.Builder<Artifact> expansionBuilder = ImmutableList.builder();
for (Pair<Artifact, FileArtifactValue> pair : aggregatingValue.getInputs()) {
expansionBuilder.add(pair.first);
}
expandedArtifacts.put(input, expansionBuilder.build());
} else if (value instanceof TreeArtifactValue) {
TreeArtifactValue treeValue = (TreeArtifactValue) value;
expandedArtifacts.put(input, ImmutableSet.<Artifact>copyOf(treeValue.getChildren()));
inputArtifactData.putAll(treeValue.getChildValues());
// Again, we cache the "digest" of the value for cache checking.
inputArtifactData.put(input, treeValue.getSelfData());
} else {
Preconditions.checkState(value instanceof FileArtifactValue, depsEntry);
inputArtifactData.put(input, (FileArtifactValue) value);
}
}
} catch (MissingInputFileException e) {
missingCount++;
if (input.getOwner() != null) {
rootCauses.add(new LabelCause(input.getOwner()));
}
} catch (ActionExecutionException e) {
actionFailures++;
if (firstActionExecutionException == null) {
firstActionExecutionException = e;
}
catastrophe = catastrophe || e.isCatastrophe();
rootCauses.addTransitive(e.getRootCauses());
}
}
// We need to rethrow first exception because it can contain useful error message
if (firstActionExecutionException != null) {
if (missingCount == 0 && actionFailures == 1) {
// having to copy the root causes to the upwards transitive closure.
throw firstActionExecutionException;
}
throw new ActionExecutionException(firstActionExecutionException.getMessage(), firstActionExecutionException.getCause(), action, rootCauses.build(), catastrophe, firstActionExecutionException.getExitCode());
}
if (missingCount > 0) {
for (Cause missingInput : rootCauses.build()) {
env.getListener().handle(Event.error(action.getOwner().getLocation(), String.format("%s: missing input file '%s'", action.getOwner().getLabel(), missingInput.getLabel())));
}
throw new ActionExecutionException(missingCount + " input file(s) do not exist", action, rootCauses.build(), /*catastrophe=*/
false);
}
return Pair.of(inputArtifactData, expandedArtifacts);
}
use of com.google.devtools.build.lib.causes.LabelCause in project bazel by bazelbuild.
the class CompletionFunction method compute.
@Nullable
@Override
public SkyValue compute(SkyKey skyKey, Environment env) throws CompletionFunctionException, InterruptedException {
TValue value = completor.getValueFromSkyKey(skyKey, env);
TopLevelArtifactContext topLevelContext = completor.getTopLevelArtifactContext(skyKey);
if (env.valuesMissing()) {
return null;
}
Map<SkyKey, ValueOrException2<MissingInputFileException, ActionExecutionException>> inputDeps = env.getValuesOrThrow(ArtifactSkyKey.mandatoryKeys(completor.getAllArtifactsToBuild(value, topLevelContext).getAllArtifacts()), MissingInputFileException.class, ActionExecutionException.class);
int missingCount = 0;
ActionExecutionException firstActionExecutionException = null;
MissingInputFileException missingInputException = null;
NestedSetBuilder<Cause> rootCausesBuilder = NestedSetBuilder.stableOrder();
for (Map.Entry<SkyKey, ValueOrException2<MissingInputFileException, ActionExecutionException>> depsEntry : inputDeps.entrySet()) {
Artifact input = ArtifactSkyKey.artifact(depsEntry.getKey());
try {
depsEntry.getValue().get();
} catch (MissingInputFileException e) {
missingCount++;
final Label inputOwner = input.getOwner();
if (inputOwner != null) {
Cause cause = new LabelCause(inputOwner);
rootCausesBuilder.add(cause);
env.getListener().handle(completor.getRootCauseError(value, cause));
}
} catch (ActionExecutionException e) {
rootCausesBuilder.addTransitive(e.getRootCauses());
if (firstActionExecutionException == null) {
firstActionExecutionException = e;
}
}
}
if (missingCount > 0) {
missingInputException = completor.getMissingFilesException(value, missingCount);
}
NestedSet<Cause> rootCauses = rootCausesBuilder.build();
if (!rootCauses.isEmpty()) {
eventBusRef.get().post(completor.createFailed(value, rootCauses));
if (firstActionExecutionException != null) {
throw new CompletionFunctionException(firstActionExecutionException);
} else {
throw new CompletionFunctionException(missingInputException);
}
}
return env.valuesMissing() ? null : completor.createResult(value);
}
Aggregations