use of com.google.devtools.build.lib.cmdline.TargetParsingException in project bazel by bazelbuild.
the class TargetPatternEvaluatorTest method testBrokenSymlinkRepaired.
@Test
public void testBrokenSymlinkRepaired() throws Exception {
reporter.removeHandler(failFastHandler);
Path tuv = scratch.dir("t/u/v");
tuv.getChild("BUILD").createSymbolicLink(new PathFragment("../../BUILD"));
try {
parseList("//t/...");
fail("TargetParsingException expected");
} catch (TargetParsingException e) {
// expected
}
scratch.file("t/BUILD", "sh_library(name='t')");
ModifiedFileSet modifiedFileSet = ModifiedFileSet.builder().modify(new PathFragment("t/BUILD")).build();
invalidate(modifiedFileSet);
reporter.addHandler(failFastHandler);
Set<Label> result = parseList("//t/...");
assertThat(result).containsExactly(Label.parseAbsolute("//t:t"), Label.parseAbsolute("//t/u/v:t"));
}
use of com.google.devtools.build.lib.cmdline.TargetParsingException in project bazel by bazelbuild.
the class CoverageCommand method setDefaultInstrumentationFilter.
/**
* Method implements a heuristic used to set default value of the
* --instrumentation_filter option. Following algorithm is used:
* 1) Identify all test targets on the command line.
* 2) Expand all test suites into the individual test targets
* 3) Calculate list of package names containing all test targets above.
* 4) Replace all "javatests/" substrings in package names with "java/".
* 5) If two packages reside in the same directory, use filter based on
* the parent directory name instead. Doing so significantly simplifies
* instrumentation filter in majority of real-life scenarios (in
* particular when dealing with my/package/... wildcards).
* 6) Set --instrumentation_filter default value to instrument everything
* in those packages.
*/
private void setDefaultInstrumentationFilter(CommandEnvironment env, OptionsParser optionsProvider) throws OptionsParsingException, AbruptExitException {
try {
BlazeRuntime runtime = env.getRuntime();
// Initialize package cache, since it is used by the TargetPatternEvaluator.
// TODO(bazel-team): Don't allow commands to setup the package cache more than once per build.
// We'll have to move it earlier in the process to allow this. Possibly: Move it to
// the command dispatcher and allow commands to annotate "need-packages".
env.setupPackageCache(optionsProvider, runtime.getDefaultsPackageContent(optionsProvider));
// Collect all possible test targets. We don't really care whether there will be parsing
// errors here - they will be reported during actual build.
TargetPatternEvaluator targetPatternEvaluator = env.newTargetPatternEvaluator();
Set<Target> testTargets = targetPatternEvaluator.parseTargetPatternList(env.getReporter(), optionsProvider.getResidue(), FilteringPolicies.FILTER_TESTS, /*keep_going=*/
true).getTargets();
SortedSet<String> packageFilters = Sets.newTreeSet();
collectInstrumentedPackages(env, testTargets, packageFilters);
optimizeFilterSet(packageFilters);
String instrumentationFilter = "//" + Joiner.on(",//").join(packageFilters);
final String instrumentationFilterOptionName = "instrumentation_filter";
if (!packageFilters.isEmpty()) {
env.getReporter().handle(Event.info("Using default value for --instrumentation_filter: \"" + instrumentationFilter + "\"."));
env.getReporter().handle(Event.info("Override the above default with --" + instrumentationFilterOptionName));
optionsProvider.parse(OptionPriority.COMPUTED_DEFAULT, "Instrumentation filter heuristic", ImmutableList.of("--" + instrumentationFilterOptionName + "=" + instrumentationFilter));
}
} catch (TargetParsingException e) {
// We can't compute heuristic - just use default filter.
} catch (InterruptedException e) {
// We cannot quit now because AbstractCommand does not have the
// infrastructure to do that. Just set a flag and return from exec() as
// early as possible. We can do this because there is always an exec()
// after an editOptions().
wasInterrupted = true;
}
}
use of com.google.devtools.build.lib.cmdline.TargetParsingException in project bazel by bazelbuild.
the class LegacyLoadingPhaseRunner method execute.
/**
* Performs target pattern evaluation, test suite expansion (if requested), and loads the
* transitive closure of the resulting targets as well as of the targets needed to use the given
* build configuration provider.
*/
@Override
public LoadingResult execute(ExtendedEventHandler eventHandler, List<String> targetPatterns, PathFragment relativeWorkingDirectory, LoadingOptions options, boolean keepGoing, boolean determineTests, @Nullable LoadingCallback callback) throws TargetParsingException, LoadingFailedException, InterruptedException {
LOG.info("Starting pattern evaluation");
Stopwatch timer = Stopwatch.createStarted();
if (options.buildTestsOnly && options.compileOneDependency) {
throw new LoadingFailedException("--compile_one_dependency cannot be used together with " + "the --build_tests_only option or the 'bazel test' command ");
}
targetPatternEvaluator.updateOffset(relativeWorkingDirectory);
ExtendedEventHandler parseFailureListener = new ParseFailureListenerImpl(eventHandler);
// Determine targets to build:
ResolvedTargets<Target> targets = getTargetsToBuild(parseFailureListener, targetPatterns, options.compileOneDependency, options.buildTagFilterList, keepGoing);
ImmutableSet<Target> filteredTargets = targets.getFilteredTargets();
boolean buildTestsOnly = options.buildTestsOnly;
ImmutableSet<Target> testsToRun = null;
ImmutableSet<Target> testFilteredTargets = ImmutableSet.of();
// then the list of filtered targets will be set as build list as well.
if (determineTests || buildTestsOnly) {
// Parse the targets to get the tests.
ResolvedTargets<Target> testTargets = determineTests(parseFailureListener, targetPatterns, options, keepGoing);
if (testTargets.getTargets().isEmpty() && !testTargets.getFilteredTargets().isEmpty()) {
eventHandler.handle(Event.warn("All specified test targets were excluded by filters"));
}
if (buildTestsOnly) {
// 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 (determineTests) {
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.
Preconditions.checkState(targets.getTargets().containsAll(testsToRun));
}
}
if (targets.hasError()) {
eventHandler.handle(Event.warn("Target pattern parsing failed. Continuing anyway"));
}
LoadingPhaseRunner.maybeReportDeprecation(eventHandler, targets.getTargets());
long targetPatternEvalTime = timer.stop().elapsed(TimeUnit.MILLISECONDS);
LOG.info("Starting test suite expansion");
timer = Stopwatch.createStarted();
ImmutableSet<Target> targetsToLoad = targets.getTargets();
ResolvedTargets<Target> expandedResult;
try {
expandedResult = expandTestSuites(eventHandler, targetsToLoad, keepGoing);
} catch (TargetParsingException e) {
throw new LoadingFailedException("Loading failed; build aborted", e);
}
ImmutableSet<Target> expandedTargetsToLoad = expandedResult.getTargets();
ImmutableSet<Target> testSuiteTargets = ImmutableSet.copyOf(Sets.difference(targetsToLoad, expandedTargetsToLoad));
long testSuiteTime = timer.stop().elapsed(TimeUnit.MILLISECONDS);
TargetPatternPhaseValue patternParsingValue = new TargetPatternPhaseValue(expandedTargetsToLoad, testsToRun, targets.hasError(), expandedResult.hasError(), filteredTargets, testFilteredTargets, /*originalTargets=*/
targets.getTargets(), testSuiteTargets, getWorkspaceName(eventHandler));
// This is the same code as SkyframeLoadingPhaseRunner.
eventHandler.post(new TargetParsingCompleteEvent(patternParsingValue.getOriginalTargets(), patternParsingValue.getFilteredTargets(), patternParsingValue.getTestFilteredTargets(), targetPatternEvalTime, targetPatterns, patternParsingValue.getTargets()));
if (callback != null) {
callback.notifyTargets(patternParsingValue.getTargets());
}
eventHandler.post(new LoadingPhaseCompleteEvent(patternParsingValue.getTargets(), patternParsingValue.getTestSuiteTargets(), packageManager.getStatistics(), testSuiteTime));
LOG.info("Target pattern evaluation finished");
return patternParsingValue.toLoadingResult();
}
use of com.google.devtools.build.lib.cmdline.TargetParsingException 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.TargetParsingException in project bazel by bazelbuild.
the class TargetPatternFunction method compute.
@Override
public SkyValue compute(SkyKey key, Environment env) throws TargetPatternFunctionException, InterruptedException {
TargetPatternValue.TargetPatternKey patternKey = ((TargetPatternValue.TargetPatternKey) key.argument());
ResolvedTargets<Target> resolvedTargets;
try {
EnvironmentBackedRecursivePackageProvider provider = new EnvironmentBackedRecursivePackageProvider(env);
RecursivePackageProviderBackedTargetPatternResolver resolver = new RecursivePackageProviderBackedTargetPatternResolver(provider, env.getListener(), patternKey.getPolicy(), MultisetSemaphore.<PackageIdentifier>unbounded());
TargetPattern parsedPattern = patternKey.getParsedPattern();
ImmutableSet<PathFragment> excludedSubdirectories = patternKey.getExcludedSubdirectories();
final Set<Target> results = CompactHashSet.create();
BatchCallback<Target, RuntimeException> callback = new BatchCallback<Target, RuntimeException>() {
@Override
public void process(Iterable<Target> partialResult) {
Iterables.addAll(results, partialResult);
}
};
parsedPattern.eval(resolver, excludedSubdirectories, callback, RuntimeException.class);
resolvedTargets = ResolvedTargets.<Target>builder().addAll(results).build();
} catch (TargetParsingException e) {
throw new TargetPatternFunctionException(e);
} catch (MissingDepException e) {
// implementations that are unconcerned with MissingDepExceptions.
return null;
}
Preconditions.checkNotNull(resolvedTargets, key);
ResolvedTargets.Builder<Label> resolvedLabelsBuilder = ResolvedTargets.builder();
for (Target target : resolvedTargets.getTargets()) {
resolvedLabelsBuilder.add(target.getLabel());
}
for (Target target : resolvedTargets.getFilteredTargets()) {
resolvedLabelsBuilder.remove(target.getLabel());
}
return new TargetPatternValue(resolvedLabelsBuilder.build());
}
Aggregations