use of com.google.devtools.build.lib.query2.proto.proto2api.Build in project bazel by bazelbuild.
the class GenQuery method create.
@Override
@Nullable
public ConfiguredTarget create(RuleContext ruleContext) throws InterruptedException, RuleErrorException {
Artifact outputArtifact = ruleContext.createOutputArtifact();
// The query string
final String query = ruleContext.attributes().get("expression", Type.STRING);
OptionsParser optionsParser = OptionsParser.newOptionsParser(QueryOptions.class);
optionsParser.setAllowResidue(false);
try {
optionsParser.parse(ruleContext.attributes().get("opts", Type.STRING_LIST));
} catch (OptionsParsingException e) {
ruleContext.attributeError("opts", "error while parsing query options: " + e.getMessage());
return null;
}
// Parsed query options
QueryOptions queryOptions = optionsParser.getOptions(QueryOptions.class);
if (queryOptions.keepGoing) {
ruleContext.attributeError("opts", "option --keep_going is not allowed");
return null;
}
if (!queryOptions.universeScope.isEmpty()) {
ruleContext.attributeError("opts", "option --universe_scope is not allowed");
return null;
}
if (optionsParser.containsExplicitOption("order_results")) {
ruleContext.attributeError("opts", "option --order_results is not allowed");
return null;
}
if (optionsParser.containsExplicitOption("noorder_results")) {
ruleContext.attributeError("opts", "option --noorder_results is not allowed");
return null;
}
if (optionsParser.containsExplicitOption("order_output")) {
ruleContext.attributeError("opts", "option --order_output is not allowed");
return null;
}
// Force results to be deterministic.
queryOptions.orderOutput = OrderOutput.FULL;
// force relative_locations to true so it has a deterministic output across machines.
queryOptions.relativeLocations = true;
final byte[] result = executeQuery(ruleContext, queryOptions, getScope(ruleContext), query);
if (result == null || ruleContext.hasErrors()) {
return null;
}
ruleContext.registerAction(new QueryResultAction(ruleContext.getActionOwner(), outputArtifact, result));
NestedSet<Artifact> filesToBuild = NestedSetBuilder.create(Order.STABLE_ORDER, outputArtifact);
return new RuleConfiguredTargetBuilder(ruleContext).setFilesToBuild(filesToBuild).add(RunfilesProvider.class, RunfilesProvider.simple(new Runfiles.Builder(ruleContext.getWorkspaceName(), ruleContext.getConfiguration().legacyExternalRunfiles()).addTransitiveArtifacts(filesToBuild).build())).build();
}
use of com.google.devtools.build.lib.query2.proto.proto2api.Build 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();
}
use of com.google.devtools.build.lib.query2.proto.proto2api.Build in project bazel by bazelbuild.
the class InfoItem method getBuildLanguageDefinition.
/**
* Returns a byte array containing a proto-buffer describing the build language.
*/
private static byte[] getBuildLanguageDefinition(RuleClassProvider provider) {
BuildLanguage.Builder resultPb = BuildLanguage.newBuilder();
Collection<RuleClass> ruleClasses = provider.getRuleClassMap().values();
for (RuleClass ruleClass : ruleClasses) {
if (!ruleClass.isDocumented()) {
continue;
}
RuleDefinition.Builder rulePb = RuleDefinition.newBuilder();
rulePb.setName(ruleClass.getName());
for (Attribute attr : ruleClass.getAttributes()) {
if (!attr.isDocumented()) {
continue;
}
AttributeDefinition.Builder attrPb = AttributeDefinition.newBuilder();
attrPb.setName(attr.getName());
// The protocol compiler, in its infinite wisdom, generates the field as one of the
// integer type and the getTypeEnum() method is missing. WTF?
attrPb.setType(ProtoUtils.getDiscriminatorFromType(attr.getType()));
attrPb.setMandatory(attr.isMandatory());
if (BuildType.isLabelType(attr.getType())) {
attrPb.setAllowedRuleClasses(getAllowedRuleClasses(ruleClasses, attr));
}
rulePb.addAttribute(attrPb);
}
resultPb.addRule(rulePb);
}
return resultPb.build().toByteArray();
}
Aggregations