Output template content and substitutions of TemplateExpansionAction actions in aquery result.
PiperOrigin-RevId: 405780883
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/actions/Template.java b/src/main/java/com/google/devtools/build/lib/analysis/actions/Template.java
index fa24165..28ecf53 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/actions/Template.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/actions/Template.java
@@ -48,6 +48,11 @@
*/
protected abstract String getKey();
+ @Override
+ public String toString() {
+ return getKey();
+ }
+
private static final class ErrorTemplate extends Template {
private final IOException e;
private final String templateName;
diff --git a/src/main/java/com/google/devtools/build/lib/query2/BUILD b/src/main/java/com/google/devtools/build/lib/query2/BUILD
index 8e8486c..32b665d 100644
--- a/src/main/java/com/google/devtools/build/lib/query2/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/query2/BUILD
@@ -28,6 +28,8 @@
"//src/main/java/com/google/devtools/build/lib/actions:commandline_item",
"//src/main/java/com/google/devtools/build/lib/actions:file_metadata",
"//src/main/java/com/google/devtools/build/lib/analysis:actions/parameter_file_write_action",
+ "//src/main/java/com/google/devtools/build/lib/analysis:actions/substitution",
+ "//src/main/java/com/google/devtools/build/lib/analysis:actions/template_expansion_action",
"//src/main/java/com/google/devtools/build/lib/analysis:analysis_cluster",
"//src/main/java/com/google/devtools/build/lib/analysis:config/build_configuration",
"//src/main/java/com/google/devtools/build/lib/analysis:config/build_options",
diff --git a/src/main/java/com/google/devtools/build/lib/query2/aquery/ActionGraphTextOutputFormatterCallback.java b/src/main/java/com/google/devtools/build/lib/query2/aquery/ActionGraphTextOutputFormatterCallback.java
index 78fe828..19b7fb8 100644
--- a/src/main/java/com/google/devtools/build/lib/query2/aquery/ActionGraphTextOutputFormatterCallback.java
+++ b/src/main/java/com/google/devtools/build/lib/query2/aquery/ActionGraphTextOutputFormatterCallback.java
@@ -29,6 +29,8 @@
import com.google.devtools.build.lib.analysis.AspectValue;
import com.google.devtools.build.lib.analysis.ConfiguredTargetValue;
import com.google.devtools.build.lib.analysis.actions.ParameterFileWriteAction;
+import com.google.devtools.build.lib.analysis.actions.Substitution;
+import com.google.devtools.build.lib.analysis.actions.TemplateExpansionAction;
import com.google.devtools.build.lib.buildeventstream.BuildEvent;
import com.google.devtools.build.lib.buildeventstream.BuildEventStreamProtos;
import com.google.devtools.build.lib.events.ExtendedEventHandler;
@@ -298,6 +300,23 @@
.append("}\n");
}
+ if (action instanceof TemplateExpansionAction) {
+ stringBuilder
+ .append(" Template: ")
+ .append(((TemplateExpansionAction) action).getTemplate())
+ .append("\n");
+ stringBuilder.append(" Substitutions: [\n");
+ for (Substitution substitution : ((TemplateExpansionAction) action).getSubstitutions()) {
+ stringBuilder
+ .append(" {")
+ .append(substitution.getKey())
+ .append(": ")
+ .append(substitution.getValue())
+ .append("}\n");
+ }
+ stringBuilder.append(" ]\n");
+ }
+
stringBuilder.append('\n');
printStream.write(stringBuilder.toString().getBytes(UTF_8));
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/BUILD b/src/main/java/com/google/devtools/build/lib/skyframe/BUILD
index 99aa2d0..78f260b 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/BUILD
@@ -228,6 +228,8 @@
"//src/main/java/com/google/devtools/build/lib/actions:thread_state_receiver",
"//src/main/java/com/google/devtools/build/lib/actionsketch:action_sketch",
"//src/main/java/com/google/devtools/build/lib/analysis:actions/parameter_file_write_action",
+ "//src/main/java/com/google/devtools/build/lib/analysis:actions/substitution",
+ "//src/main/java/com/google/devtools/build/lib/analysis:actions/template_expansion_action",
"//src/main/java/com/google/devtools/build/lib/analysis:analysis_cluster",
"//src/main/java/com/google/devtools/build/lib/analysis:analysis_options",
"//src/main/java/com/google/devtools/build/lib/analysis:aspect_collection",
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/actiongraph/v2/ActionGraphDump.java b/src/main/java/com/google/devtools/build/lib/skyframe/actiongraph/v2/ActionGraphDump.java
index 5cc56c9..53f6879 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/actiongraph/v2/ActionGraphDump.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/actiongraph/v2/ActionGraphDump.java
@@ -30,6 +30,8 @@
import com.google.devtools.build.lib.analysis.ConfiguredTargetValue;
import com.google.devtools.build.lib.analysis.actions.ParameterFileWriteAction;
import com.google.devtools.build.lib.analysis.actions.SpawnAction;
+import com.google.devtools.build.lib.analysis.actions.Substitution;
+import com.google.devtools.build.lib.analysis.actions.TemplateExpansionAction;
import com.google.devtools.build.lib.analysis.configuredtargets.RuleConfiguredTarget;
import com.google.devtools.build.lib.buildeventstream.BuildEvent;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
@@ -235,6 +237,16 @@
knownArtifacts.dataToIdAndStreamOutputProto(action.getPrimaryOutput()));
}
+ if (action instanceof TemplateExpansionAction) {
+ actionBuilder.setTemplateContent(((TemplateExpansionAction) action).getTemplate().toString());
+ for (Substitution substitution : ((TemplateExpansionAction) action).getSubstitutions()) {
+ actionBuilder.addSubstitutions(
+ AnalysisProtosV2.KeyValuePair.newBuilder()
+ .setKey(substitution.getKey())
+ .setValue(substitution.getValue()));
+ }
+ }
+
aqueryOutputHandler.outputAction(actionBuilder.build());
}
diff --git a/src/main/protobuf/analysis_v2.proto b/src/main/protobuf/analysis_v2.proto
index a828925..b886fde 100644
--- a/src/main/protobuf/analysis_v2.proto
+++ b/src/main/protobuf/analysis_v2.proto
@@ -104,6 +104,14 @@
// The execution platform for this action. Empty if the action has no
// execution platform.
string execution_platform = 14;
+
+ // The template content of the action, if it is TemplateExpand action.
+ string template_content = 15;
+
+ // The list of substitution should be performed on the template. The key is
+ // the string to be substituted and the value is the string to be substituted
+ // to.
+ repeated KeyValuePair substitutions = 16;
}
// Represents a single target (without configuration information) that is
diff --git a/src/test/shell/integration/aquery_test.sh b/src/test/shell/integration/aquery_test.sh
index f51ee77..f69ada1 100755
--- a/src/test/shell/integration/aquery_test.sh
+++ b/src/test/shell/integration/aquery_test.sh
@@ -1406,6 +1406,89 @@
expect_log "-fastbuild: 1"
}
+function test_aquery_include_template_substitution_for_template_expand_of_py_binary() {
+ local pkg="${FUNCNAME[0]}"
+ mkdir -p "$pkg" || fail "mkdir -p $pkg"
+ cat > "$pkg/BUILD" <<'EOF'
+py_binary(
+ name='foo',
+ srcs=['foo.py']
+)
+EOF
+
+ # aquery returns template content and substitutions in TemplateExpand actions
+ # of py_binary targets.
+ QUERY="//$pkg:foo"
+
+ bazel aquery --output=text ${QUERY} > output 2> "$TEST_log" \
+ || fail "Expected success"
+ cat output >> "$TEST_log"
+
+ assert_contains "PYTHON_BINARY = '%python_binary%'" output
+ assert_contains "{%python_binary%:" output
+
+ bazel aquery --output=jsonproto ${QUERY} > output 2> "$TEST_log" \
+ || fail "Expected success"
+
+ assert_contains "\"templateContent\":" output
+ assert_contains "\"key\": \"%python_binary%\"" output
+}
+
+function test_aquery_include_template_substitution_for_template_expand_action() {
+ local pkg="${FUNCNAME[0]}"
+ mkdir -p "$pkg" || fail "mkdir -p $pkg"
+
+ cat > "$pkg/template.txt" <<'EOF'
+The token should be substituted: {TOKEN1}
+EOF
+
+ cat > "$pkg/test.bzl" <<'EOF'
+def test_template(**kwargs):
+ _test_template(
+ **kwargs
+ )
+def _test_template_impl(ctx):
+ ctx.actions.expand_template(
+ template = ctx.file.template,
+ output = ctx.outputs.output,
+ substitutions = {
+ "{TOKEN1}": "123456",
+ },
+ )
+_test_template = rule(
+ implementation = _test_template_impl,
+ attrs = {
+ "template": attr.label(
+ allow_single_file = True,
+ ),
+ "output": attr.output(mandatory = True),
+ },
+)
+EOF
+
+ cat > "$pkg/BUILD" <<'EOF'
+load('test.bzl', 'test_template')
+test_template(name='foo', template='template.txt', output='output.txt')
+EOF
+
+ # aquery returns template content and substitutions of TemplateExpand actions.
+ QUERY="//$pkg:foo"
+
+ bazel aquery --output=text ${QUERY} > output 2> "$TEST_log" \
+ || fail "Expected success"
+ cat output >> "$TEST_log"
+
+ assert_contains "Template: ARTIFACT: $pkg/template.txt" output
+ assert_contains "{{TOKEN1}: 123456}" output
+
+ bazel aquery --output=jsonproto ${QUERY} > output 2> "$TEST_log" \
+ || fail "Expected success"
+
+ assert_contains "\"templateContent\": \"ARTIFACT: $pkg/template.txt\"" output
+ assert_contains "\"key\": \"{TOKEN1}\"" output
+ assert_contains "\"value\": \"123456\"" output
+}
+
# Usage: assert_matches expected_pattern actual
function assert_matches() {
[[ "$2" =~ $1 ]] || fail "Expected to match '$1', was: $2"