use of com.google.devtools.build.lib.cmdline.TargetParsingException in project bazel by bazelbuild.
the class AbstractBlazeQueryEnvironment method evaluateQuery.
/**
* Evaluate the specified query expression in this environment, streaming results to the given
* {@code callback}. {@code callback.start()} will be called before query evaluation and
* {@code callback.close()} will be unconditionally called at the end of query evaluation
* (i.e. regardless of whether it was successful).
*
* @return a {@link QueryEvalResult} object that contains the resulting set of targets and a bit
* to indicate whether errors occurred during evaluation; note that the
* success status can only be false if {@code --keep_going} was in effect
* @throws QueryException if the evaluation failed and {@code --nokeep_going} was in
* effect
*/
public QueryEvalResult evaluateQuery(QueryExpression expr, ThreadSafeOutputFormatterCallback<T> callback) throws QueryException, InterruptedException, IOException {
EmptinessSensingCallback<T> emptySensingCallback = new EmptinessSensingCallback<>(callback);
long startTime = System.currentTimeMillis();
// In the --nokeep_going case, errors are reported in the order in which the patterns are
// specified; using a linked hash set here makes sure that the left-most error is reported.
Set<String> targetPatternSet = new LinkedHashSet<>();
expr.collectTargetPatterns(targetPatternSet);
try {
preloadOrThrow(expr, targetPatternSet);
} catch (TargetParsingException e) {
// Unfortunately, by evaluating the patterns in parallel, we lose some location information.
throw new QueryException(expr, e.getMessage());
}
IOException ioExn = null;
boolean failFast = true;
try {
callback.start();
evalTopLevelInternal(expr, emptySensingCallback);
failFast = false;
} catch (QueryException e) {
throw new QueryException(e, expr);
} catch (InterruptedException e) {
throw e;
} finally {
try {
callback.close(failFast);
} catch (IOException e) {
// Only throw this IOException if we weren't about to throw a different exception.
ioExn = e;
}
}
if (ioExn != null) {
throw ioExn;
}
long elapsedTime = System.currentTimeMillis() - startTime;
if (elapsedTime > 1) {
logger.info("Spent " + elapsedTime + " milliseconds evaluating query");
}
if (eventHandler.hasErrors()) {
if (!keepGoing) {
// of target patterns that don't cause evaluation to fail per se.
throw new QueryException("Evaluation of query \"" + expr + "\" failed due to BUILD file errors");
} else {
eventHandler.handle(Event.warn("--keep_going specified, ignoring errors. " + "Results may be inaccurate"));
}
}
return new QueryEvalResult(!eventHandler.hasErrors(), emptySensingCallback.isEmpty());
}
use of com.google.devtools.build.lib.cmdline.TargetParsingException in project bazel by bazelbuild.
the class PrepareDepsOfPatternValue method excludedDirectoriesBeneath.
private static ImmutableSet<PathFragment> excludedDirectoriesBeneath(TargetPatternKey targetPatternKey, int position, List<TargetPatternSkyKeyOrException> keysMaybe) {
ImmutableSet.Builder<PathFragment> excludedDirectoriesBuilder = ImmutableSet.builder();
for (int j = position + 1; j < keysMaybe.size(); j++) {
TargetPatternSkyKeyOrException laterPatternMaybe = keysMaybe.get(j);
SkyKey laterSkyKey;
try {
laterSkyKey = laterPatternMaybe.getSkyKey();
} catch (TargetParsingException ignored) {
laterSkyKey = null;
}
if (laterSkyKey != null) {
TargetPatternKey laterTargetPatternKey = (TargetPatternKey) laterSkyKey.argument();
TargetPattern laterParsedPattern = laterTargetPatternKey.getParsedPattern();
if (laterTargetPatternKey.isNegative() && laterParsedPattern.getType() == Type.TARGETS_BELOW_DIRECTORY && targetPatternKey.getParsedPattern().containsDirectoryOfTBDForTBD(laterParsedPattern)) {
excludedDirectoriesBuilder.add(laterParsedPattern.getDirectoryForTargetsUnderDirectory().getPackageFragment());
}
}
}
return excludedDirectoriesBuilder.build();
}
use of com.google.devtools.build.lib.cmdline.TargetParsingException in project bazel by bazelbuild.
the class PrepareDepsOfPatternValue method keys.
/**
* Returns an iterable of {@link PrepareDepsOfPatternSkyKeyOrException}, with {@link
* TargetPatternKey} arguments. Negative target patterns of type other than {@link
* Type#TARGETS_BELOW_DIRECTORY} are not permitted. If a provided pattern fails to parse or is
* negative but not a {@link Type#TARGETS_BELOW_DIRECTORY}, an element in the returned iterable
* will throw when its {@link PrepareDepsOfPatternSkyKeyOrException#getSkyKey} method is called
* and will return the failing pattern when its {@link
* PrepareDepsOfPatternSkyKeyOrException#getOriginalPattern} method is called.
*
* <p>There may be fewer returned elements than patterns provided as input. This function will
* combine negative {@link Type#TARGETS_BELOW_DIRECTORY} patterns with preceding patterns to
* return an iterable of SkyKeys that avoids loading excluded directories during evaluation.
*
* @param patterns The list of patterns, e.g. [//foo/..., -//foo/biz/...]. If a pattern's first
* character is "-", it is treated as a negative pattern.
* @param offset The offset to apply to relative target patterns.
*/
@ThreadSafe
public static Iterable<PrepareDepsOfPatternSkyKeyOrException> keys(List<String> patterns, String offset) {
List<TargetPatternSkyKeyOrException> keysMaybe = ImmutableList.copyOf(TargetPatternValue.keys(patterns, FilteringPolicies.NO_FILTER, offset));
// This code path is evaluated only for query universe preloading, and the quadratic cost of
// the code below (i.e. for each pattern, consider each later pattern as a candidate for
// subdirectory exclusion) is only acceptable because all the use cases for query universe
// preloading involve short (<10 items) pattern sequences.
ImmutableList.Builder<PrepareDepsOfPatternSkyKeyOrException> builder = ImmutableList.builder();
for (int i = 0; i < keysMaybe.size(); i++) {
TargetPatternSkyKeyOrException keyMaybe = keysMaybe.get(i);
SkyKey skyKey;
try {
skyKey = keyMaybe.getSkyKey();
} catch (TargetParsingException e) {
// keyMaybe.getSkyKey() may throw TargetParsingException if its corresponding pattern
// failed to parse. If so, wrap the exception and return it, so that our caller can
// deal with it.
skyKey = null;
builder.add(new PrepareDepsOfPatternSkyKeyException(e, keyMaybe.getOriginalPattern()));
}
if (skyKey != null) {
TargetPatternKey targetPatternKey = (TargetPatternKey) skyKey.argument();
if (targetPatternKey.isNegative()) {
if (!targetPatternKey.getParsedPattern().getType().equals(Type.TARGETS_BELOW_DIRECTORY)) {
builder.add(new PrepareDepsOfPatternSkyKeyException(new TargetParsingException("Negative target patterns of types other than \"targets below directory\"" + " are not permitted."), targetPatternKey.toString()));
}
// Otherwise it's a negative TBD pattern which was combined with previous patterns as an
// excluded directory. These can be skipped because there's no PrepareDepsOfPattern work
// to be done for them.
} else {
builder.add(new PrepareDepsOfPatternSkyKeyValue(setExcludedDirectories(targetPatternKey, excludedDirectoriesBeneath(targetPatternKey, i, keysMaybe))));
}
}
}
return builder.build();
}
use of com.google.devtools.build.lib.cmdline.TargetParsingException in project bazel by bazelbuild.
the class PrepareDepsOfPatternsFunction method compute.
/**
* Given a {@link SkyKey} that contains a sequence of target patterns, when this function returns
* {@link PrepareDepsOfPatternsValue}, then all targets matching that sequence, and those targets'
* transitive dependencies, have been loaded.
*/
@Nullable
@Override
public SkyValue compute(SkyKey skyKey, Environment env) throws InterruptedException {
EventHandler eventHandler = env.getListener();
ImmutableList<SkyKey> skyKeys = getSkyKeys(skyKey, eventHandler);
Map<SkyKey, ValueOrException<TargetParsingException>> tokensByKey = env.getValuesOrThrow(skyKeys, TargetParsingException.class);
if (env.valuesMissing()) {
return null;
}
boolean handlerIsParseFailureListener = eventHandler instanceof ParseFailureListener;
for (SkyKey key : skyKeys) {
try {
// The only exception type throwable by PrepareDepsOfPatternFunction is
// TargetParsingException. Therefore all ValueOrException values in the map will either
// be non-null or throw TargetParsingException when get is called.
Preconditions.checkNotNull(tokensByKey.get(key).get());
} catch (TargetParsingException e) {
// If a target pattern can't be evaluated, notify the user of the problem and keep going.
handleTargetParsingException(eventHandler, handlerIsParseFailureListener, key, e);
}
}
return new PrepareDepsOfPatternsValue(getTargetPatternKeys(skyKeys));
}
use of com.google.devtools.build.lib.cmdline.TargetParsingException in project bazel by bazelbuild.
the class SkylarkAspectsTest method multipleAspects.
@Test
public void multipleAspects() throws Exception {
scratch.file("test/aspect.bzl", "def _aspect_impl(target,ctx):", " return struct()", "my_aspect = aspect(implementation = _aspect_impl)", "def _dummy_impl(ctx):", " pass", "r1 = rule(_dummy_impl, ", " attrs = { 'deps' : attr.label_list(aspects = [my_aspect, my_aspect]) })");
scratch.file("test/BUILD", "load(':aspect.bzl', 'r1')", "r1(name = 't1')");
reporter.removeHandler(failFastHandler);
try {
AnalysisResult result = update("//test:r1");
assertThat(keepGoing()).isTrue();
assertThat(result.hasError()).isTrue();
} catch (TargetParsingException | ViewCreationFailedException expected) {
// expected.
}
assertContainsEvent("aspect //test:aspect.bzl%my_aspect added more than once");
}
Aggregations