use of com.google.devtools.build.lib.query2.engine.QueryEnvironment.Setting in project bazel by bazelbuild.
the class XmlOutputFormatter method createTargetElement.
/**
* Creates and returns a new DOM tree for the specified build target.
*
* XML structure:
* - element tag is <source-file>, <generated-file> or <rule
* class="cc_library">, following the terminology of
* {@link Target#getTargetKind()}.
* - 'name' attribute is target's label.
* - 'location' attribute is consistent with output of --output location.
* - rule attributes are represented in the DOM structure.
* @throws InterruptedException
*/
private Element createTargetElement(Document doc, Target target) throws InterruptedException {
Element elem;
if (target instanceof Rule) {
Rule rule = (Rule) target;
elem = doc.createElement("rule");
elem.setAttribute("class", rule.getRuleClass());
for (Attribute attr : rule.getAttributes()) {
PossibleAttributeValues values = getPossibleAttributeValues(rule, attr);
if (values.source == AttributeValueSource.RULE || options.xmlShowDefaultValues) {
Element attrElem = createValueElement(doc, attr.getType(), values);
attrElem.setAttribute("name", attr.getName());
elem.appendChild(attrElem);
}
}
// host-configuration outputs, and default values.
for (Label label : rule.getLabels(dependencyFilter)) {
Element inputElem = doc.createElement("rule-input");
inputElem.setAttribute("name", label.toString());
elem.appendChild(inputElem);
}
for (Label label : aspectResolver.computeAspectDependencies(target, dependencyFilter).values()) {
Element inputElem = doc.createElement("rule-input");
inputElem.setAttribute("name", label.toString());
elem.appendChild(inputElem);
}
for (OutputFile outputFile : rule.getOutputFiles()) {
Element outputElem = doc.createElement("rule-output");
outputElem.setAttribute("name", outputFile.getLabel().toString());
elem.appendChild(outputElem);
}
for (String feature : rule.getFeatures()) {
Element outputElem = doc.createElement("rule-default-setting");
outputElem.setAttribute("name", feature);
elem.appendChild(outputElem);
}
} else if (target instanceof PackageGroup) {
PackageGroup packageGroup = (PackageGroup) target;
elem = doc.createElement("package-group");
elem.setAttribute("name", packageGroup.getName());
Element includes = createValueElement(doc, BuildType.LABEL_LIST, packageGroup.getIncludes());
includes.setAttribute("name", "includes");
elem.appendChild(includes);
Element packages = createValueElement(doc, Type.STRING_LIST, packageGroup.getContainedPackages());
packages.setAttribute("name", "packages");
elem.appendChild(packages);
} else if (target instanceof OutputFile) {
OutputFile outputFile = (OutputFile) target;
elem = doc.createElement("generated-file");
elem.setAttribute("generating-rule", outputFile.getGeneratingRule().getLabel().toString());
} else if (target instanceof InputFile) {
elem = doc.createElement("source-file");
InputFile inputFile = (InputFile) target;
if (inputFile.getName().equals("BUILD")) {
addSubincludedFilesToElement(doc, elem, inputFile);
addSkylarkFilesToElement(doc, elem, inputFile);
addFeaturesToElement(doc, elem, inputFile);
elem.setAttribute("package_contains_errors", String.valueOf(inputFile.getPackage().containsErrors()));
}
addPackageGroupsToElement(doc, elem, inputFile);
} else if (target instanceof EnvironmentGroup) {
EnvironmentGroup envGroup = (EnvironmentGroup) target;
elem = doc.createElement("environment-group");
elem.setAttribute("name", envGroup.getName());
Element environments = createValueElement(doc, BuildType.LABEL_LIST, envGroup.getEnvironments());
environments.setAttribute("name", "environments");
elem.appendChild(environments);
Element defaults = createValueElement(doc, BuildType.LABEL_LIST, envGroup.getDefaults());
defaults.setAttribute("name", "defaults");
elem.appendChild(defaults);
} else if (target instanceof FakeSubincludeTarget) {
elem = doc.createElement("source-file");
} else {
throw new IllegalArgumentException(target.toString());
}
elem.setAttribute("name", target.getLabel().toString());
String location = getLocation(target, options.relativeLocations);
if (!options.xmlLineNumbers) {
int firstColon = location.indexOf(':');
if (firstColon != -1) {
location = location.substring(0, firstColon);
}
}
elem.setAttribute("location", location);
return elem;
}
use of com.google.devtools.build.lib.query2.engine.QueryEnvironment.Setting in project bazel by bazelbuild.
the class QueryCommand method exec.
/**
* Exit codes:
* 0 on successful evaluation.
* 1 if query evaluation did not complete.
* 2 if query parsing failed.
* 3 if errors were reported but evaluation produced a partial result
* (only when --keep_going is in effect.)
*/
@Override
public ExitCode exec(CommandEnvironment env, OptionsProvider options) {
BlazeRuntime runtime = env.getRuntime();
QueryOptions queryOptions = options.getOptions(QueryOptions.class);
try {
env.setupPackageCache(options, runtime.getDefaultsPackageContent());
} catch (InterruptedException e) {
env.getReporter().handle(Event.error("query interrupted"));
return ExitCode.INTERRUPTED;
} catch (AbruptExitException e) {
env.getReporter().handle(Event.error(null, "Unknown error: " + e.getMessage()));
return e.getExitCode();
}
String query;
if (!options.getResidue().isEmpty()) {
if (!queryOptions.queryFile.isEmpty()) {
env.getReporter().handle(Event.error("Command-line query and --query_file cannot both be specified"));
return ExitCode.COMMAND_LINE_ERROR;
}
query = Joiner.on(' ').join(options.getResidue());
} else if (!queryOptions.queryFile.isEmpty()) {
// Works for absolute or relative query file.
Path residuePath = env.getWorkingDirectory().getRelative(queryOptions.queryFile);
try {
query = new String(FileSystemUtils.readContent(residuePath), StandardCharsets.UTF_8);
} catch (IOException e) {
env.getReporter().handle(Event.error("I/O error reading from " + residuePath.getPathString()));
return ExitCode.COMMAND_LINE_ERROR;
}
} else {
env.getReporter().handle(Event.error(String.format("missing query expression. Type '%s help query' for syntax and help", runtime.getProductName())));
return ExitCode.COMMAND_LINE_ERROR;
}
Iterable<OutputFormatter> formatters = runtime.getQueryOutputFormatters();
OutputFormatter formatter = OutputFormatter.getFormatter(formatters, queryOptions.outputFormat);
if (formatter == null) {
env.getReporter().handle(Event.error(String.format("Invalid output format '%s'. Valid values are: %s", queryOptions.outputFormat, OutputFormatter.formatterNames(formatters))));
return ExitCode.COMMAND_LINE_ERROR;
}
Set<Setting> settings = queryOptions.toSettings();
boolean streamResults = QueryOutputUtils.shouldStreamResults(queryOptions, formatter);
QueryEvalResult result;
AbstractBlazeQueryEnvironment<Target> queryEnv = newQueryEnvironment(env, queryOptions.keepGoing, !streamResults, queryOptions.universeScope, queryOptions.loadingPhaseThreads, settings);
// 1. Parse and transform query:
QueryExpression expr;
try {
expr = QueryExpression.parse(query, queryEnv);
} catch (QueryException e) {
env.getReporter().handle(Event.error(null, "Error while parsing '" + query + "': " + e.getMessage()));
return ExitCode.COMMAND_LINE_ERROR;
}
expr = queryEnv.transformParsedQuery(expr);
OutputStream out = env.getReporter().getOutErr().getOutputStream();
ThreadSafeOutputFormatterCallback<Target> callback;
if (streamResults) {
disableAnsiCharactersFiltering(env);
// 2. Evaluate expression:
StreamedFormatter streamedFormatter = ((StreamedFormatter) formatter);
streamedFormatter.setOptions(queryOptions, queryOptions.aspectDeps.createResolver(env.getPackageManager(), env.getReporter()));
callback = streamedFormatter.createStreamCallback(out, queryOptions, queryEnv);
} else {
callback = QueryUtil.newOrderedAggregateAllOutputFormatterCallback();
}
boolean catastrophe = true;
try {
result = queryEnv.evaluateQuery(expr, callback);
catastrophe = false;
} catch (QueryException e) {
catastrophe = false;
// Keep consistent with reportBuildFileError()
env.getReporter().handle(Event.error(e.getMessage() == null ? e.toString() : e.getMessage()));
return ExitCode.ANALYSIS_FAILURE;
} catch (InterruptedException e) {
catastrophe = false;
IOException ioException = callback.getIoException();
if (ioException == null || ioException instanceof ClosedByInterruptException) {
env.getReporter().handle(Event.error("query interrupted"));
return ExitCode.INTERRUPTED;
} else {
env.getReporter().handle(Event.error("I/O error: " + e.getMessage()));
return ExitCode.LOCAL_ENVIRONMENTAL_ERROR;
}
} catch (IOException e) {
catastrophe = false;
env.getReporter().handle(Event.error("I/O error: " + e.getMessage()));
return ExitCode.LOCAL_ENVIRONMENTAL_ERROR;
} finally {
if (!catastrophe) {
try {
out.flush();
} catch (IOException e) {
env.getReporter().handle(Event.error("Failed to flush query results: " + e.getMessage()));
return ExitCode.LOCAL_ENVIRONMENTAL_ERROR;
}
}
}
env.getEventBus().post(new NoBuildEvent());
if (!streamResults) {
disableAnsiCharactersFiltering(env);
// 3. Output results:
try {
Set<Target> targets = ((AggregateAllOutputFormatterCallback<Target>) callback).getResult();
QueryOutputUtils.output(queryOptions, result, targets, formatter, env.getReporter().getOutErr().getOutputStream(), queryOptions.aspectDeps.createResolver(env.getPackageManager(), env.getReporter()));
} catch (ClosedByInterruptException | InterruptedException e) {
env.getReporter().handle(Event.error("query interrupted"));
return ExitCode.INTERRUPTED;
} catch (IOException e) {
env.getReporter().handle(Event.error("I/O error: " + e.getMessage()));
return ExitCode.LOCAL_ENVIRONMENTAL_ERROR;
} finally {
try {
out.flush();
} catch (IOException e) {
env.getReporter().handle(Event.error("Failed to flush query results: " + e.getMessage()));
return ExitCode.LOCAL_ENVIRONMENTAL_ERROR;
}
}
}
if (result.isEmpty()) {
env.getReporter().handle(Event.info("Empty results"));
}
return result.getSuccess() ? ExitCode.SUCCESS : ExitCode.PARTIAL_ANALYSIS_FAILURE;
}
use of com.google.devtools.build.lib.query2.engine.QueryEnvironment.Setting in project bazel by bazelbuild.
the class FetchCommand method exec.
@Override
public ExitCode exec(CommandEnvironment env, OptionsProvider options) {
BlazeRuntime runtime = env.getRuntime();
if (options.getResidue().isEmpty()) {
env.getReporter().handle(Event.error(String.format("missing fetch expression. Type '%s help fetch' for syntax and help", env.getRuntime().getProductName())));
return ExitCode.COMMAND_LINE_ERROR;
}
try {
env.setupPackageCache(options, runtime.getDefaultsPackageContent());
} catch (InterruptedException e) {
env.getReporter().handle(Event.error("fetch interrupted"));
return ExitCode.INTERRUPTED;
} catch (AbruptExitException e) {
env.getReporter().handle(Event.error(null, "Unknown error: " + e.getMessage()));
return e.getExitCode();
}
PackageCacheOptions pkgOptions = options.getOptions(PackageCacheOptions.class);
if (!pkgOptions.fetch) {
env.getReporter().handle(Event.error(null, "You cannot run fetch with --fetch=false"));
return ExitCode.COMMAND_LINE_ERROR;
}
// Querying for all of the dependencies of the targets has the side-effect of populating the
// Skyframe graph for external targets, which requires downloading them. The JDK is required to
// build everything but isn't counted as a dep in the build graph so we add it manually.
ImmutableList.Builder<String> labelsToLoad = new ImmutableList.Builder<String>().addAll(options.getResidue());
String query = Joiner.on(" union ").join(labelsToLoad.build());
query = "deps(" + query + ")";
AbstractBlazeQueryEnvironment<Target> queryEnv = QueryCommand.newQueryEnvironment(env, options.getOptions(FetchOptions.class).keepGoing, false, Lists.<String>newArrayList(), 200, Sets.<Setting>newHashSet());
// 1. Parse query:
QueryExpression expr;
try {
expr = QueryExpression.parse(query, queryEnv);
} catch (QueryException e) {
env.getReporter().handle(Event.error(null, "Error while parsing '" + query + "': " + e.getMessage()));
return ExitCode.COMMAND_LINE_ERROR;
}
// 2. Evaluate expression:
try {
queryEnv.evaluateQuery(expr, new ThreadSafeOutputFormatterCallback<Target>() {
@Override
public void processOutput(Iterable<Target> partialResult) {
// Throw away the result.
}
});
} catch (InterruptedException e) {
return ExitCode.COMMAND_LINE_ERROR;
} catch (QueryException e) {
// Keep consistent with reportBuildFileError()
env.getReporter().handle(Event.error(e.getMessage()));
return ExitCode.COMMAND_LINE_ERROR;
} catch (IOException e) {
// Should be impossible since our OutputFormatterCallback doesn't throw IOException.
throw new IllegalStateException(e);
}
env.getReporter().handle(Event.progress("All external dependencies fetched successfully."));
return ExitCode.SUCCESS;
}
use of com.google.devtools.build.lib.query2.engine.QueryEnvironment.Setting in project bazel by bazelbuild.
the class GenQuery method doQuery.
@SuppressWarnings("unchecked")
@Nullable
private byte[] doQuery(QueryOptions queryOptions, PackageProvider packageProvider, Predicate<Label> labelFilter, TargetPatternEvaluator evaluator, String query, RuleContext ruleContext) throws InterruptedException {
DigraphQueryEvalResult<Target> queryResult;
OutputFormatter formatter;
AggregateAllOutputFormatterCallback<Target> targets = QueryUtil.newOrderedAggregateAllOutputFormatterCallback();
try {
Set<Setting> settings = queryOptions.toSettings();
// Turns out, if we have two targets with a cycle of length 2 were one of
// the edges is of type NODEP_LABEL type, the targets both show up in
// each other's result for deps(X) when the query is executed using
// 'blaze query'. This obviously does not fly when doing the query as a
// part of the build, thus, there is a slight discrepancy between the
// behavior of the query engine in these two use cases.
settings.add(Setting.NO_NODEP_DEPS);
ImmutableList<OutputFormatter> outputFormatters = QUERY_OUTPUT_FORMATTERS.get(ruleContext.getAnalysisEnvironment().getSkyframeEnv());
// This is a precomputed value so it should have been injected by the rules module by the
// time we get there.
formatter = OutputFormatter.getFormatter(Preconditions.checkNotNull(outputFormatters), queryOptions.outputFormat);
// All the packages are already loaded at this point, so there is no need
// to start up many threads. 4 are started up to make good use of multiple
// cores.
BlazeQueryEnvironment queryEnvironment = (BlazeQueryEnvironment) QUERY_ENVIRONMENT_FACTORY.create(/*transitivePackageLoader=*/
null, /*graph=*/
null, packageProvider, evaluator, /*keepGoing=*/
false, ruleContext.attributes().get("strict", Type.BOOLEAN), /*orderedResults=*/
!QueryOutputUtils.shouldStreamResults(queryOptions, formatter), /*universeScope=*/
ImmutableList.<String>of(), /*loadingPhaseThreads=*/
4, labelFilter, getEventHandler(ruleContext), settings, ImmutableList.<QueryFunction>of(), /*packagePath=*/
null, /*blockUniverseEvaluationErrors=*/
false);
queryResult = (DigraphQueryEvalResult<Target>) queryEnvironment.evaluateQuery(query, targets);
} catch (SkyframeRestartQueryException e) {
// inconsistent from run to run, and make detecting legitimate errors more difficult.
return null;
} catch (QueryException e) {
ruleContext.ruleError("query failed: " + e.getMessage());
return null;
} catch (IOException e) {
throw new RuntimeException(e);
}
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
try {
QueryOutputUtils.output(queryOptions, queryResult, targets.getResult(), formatter, outputStream, queryOptions.aspectDeps.createResolver(packageProvider, getEventHandler(ruleContext)));
} catch (ClosedByInterruptException e) {
throw new InterruptedException(e.getMessage());
} catch (IOException e) {
throw new RuntimeException(e);
}
return outputStream.toByteArray();
}
Aggregations