Search in sources :

Example 1 with TargetPatternKey

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);
}
Also used : TargetPatternKey(com.google.devtools.build.lib.skyframe.TargetPatternValue.TargetPatternKey) PathFragment(com.google.devtools.build.lib.vfs.PathFragment)

Example 2 with TargetPatternKey

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();
}
Also used : SkyKey(com.google.devtools.build.skyframe.SkyKey) Order(com.google.devtools.build.skyframe.NotifyingHelper.Order) TargetPatternKey(com.google.devtools.build.lib.skyframe.TargetPatternValue.TargetPatternKey) Listener(com.google.devtools.build.skyframe.NotifyingHelper.Listener) EventType(com.google.devtools.build.skyframe.NotifyingHelper.EventType) CountDownLatch(java.util.concurrent.CountDownLatch) Test(org.junit.Test)

Example 3 with TargetPatternKey

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();
}
Also used : RootedPath(com.google.devtools.build.lib.vfs.RootedPath) Path(com.google.devtools.build.lib.vfs.Path) TargetPatternKey(com.google.devtools.build.lib.skyframe.TargetPatternValue.TargetPatternKey) ImmutableList(com.google.common.collect.ImmutableList) ArrayList(java.util.ArrayList) PathFragment(com.google.devtools.build.lib.vfs.PathFragment) RootedPath(com.google.devtools.build.lib.vfs.RootedPath) TargetPattern(com.google.devtools.build.lib.cmdline.TargetPattern) PackageIdentifier(com.google.devtools.build.lib.cmdline.PackageIdentifier) RepositoryDirectoryValue(com.google.devtools.build.lib.rules.repository.RepositoryDirectoryValue)

Example 4 with TargetPatternKey

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();
}
Also used : SkyKey(com.google.devtools.build.skyframe.SkyKey) TargetPatternKey(com.google.devtools.build.lib.skyframe.TargetPatternValue.TargetPatternKey) ArrayList(java.util.ArrayList) TargetPatternSkyKeyOrException(com.google.devtools.build.lib.skyframe.TargetPatternValue.TargetPatternSkyKeyOrException) ValueOrException(com.google.devtools.build.skyframe.ValueOrException) SkyValue(com.google.devtools.build.skyframe.SkyValue) Target(com.google.devtools.build.lib.packages.Target) TargetParsingException(com.google.devtools.build.lib.cmdline.TargetParsingException) ResolvedTargets(com.google.devtools.build.lib.cmdline.ResolvedTargets)

Example 5 with TargetPatternKey

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;
}
Also used : SkyKey(com.google.devtools.build.skyframe.SkyKey) TargetPatternKey(com.google.devtools.build.lib.skyframe.TargetPatternValue.TargetPatternKey) TargetProvider(com.google.devtools.build.lib.pkgcache.TargetProvider) ArrayList(java.util.ArrayList) TargetPatternSkyKeyOrException(com.google.devtools.build.lib.skyframe.TargetPatternValue.TargetPatternSkyKeyOrException) ValueOrException(com.google.devtools.build.skyframe.ValueOrException) CompileOneDependencyTransformer(com.google.devtools.build.lib.pkgcache.CompileOneDependencyTransformer) Target(com.google.devtools.build.lib.packages.Target) TargetParsingException(com.google.devtools.build.lib.cmdline.TargetParsingException) ResolvedTargets(com.google.devtools.build.lib.cmdline.ResolvedTargets) MissingDepException(com.google.devtools.build.lib.skyframe.EnvironmentBackedRecursivePackageProvider.MissingDepException)

Aggregations

TargetPatternKey (com.google.devtools.build.lib.skyframe.TargetPatternValue.TargetPatternKey)8 SkyKey (com.google.devtools.build.skyframe.SkyKey)5 TargetParsingException (com.google.devtools.build.lib.cmdline.TargetParsingException)4 TargetPatternSkyKeyOrException (com.google.devtools.build.lib.skyframe.TargetPatternValue.TargetPatternSkyKeyOrException)4 PathFragment (com.google.devtools.build.lib.vfs.PathFragment)3 ArrayList (java.util.ArrayList)3 ImmutableList (com.google.common.collect.ImmutableList)2 ResolvedTargets (com.google.devtools.build.lib.cmdline.ResolvedTargets)2 TargetPattern (com.google.devtools.build.lib.cmdline.TargetPattern)2 Target (com.google.devtools.build.lib.packages.Target)2 ValueOrException (com.google.devtools.build.skyframe.ValueOrException)2 ImmutableSet (com.google.common.collect.ImmutableSet)1 PackageIdentifier (com.google.devtools.build.lib.cmdline.PackageIdentifier)1 ThreadSafe (com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadSafe)1 CompileOneDependencyTransformer (com.google.devtools.build.lib.pkgcache.CompileOneDependencyTransformer)1 TargetProvider (com.google.devtools.build.lib.pkgcache.TargetProvider)1 RepositoryDirectoryValue (com.google.devtools.build.lib.rules.repository.RepositoryDirectoryValue)1 MissingDepException (com.google.devtools.build.lib.skyframe.EnvironmentBackedRecursivePackageProvider.MissingDepException)1 Path (com.google.devtools.build.lib.vfs.Path)1 RootedPath (com.google.devtools.build.lib.vfs.RootedPath)1