--- layout: documentation title: Aquery (Action Graph Query) ---

# Aquery (Action Graph Query)

## Overview

Caution: The aquery command is still experimental and its API will change.

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 we 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. 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):

    $ bazel aquery 'deps(//some:label)'
    action 'Writing file some_file_name'
      Mnemonic: ...
      Owner: ...
      Configuration: ...
      ActionKey: ...
      Inputs: [...]
      Outputs: [...]

## Basic Syntax

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.
- `function(...)`: the standard functions as traditional `query`.
- `//target` is the label to the interested target.

    # 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))'

## Aquery Functions

There are currently 3 `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:

      $ bazel aquery 'mnemonic("Cpp.*", (inputs(".*cpp", inputs("foo.*", //src/target_a))))'

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:

              $ 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))

## Options

### Build Options

`aquery` runs on top of a regular Bazel build and thus inherits the set of options available during a build.

### Aquery options

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

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

#### `--include_commandline, default=true`

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

#### `--include_aspects, default=false`

Whether to include Aspect-generated actions in the output.

#### `--include_param_files, default=false`

Include the content of the param files used in the command (potentially large). Warning: Enabling this flag will automatically enable the `--include_commandline` flag.

## Miscellaneous

### Aspect-on-Aspect

It is possible for 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:

      t0
      ^
      | <- a1
      t1
      ^
      | <- a2
      t2

Let ti be a target of rule ri, which applies an Aspect ai 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:

      action ...
      Mnemonic: ...
      Target: //my_pkg:t0
      Configuration: ...
      AspectDescriptors: [//my_pkg:rule.bzl%a2(foo=...)
        -> //my_pkg:rule.bzl%a1(bar=...)]
      ...

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:

      AspectClass([param=value,...])

`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.

## Known Issues

The list of aquery issues/planned features can be found on GitHub.

## Updates

Aquery is a work in progress, and its API might change in the future. Please contact twerth@google.com and leba@google.com for any issue/feature request.