# Set up Churro

> Instructions for a coding agent setting up Churro for a user. Churro is a cache of precompiled Rust dependencies: our builders compile popular crates.io crates, and Cargo downloads them instead of compiling them. Follow the steps in order; each one says how to check it worked.

How it works, in one paragraph: Churro is a `RUSTC_WRAPPER`, so Cargo runs it in place of `rustc`. For each dependency, if the cache holds a result built from exactly the same inputs (source, compiler, target, flags, features, environment), Churro downloads it and checks its signatures and hashes. Otherwise it runs `rustc` as usual. It never edits code, `Cargo.toml` or `Cargo.lock`, and it never uploads anything. The worst case is a normal build.

You're done when `churro --version` works, `RUSTC_WRAPPER=churro` is set wherever the user chose, and you've shown them `churro stats` after a build. Do every step you can yourself, and tell the user clearly when one needs them. If Churro is already partly set up, skip the steps that are done.

## Rules for you, the agent

- Ask the user before you edit anything outside the project: shell profiles, `~/.cargo/config.toml`, CI secrets.
- Don't set `rustc-wrapper` in the project's committed `.cargo/config.toml`. Builds would fail for anyone who doesn't have Churro installed.
- Churro replaces any `RUSTC_WRAPPER` already in use (such as sccache); the two don't chain. If one is set, ask the user before replacing it.
- Show the user the output of `churro stats` at the end, not a summary you made up.

## 1. Check the prerequisites

```sh
cargo --version
echo "RUSTC_WRAPPER=${RUSTC_WRAPPER:-unset}"
grep -s rustc-wrapper .cargo/config.toml ~/.cargo/config.toml
```

- No `cargo`: stop and ask the user to install Rust from https://rustup.rs.
- `RUSTC_WRAPPER` or `rustc-wrapper` already set to something other than `churro`: ask the user before going on.

## 2. Install the client

```sh
cargo install --locked --git https://github.com/usechurro/churro churro-client
churro --version
```

This compiles Churro from source, which takes a few minutes. It installs `churro` into `~/.cargo/bin`. If `churro --version` says the command isn't found, `~/.cargo/bin` isn't on `PATH`; tell the user.

## 3. Turn it on

Ask the user which of these they want. The first is enough to try it out.

**Just this shell**, for trying it:

```sh
export RUSTC_WRAPPER=churro CHURRO_HOST_ARTIFACTS=1
```

**Every project on this machine**: add the same line to the user's shell profile (`~/.zshrc`, `~/.bashrc` or `~/.config/fish/config.fish` with `set -gx`). Ask first.

**CI**: see [CI](#ci) below.

`CHURRO_HOST_ARTIFACTS=1` also serves proc macros and build scripts from the cache. It's experimental; leave it out if the user prefers.

## 4. Check the configuration

```sh
churro config
```

Read the `endpoint:` line:

- A URL: Churro will look dependencies up in that cache.
- `(none: everything compiles locally)`: this build of Churro has no shared cache configured. It still keeps a local cache on this machine, so the same dependencies built again in another checkout, worktree or project come from there. Tell the user; if they run their own cache, see [Using your own cache](#using-your-own-cache).
- `(not used: no root key)`: an endpoint is set but no key to verify it, so nothing from it would be trusted. Add the cache's root keys.

## 5. Build and check the result

Build in an empty target directory, so nothing is reused from an earlier build. Set the variables on the command itself: your shell may not keep an `export` from one command to the next.

```sh
RUSTC_WRAPPER=churro CHURRO_HOST_ARTIFACTS=1 CARGO_TARGET_DIR="$(mktemp -d)" cargo build
churro stats
```

`churro stats` counts every compile Churro has seen on this machine, by outcome:

| outcome | meaning |
|---|---|
| `hit-remote` | downloaded from the shared cache, already compiled |
| `hit-local` | reused from this machine's Churro cache |
| `miss` | not cached yet, so compiled here as usual and kept locally |
| `pass` | handed straight to `rustc`, with the reason listed (your own crates always are) |

A second build of the same project in another empty target directory should turn most misses into `hit-local`.

## 6. Tell the user

Say what you changed and where, paste the `churro stats` output, and say how to turn it off (below).

Optionally, offer to install the Churro Agent Skill, so later sessions know the commands and fixes without this page:

```sh
npx skills add https://churro.sh
```

## CI

The same two variables, set for the build steps, plus an install step. In GitHub Actions:

```yaml
env:
  RUSTC_WRAPPER: churro
  CHURRO_HOST_ARTIFACTS: "1"

steps:
  - uses: actions/checkout@v4
  - name: Install churro
    run: cargo install --locked --git https://github.com/usechurro/churro churro-client
    env:
      RUSTC_WRAPPER: ""
  - run: cargo build --locked
  - run: churro stats
```

The install step runs without the wrapper, since `churro` doesn't exist until it finishes. A fresh CI runner has an empty local cache, so it only gains from a shared cache: check that `churro config` shows an endpoint there (set `CHURRO_ENDPOINT` and `CHURRO_TRUST_ROOTS` for your own cache). `churro daemon start --profile dev` as an early step starts fetching dependencies before the build asks for them.

## Using your own cache

Teams can run their own cache with the same client and checks (see the [self-hosting commands](https://churro.sh/index.md#run-your-own)). `cargo ops client-config` prints the settings for its users. They go in `~/.config/churro/config.toml`:

```toml
endpoint = "https://cache.example.com"
[trust]
roots = ["<base64 ed25519 public key>"]
```

or in environment variables, which take precedence: `CHURRO_ENDPOINT` and `CHURRO_TRUST_ROOTS` (comma-separated).

## Turn it off

- One build without it: `CHURRO_DISABLE=1 cargo build`
- Off for good: remove the `RUSTC_WRAPPER` line you added, then `unset RUSTC_WRAPPER CHURRO_HOST_ARTIFACTS`
- Delete the local cache: `churro clean`
- Uninstall: `cargo uninstall churro-client`

## Troubleshooting

- **`could not execute process 'churro'`**: `churro` isn't on `PATH`. Add `~/.cargo/bin`, or unset `RUSTC_WRAPPER`.
- **No `hit-remote` at all**: run `churro config`. Without an endpoint and a root key nothing is looked up remotely. The shared cache is compiled for Linux, so builds on macOS and other systems only get local hits.
- **A dependency never hits**: a result is only used when every input matches: the exact crate version in `Cargo.lock`, the Rust release, target, profile, features, flags and environment. Changing any of them makes a different build.
- **A build fails with Churro but not without**: confirm with `CHURRO_DISABLE=1 cargo build`, then report it at https://github.com/usechurro/churro/issues with the error.
- **Help**: `churro help` lists every command and variable.

## More

- What Churro is and why it's safe: https://churro.sh/index.md
- Which crates are in the cache, and the public API: https://churro.sh/catalog.md
- An Agent Skill for Churro: https://churro.sh/.well-known/agent-skills/churro/SKILL.md
- Source: https://github.com/usechurro/churro
