Fix formatting of generated BUILD.bazel files#85
Merged
miridius merged 1 commit intoMay 11, 2026
Conversation
bb0736d to
e190648
Compare
e190648 to
02fb218
Compare
02fb218 to
105b9b0
Compare
miridius
added a commit
that referenced
this pull request
May 11, 2026
Three additional rules to match `buildifier` output:
- **load() args sorted**: `load("...bzl", "clojure_library", "clojure_test")`
not `load("...bzl", "clojure_test", "clojure_library")` — args after
the bzl path go alphabetical.
- **`//pkg:pkg` shortened to `//pkg`**: when the target name equals the
last path segment, omit the explicit `:name` (label-canonicalisation
rule applied via `shorten-label` in `emit-bazel* String`).
- **trailing newline on generated BUILD.bazel**: both `gen-dir` and
`gen-deps-build` now spit a final `\n`.
Caught dogfooding against the rules_clojure#84 Gazelle plugin output —
the remaining diffs after #85 were the buildifier rules above.
Rewrite `emit-bazel*` to produce output identical to
`buildifier --type=build`. A round-trip test pipes generated content
through buildifier and asserts zero diff.
Generated `BUILD.bazel` files previously used non-standard formatting:
all kwargs on one line, no attribute sorting, no trailing commas, an
`#autogenerated` comment header. IDEs configured with buildifier would
reformat the entire file on open, creating noisy diffs (banksy#15022
comment). The first re-run of `gen_srcs` after this lands will produce
a one-time diff on every generated BUILD.bazel.
Emission changes (gen_build.clj):
- attr-priority + sortable-list-attrs match buildifier's NamePriority +
IsSortableListArg subsets
- label-sort-key uses phase ordering (: < // < @)
- emit-bazel-kwargs returns sorted "k = v" entry strings; multi-element
list values render multi-line via emit-vector
- IPersistentList: inline when positional-only or single-kwarg-no-
positional, multi-line otherwise (4-space arg indent, trailing comma)
- IPersistentList: load() args after the bzl path are sorted alphabetic
- IPersistentVector: standalone inline with ", " separator
- IPersistentMap: dict literals use `{"k": "v"}` (no space before `:`)
- emit-bazel* String: `//path/pkg:pkg` shortens to `//path/pkg`
- build-file-header replaces the "#autogenerated" comment with a
Starlark triple-quoted docstring
Generated content layout (gen-dir, gen-deps-build):
- docstring header at top
- load() before package()
- distinct over dedupe in __clj_lib deps construction
- trailing newline at end of file
Tests (gen_build_test.clj):
- Vector inline (empty, single, multi-element)
- Inline function calls (positional-only, single-kwarg)
- Multi-kwarg multi-line with sorted attrs
- Attribute priority ordering
- Label sort phase ordering; unsortable attrs (aot) preserved
- Buildifier round-trip — fails explicitly when buildifier absent
CI / build:
- MODULE.bazel: `buildifier_prebuilt` 8.5.1.2 as a dev_dependency
- test BUILD: gen-build-test declares buildifier as a `data` dep and
exports its runfiles path via the `BUILDIFIER` env var; the test
resolves it through test-utils/runfiles-env — no PATH lookup
- .circleci/config.yml: no install step needed
Addresses: TOOL-518
b1cf607 to
7945bd3
Compare
Contributor
Author
|
@english — heads-up that the branch has changed substantively since your approval on
(1) fixes a CI failure, (2)–(5) were caught dogfooding against #84's Gazelle plugin output in banksy. Do you want to re-review or are you happy to keep the existing approval? posted by Claude |
english
approved these changes
May 11, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Generated
BUILD.bazelfiles use non-standard formatting: all kwargs on one line, no attribute sorting, no trailing commas,#autogeneratedcomment header. This causes IDEs configured with buildifier to reformat the entire file on open, creating noisy diffs (banksy#15022 comment).Solution
Rewrite the
emit-bazel*multimethod system ingen_build.cljto produce output identical tobuildifier --type=build. All formatting rules were verified empirically by running buildifier on sample files and by regenerating the entire banksy-3 tree (1373 BUILD files) and confirming gazelle from #84 produces byte-identical output.NamePrioritytable (namefirst,srcsearly,depslast, unknowns alphabetically)byStringExpr(:<//<@, then lexicographic within phase). Only for known sortable attrs (deps, srcs, resources, etc.) — ordering-sensitive attrs likeaotare preservedpackage(...)) or positional-only (load(...))load()args sorted: positional symbol args after the bzl path go alphabetical (buildifier rule){"k": "v"}(no space before colon)//path/to/pkg:pkg→//path/to/pkgwhen the target name equals the trailing path segment", "separator (multi-line still happens for kwarg-context list values)#autogeneratedcomment;loadbeforepackage; final\nat end of fileA buildifier round-trip test pipes generated content through
buildifier --type=build(provided as abazel_depviabuildifier_prebuilt, resolved at test time throughrunfiles-env) and asserts zero diff.Before
After
CI / build
MODULE.bazelgainsbuildifier_prebuiltas adev_dependency; thegen-build-testtarget declares the buildifier binary indataand exports its runfiles path via theBUILDIFIERenv var. The round-trip test resolves it throughtest-utils/runfiles-env— nowhich/PATH lookup..circleci/config.yml: no install step needed (deps come from bazel).Reviewers: note
The first re-run of
gen_srcsafter this lands will produce a one-time diff on every generatedBUILD.bazel(header swap + reformat + label shortening + load symbol sort). The round-trip test fails explicitly ifbuildifieris absent rather than silently skipping.