Gazelle is a tool in a lineage that started internally at Google.
glaze
was developed by the Go team to make the Go language easier to roll out within Google. It had the advantage that the semantics of the Go language were built with Bazel in mind, simplifying tasks like resolving import statements to the package which exports them.
Gazelle was written by Jay Conrod at Google, and is now community-maintained under the Linux Foundation in https://github.com/bazel-contrib/bazel-gazelle.
Basics
BUILD files are “bare facts” that describe the source code and its dependencies. These facts are mostly trivial to derive from the source code itself. So why force engineers to write these by hand?
At a high level, it operates following the Visitor pattern:
- Walk the source tree similar to bazel, respecting
.bazelignore
etc - When descending into a folder, if it already has a
BUILD
file, read the special comments called “directives” and use those configuration values. - Locate the source files of interest, generally based on file extensions.
- Declare bazel targets to generate and what those targets import+export.
- Targets are often chosen based on configuration and the source files located
- Imports are often found by parsing source file import statements (similar to an IDE)
- Exports are often based on file paths or by parsing source file package declarations
- After the walk is complete the target imports are resolved and reflected into attributes such as
deps
- Merge the updates to the
BUILD
file, creating a new one if appropriate.
This is non-destructive: hand-edits to the BUILD
file are preserved.
To opt-out of Gazelle managing a syntax element, use the #keep
comment, for example:
py_library(
name = "keeps",
# Don't manage this attribute at all
# keep
srcs = glob(["*.py"]),
deps = [
# Don't remove this even if it seems unused
"@pypi//some-pkg:pkg", # keep
],
)
# Leave this entire rule alone
# keep
js_library(
name = "ignore",
srcs = glob(["*.mjs"]),
)
Note: the bazel-gazelle repo also has some Go-specifics like the go_repository
rule which runs Gazelle on third-party Go packages to generate their BUILD files dynamically.