use of com.google.devtools.build.lib.cmdline.PackageIdentifier in project bazel by bazelbuild.
the class SkyframeBuildView method configureTargets.
/**
* Analyzes the specified targets using Skyframe as the driving framework.
*
* @return the configured targets that should be built along with a WalkableGraph of the analysis.
*/
public SkyframeAnalysisResult configureTargets(ExtendedEventHandler eventHandler, List<ConfiguredTargetKey> values, List<AspectValueKey> aspectKeys, EventBus eventBus, boolean keepGoing, int numThreads) throws InterruptedException, ViewCreationFailedException {
enableAnalysis(true);
EvaluationResult<ActionLookupValue> result;
try {
result = skyframeExecutor.configureTargets(eventHandler, values, aspectKeys, keepGoing, numThreads);
} finally {
enableAnalysis(false);
}
ImmutableMap<ActionAnalysisMetadata, ConflictException> badActions = skyframeExecutor.findArtifactConflicts();
Collection<AspectValue> goodAspects = Lists.newArrayListWithCapacity(values.size());
NestedSetBuilder<Package> packages = NestedSetBuilder.stableOrder();
for (AspectValueKey aspectKey : aspectKeys) {
AspectValue value = (AspectValue) result.get(aspectKey.getSkyKey());
if (value == null) {
// Skip aspects that couldn't be applied to targets.
continue;
}
goodAspects.add(value);
packages.addTransitive(value.getTransitivePackages());
}
// Filter out all CTs that have a bad action and convert to a list of configured targets. This
// code ensures that the resulting list of configured targets has the same order as the incoming
// list of values, i.e., that the order is deterministic.
Collection<ConfiguredTarget> goodCts = Lists.newArrayListWithCapacity(values.size());
for (ConfiguredTargetKey value : values) {
ConfiguredTargetValue ctValue = (ConfiguredTargetValue) result.get(ConfiguredTargetValue.key(value));
if (ctValue == null) {
continue;
}
goodCts.add(ctValue.getConfiguredTarget());
packages.addTransitive(ctValue.getTransitivePackages());
}
ImmutableMap<PackageIdentifier, Path> packageRoots = LoadingPhaseRunner.collectPackageRoots(packages.build().toCollection());
if (!result.hasError() && badActions.isEmpty()) {
return new SkyframeAnalysisResult(/*hasLoadingError=*/
false, /*hasAnalysisError=*/
false, ImmutableList.copyOf(goodCts), result.getWalkableGraph(), ImmutableList.copyOf(goodAspects), packageRoots);
}
// for keeping this code in parity with legacy we just report the first error for now.
if (!keepGoing) {
for (Map.Entry<ActionAnalysisMetadata, ConflictException> bad : badActions.entrySet()) {
ConflictException ex = bad.getValue();
try {
ex.rethrowTyped();
} catch (MutableActionGraph.ActionConflictException ace) {
ace.reportTo(eventHandler);
String errorMsg = "Analysis of target '" + bad.getKey().getOwner().getLabel() + "' failed; build aborted";
throw new ViewCreationFailedException(errorMsg);
} catch (ArtifactPrefixConflictException apce) {
eventHandler.handle(Event.error(apce.getMessage()));
}
throw new ViewCreationFailedException(ex.getMessage());
}
Map.Entry<SkyKey, ErrorInfo> error = result.errorMap().entrySet().iterator().next();
SkyKey topLevel = error.getKey();
ErrorInfo errorInfo = error.getValue();
assertSaneAnalysisError(errorInfo, topLevel);
skyframeExecutor.getCyclesReporter().reportCycles(errorInfo.getCycleInfo(), topLevel, eventHandler);
Throwable cause = errorInfo.getException();
Preconditions.checkState(cause != null || !Iterables.isEmpty(errorInfo.getCycleInfo()), errorInfo);
String errorMsg = null;
if (topLevel.argument() instanceof ConfiguredTargetKey) {
errorMsg = "Analysis of target '" + ConfiguredTargetValue.extractLabel(topLevel) + "' failed; build aborted";
} else if (topLevel.argument() instanceof AspectValueKey) {
AspectValueKey aspectKey = (AspectValueKey) topLevel.argument();
errorMsg = "Analysis of aspect '" + aspectKey.getDescription() + "' failed; build aborted";
} else {
assert false;
}
if (cause instanceof ActionConflictException) {
((ActionConflictException) cause).reportTo(eventHandler);
}
throw new ViewCreationFailedException(errorMsg);
}
boolean hasLoadingError = false;
// --keep_going : We notify the error and return a ConfiguredTargetValue
for (Map.Entry<SkyKey, ErrorInfo> errorEntry : result.errorMap().entrySet()) {
// TODO(ulfjack): this is quadratic - if there are a lot of CTs, this could be rather slow.
if (!values.contains(errorEntry.getKey().argument())) {
continue;
}
SkyKey errorKey = errorEntry.getKey();
ConfiguredTargetKey label = (ConfiguredTargetKey) errorKey.argument();
Label topLevelLabel = label.getLabel();
ErrorInfo errorInfo = errorEntry.getValue();
assertSaneAnalysisError(errorInfo, errorKey);
skyframeExecutor.getCyclesReporter().reportCycles(errorInfo.getCycleInfo(), errorKey, eventHandler);
Exception cause = errorInfo.getException();
Label analysisRootCause = null;
if (cause instanceof ConfiguredValueCreationException) {
ConfiguredValueCreationException ctCause = (ConfiguredValueCreationException) cause;
for (Label rootCause : ctCause.getRootCauses()) {
hasLoadingError = true;
eventBus.post(new LoadingFailureEvent(topLevelLabel, rootCause));
}
analysisRootCause = ctCause.getAnalysisRootCause();
} else if (!Iterables.isEmpty(errorInfo.getCycleInfo())) {
analysisRootCause = maybeGetConfiguredTargetCycleCulprit(topLevelLabel, errorInfo.getCycleInfo());
} else if (cause instanceof ActionConflictException) {
((ActionConflictException) cause).reportTo(eventHandler);
}
eventHandler.handle(Event.warn("errors encountered while analyzing target '" + topLevelLabel + "': it will not be built"));
if (analysisRootCause != null) {
eventBus.post(new AnalysisFailureEvent(LabelAndConfiguration.of(topLevelLabel, label.getConfiguration()), analysisRootCause));
}
}
Collection<Exception> reportedExceptions = Sets.newHashSet();
for (Map.Entry<ActionAnalysisMetadata, ConflictException> bad : badActions.entrySet()) {
ConflictException ex = bad.getValue();
try {
ex.rethrowTyped();
} catch (MutableActionGraph.ActionConflictException ace) {
ace.reportTo(eventHandler);
eventHandler.handle(Event.warn("errors encountered while analyzing target '" + bad.getKey().getOwner().getLabel() + "': it will not be built"));
} catch (ArtifactPrefixConflictException apce) {
if (reportedExceptions.add(apce)) {
eventHandler.handle(Event.error(apce.getMessage()));
}
}
}
if (!badActions.isEmpty()) {
// In order to determine the set of configured targets transitively error free from action
// conflict issues, we run a post-processing update() that uses the bad action map.
EvaluationResult<PostConfiguredTargetValue> actionConflictResult = skyframeExecutor.postConfigureTargets(eventHandler, values, keepGoing, badActions);
goodCts = Lists.newArrayListWithCapacity(values.size());
for (ConfiguredTargetKey value : values) {
PostConfiguredTargetValue postCt = actionConflictResult.get(PostConfiguredTargetValue.key(value));
if (postCt != null) {
goodCts.add(postCt.getCt());
}
}
}
return new SkyframeAnalysisResult(hasLoadingError, result.hasError() || !badActions.isEmpty(), ImmutableList.copyOf(goodCts), result.getWalkableGraph(), ImmutableList.copyOf(goodAspects), packageRoots);
}
use of com.google.devtools.build.lib.cmdline.PackageIdentifier in project bazel by bazelbuild.
the class RecursivePackageProviderBackedTargetPatternResolver method findTargetsBeneathDirectoryAsyncImpl.
private <E extends Exception> ListenableFuture<Void> findTargetsBeneathDirectoryAsyncImpl(final RepositoryName repository, final String originalPattern, String directory, boolean rulesOnly, ImmutableSet<PathFragment> excludedSubdirectories, final ThreadSafeBatchCallback<Target, E> callback, ListeningExecutorService executor) {
final FilteringPolicy actualPolicy = rulesOnly ? FilteringPolicies.and(FilteringPolicies.RULES_ONLY, policy) : policy;
final PathFragment pathFragment;
Iterable<PathFragment> packagesUnderDirectory;
try {
pathFragment = TargetPatternResolverUtil.getPathFragment(directory);
packagesUnderDirectory = recursivePackageProvider.getPackagesUnderDirectory(eventHandler, repository, pathFragment, excludedSubdirectories);
} catch (TargetParsingException e) {
return Futures.immediateFailedFuture(e);
} catch (InterruptedException e) {
return Futures.immediateCancelledFuture();
}
Iterable<PackageIdentifier> pkgIds = Iterables.transform(packagesUnderDirectory, new Function<PathFragment, PackageIdentifier>() {
@Override
public PackageIdentifier apply(PathFragment path) {
return PackageIdentifier.create(repository, path);
}
});
final AtomicBoolean foundTarget = new AtomicBoolean(false);
// For very large sets of packages, we may not want to process all of them at once, so we split
// into batches.
List<List<PackageIdentifier>> partitions = ImmutableList.copyOf(Iterables.partition(pkgIds, MAX_PACKAGES_BULK_GET));
ArrayList<ListenableFuture<Void>> futures = new ArrayList<>(partitions.size());
for (final Iterable<PackageIdentifier> pkgIdBatch : partitions) {
futures.add(executor.submit(new Callable<Void>() {
@Override
public Void call() throws E, TargetParsingException, InterruptedException {
ImmutableSet<PackageIdentifier> pkgIdBatchSet = ImmutableSet.copyOf(pkgIdBatch);
packageSemaphore.acquireAll(pkgIdBatchSet);
try {
Iterable<ResolvedTargets<Target>> resolvedTargets = bulkGetTargetsInPackage(originalPattern, pkgIdBatch, NO_FILTER).values();
List<Target> filteredTargets = new ArrayList<>(calculateSize(resolvedTargets));
for (ResolvedTargets<Target> targets : resolvedTargets) {
for (Target target : targets.getTargets()) {
// Perform the no-targets-found check before applying the filtering policy
// so we only return the error if the input directory's subtree really
// contains no targets.
foundTarget.set(true);
if (actualPolicy.shouldRetain(target, false)) {
filteredTargets.add(target);
}
}
}
callback.process(filteredTargets);
} finally {
packageSemaphore.releaseAll(pkgIdBatchSet);
}
return null;
}
}));
}
return Futures.whenAllSucceed(futures).call(new Callable<Void>() {
@Override
public Void call() throws TargetParsingException {
if (!foundTarget.get()) {
throw new TargetParsingException("no targets found beneath '" + pathFragment + "'");
}
return null;
}
});
}
use of com.google.devtools.build.lib.cmdline.PackageIdentifier in project bazel by bazelbuild.
the class TestSuiteExpansionFunction method labelsToTargets.
static ResolvedTargets<Target> labelsToTargets(Environment env, ImmutableSet<Label> labels, boolean hasError) throws InterruptedException {
Set<PackageIdentifier> pkgIdentifiers = new LinkedHashSet<>();
for (Label label : labels) {
pkgIdentifiers.add(label.getPackageIdentifier());
}
// Don't bother to check for exceptions - the incoming list should only contain valid targets.
Map<SkyKey, SkyValue> packages = env.getValues(PackageValue.keys(pkgIdentifiers));
if (env.valuesMissing()) {
return null;
}
ResolvedTargets.Builder<Target> builder = ResolvedTargets.builder();
builder.mergeError(hasError);
Map<PackageIdentifier, Package> packageMap = new HashMap<>();
for (Entry<SkyKey, SkyValue> entry : packages.entrySet()) {
packageMap.put((PackageIdentifier) entry.getKey().argument(), ((PackageValue) entry.getValue()).getPackage());
}
for (Label label : labels) {
Package pkg = packageMap.get(label.getPackageIdentifier());
if (pkg == null) {
continue;
}
try {
builder.add(pkg.getTarget(label.getName()));
if (pkg.containsErrors()) {
builder.setError();
}
} catch (NoSuchTargetException e) {
builder.setError();
}
}
return builder.build();
}
use of com.google.devtools.build.lib.cmdline.PackageIdentifier in project bazel by bazelbuild.
the class TestsInSuiteFunction method getPrerequisites.
/**
* Adds the set of targets found in the attribute named {@code attrName}, which must be of label
* list type, of the {@code test_suite} rule named {@code testSuite}. Returns true if the method
* found a problem during the lookup process; the actual error message is reported to the
* environment.
*/
private static boolean getPrerequisites(Environment env, Rule testSuite, String attrName, List<Target> targets) throws InterruptedException {
List<Label> labels = NonconfigurableAttributeMapper.of(testSuite).get(attrName, BuildType.LABEL_LIST);
Set<PackageIdentifier> pkgIdentifiers = new LinkedHashSet<>();
for (Label label : labels) {
pkgIdentifiers.add(label.getPackageIdentifier());
}
Map<SkyKey, ValueOrException<BuildFileNotFoundException>> packages = env.getValuesOrThrow(PackageValue.keys(pkgIdentifiers), BuildFileNotFoundException.class);
if (env.valuesMissing()) {
return false;
}
boolean hasError = false;
Map<PackageIdentifier, Package> packageMap = new HashMap<>();
for (Entry<SkyKey, ValueOrException<BuildFileNotFoundException>> entry : packages.entrySet()) {
try {
packageMap.put((PackageIdentifier) entry.getKey().argument(), ((PackageValue) entry.getValue().get()).getPackage());
} catch (BuildFileNotFoundException e) {
env.getListener().handle(Event.error(e.getMessage()));
hasError = true;
}
}
for (Label label : labels) {
Package pkg = packageMap.get(label.getPackageIdentifier());
if (pkg == null) {
continue;
}
try {
targets.add(pkg.getTarget(label.getName()));
} catch (NoSuchTargetException e) {
env.getListener().handle(Event.error(e.getMessage()));
hasError = true;
}
}
return hasError;
}
use of com.google.devtools.build.lib.cmdline.PackageIdentifier in project bazel by bazelbuild.
the class SkylarkImportLookupFunction method labelsForAbsoluteImports.
/**
* Computes the set of Labels corresponding to a collection of PathFragments representing absolute
* import paths.
*
* @return a map from the computed {@link Label}s to the corresponding {@link PathFragment}s;
* {@code null} if any Skyframe dependencies are unavailable.
* @throws SkylarkImportFailedException
*/
@Nullable
static ImmutableMap<PathFragment, Label> labelsForAbsoluteImports(ImmutableSet<PathFragment> pathsToLookup, Environment env) throws SkylarkImportFailedException, InterruptedException {
// Import PathFragments are absolute, so there is a 1-1 mapping from corresponding Labels.
ImmutableMap.Builder<PathFragment, Label> outputMap = new ImmutableMap.Builder<>();
// The SkyKey here represents the directory containing an import PathFragment, hence there
// can in general be multiple imports per lookup.
Multimap<SkyKey, PathFragment> lookupMap = LinkedHashMultimap.create();
for (PathFragment importPath : pathsToLookup) {
PathFragment relativeImportPath = importPath.toRelative();
PackageIdentifier pkgToLookUp = PackageIdentifier.createInMainRepo(relativeImportPath.getParentDirectory());
lookupMap.put(ContainingPackageLookupValue.key(pkgToLookUp), importPath);
}
// Attempt to find a package for every directory containing an import.
Map<SkyKey, ValueOrException2<BuildFileNotFoundException, InconsistentFilesystemException>> lookupResults = env.getValuesOrThrow(lookupMap.keySet(), BuildFileNotFoundException.class, InconsistentFilesystemException.class);
if (env.valuesMissing()) {
return null;
}
try {
// Process lookup results.
for (Entry<SkyKey, ValueOrException2<BuildFileNotFoundException, InconsistentFilesystemException>> entry : lookupResults.entrySet()) {
ContainingPackageLookupValue lookupValue = (ContainingPackageLookupValue) entry.getValue().get();
if (!lookupValue.hasContainingPackage()) {
// Although multiple imports may be in the same package-less directory, we only
// report an error for the first one.
PackageIdentifier lookupKey = ((PackageIdentifier) entry.getKey().argument());
PathFragment importFile = lookupKey.getPackageFragment();
throw SkylarkImportFailedException.noBuildFile(importFile);
}
PackageIdentifier pkgIdForImport = lookupValue.getContainingPackageName();
PathFragment containingPkgPath = pkgIdForImport.getPackageFragment();
for (PathFragment importPath : lookupMap.get(entry.getKey())) {
PathFragment relativeImportPath = importPath.toRelative();
String targetNameForImport = relativeImportPath.relativeTo(containingPkgPath).toString();
try {
outputMap.put(importPath, Label.create(pkgIdForImport, targetNameForImport));
} catch (LabelSyntaxException e) {
// simple path.
throw new SkylarkImportFailedException(e);
}
}
}
} catch (BuildFileNotFoundException e) {
// Thrown when there are IO errors looking for BUILD files.
throw new SkylarkImportFailedException(e);
} catch (InconsistentFilesystemException e) {
throw new SkylarkImportFailedException(e);
}
return outputMap.build();
}
Aggregations