aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib
diff options
context:
space:
mode:
authorGravatar gregce <gregce@google.com>2017-04-12 17:42:04 +0000
committerGravatar Jakob Buchgraber <buchgr@google.com>2017-04-13 09:36:50 +0200
commit57daac0d426e75914dccc122d322a74eb72685ba (patch)
treef5d8a4c437e2044327d254bd68c1fb10ae812222 /src/main/java/com/google/devtools/build/lib
parent276591254da669286dbb49a8c9c3328299354300 (diff)
Add select() support for "query --output=build".
Before this change, attributes with select() were completely skipped. This doesn't attempt to merge "trivial" selects, e.g. even though: attr = [":foo"] + select({"//conditions:default": [":bar"]}) always resolves to: attr = [":foo", ":bar"] this change still produces: attr = [":foo"] + [":bar"] We could merge these in a future change, if desired. But it's not even clear that's desired. There's conceptual value in keeping the lists separate since that's how they were originally written. That gives users a cue to maybe refactor their rules. RELNOTES[NEW]: "query --output=build" now includes select()s PiperOrigin-RevId: 152956939
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib')
-rw-r--r--src/main/java/com/google/devtools/build/lib/query2/output/OutputFormatter.java81
1 files changed, 57 insertions, 24 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/query2/output/OutputFormatter.java b/src/main/java/com/google/devtools/build/lib/query2/output/OutputFormatter.java
index 5c314b6a5c..2fa79b68a2 100644
--- a/src/main/java/com/google/devtools/build/lib/query2/output/OutputFormatter.java
+++ b/src/main/java/com/google/devtools/build/lib/query2/output/OutputFormatter.java
@@ -419,6 +419,7 @@ public abstract class OutputFormatter implements Serializable {
private void outputRule(Rule rule, PrintStream printStream) throws InterruptedException {
final String lineTerm = options.getLineTerminator();
+ final String outputAttributePattern = " %s = %s," + lineTerm;
printStream.printf("# %s%s", rule.getLocation(), lineTerm);
printStream.printf("%s(%s", rule.getRuleClass(), lineTerm);
printStream.printf(" name = \"%s\",%s", rule.getName(), lineTerm);
@@ -432,42 +433,74 @@ public abstract class OutputFormatter implements Serializable {
continue;
}
if (attributeMap.isConfigurable(attr.getName())) {
- continue; // TODO(bazel-team): handle configurable attributes.
+ // We don't know the actual value for configurable attributes, so we reconstruct
+ // the select without trying to resolve it.
+ printStream.printf(outputAttributePattern,
+ attr.getPublicName(),
+ outputConfigurableAttrValue(rule, attributeMap, attr));
+ continue;
}
PossibleAttributeValues values = getPossibleAttributeValues(rule, attr);
if (values.source != AttributeValueSource.RULE) {
continue; // Don't print default values.
}
if (Iterables.size(values) != 1) {
- // Computed defaults that depend on configurable attributes can also have multiple
- // values.
+ // Computed defaults that depend on configurable attributes can have multiple values.
continue;
}
- Object value = Iterables.getOnlyElement(values);
- printStream.printf(" %s = ", attr.getPublicName());
- if (value instanceof Label) {
- value = ((Label) value).getDefaultCanonicalForm();
- } else if (value instanceof License) {
- List<String> licenseTypes = new ArrayList<>();
- for (License.LicenseType licenseType : ((License) value).getLicenseTypes()) {
- licenseTypes.add(licenseType.toString().toLowerCase());
- }
- value = licenseTypes;
- } else if (value instanceof List<?> && EvalUtils.isImmutable(value)) {
- // Display it as a list (and not as a tuple). Attributes can never be tuples.
- value = new ArrayList<>((List<?>) value);
- } else if (value instanceof TriState) {
- value = ((TriState) value).toInt();
- }
- // It is *much* faster to write to a StringBuilder compared to the PrintStream object.
- StringBuilder builder = new StringBuilder();
- Printer.write(builder, value);
- printStream.print(builder);
- printStream.printf(",%s", lineTerm);
+ printStream.printf(outputAttributePattern,
+ attr.getPublicName(),
+ outputAttrValue(Iterables.getOnlyElement(values)));
}
printStream.printf(")\n%s", lineTerm);
}
+ /**
+ * Returns the given attribute value with BUILD output syntax. Does not support selects.
+ */
+ private String outputAttrValue(Object value) {
+ if (value instanceof Label) {
+ value = ((Label) value).getDefaultCanonicalForm();
+ } else if (value instanceof License) {
+ List<String> licenseTypes = new ArrayList<>();
+ for (License.LicenseType licenseType : ((License) value).getLicenseTypes()) {
+ licenseTypes.add(licenseType.toString().toLowerCase());
+ }
+ value = licenseTypes;
+ } else if (value instanceof List<?> && EvalUtils.isImmutable(value)) {
+ // Display it as a list (and not as a tuple). Attributes can never be tuples.
+ value = new ArrayList<>((List<?>) value);
+ } else if (value instanceof TriState) {
+ value = ((TriState) value).toInt();
+ }
+ // It is *much* faster to write to a StringBuilder compared to the PrintStream object.
+ StringBuilder builder = new StringBuilder();
+ Printer.write(builder, value);
+ return builder.toString();
+ }
+
+ /**
+ * Returns the given configurable attribute value with BUILD output syntax.
+ *
+ * <p>Since query doesn't know which select path should be chosen, this doesn't try to
+ * resolve the final value. Instead it just reconstructs the select.
+ */
+ private String outputConfigurableAttrValue(Rule rule, RawAttributeMapper attributeMap,
+ Attribute attr) {
+ List<String> selectors = new ArrayList<>();
+ for (BuildType.Selector<?> selector : ((BuildType.SelectorList<?>)
+ attributeMap.getRawAttributeValue(rule, attr)).getSelectors()) {
+ if (selector.isUnconditional()) {
+ selectors.add(outputAttrValue(
+ Iterables.getOnlyElement(selector.getEntries().entrySet()).getValue()));
+ } else {
+ selectors.add(String.format("select(%s)", outputAttrValue(selector.getEntries())));
+ }
+ }
+ return String.join(" + ", selectors);
+ }
+
+
@Override
public void processOutput(Iterable<Target> partialResult) throws InterruptedException {