> ## Documentation Index
> Fetch the complete documentation index at: https://bazel-pr-29946.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Action Graph Query (aquery)

The `aquery` command allows you to query for actions in your build graph.
It operates on the post-analysis Configured Target Graph and exposes
information about **Actions, Artifacts and their relationships.**

`aquery` is useful when you are interested in the properties of the Actions/Artifacts
generated from the Configured Target Graph. For example, the actual commands run
and their inputs/outputs/mnemonics.

The tool accepts several command-line [options](#command-options).
Notably, the aquery command runs on top of a regular Bazel build and inherits
the set of options available during a build.

It supports the same set of functions that is also available to traditional
`query` but `siblings`, `buildfiles` and
`tests`.

An example `aquery` output (without specific details):

<pre>
  \$ bazel aquery 'deps(//some:label)'
  action 'Writing file some\_file\_name'
  Mnemonic: ...
  Target: ...
  Configuration: ...
  ActionKey: ...
  Inputs: \[...]
  Outputs: \[...]
</pre>

<h2 id="basic-syntax">
  Basic syntax
</h2>

A simple example of the syntax for `aquery` is as follows:

`bazel aquery "aquery_function(function(//target))"`

The query expression (in quotes) consists of the following:

* `aquery_function(...)`: functions specific to `aquery`.
  More details [below](#using-aquery-functions).
* `function(...)`: the standard [functions](/versions/8.3.1/query/language#functions)
  as traditional `query`.
* `//target` is the label to the interested target.

<pre>
  # aquery examples:

  # Get the action graph generated while building //src/target\_a

  \$ bazel aquery '//src/target\_a'

  # Get the action graph generated while building all dependencies of //src/target\_a

  \$ bazel aquery 'deps(//src/target\_a)'

  # Get the action graph generated while building all dependencies of //src/target\_a

  # whose inputs filenames match the regex ".\*cpp".

  \$ bazel aquery 'inputs(".\*cpp", deps(//src/target\_a))'
</pre>

<h2 id="using-aquery-functions">
  Using aquery functions
</h2>

There are three `aquery` functions:

* `inputs`: filter actions by inputs.
* `outputs`: filter actions by outputs
* `mnemonic`: filter actions by mnemonic

`expr ::= inputs(word, expr)`

The `inputs` operator returns the actions generated from building `expr`,
whose input filenames match the regex provided by `word`.

`$ bazel aquery 'inputs(".*cpp", deps(//src/target_a))'`

`outputs` and `mnemonic` functions share a similar syntax.

You can also combine functions to achieve the AND operation. For example:

<pre>
  \$ bazel aquery 'mnemonic("Cpp.\*", (inputs(".*cpp", inputs("foo.*", //src/target\_a))))'
</pre>

The above command would find all actions involved in building `//src/target_a`,
whose mnemonics match `"Cpp.*"` and inputs match the patterns
`".*cpp"` and `"foo.*"`.

Important: aquery functions can't be nested inside non-aquery functions.
Conceptually, this makes sense since the output of aquery functions is Actions,
not Configured Targets.

An example of the syntax error produced:

<pre>
  \$ bazel aquery 'deps(inputs(".\*cpp", //src/target\_a))'
  ERROR: aquery filter functions (inputs, outputs, mnemonic) produce actions,
  and therefore can't be the input of other function types: deps
  deps(inputs(".\*cpp", //src/target\_a))
</pre>

<h2 id="options">
  Options
</h2>

<h3 id="build-options">
  Build options
</h3>

`aquery` runs on top of a regular Bazel build and thus inherits the set of
[options](/versions/8.3.1/reference/command-line-reference#build-options)
available during a build.

<h3 id="aquery-options">
  Aquery options
</h3>

#### `--output=(text|summary|proto|jsonproto|textproto), default=text`

The default output format (`text`) is human-readable,
use `proto`, `textproto`, or `jsonproto` for machine-readable format.
The proto message is `analysis.ActionGraphContainer`.

<h4 id="include-commandline">
  `--include_commandline, default=true`
</h4>

Includes the content of the action command lines in the output (potentially large).

<h4 id="include-artifacts">
  `--include_artifacts, default=true`
</h4>

Includes names of the action inputs and outputs in the output (potentially large).

<h4 id="include-aspects">
  `--include_aspects, default=true`
</h4>

Whether to include Aspect-generated actions in the output.

<h4 id="include-param-files">
  `--include_param_files, default=false`
</h4>

Include the content of the param files used in the command (potentially large).

Warning: Enabling this flag will automatically enable the `--include_commandline` flag.

<h4 id="include-file-write-contents">
  `--include_file_write_contents, default=false`
</h4>

Include file contents for the `actions.write()` action and the contents of the
manifest file for the `SourceSymlinkManifest` action The file contents is
returned in the `file_contents` field with `--output=`xxx`proto`.
With `--output=text`, the output has

```
FileWriteContents: [<base64-encoded file contents>]
```

line

<h4 id="skyframe-state">
  `--skyframe_state, default=false`
</h4>

Without performing extra analysis, dump the Action Graph from Skyframe.

Note: Specifying a target with `--skyframe_state` is currently not supported.
This flag is only available with `--output=proto` or `--output=textproto`.

<h2 id="other-tools-features">
  Other tools and features
</h2>

<h3 id="querying-against-skyframe">
  Querying against the state of Skyframe
</h3>

[Skyframe](/versions/8.3.1/reference/skyframe) is the evaluation and
incrementality model of Bazel. On each instance of Bazel server, Skyframe stores the dependency graph
constructed from the previous runs of the [Analysis phase](/versions/8.3.1/run/build#analysis).

In some cases, it is useful to query the Action Graph on Skyframe.
An example use case would be:

1. Run `bazel build //target_a`
2. Run `bazel build //target_b`
3. File `foo.out` was generated.

*As a Bazel user, I want to determine if `foo.out` was generated from building
`//target_a` or `//target_b`*.

One could run `bazel aquery 'outputs("foo.out", //target_a)'` and
`bazel aquery 'outputs("foo.out", //target_b)'` to figure out the action responsible
for creating `foo.out`, and in turn the target. However, the number of different
targets previously built can be larger than 2, which makes running multiple `aquery`
commands a hassle.

As an alternative, the `--skyframe_state` flag can be used:

<pre>
  # List all actions on Skyframe's action graph

  \$ bazel aquery --output=proto --skyframe\_state

  # or

  # List all actions on Skyframe's action graph, whose output matches "foo.out"

  \$ bazel aquery --output=proto --skyframe\_state 'outputs("foo.out")'
</pre>

With `--skyframe_state` mode, `aquery` takes the content of the Action Graph
that Skyframe keeps on the instance of Bazel, (optionally) performs filtering on it and
outputs the content, without re-running the analysis phase.

<h4 id="special-considerations">
  Special considerations
</h4>

<h5 id="output-format">
  Output format
</h5>

`--skyframe_state` is currently only available for `--output=proto`
and `--output=textproto`

<h5 id="target-labels-non-inclusion">
  Non-inclusion of target labels in the query expression
</h5>

Currently, `--skyframe_state` queries the whole action graph that exists on Skyframe,
regardless of the targets. Having the target label specified in the query together with
`--skyframe_state` is considered a syntax error:

<pre>
  # WRONG: Target Included

  \$ bazel aquery --output=proto --skyframe\_state **//target\_a**
  ERROR: Error while parsing '//target\_a)': Specifying build target(s) \[//target\_a] with --skyframe\_state is currently not supported.

  # WRONG: Target Included

  \$ bazel aquery --output=proto --skyframe\_state 'inputs(".\*.java", **//target\_a**)'
  ERROR: Error while parsing '//target\_a)': Specifying build target(s) \[//target\_a] with --skyframe\_state is currently not supported.

  # CORRECT: Without Target

  $bazel aquery --output=proto --skyframe_state
     $ bazel aquery --output=proto --skyframe\_state 'inputs(".\*.java")'
</pre>

<h3 id="comparing-aquery-outputs">
  Comparing aquery outputs
</h3>

You can compare the outputs of two different aquery invocations using the `aquery_differ` tool.
For instance: when you make some changes to your rule definition and want to verify that the
command lines being run did not change. `aquery_differ` is the tool for that.

The tool is available in the [bazelbuild/bazel](https://github.com/bazelbuild/bazel/tree/master/tools/aquery_differ) repository.
To use it, clone the repository to your local machine. An example usage:

<pre>
  \$ bazel run //tools/aquery\_differ -- \
  \--before=/path/to/before.proto \
  \--after=/path/to/after.proto \
  \--input\_type=proto \
  \--attrs=cmdline \
  \--attrs=inputs
</pre>

The above command returns the difference between the `before` and `after` aquery outputs:
which actions were present in one but not the other, which actions have different
command line/inputs in each aquery output, ...). The result of running the above command would be:

<pre>
  Aquery output 'after' change contains an action that generates the following outputs that aquery output 'before' change doesn't:
  ...
  /list of output files/
  ...

  \[cmdline]
  Difference in the action that generates the following output(s):
  /path/to/abc.out
  \--- /path/to/before.proto
  \+++ /path/to/after.proto
  @@ -1,3 +1,3 @@
  ...
  /cmdline diff, in unified diff format/
  ...
</pre>

<h4 id="command-options">
  Command options
</h4>

`--before, --after`: The aquery output files to be compared

`--input_type=(proto|text_proto), default=proto`: the format of the input
files. Support is provided for `proto` and `textproto` aquery output.

`--attrs=(cmdline|inputs), default=cmdline`: the attributes of actions
to be compared.

<h3 id="aspect-on-aspect">
  Aspect-on-aspect
</h3>

It is possible for [Aspects](/versions/8.3.1/extending/aspects)
to be applied on top of each other. The aquery output of the action generated by
these Aspects would then include the *Aspect path*, which is the sequence of
Aspects applied to the target which generated the action.

An example of Aspect-on-Aspect:

<pre>
  t0
  ^
  \| \<- a1
  t1
  ^
  \| \<- a2
  t2
</pre>

Let t<sub>i</sub> be a target of rule r<sub>i</sub>, which applies an Aspect a<sub>i</sub>
to its dependencies.

Assume that a2 generates an action X when applied to target t0. The text output of
`bazel aquery --include_aspects 'deps(//t2)'` for action X would be:

<pre>
  action ...
  Mnemonic: ...
  Target: //my\_pkg:t0
  Configuration: ...
  AspectDescriptors: \[//my\_pkg:rule.bzl%**a2**(foo=...)
  -> //my\_pkg:rule.bzl%**a1**(bar=...)]
  ...
</pre>

This means that action `X` was generated by Aspect `a2` applied onto
`a1(t0)`, where `a1(t0)` is the result of Aspect `a1` applied
onto target `t0`.

Each `AspectDescriptor` has the following format:

<pre>
  AspectClass(\[param=value,...])
</pre>

`AspectClass` could be the name of the Aspect class (for native Aspects) or
`bzl_file%aspect_name` (for Starlark Aspects). `AspectDescriptor` are
sorted in topological order of the
[dependency graph](/versions/8.3.1/extending/aspects#aspect_basics).

<h3 id="linking-with-json-profile">
  Linking with the JSON profile
</h3>

While aquery provides information about the actions being run in a build (why they're being run,
their inputs/outputs), the [JSON profile](/versions/8.3.1/rules/performance#performance-profiling)
tells us the timing and duration of their execution.
It is possible to combine these 2 sets of information via a common denominator: an action's primary output.

To include actions' outputs in the JSON profile, generate the profile with
`--experimental_include_primary_output --noslim_profile`.
Slim profiles are incompatible with the inclusion of primary outputs. An action's primary output
is included by default by aquery.

We don't currently provide a canonical tool to combine these 2 data sources, but you should be
able to build your own script with the above information.

<h2 id="known-issues">
  Known issues
</h2>

<h3 id="handling-shared-actions">
  Handling shared actions
</h3>

Sometimes actions are
[shared](https://source.bazel.build/bazel/+/master:src/main/java/com/google/devtools/build/lib/actions/Actions.java;l=59;drc=146d51aa1ec9dcb721a7483479ef0b1ac21d39f1)
between configured targets.

In the execution phase, those shared actions are
[simply considered as one](https://source.bazel.build/bazel/+/master:src/main/java/com/google/devtools/build/lib/actions/Actions.java;l=241;drc=003b8734036a07b496012730964ac220f486b61f) and only executed once.
However, aquery operates on the pre-execution, post-analysis action graph, and hence treats these
like separate actions whose output Artifacts have the exact same `execPath`. As a result,
equivalent Artifacts appear duplicated.

The list of aquery issues/planned features can be found on
[GitHub](https://github.com/bazelbuild/bazel/labels/team-Performance).

<h2 id="faqs">
  FAQs
</h2>

<h3 id="actionkey-same">
  The ActionKey remains the same even though the content of an input file changed.
</h3>

In the context of aquery, the `ActionKey` refers to the `String` gotten from
[ActionAnalysisMetadata#getKey](https://source.bazel.build/bazel/+/master:src/main/java/com/google/devtools/build/lib/actions/ActionAnalysisMetadata.java;l=89;drc=8b856f5484f0117b2aebc302f849c2a15f273310):

<pre>
  Returns a string encoding all of the significant behaviour of this Action that might affect the
  output. The general contract of `getKey` is this: if the work to be performed by the
  execution of this action changes, the key must change.

  ...

  Examples of changes that should affect the key are:

  * Changes to the BUILD file that materially affect the rule which gave rise to this Action.
  * Changes to the command-line options, environment, or other global configuration resources
    which affect the behaviour of this kind of Action (other than changes to the names of the
    input/output files, which are handled externally).
  * An upgrade to the build tools which changes the program logic of this kind of Action
    (typically this is achieved by incorporating a UUID into the key, which is changed each
    time the program logic of this action changes).
    Note the following exception: for actions that discover inputs, the key must change if any
    input names change or else action validation may falsely validate.
</pre>

This excludes the changes to the content of the input files, and is not to be confused with
[RemoteCacheClient#ActionKey](https://source.bazel.build/bazel/+/master:src/main/java/com/google/devtools/build/lib/remote/common/RemoteCacheClient.java;l=38;drc=21577f202eb90ce94a337ebd2ede824d609537b6).

<h2 id="updates">
  Updates
</h2>

For any issues/feature requests, please file an issue [here](https://github.com/bazelbuild/bazel/issues/new).
