Documentation Index
Fetch the complete documentation index at: https://docs.aspect.build/llms.txt
Use this file to discover all available pages before exploring further.
This is the per-task migration guide for
aspect gazelle. See Migrating from legacy YAML-configured tasks for shared setup (CLI version pinning, the recommended two-step migration path, top-level workspaces:).gazelle task ran a bazel-gazelle .check target against the repo and annotated the build with the produced diff if BUILD files were out of date. aspect gazelle replaces it (and also subsumes the older configure task — see below).
aspect gazelle builds your gazelle target and runs it once with -mode=diff to capture the unified diff that gazelle would produce. From there, two modes:
- Default (apply mode): the captured diff is applied to your working tree via
git apply -p0. Best for local development. --check(check mode): the diff is reported without modifying the tree. Recommended for CI.
Two legacy tasks, one new task
Rosetta had two different YAML tasks that both produced “BUILD files are out of date” verdicts:gazelle— ran a user-definedgazelle.checktarget (default//:gazelle.check) and looked at its exit code + stderr. Most users with bespoke gazelle setups landed here.configure— ran the legacy aspect-cli’s built-inbazel configurecommand, which embedded a prebuilt gazelle binary inside the CLI itself. No//tools/gazelletarget was required because the binary shipped with the CLI. This task wasn’t in wide use; it was the path for repos that didn’t want to maintain their own gazelle target.
aspect gazelle. Today the new task needs a //tools/gazelle:gazelle target wired to aspect_gazelle_prebuilt — see Setup. For configure users, the key thing is that aspect_gazelle_prebuilt fetches a prebuilt gazelle binary, so you keep configure’s “no Go toolchain, no build-from-source” benefit; the only new step is declaring that one target once in tools/gazelle/BUILD.
Setup
Addaspect_gazelle_prebuilt to MODULE.bazel and define a gazelle target. We recommend the prebuilt binary (no Go toolchain required); see the aspect-gazelle release notes for the latest version.
bazel-contrib/bazel-gazelle macro + a Go toolchain), aspect gazelle works against that too. The current implementation’s runtime -mode=diff override is portable across both prebuilt and from-source wrappers.
What changed
| Area | YAML-configured tasks | Aspect CLI tasks |
|---|---|---|
| Invocation | rosetta run gazelle · rosetta run configure (which called bazel configure internally) | aspect gazelle |
| Gazelle binary | gazelle: user-supplied target (default //:gazelle.check) · configure: built into the legacy aspect-cli | User-supplied target (default //tools/gazelle:gazelle); future: bundled, like configure |
| Target | gazelle: target: (default //:gazelle.check) · configure: n/a — used the bundled binary | --gazelle-target (default //tools/gazelle:gazelle) |
| Mode | Both always -mode diff (gazelle.check ran gazelle that way; bazel configure passed --mode=diff) | Default applies via git apply -p0; --check keeps tree clean (recommended in CI) |
| Gazelle subcommand | Always the default (no explicit subcommand) | --gazelle-command=fix|update (default: none — gazelle’s own default applies) |
| Extra gazelle flags | None — no passthrough | --gazelle-flag=<flag> (repeatable) — forwarded to the gazelle binary |
| Directory scope | Whole repo | Positional args after flags: aspect gazelle tools/go services/api — gazelle only walks those subtrees |
| Detection | gazelle: exit code from the gazelle binary; non-zero meant BUILDs out of date · configure: special CONFIGURE_DIFF exit code | Captured -mode=diff stdout — non-empty diff = BUILDs out of date |
| Apply path | Both out-of-band: user runs bazel run //:gazelle (or bazel configure for the configure task) after the failed CI step, then commits | In-band by default: git apply -p0 <captured-diff> updates the working tree as part of the aspect gazelle invocation. --check mirrors the legacy diff-only behavior (recommended in CI) |
| Gazelle invocations per task run | One (the gazelle binary itself) | One — the apply step uses git apply, not a second gazelle invocation, which avoids re-running gazelle’s slow whole-repo scan |
| Diff archival | Both: annotated with the (truncated) task output | --upload-gazelle-diff (off by default) uploads the patch as a CI artifact via the same uploader build/test/format use; download URL is recorded on ArtifactsTrait.artifact_urls["gazelle_diff"] |
| Workspaces | workspaces: top-level list ran each task once per directory | cd <dir> in your CI config; run aspect gazelle from there. To cover multiple workspaces, declare a separate CI step per directory. |
Configuration migration
Many of the settings below can be applied in either of two ways:- CLI flag — pass the flag at invocation time (e.g.
aspect gazelle --check). Good for overrides on individual task invocations, or experimenting with a setting before committing it. .aspect/config.axl— declare it once in your repo’s AXL config so everyaspect gazelleinvocation picks it up. Good for settings that should apply to all invocations of a task type.
Gazelle target
Before —.aspect/workflows/config.yaml:
config.axl:
The default gazelle target moved from
//:gazelle.check to //tools/gazelle:gazelle. Two reasons for the change:- Out of the root package. Defining
gazelle()at//tools/gazelleinstead of//:gazelle.checkkeeps the gazelleload(...)out of your rootBUILD.bazel. Loads in the root package fire on every invocation that touches it (any wildcard, query, or rule that resolves a root-package label), so keeping gazelle-only machinery out of that path saves fetch and analysis overhead on commands that have nothing to do with gazelle. - No more
.checksuffix. The task drives gazelle in-mode=diffat runtime via a flag override, so a single target works for both apply and check semantics.
gazelle.check target lives at the root, point --gazelle-target at the apply target (//:gazelle, not //:gazelle.check). Or migrate the BUILD file to tools/gazelle/BUILD to match the new default — see the Setup section.Migrating from the configure task
If your repo previously had:
aspect_gazelle target backed by aspect_gazelle_prebuilt at //tools/gazelle:gazelle (see Setup) and switch to aspect gazelle. aspect_gazelle_prebuilt fetches a prebuilt gazelle binary, so you keep configure’s “no Go toolchain, no build-from-source” benefit. Once that’s wired up, aspect gazelle --check is the direct replacement for rosetta run configure.
Mode: apply vs. check
Before — both legacy tasks always ran in diff-only mode. The user fixed any reported issues by re-runningbazel run :gazelle (for the gazelle task) or bazel configure (for configure).
After — default behavior applies the diff for you (handy locally), --check matches the legacy diff-only behavior (recommended in CI):
aspect gazelle and “actually update my BUILDs” are usually the same intent. Saving the user from a second invocation matters more than tree-cleanliness on a developer workstation. CI inverts both incentives — --check is the right default there.
In default (apply) mode the task captures the patch from gazelle -mode=diff, then runs git apply -p0 <patch> rather than re-invoking gazelle a second time. On large monorepos that skips the second whole-repo scan, which is gazelle’s slow phase.
Forgetting
--check on CI is not a footgun. The exit code is identical with or without it: any non-empty diff exits 1. Default mode just additionally applies the patch via git apply -p0 to the runner’s checkout (which CI throws away anyway), so you pay a few milliseconds of git apply and get slightly stranger terminal output (“Gazelle updated N files” instead of “would update”) before the same trailing ERROR: BUILD files are out of date and red CI step. --check is recommended on CI because it’s faster and cleaner, not because forgetting it is unsafe.Gazelle subcommand (fix vs update)
The legacy tasks always ran gazelle without an explicit subcommand (defaulting to update / fix depending on the language plugin). aspect gazelle exposes this as --gazelle-command:
--gazelle-command=fix when you want gazelle to clean up deleted files or apply language-specific migrations on top of normal rule generation.
update-repos is intentionally not supported here — its interaction with -mode=diff is untested. Run it directly with bazel run //tools/gazelle:gazelle -- update-repos when you need to update Go repository rules.
Passing arbitrary gazelle flags (--gazelle-flag)
--gazelle-flag passes extra flags directly to the gazelle binary (repeatable):
-progress— print progress output (aspect-gazelle prebuilt only).-cache— enable gazelle’s build cache (aspect-gazelle prebuilt only).-r— recurse into subdirectories.- Any other upstream gazelle flag not yet exposed as a first-class task arg.
aspect_gazelle_prebuilt (like -progress and -cache) will cause errors if you’re using a from-source gazelle target that doesn’t recognize them. Don’t set those in config.axl if your target may vary.
Any -mode/--mode flag passed via --gazelle-flag is ignored — the task controls mode internally, and changes are applied via git apply rather than a second gazelle invocation, so there’s no gazelle call that a user-supplied -mode would reach.
Limiting scope with directories
Pass directories as positional arguments after all flags. Gazelle limits its walk to those subtrees:.aspect/config.axl, set dirs as a list:
Diff archival
Before — the legacy tasks attached the diff to a CI annotation (truncated to ~20 lines, with the rest in the terminal-detail block). After —--upload-gazelle-diff (default false):
gazelle.patch via the same uploader build/test use for testlogs. Works on GitHub Actions, Buildkite, CircleCI, and GitLab. The download URL (where the CI provider returns one) lands on ArtifactsTrait.artifact_urls["gazelle_diff"] so future status-check features can link to it.
No-op when the working tree is clean (no diff to upload), or when not running on a recognized CI host.
Examples
Standard gazelle check on PRs
Before —.aspect/workflows/config.yaml:
Archive the diff as a CI artifact (--upload-gazelle-diff)
--upload-gazelle-diff writes gazelle’s patch to a tmpfile and uploads it as gazelle.patch via the same uploader build/test use, so reviewers can apply it locally without re-running gazelle:
ArtifactsTrait.artifact_urls["gazelle_diff"] for downstream status-check or annotation features to surface.
