use of com.google.devtools.build.lib.query2.proto.proto2api.Build in project bazel by bazelbuild.
the class SkyQueryEnvironment method getRBuildFiles.
/**
* Calculates the set of {@link Package} objects, represented as source file targets, that depend
* on the given list of BUILD files and subincludes (other files are filtered out).
*/
@ThreadSafe
QueryTaskFuture<Void> getRBuildFiles(Collection<PathFragment> fileIdentifiers, Callback<Target> callback) {
try {
Collection<SkyKey> files = getSkyKeysForFileFragments(fileIdentifiers);
Uniquifier<SkyKey> keyUniquifier = new UniquifierImpl<>(SkyKeyKeyExtractor.INSTANCE, /*concurrencyLevel=*/
1);
Collection<SkyKey> current = keyUniquifier.unique(graph.getSuccessfulValues(files).keySet());
Set<SkyKey> resultKeys = CompactHashSet.create();
while (!current.isEmpty()) {
Collection<Iterable<SkyKey>> reverseDeps = graph.getReverseDeps(current).values();
current = new HashSet<>();
for (SkyKey rdep : Iterables.concat(reverseDeps)) {
if (rdep.functionName().equals(SkyFunctions.PACKAGE)) {
resultKeys.add(rdep);
// too.
if (rdep.equals(PackageValue.key(Label.EXTERNAL_PACKAGE_IDENTIFIER))) {
if (keyUniquifier.unique(rdep)) {
current.add(rdep);
}
}
} else if (!rdep.functionName().equals(SkyFunctions.PACKAGE_LOOKUP)) {
// to rbuildfiles.
if (keyUniquifier.unique(rdep)) {
current.add(rdep);
}
}
}
if (resultKeys.size() >= BATCH_CALLBACK_SIZE) {
for (Iterable<SkyKey> batch : Iterables.partition(resultKeys, BATCH_CALLBACK_SIZE)) {
callback.process(getBuildFilesForPackageValues(graph.getSuccessfulValues(batch).values()));
}
resultKeys.clear();
}
}
callback.process(getBuildFilesForPackageValues(graph.getSuccessfulValues(resultKeys).values()));
return immediateSuccessfulFuture(null);
} catch (QueryException e) {
return immediateFailedFuture(e);
} catch (InterruptedException e) {
return immediateCancelledFuture();
}
}
use of com.google.devtools.build.lib.query2.proto.proto2api.Build 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.proto.proto2api.Build 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.proto.proto2api.Build in project bazel by bazelbuild.
the class ProtoOutputFormatter method toTargetProtoBuffer.
/** Converts a logical {@link Target} object into a {@link Build.Target} protobuffer. */
@VisibleForTesting
public Build.Target toTargetProtoBuffer(Target target) throws InterruptedException {
Build.Target.Builder targetPb = Build.Target.newBuilder();
String location = getLocation(target, relativeLocations);
if (target instanceof Rule) {
Rule rule = (Rule) target;
Build.Rule.Builder rulePb = Build.Rule.newBuilder().setName(rule.getLabel().toString()).setRuleClass(rule.getRuleClass());
if (includeLocation()) {
rulePb.setLocation(location);
}
Map<Attribute, Build.Attribute> serializedAttributes = Maps.newHashMap();
for (Attribute attr : rule.getAttributes()) {
if ((!includeDefaultValues && !rule.isAttributeValueExplicitlySpecified(attr)) || !includeAttribute(rule, attr)) {
continue;
}
Object flattenedAttributeValue = flattenAttributeValues(attr.getType(), getPossibleAttributeValues(rule, attr));
Build.Attribute serializedAttribute = AttributeFormatter.getAttributeProto(attr, flattenedAttributeValue, rule.isAttributeValueExplicitlySpecified(attr), /*encodeBooleanAndTriStateAsIntegerAndString=*/
true);
rulePb.addAttribute(serializedAttribute);
serializedAttributes.put(attr, serializedAttribute);
}
postProcess(rule, rulePb, serializedAttributes);
Environment env = rule.getRuleClassObject().getRuleDefinitionEnvironment();
if (env != null && includeRuleDefinitionEnvironment()) {
// The RuleDefinitionEnvironment is always defined for Skylark rules and
// always null for non Skylark rules.
rulePb.addAttribute(Build.Attribute.newBuilder().setName(RULE_IMPLEMENTATION_HASH_ATTR_NAME).setType(ProtoUtils.getDiscriminatorFromType(Type.STRING)).setStringValue(env.getTransitiveContentHashCode()));
}
ImmutableMultimap<Attribute, Label> aspectsDependencies = aspectResolver.computeAspectDependencies(target, dependencyFilter);
// Add information about additional attributes from aspects.
for (Entry<Attribute, Collection<Label>> entry : aspectsDependencies.asMap().entrySet()) {
Attribute attribute = entry.getKey();
Collection<Label> labels = entry.getValue();
if (!includeAspectAttribute(attribute, labels)) {
continue;
}
Object attributeValue = getAspectAttributeValue(attribute, labels);
Build.Attribute serializedAttribute = AttributeFormatter.getAttributeProto(attribute, attributeValue, /*explicitlySpecified=*/
false, /*encodeBooleanAndTriStateAsIntegerAndString=*/
true);
rulePb.addAttribute(serializedAttribute);
}
if (includeRuleInputsAndOutputs()) {
// Add all deps from aspects as rule inputs of current target.
for (Label label : aspectsDependencies.values()) {
rulePb.addRuleInput(label.toString());
}
// host-configuration outputs, and default values.
for (Label label : rule.getLabels(dependencyFilter)) {
rulePb.addRuleInput(label.toString());
}
for (OutputFile outputFile : rule.getOutputFiles()) {
Label fileLabel = outputFile.getLabel();
rulePb.addRuleOutput(fileLabel.toString());
}
}
for (String feature : rule.getFeatures()) {
rulePb.addDefaultSetting(feature);
}
targetPb.setType(RULE);
targetPb.setRule(rulePb);
} else if (target instanceof OutputFile) {
OutputFile outputFile = (OutputFile) target;
Label label = outputFile.getLabel();
Rule generatingRule = outputFile.getGeneratingRule();
GeneratedFile.Builder output = GeneratedFile.newBuilder().setGeneratingRule(generatingRule.getLabel().toString()).setName(label.toString());
if (includeLocation()) {
output.setLocation(location);
}
targetPb.setType(GENERATED_FILE);
targetPb.setGeneratedFile(output.build());
} else if (target instanceof InputFile) {
InputFile inputFile = (InputFile) target;
Label label = inputFile.getLabel();
Build.SourceFile.Builder input = Build.SourceFile.newBuilder().setName(label.toString());
if (includeLocation()) {
input.setLocation(location);
}
if (inputFile.getName().equals("BUILD")) {
Set<Label> subincludeLabels = new LinkedHashSet<>();
subincludeLabels.addAll(aspectResolver == null ? inputFile.getPackage().getSubincludeLabels() : aspectResolver.computeBuildFileDependencies(inputFile.getPackage(), BuildFileDependencyMode.SUBINCLUDE));
subincludeLabels.addAll(aspectResolver == null ? inputFile.getPackage().getSkylarkFileDependencies() : aspectResolver.computeBuildFileDependencies(inputFile.getPackage(), BuildFileDependencyMode.SKYLARK));
for (Label skylarkFileDep : subincludeLabels) {
input.addSubinclude(skylarkFileDep.toString());
}
for (String feature : inputFile.getPackage().getFeatures()) {
input.addFeature(feature);
}
input.setPackageContainsErrors(inputFile.getPackage().containsErrors());
}
for (Label visibilityDependency : target.getVisibility().getDependencyLabels()) {
input.addPackageGroup(visibilityDependency.toString());
}
for (Label visibilityDeclaration : target.getVisibility().getDeclaredLabels()) {
input.addVisibilityLabel(visibilityDeclaration.toString());
}
targetPb.setType(SOURCE_FILE);
targetPb.setSourceFile(input);
} else if (target instanceof FakeSubincludeTarget) {
Label label = target.getLabel();
SourceFile.Builder input = SourceFile.newBuilder().setName(label.toString());
if (includeLocation()) {
input.setLocation(location);
}
targetPb.setType(SOURCE_FILE);
targetPb.setSourceFile(input.build());
} else if (target instanceof PackageGroup) {
PackageGroup packageGroup = (PackageGroup) target;
Build.PackageGroup.Builder packageGroupPb = Build.PackageGroup.newBuilder().setName(packageGroup.getLabel().toString());
for (String containedPackage : packageGroup.getContainedPackages()) {
packageGroupPb.addContainedPackage(containedPackage);
}
for (Label include : packageGroup.getIncludes()) {
packageGroupPb.addIncludedPackageGroup(include.toString());
}
targetPb.setType(PACKAGE_GROUP);
targetPb.setPackageGroup(packageGroupPb);
} else if (target instanceof EnvironmentGroup) {
EnvironmentGroup envGroup = (EnvironmentGroup) target;
Build.EnvironmentGroup.Builder envGroupPb = Build.EnvironmentGroup.newBuilder().setName(envGroup.getLabel().toString());
for (Label env : envGroup.getEnvironments()) {
envGroupPb.addEnvironment(env.toString());
}
for (Label defaultEnv : envGroup.getDefaults()) {
envGroupPb.addDefault(defaultEnv.toString());
}
targetPb.setType(ENVIRONMENT_GROUP);
targetPb.setEnvironmentGroup(envGroupPb);
} else {
throw new IllegalArgumentException(target.toString());
}
return targetPb.build();
}
use of com.google.devtools.build.lib.query2.proto.proto2api.Build 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());
}
Aggregations