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

# Dependency and Action Graphs

> Understand how Bazel rule implementations lower the dependency graph into the action graph, and inspect both with query, cquery, and aquery.

**Goal**: Understand how rule implementations lower the Dependency graph to the Action graph and how the commands `query` , `cquery` , and `aquery` allow you to inspect these graphs.

## The Dependency Graph

In the **Loading phase**, Bazel loads all of the `BUILD.bazel` files needed for whatever targets or target patterns you request.

These targets form a Directed Acyclic Graph (DAG) called the "dependency graph".

Each node is a target, and the edges are dependencies. The edges have different types, which are often:

* `srcs` are source files in version control
* `deps` are other targets that produce some outputs
* `data` files, which should be propagated to any binary or test that transitively depends on this, is better thought of as “runtime\_deps”

```mermaid theme={null}
graph TD
  foo_bin --> |dep| bar_lib
  bar_lib --> |src| lib.py
  bar_lib --> |data| config.json
  bar_lib --> |dep| TP["@some_third_party//:lib"]
```

### Exercise: `bazel query`

Perform some queries in the examples repo. For example:

* Which binary targets can be run?
* Which tests are short timeouts?
* Which target depends on a proto\_library and why?

# Configuration and Transitions

Take this example:

```python theme={null}
cc_binary(
    name = "server",
    srcs = ["server.cc"],
    deps = select({
        "//build_env:debug": [":debug_logging_lib"],
        "//build_env:mobile": [":mobile_shim"],
        "//conditions:default": [":prod_lib"],
    }),
)
```

This graph may differ based on configuration, for example the `select` function can change the `deps` of a target depending on the target platform. The “Configured dependency graph” includes a hash of the configuration.

When a node in the Configured Dependency Graph has a different configuration than its child, this is called a “transition”.

For example, this graph in the examples repo transitions between a configuration for building Java test code (with hash `8201991`) and another configuration for the rest (with hash `db7e569`)

<img src="https://mintcdn.com/aspectbuild/gtqBKXWWd-jWHweY/learning/bazel-201/java_query.svg?fit=max&auto=format&n=gtqBKXWWd-jWHweY&q=85&s=569df4aeafa7b1ec8c5cfa3e6396746f" alt="java_query.svg" width="1045" height="443" data-path="learning/bazel-201/java_query.svg" />

### Exercise: `bazel cquery`

<Warning>
  `cquery` means "configured query" which is typically what you want, as it is faster.
</Warning>

The [Bazel query guide](https://bazel.build/query/guide) and [cquery documentation](https://bazel.build/query/cquery) are quite good. Here are some queries you can try in the `logger` folder now to get started.

* What are all the binary targets in the repository?

```
bazel cquery 'kind(.*_binary, //...)'
```

* What are all the binary targets in the `logger` project?

```
bazel cquery 'kind(.*_binary, //logger/...)'
```

* Draw a diagram of all the dependencies of a target.

```
# apt install graphviz xdot
# brew install graphviz xdot
xdot <(bazel query "deps(//logger/client/src/build/aspect:JavaLoggingClient)" --notool_deps --noimplicit_deps  --output graph)
```

* Why does your binary depend on a particular third-party library?

### The Action Graph

In the **Analysis phase**, the dependency graph is "lowered" to an action graph.

In the action graph, each node is a subprocess to spawn (invoking some tool) with the arguments, environment, and so on for invoking it. The edges are Providers which are output by one action and needed as inputs to another.

As a special case, the “DefaultInfo” provider gives the default output files of the action.

```mermaid theme={null}
graph TD
  tsc["tsc<br>--flag1 --flag2"] --> |DefaultInfo| swc
```

The graphs are NOT one-to-one!
For example, a `ts_project` rule with a custom transpiler produces several actions.

### Querying the action graph

This is a valuable skill when debugging a failure of some rule, especially when required inputs aren't declared.

You can run arbitrary starlark programs on the action graph with `--output=starlark` which is a powerful tool.

### Exercise: `bazel aquery`

* What are the declared input files to the compile action for a library target you've created?
* What providers are produced by the library target? (You'll need a tiny Starlark program)

## Summary

|                    | **Dependency Graph**              | **Action Graph**           |
| ------------------ | --------------------------------- | -------------------------- |
| Represents         | Logical structure of the code     | Subprocess spawns of tools |
| Constructed during | Loading phase                     | Analysis phase             |
| Nodes are          | Targets                           | Actions                    |
| Edges are          | Dependencies                      | Providers (files)          |
| Inspect with       | `bazel query`<br />`bazel cquery` | `bazel aquery`             |
