Pre-built binary
We recommend that developers execute a pre-compiled binary.
- You could create a custom workflow for your repository to build the binary when needed, for the right architectures, and then publish it somewhere that your developers use. Consider creating a
tools/gazelle
redirect in the repo to make it easy to locate - see https://blog.aspect.build/run-tools-installed-by-bazel Much easier: Aspect CLI has a pre-built binary included, available with the
configure
command. See https://docs.aspect.build/cli/commands/aspect_configure for the built-in language extensions. This includes the ability to write extensions in Starlark, which we’ll explore extensively.
Building from source
load("@bazel_gazelle//:def.bzl", "gazelle", "gazelle_binary")
gazelle_binary(
name = "my_gazelle_binary",
# NB: order matters!
languages = [
"@bazel_gazelle//language/proto", # Built-in rule from gazelle for Protos.
# Any languages that depend on Gazelle's proto plugin must come after it.
"@bazel_gazelle//language/go", # Built-in rule from gazelle for Golang.
"@rules_python//gazelle", # Use gazelle from rules_python.
"//bazel/my/extension", # A custom first-party extension, a `go_library`
],
visibility = ["//visibility:public"],
)
# gazelle:prefix example.com/project
gazelle(
name = "gazelle",
gazelle = ":my_gazelle_binary",
)
What’s wrong with building from source?
There is some reasoning in this blog post https://plaid.com/blog/hello-bazel/:
• Avoid running Gazelle with bazel run
; use a prebuilt version of the Gazelle binary instead. Although Bazel excels at incremental builds, it can add noticeable latency when fetching updated external repositories or rebuilding its analysis cache. Moreover, if you maintain a custom Gazelle plugin in the same repository, you may encounter a “Catch-22” situation: Gazelle is needed to generate the correct BUILD files, but the BUILD files must be correct for Gazelle to run.
Additional Downsides:
- Broken BUILD files referenced (even transitively) by
load
statements will break compilation of gazelle, preventing it from fixing them - Any changes to custom extensions in your repo will cause your developers to re-build the binary
- While the Go toolchain is hermetic under Bazel, the cgo toolchain is not (without some additional work). Extensions that need it (such as rules_python) may not compile correctly on some developer’s machines. See this PR for example.
- If you have no Go code in your repository, all developers will be subject to an unnecessary toolchain download and extra complexity.
Checking on CI
CI steps should verify that the repository is “gazelle-clean” in case developers haven’t run the tool.
You could have a CI step that just runs a //:gazelle.check
with --mode=diff
so the exit code is non-zero if Gazelle makes any changes.
Aspect Workflows has this feature built-in! Check out https://aspect.build/workflows