use of com.google.devtools.build.lib.cmdline.ResolvedTargets 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.ResolvedTargets in project bazel by bazelbuild.
the class TargetPatternPhaseFunction method compute.
@Override
public TargetPatternPhaseValue compute(SkyKey key, Environment env) throws InterruptedException {
TargetPatternList options = (TargetPatternList) key.argument();
PackageValue packageValue = null;
boolean workspaceError = false;
try {
packageValue = (PackageValue) env.getValueOrThrow(PackageValue.key(Label.EXTERNAL_PACKAGE_IDENTIFIER), NoSuchPackageException.class);
} catch (NoSuchPackageException e) {
env.getListener().handle(Event.error(e.getMessage()));
workspaceError = true;
}
if (env.valuesMissing()) {
return null;
}
String workspaceName = "";
if (!workspaceError) {
workspaceName = packageValue.getPackage().getWorkspaceName();
}
// Determine targets to build:
ResolvedTargets<Target> targets = getTargetsToBuild(env, options);
// If the --build_tests_only option was specified or we want to run tests, we need to determine
// the list of targets to test. For that, we remove manual tests and apply the command-line
// filters. Also, if --build_tests_only is specified, then the list of filtered targets will be
// set as build list as well.
ResolvedTargets<Target> testTargets = null;
if (options.getDetermineTests() || options.getBuildTestsOnly()) {
testTargets = determineTests(env, options.getTargetPatterns(), options.getOffset(), options.getTestFilter());
Preconditions.checkState(env.valuesMissing() || (testTargets != null));
}
Map<Label, SkyKey> testExpansionKeys = new LinkedHashMap<>();
if (targets != null) {
for (Target target : targets.getTargets()) {
if (TargetUtils.isTestSuiteRule(target)) {
Label label = target.getLabel();
SkyKey testExpansionKey = TestSuiteExpansionValue.key(ImmutableSet.of(label));
testExpansionKeys.put(label, testExpansionKey);
}
}
}
Map<SkyKey, SkyValue> expandedTests = env.getValues(testExpansionKeys.values());
if (env.valuesMissing()) {
return null;
}
ImmutableSet<Target> filteredTargets = targets.getFilteredTargets();
ImmutableSet<Target> testsToRun = null;
ImmutableSet<Target> testFilteredTargets = ImmutableSet.of();
if (testTargets != null) {
// Parse the targets to get the tests.
if (testTargets.getTargets().isEmpty() && !testTargets.getFilteredTargets().isEmpty()) {
env.getListener().handle(Event.warn("All specified test targets were excluded by filters"));
}
if (options.getBuildTestsOnly()) {
// Replace original targets to build with test targets, so that only targets that are
// actually going to be built are loaded in the loading phase. Note that this has a side
// effect that any test_suite target requested to be built is replaced by the set of *_test
// targets it represents; for example, this affects the status and the summary reports.
Set<Target> allFilteredTargets = new HashSet<>();
allFilteredTargets.addAll(targets.getTargets());
allFilteredTargets.addAll(targets.getFilteredTargets());
allFilteredTargets.removeAll(testTargets.getTargets());
allFilteredTargets.addAll(testTargets.getFilteredTargets());
testFilteredTargets = ImmutableSet.copyOf(allFilteredTargets);
filteredTargets = ImmutableSet.of();
targets = ResolvedTargets.<Target>builder().merge(testTargets).mergeError(targets.hasError()).build();
if (options.getDetermineTests()) {
testsToRun = testTargets.getTargets();
}
} else /*if (determineTests)*/
{
testsToRun = testTargets.getTargets();
targets = ResolvedTargets.<Target>builder().merge(targets).addAll(testsToRun).mergeError(testTargets.hasError()).build();
// filteredTargets is correct in this case - it cannot contain tests that got back in
// through test_suite expansion, because the test determination would also filter those out.
// However, that's not obvious, and it might be better to explicitly recompute it.
}
if (testsToRun != null) {
// Note that testsToRun can still be null here, if buildTestsOnly && !shouldRunTests.
if (!targets.getTargets().containsAll(testsToRun)) {
throw new IllegalStateException(String.format("Internal consistency check failed; some targets are scheduled for test execution " + "but not for building (%s)", Sets.difference(testsToRun, targets.getTargets())));
}
}
}
if (targets.hasError()) {
env.getListener().handle(Event.warn("Target pattern parsing failed."));
}
LoadingPhaseRunner.maybeReportDeprecation(env.getListener(), targets.getTargets());
boolean preExpansionError = targets.hasError();
ResolvedTargets.Builder<Target> expandedTargetsBuilder = ResolvedTargets.builder();
for (Target target : targets.getTargets()) {
if (TargetUtils.isTestSuiteRule(target)) {
SkyKey expansionKey = Preconditions.checkNotNull(testExpansionKeys.get(target.getLabel()));
TestSuiteExpansionValue testExpansion = (TestSuiteExpansionValue) expandedTests.get(expansionKey);
expandedTargetsBuilder.merge(testExpansion.getTargets());
} else {
expandedTargetsBuilder.add(target);
}
}
ResolvedTargets<Target> expandedTargets = expandedTargetsBuilder.build();
Set<Target> testSuiteTargets = Sets.difference(targets.getTargets(), expandedTargets.getTargets());
return new TargetPatternPhaseValue(expandedTargets.getTargets(), testsToRun, preExpansionError, expandedTargets.hasError() || workspaceError, filteredTargets, testFilteredTargets, targets.getTargets(), ImmutableSet.copyOf(testSuiteTargets), workspaceName);
}
use of com.google.devtools.build.lib.cmdline.ResolvedTargets in project bazel by bazelbuild.
the class TargetPatternsResultBuilder method transformLabelsIntoTargets.
/**
* Transforms {@code ResolvedTargets<Label>} to {@code ResolvedTargets<Target>}. Note that this
* method is using information about packages, so {@link #precomputePackages} has to be called
* before this method.
*/
protected ResolvedTargets.Builder<Target> transformLabelsIntoTargets(ResolvedTargets<Label> resolvedLabels) {
// precomputePackages has to be called before this method.
ResolvedTargets.Builder<Target> resolvedTargetsBuilder = ResolvedTargets.builder();
Preconditions.checkNotNull(packages);
for (Label label : resolvedLabels.getTargets()) {
resolvedTargetsBuilder.add(getExistingTarget(label));
}
for (Label label : resolvedLabels.getFilteredTargets()) {
resolvedTargetsBuilder.remove(getExistingTarget(label));
}
return resolvedTargetsBuilder;
}
use of com.google.devtools.build.lib.cmdline.ResolvedTargets 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.ResolvedTargets in project bazel by bazelbuild.
the class TestsInSuiteFunction method computeTestsInSuite.
/**
* Populates 'result' with all the tests associated with the specified 'testSuite'. Throws an
* exception if any target is missing.
*
* <p>CAUTION! Keep this logic consistent with {@code TestSuite}!
*/
private static ResolvedTargets<Target> computeTestsInSuite(Environment env, Rule testSuite, boolean strict) throws InterruptedException {
ResolvedTargets.Builder<Target> builder = ResolvedTargets.builder();
List<Target> testsAndSuites = new ArrayList<>();
// Note that testsAndSuites can contain input file targets; the test_suite rule does not
// restrict the set of targets that can appear in tests or suites.
builder.mergeError(getPrerequisites(env, testSuite, "tests", testsAndSuites));
// 1. Add all tests
for (Target test : testsAndSuites) {
if (TargetUtils.isTestRule(test)) {
builder.add(test);
} else if (strict && !TargetUtils.isTestSuiteRule(test)) {
// If strict mode is enabled, then give an error for any non-test, non-test-suite targets.
// TODO(ulfjack): We need to throw to end the process if we happen to be in --nokeep_going,
// but we can't know whether or not we are at this point.
env.getListener().handle(Event.error(testSuite.getLocation(), "in test_suite rule '" + testSuite.getLabel() + "': expecting a test or a test_suite rule but '" + test.getLabel() + "' is not one."));
builder.setError();
}
}
// 2. Add implicit dependencies on tests in same package, if any.
List<Target> implicitTests = new ArrayList<>();
builder.mergeError(getPrerequisites(env, testSuite, "$implicit_tests", implicitTests));
for (Target target : implicitTests) {
// add it here anyway for compatibility with future code.
if (TargetUtils.isTestRule(target)) {
builder.add(target);
}
}
// 3. Filter based on tags, size, env.
filterTests(testSuite, builder);
// 4. Expand all suites recursively.
for (Target suite : testsAndSuites) {
if (TargetUtils.isTestSuiteRule(suite)) {
TestsInSuiteValue value = (TestsInSuiteValue) env.getValue(TestsInSuiteValue.key(suite, strict));
if (value == null) {
continue;
}
builder.merge(value.getTargets());
}
}
return builder.build();
}
Aggregations