use of com.google.devtools.build.lib.skyframe.TargetPatternValue.TargetPatternKey in project bazel by bazelbuild.
the class SkyQueryEnvironment method getPatternAndExcludes.
private Pair<TargetPattern, ImmutableSet<PathFragment>> getPatternAndExcludes(String pattern) throws TargetParsingException, InterruptedException {
TargetPatternKey targetPatternKey = ((TargetPatternKey) TargetPatternValue.key(pattern, TargetPatternEvaluator.DEFAULT_FILTERING_POLICY, parserPrefix).argument());
ImmutableSet<PathFragment> subdirectoriesToExclude = targetPatternKey.getAllSubdirectoriesToExclude(blacklistPatternsSupplier);
return Pair.of(targetPatternKey.getParsedPattern(), subdirectoriesToExclude);
}
use of com.google.devtools.build.lib.skyframe.TargetPatternValue.TargetPatternKey in project bazel by bazelbuild.
the class BuildViewTest method testGenQueryWithBadTargetAndUnfinishedTarget.
/**
* Regression test for bug when a configured target has missing deps, but also depends
* transitively on an error. We build //foo:query, which depends on a valid and an invalid target
* pattern. We ensure that by the time it requests its dependent target patterns, the invalid one
* is ready, and throws (though not before the request is registered). Then, when bubbling the
* invalid target pattern error up, we ensure that it bubbles into //foo:query, which must cope
* with the combination of an error and a missing dep.
*/
@Test
public void testGenQueryWithBadTargetAndUnfinishedTarget() throws Exception {
// The target //foo:zquery is used to force evaluation of //foo:nosuchtarget before the target
// patterns in //foo:query are enqueued for evaluation. That way, //foo:query will depend on one
// invalid target pattern and two target patterns that haven't been evaluated yet.
// It is important that 'query' come before 'zquery' alphabetically, so that when the error is
// bubbling up, it goes to the //foo:query node -- we use a graph implementation in which the
// reverse deps of each entry are ordered alphabetically. It is also important that a missing
// target pattern is requested before the exception is thrown, so we have both //foo:b and
// //foo:z missing from the deps, in the hopes that at least one of them will come before
// //foo:nosuchtarget.
scratch.file("foo/BUILD", "genquery(name = 'query',", " expression = 'deps(//foo:b) except //foo:nosuchtarget except //foo:z',", " scope = ['//foo:a'])", "genquery(name = 'zquery',", " expression = 'deps(//foo:nosuchtarget)',", " scope = ['//foo:a'])", "sh_library(name = 'a')", "sh_library(name = 'b')", "sh_library(name = 'z')");
Listener listener = new Listener() {
private final CountDownLatch errorDone = new CountDownLatch(1);
private final CountDownLatch realQueryStarted = new CountDownLatch(1);
@Override
public void accept(SkyKey key, EventType type, Order order, Object context) {
if (!key.functionName().equals(SkyFunctions.TARGET_PATTERN)) {
return;
}
String label = ((TargetPatternKey) key.argument()).getPattern();
if (label.equals("//foo:nosuchtarget")) {
if (type == EventType.SET_VALUE) {
// Inform //foo:query-dep-registering thread that it may proceed.
errorDone.countDown();
// Wait to make sure //foo:query-dep-registering process has started.
TrackingAwaiter.INSTANCE.awaitLatchAndTrackExceptions(realQueryStarted, "//foo:query did not request dep in time");
} else if (type == EventType.ADD_REVERSE_DEP && context.toString().contains("foo:query")) {
// Make sure that when foo:query requests foo:nosuchtarget, it's already done.
TrackingAwaiter.INSTANCE.awaitLatchAndTrackExceptions(errorDone, "//foo:nosuchtarget did not evaluate in time");
}
} else if ((label.equals("//foo:b") || label.equals("//foo:z")) && type == EventType.CREATE_IF_ABSENT) {
// Inform error-evaluating thread that it may throw an exception.
realQueryStarted.countDown();
TrackingAwaiter.INSTANCE.awaitLatchAndTrackExceptions(errorDone, "//foo:nosuchtarget did not evaluate in time");
// Don't let the target pattern //foo:{b,z} get enqueued for evaluation until we
// receive an interrupt signal from the threadpool. The interrupt means that
// evaluation is shutting down, and so //foo:{b,z} definitely won't get evaluated.
CountDownLatch waitForInterrupt = new CountDownLatch(1);
try {
waitForInterrupt.await(TestUtils.WAIT_TIMEOUT_SECONDS, TimeUnit.SECONDS);
throw new IllegalStateException("node was not interrupted in time");
} catch (InterruptedException e) {
// Expected.
Thread.currentThread().interrupt();
}
}
}
};
injectGraphListenerForTesting(listener, /*deterministic=*/
true);
reporter.removeHandler(failFastHandler);
try {
update("//foo:query", "//foo:zquery");
fail();
} catch (ViewCreationFailedException e) {
Truth.assertThat(e.getMessage()).contains("Analysis of target '//foo:query' failed; build aborted");
}
TrackingAwaiter.INSTANCE.assertNoErrors();
}
use of com.google.devtools.build.lib.skyframe.TargetPatternValue.TargetPatternKey in project bazel by bazelbuild.
the class GraphBackedRecursivePackageProvider method getPackagesUnderDirectory.
@Override
public Iterable<PathFragment> getPackagesUnderDirectory(ExtendedEventHandler eventHandler, RepositoryName repository, PathFragment directory, ImmutableSet<PathFragment> excludedSubdirectories) throws InterruptedException {
PathFragment.checkAllPathsAreUnder(excludedSubdirectories, directory);
// Check that this package is covered by at least one of our universe patterns.
boolean inUniverse = false;
for (TargetPatternKey patternKey : universeTargetPatternKeys) {
TargetPattern pattern = patternKey.getParsedPattern();
boolean isTBD = pattern.getType().equals(Type.TARGETS_BELOW_DIRECTORY);
PackageIdentifier packageIdentifier = PackageIdentifier.create(repository, directory);
if (isTBD && pattern.containsAllTransitiveSubdirectoriesForTBD(packageIdentifier)) {
inUniverse = true;
break;
}
}
if (!inUniverse) {
return ImmutableList.of();
}
List<Path> roots = new ArrayList<>();
if (repository.isMain()) {
roots.addAll(pkgPath.getPathEntries());
} else {
RepositoryDirectoryValue repositoryValue = (RepositoryDirectoryValue) graph.getValue(RepositoryDirectoryValue.key(repository));
if (repositoryValue == null) {
// "nothing".
return ImmutableList.of();
}
roots.add(repositoryValue.getPath());
}
// If we found a TargetsBelowDirectory pattern in the universe that contains this directory,
// then we can look for packages in and under it in the graph. If we didn't find one, then the
// directory wasn't in the universe, so return an empty list.
ImmutableList.Builder<PathFragment> builder = ImmutableList.builder();
for (Path root : roots) {
RootedPath rootedDir = RootedPath.toRootedPath(root, directory);
TraversalInfo info = new TraversalInfo(rootedDir, excludedSubdirectories);
collectPackagesUnder(eventHandler, repository, ImmutableSet.of(info), builder);
}
return builder.build();
}
use of com.google.devtools.build.lib.skyframe.TargetPatternValue.TargetPatternKey in project bazel by bazelbuild.
the class TargetPatternPhaseFunction method determineTests.
/**
* Interpret test target labels from the command-line arguments and return the corresponding set
* of targets, handling the filter flags, and expanding test suites.
*
* @param targetPatterns the list of command-line target patterns specified by the user
* @param testFilter the test filter
*/
private static ResolvedTargets<Target> determineTests(Environment env, List<String> targetPatterns, String offset, TestFilter testFilter) throws InterruptedException {
List<SkyKey> patternSkyKeys = new ArrayList<>();
for (TargetPatternSkyKeyOrException keyOrException : TargetPatternValue.keys(targetPatterns, FilteringPolicies.FILTER_TESTS, offset)) {
try {
patternSkyKeys.add(keyOrException.getSkyKey());
} catch (TargetParsingException e) {
// Skip.
}
}
Map<SkyKey, ValueOrException<TargetParsingException>> resolvedPatterns = env.getValuesOrThrow(patternSkyKeys, TargetParsingException.class);
if (env.valuesMissing()) {
return null;
}
List<SkyKey> expandedSuiteKeys = new ArrayList<>();
for (SkyKey key : patternSkyKeys) {
TargetPatternValue value;
try {
value = (TargetPatternValue) resolvedPatterns.get(key).get();
} catch (TargetParsingException e) {
// Skip.
continue;
}
expandedSuiteKeys.add(TestSuiteExpansionValue.key(value.getTargets().getTargets()));
}
Map<SkyKey, SkyValue> expandedSuites = env.getValues(expandedSuiteKeys);
if (env.valuesMissing()) {
return null;
}
ResolvedTargets.Builder<Target> testTargetsBuilder = ResolvedTargets.builder();
for (SkyKey key : patternSkyKeys) {
TargetPatternKey pattern = (TargetPatternKey) key.argument();
TargetPatternValue value;
try {
value = (TargetPatternValue) resolvedPatterns.get(key).get();
} catch (TargetParsingException e) {
// This was already reported in getTargetsToBuild (maybe merge the two code paths?).
continue;
}
TestSuiteExpansionValue expandedSuitesValue = (TestSuiteExpansionValue) expandedSuites.get(TestSuiteExpansionValue.key(value.getTargets().getTargets()));
if (pattern.isNegative()) {
ResolvedTargets<Target> negativeTargets = expandedSuitesValue.getTargets();
testTargetsBuilder.filter(Predicates.not(Predicates.in(negativeTargets.getTargets())));
testTargetsBuilder.mergeError(negativeTargets.hasError());
} else {
ResolvedTargets<Target> positiveTargets = expandedSuitesValue.getTargets();
testTargetsBuilder.addAll(positiveTargets.getTargets());
testTargetsBuilder.mergeError(positiveTargets.hasError());
}
}
testTargetsBuilder.filter(testFilter);
return testTargetsBuilder.build();
}
use of com.google.devtools.build.lib.skyframe.TargetPatternValue.TargetPatternKey in project bazel by bazelbuild.
the class TargetPatternPhaseFunction method getTargetsToBuild.
/**
* Interpret the command-line arguments.
*
* @param options the command-line arguments in structured form
*/
private static ResolvedTargets<Target> getTargetsToBuild(Environment env, TargetPatternList options) throws InterruptedException {
List<SkyKey> patternSkyKeys = new ArrayList<>();
for (TargetPatternSkyKeyOrException keyOrException : TargetPatternValue.keys(options.getTargetPatterns(), FilteringPolicies.FILTER_MANUAL, options.getOffset())) {
try {
patternSkyKeys.add(keyOrException.getSkyKey());
} catch (TargetParsingException e) {
// Skip.
}
}
Map<SkyKey, ValueOrException<TargetParsingException>> resolvedPatterns = env.getValuesOrThrow(patternSkyKeys, TargetParsingException.class);
if (env.valuesMissing()) {
return null;
}
ResolvedTargets.Builder<Target> builder = ResolvedTargets.builder();
for (SkyKey key : patternSkyKeys) {
TargetPatternKey pattern = (TargetPatternKey) key.argument();
TargetPatternValue value;
try {
value = (TargetPatternValue) resolvedPatterns.get(key).get();
} catch (TargetParsingException e) {
// TODO(ulfjack): Report to EventBus.
String rawPattern = pattern.getPattern();
String errorMessage = e.getMessage();
env.getListener().handle(Event.error("Skipping '" + rawPattern + "': " + errorMessage));
builder.setError();
continue;
}
// TODO(ulfjack): This is terribly inefficient.
ResolvedTargets<Target> asTargets = TestSuiteExpansionFunction.labelsToTargets(env, value.getTargets().getTargets(), value.getTargets().hasError());
if (pattern.isNegative()) {
builder.filter(Predicates.not(Predicates.in(asTargets.getTargets())));
} else {
builder.merge(asTargets);
}
}
ResolvedTargets<Target> result = builder.filter(TargetUtils.tagFilter(options.getBuildTargetFilter())).build();
if (options.getCompileOneDependency()) {
TargetProvider targetProvider = new EnvironmentBackedRecursivePackageProvider(env);
try {
return new CompileOneDependencyTransformer(targetProvider).transformCompileOneDependency(env.getListener(), result);
} catch (MissingDepException e) {
return null;
} catch (TargetParsingException e) {
env.getListener().handle(Event.error(e.getMessage()));
return ResolvedTargets.failed();
}
}
return result;
}
Aggregations