Add "jsonproto" option to aquery/cquery --output flag.
Closes #10421
Closes #10426.
PiperOrigin-RevId: 286370369
diff --git a/src/main/java/com/google/devtools/build/lib/BUILD b/src/main/java/com/google/devtools/build/lib/BUILD
index 1b2c39e..c1ed327 100644
--- a/src/main/java/com/google/devtools/build/lib/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/BUILD
@@ -685,6 +685,7 @@
"//third_party:guava",
"//third_party:jsr305",
"//third_party/protobuf:protobuf_java",
+ "//third_party/protobuf:protobuf_java_util",
"@remoteapis//:build_bazel_remote_execution_v2_remote_execution_java_proto",
],
)
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 63d5a91..3a43ae3 100644
--- a/src/main/java/com/google/devtools/build/lib/query2/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/query2/BUILD
@@ -53,6 +53,7 @@
"//third_party:guava",
"//third_party:jsr305",
"//third_party/protobuf:protobuf_java",
+ "//third_party/protobuf:protobuf_java_util",
],
)
diff --git a/src/main/java/com/google/devtools/build/lib/query2/aquery/ActionGraphProtoOutputFormatterCallback.java b/src/main/java/com/google/devtools/build/lib/query2/aquery/ActionGraphProtoOutputFormatterCallback.java
index ee4158b..9283a24 100644
--- a/src/main/java/com/google/devtools/build/lib/query2/aquery/ActionGraphProtoOutputFormatterCallback.java
+++ b/src/main/java/com/google/devtools/build/lib/query2/aquery/ActionGraphProtoOutputFormatterCallback.java
@@ -25,6 +25,7 @@
import com.google.devtools.build.lib.skyframe.SkyframeExecutor;
import com.google.devtools.build.lib.skyframe.actiongraph.ActionGraphDump;
import com.google.protobuf.TextFormat;
+import com.google.protobuf.util.JsonFormat;
import java.io.IOException;
import java.io.OutputStream;
@@ -34,7 +35,8 @@
/** Defines the types of proto output this class can handle. */
public enum OutputType {
BINARY("proto"),
- TEXT("textproto");
+ TEXT("textproto"),
+ JSON("jsonproto");
private final String formatName;
@@ -50,6 +52,7 @@
private final OutputType outputType;
private final ActionGraphDump actionGraphDump;
private final AqueryActionFilter actionFilters;
+ private final JsonFormat.Printer jsonPrinter = JsonFormat.printer();
ActionGraphProtoOutputFormatterCallback(
ExtendedEventHandler eventHandler,
@@ -110,6 +113,10 @@
case TEXT:
TextFormat.print(actionGraphContainer, printStream);
break;
+ case JSON:
+ jsonPrinter.appendTo(actionGraphContainer, printStream);
+ printStream.println();
+ break;
default:
throw new IllegalStateException("Unknown outputType " + outputType.formatName());
}
diff --git a/src/main/java/com/google/devtools/build/lib/query2/aquery/ActionGraphQueryEnvironment.java b/src/main/java/com/google/devtools/build/lib/query2/aquery/ActionGraphQueryEnvironment.java
index 5e0e91e..00d7772 100644
--- a/src/main/java/com/google/devtools/build/lib/query2/aquery/ActionGraphQueryEnvironment.java
+++ b/src/main/java/com/google/devtools/build/lib/query2/aquery/ActionGraphQueryEnvironment.java
@@ -178,6 +178,14 @@
accessor,
StreamedOutputHandler.OutputType.TEXT,
actionFilters),
+ new ActionGraphProtoV2OutputFormatterCallback(
+ eventHandler,
+ aqueryOptions,
+ out,
+ skyframeExecutor,
+ accessor,
+ StreamedOutputHandler.OutputType.JSON,
+ actionFilters),
new ActionGraphTextOutputFormatterCallback(
eventHandler, aqueryOptions, out, skyframeExecutor, accessor, actionFilters))
: ImmutableList.of(
@@ -197,6 +205,14 @@
accessor,
OutputType.TEXT,
actionFilters),
+ new ActionGraphProtoOutputFormatterCallback(
+ eventHandler,
+ aqueryOptions,
+ out,
+ skyframeExecutor,
+ accessor,
+ OutputType.JSON,
+ actionFilters),
new ActionGraphTextOutputFormatterCallback(
eventHandler, aqueryOptions, out, skyframeExecutor, accessor, actionFilters));
}
diff --git a/src/main/java/com/google/devtools/build/lib/query2/aquery/AqueryOptions.java b/src/main/java/com/google/devtools/build/lib/query2/aquery/AqueryOptions.java
index da45a89..d0ed617 100644
--- a/src/main/java/com/google/devtools/build/lib/query2/aquery/AqueryOptions.java
+++ b/src/main/java/com/google/devtools/build/lib/query2/aquery/AqueryOptions.java
@@ -28,7 +28,7 @@
effectTags = {OptionEffectTag.TERMINAL_OUTPUT},
help =
"The format in which the aquery results should be printed. Allowed values for aquery "
- + "are: text, textproto, proto.")
+ + "are: text, textproto, proto, jsonproto.")
public String outputFormat;
@Option(
diff --git a/src/main/java/com/google/devtools/build/lib/query2/cquery/ConfiguredTargetQueryEnvironment.java b/src/main/java/com/google/devtools/build/lib/query2/cquery/ConfiguredTargetQueryEnvironment.java
index e6d82f7..5b05015 100644
--- a/src/main/java/com/google/devtools/build/lib/query2/cquery/ConfiguredTargetQueryEnvironment.java
+++ b/src/main/java/com/google/devtools/build/lib/query2/cquery/ConfiguredTargetQueryEnvironment.java
@@ -193,6 +193,14 @@
accessor,
aspectResolver,
OutputType.TEXT),
+ new ProtoOutputFormatterCallback(
+ eventHandler,
+ cqueryOptions,
+ out,
+ skyframeExecutor,
+ accessor,
+ aspectResolver,
+ OutputType.JSON),
new BuildOutputFormatterCallback(
eventHandler, cqueryOptions, out, skyframeExecutor, accessor));
}
diff --git a/src/main/java/com/google/devtools/build/lib/query2/cquery/CqueryOptions.java b/src/main/java/com/google/devtools/build/lib/query2/cquery/CqueryOptions.java
index 11884c2..2de9e3a 100644
--- a/src/main/java/com/google/devtools/build/lib/query2/cquery/CqueryOptions.java
+++ b/src/main/java/com/google/devtools/build/lib/query2/cquery/CqueryOptions.java
@@ -45,8 +45,8 @@
effectTags = {OptionEffectTag.TERMINAL_OUTPUT},
help =
"The format in which the cquery results should be printed. Allowed values for cquery "
- + "are: label, textproto, transitions, proto. If you select 'transitions', you also "
- + "have to specify the --transitions=(lite|full) option.")
+ + "are: label, textproto, transitions, proto, jsonproto. If you select "
+ + "'transitions', you also have to specify the --transitions=(lite|full) option.")
public String outputFormat;
@Option(
diff --git a/src/main/java/com/google/devtools/build/lib/query2/cquery/ProtoOutputFormatterCallback.java b/src/main/java/com/google/devtools/build/lib/query2/cquery/ProtoOutputFormatterCallback.java
index 10eaf03..cc79c8b 100644
--- a/src/main/java/com/google/devtools/build/lib/query2/cquery/ProtoOutputFormatterCallback.java
+++ b/src/main/java/com/google/devtools/build/lib/query2/cquery/ProtoOutputFormatterCallback.java
@@ -35,6 +35,7 @@
import com.google.devtools.build.lib.skyframe.SkyframeExecutor;
import com.google.protobuf.Message;
import com.google.protobuf.TextFormat;
+import com.google.protobuf.util.JsonFormat;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Map;
@@ -45,7 +46,8 @@
/** Defines the types of proto output this class can handle. */
public enum OutputType {
BINARY("proto"),
- TEXT("textproto");
+ TEXT("textproto"),
+ JSON("jsonproto");
private final String formatName;
@@ -60,6 +62,7 @@
private final OutputType outputType;
private final AspectResolver resolver;
+ private final JsonFormat.Printer jsonPrinter = JsonFormat.printer();
private AnalysisProtos.CqueryResult.Builder protoResult;
@@ -108,6 +111,10 @@
case TEXT:
TextFormat.print(message, printStream);
break;
+ case JSON:
+ jsonPrinter.appendTo(message, printStream);
+ printStream.append('\n');
+ break;
default:
throw new IllegalStateException("Unknown outputType " + outputType.formatName());
}
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/actiongraph/v2/StreamedOutputHandler.java b/src/main/java/com/google/devtools/build/lib/skyframe/actiongraph/v2/StreamedOutputHandler.java
index b857b6e..6412f03 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/actiongraph/v2/StreamedOutputHandler.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/actiongraph/v2/StreamedOutputHandler.java
@@ -16,6 +16,7 @@
import com.google.devtools.build.lib.analysis.AnalysisProtosV2.ActionGraphComponent;
import com.google.devtools.build.lib.analysis.AnalysisProtosV2.ActionGraphContainer;
import com.google.protobuf.CodedOutputStream;
+import com.google.protobuf.util.JsonFormat;
import java.io.IOException;
import java.io.PrintStream;
@@ -24,7 +25,8 @@
/** Defines the types of proto output this class can handle. */
public enum OutputType {
BINARY("proto"),
- TEXT("textproto");
+ TEXT("textproto"),
+ JSON("jsonproto");
private final String formatName;
@@ -40,6 +42,7 @@
private final OutputType outputType;
private final CodedOutputStream outputStream;
private final PrintStream printStream;
+ private final JsonFormat.Printer jsonPrinter = JsonFormat.printer();
public StreamedOutputHandler(
OutputType outputType, CodedOutputStream outputStream, PrintStream printStream) {
@@ -62,6 +65,10 @@
case TEXT:
printStream.print(wrapperActionGraphComponent(message));
break;
+ case JSON:
+ jsonPrinter.appendTo(message, printStream);
+ printStream.println();
+ break;
}
}
@@ -76,6 +83,7 @@
outputStream.flush();
break;
case TEXT:
+ case JSON:
printStream.flush();
printStream.close();
break;
diff --git a/src/test/shell/integration/aquery_test.sh b/src/test/shell/integration/aquery_test.sh
index 30425c1..e57d63e 100755
--- a/src/test/shell/integration/aquery_test.sh
+++ b/src/test/shell/integration/aquery_test.sh
@@ -132,7 +132,6 @@
assert_not_contains "echo unused" output
}
-
function test_aquery_include_artifacts() {
local pkg="${FUNCNAME[0]}"
mkdir -p "$pkg" || fail "mkdir -p $pkg"
@@ -187,6 +186,32 @@
assert_not_contains "echo unused" output
}
+function test_aquery_jsonproto() {
+ local pkg="${FUNCNAME[0]}"
+ mkdir -p "$pkg" || fail "mkdir -p $pkg"
+ cat > "$pkg/BUILD" <<'EOF'
+genrule(
+ name = "bar",
+ srcs = ["dummy.txt"],
+ outs = ["bar_out.txt"],
+ cmd = "echo unused > $(OUTS)",
+)
+EOF
+ echo "hello aquery" > "$pkg/in.txt"
+
+ bazel aquery --output=jsonproto "//$pkg:bar" > output 2> "$TEST_log" \
+ || fail "Expected success"
+ cat output >> "$TEST_log"
+ assert_contains "\"execPath\": \"$pkg/dummy.txt\"" output
+ assert_contains "\"mnemonic\": \"Genrule\"" output
+ assert_contains "\"mnemonic\": \".*-fastbuild\"" output
+ assert_contains "echo unused" output
+
+ bazel aquery --output=jsonproto --noinclude_commandline "//$pkg:bar" > output \
+ 2> "$TEST_log" || fail "Expected success"
+ assert_not_contains "echo unused" output
+}
+
function test_aquery_skylark_env() {
local pkg="${FUNCNAME[0]}"
mkdir -p "$pkg" || fail "mkdir -p $pkg"
@@ -1113,4 +1138,33 @@
assert_contains "mnemonic: \".*-fastbuild\"" output
assert_contains "echo unused" output
}
+
+function test_basic_aquery_jsonproto_v2() {
+ local pkg="${FUNCNAME[0]}"
+ mkdir -p "$pkg" || fail "mkdir -p $pkg"
+ cat > "$pkg/BUILD" <<'EOF'
+genrule(
+ name = "bar",
+ srcs = ["dummy.txt"],
+ outs = ["bar_out.txt"],
+ cmd = "echo unused > $(OUTS)",
+)
+EOF
+ bazel aquery --incompatible_proto_output_v2 --output=jsonproto "//$pkg:bar" > output 2> "$TEST_log" \
+ || fail "Expected success"
+ cat output >> "$TEST_log"
+
+ # Verify than ids come in integers instead of strings.
+ assert_contains "\"id\": 1," output
+ assert_not_contains "\"id\": \"1\"" output
+
+ # Verify that paths are broken down to path fragments.
+ assert_contains "\"pathFragment\": {" output
+
+ # Verify that the appropriate action was included.
+ assert_contains "\"label\": \"dummy.txt\"" output
+ assert_contains "\"mnemonic\": \"Genrule\"" output
+ assert_contains "\"mnemonic\": \".*-fastbuild\"" output
+ assert_contains "echo unused" output
+}
run_suite "${PRODUCT_NAME} action graph query tests"