Skip to content

feat(builtins): add buildifier format and lint built-ins#896

Merged
jdx merged 3 commits intojdx:mainfrom
plx:feat/add-buildifier-as-builtin-linter
Apr 30, 2026
Merged

feat(builtins): add buildifier format and lint built-ins#896
jdx merged 3 commits intojdx:mainfrom
plx:feat/add-buildifier-as-builtin-linter

Conversation

@plx
Copy link
Copy Markdown
Contributor

@plx plx commented Apr 30, 2026

I added support for buildifier, which is a tool for formatting and linting starlark (e.g. Bazel's BUILD files, .bzl files, and so on).

I modeled the two new additions on buf, which is also present as buf_format and buf_lint.

I ran hk fix --all before opening the PR, and have made some exploratory usage of these new built-ins as part of evaluating hk adoption for a large bazel project.

Appreciate your attention (and hk!), and am happy to make any adjustments you need.

plx and others added 2 commits April 30, 2026 15:52
Add buildifier as two built-in linters for Bazel/Starlark files:
- buildifier_format: formatting check/fix using -mode=check
- buildifier_lint: lint warnings + formatting using -lint=warn/-lint=fix

Covers BUILD, BUILD.bazel, WORKSPACE, WORKSPACE.bazel, MODULE.bazel,
*.bzl, *.star, and *.sky files.
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces built-in formatting and linting steps for Bazel using the buildifier tool, along with a corresponding tool stub. The review feedback identifies a logical error in the linting test case, which incorrectly expects buildifier to resolve missing load statements. Additionally, the reviewer suggests expanding the file glob patterns to include more Bazel-specific extensions and subdirectories, adding check_diff commands for better efficiency, and correcting a version typo in the tool stub.

Comment on lines +30 to +47
local const before =
"""
cc_library(
name = "foo",
srcs = ["Foo.cc"],
)

"""
local const after =
"""
load("@rules_cc//cc:cc_library.bzl", "cc_library")

cc_library(
name = "foo",
srcs = ["Foo.cc"],
)

"""
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

This test case expects buildifier -lint=fix to automatically add a missing load statement. However, buildifier is a formatter and linter; it does not have the capability to resolve and add missing dependencies (that is typically handled by tools like gazelle). This test will likely fail as the fix command won't produce the expected after content.

Consider using a fixable lint issue such as out-of-order-load or unsorted-dict-items for this test.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's actually going on here is that:

Or, tl;dr: this test example looks like a (nonexistant) generic automatic-import-finder thing, but is just a narrow-purpose rule targeting a list of known rules.

Comment thread pkl/builtins/buildifier_format.pkl Outdated
Comment on lines +16 to +25
glob = List(
"**/BUILD",
"**/BUILD.bazel",
"WORKSPACE",
"WORKSPACE.bazel",
"MODULE.bazel",
"**/*.bzl",
"**/*.star",
"**/*.sky"
)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The glob list is missing some common Bazel/Starlark file patterns and some entries are restricted to the root directory. It is better to include **/WORKSPACE, **/MODULE.bazel, **/REPO.bazel, and **/*.BUILD to ensure all relevant files are covered regardless of their location in the repository.

  glob = List(
    "**/BUILD",
    "**/BUILD.bazel",
    "**/WORKSPACE",
    "**/WORKSPACE.bazel",
    "**/MODULE.bazel",
    "**/REPO.bazel",
    "**/*.bzl",
    "**/*.star",
    "**/*.sky",
    "**/*.BUILD"
  )

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This and the other similar comment are a good idea—will expand the list.

"**/*.star",
"**/*.sky"
)
check = "buildifier -mode=check {{ files }}"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Adding check_diff allows hk to use git apply for applying formatting changes. This is generally more efficient and safer than running the full fix command when only formatting changes are needed.

  check = "buildifier -mode=check {{ files }}"
  check_diff = "buildifier -mode=diff {{ files }}"

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This and the other similar comment are a good idea—will investigate and update.

Comment thread pkl/builtins/buildifier_lint.pkl Outdated
Comment on lines +16 to +25
glob = List(
"**/BUILD",
"**/BUILD.bazel",
"WORKSPACE",
"WORKSPACE.bazel",
"MODULE.bazel",
"**/*.bzl",
"**/*.star",
"**/*.sky"
)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The glob list should be expanded to include all relevant Bazel and Starlark files, matching the improvements suggested for the formatter builtin.

  glob = List(
    "**/BUILD",
    "**/BUILD.bazel",
    "**/WORKSPACE",
    "**/WORKSPACE.bazel",
    "**/MODULE.bazel",
    "**/REPO.bazel",
    "**/*.bzl",
    "**/*.star",
    "**/*.sky",
    "**/*.BUILD"
  )

"**/*.star",
"**/*.sky"
)
check = "buildifier -mode=check -lint=warn {{ files }}"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Adding check_diff with -lint=warn allows hk to apply both formatting and lint fixes via patches, which is more efficient than running the fix command.

  check = "buildifier -mode=check -lint=warn {{ files }}"
  check_diff = "buildifier -mode=diff -lint=warn {{ files }}"

@@ -0,0 +1,4 @@
#!/usr/bin/env -S mise tool-stub

version = "8.5.1"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The version 8.5.1 appears to be a typo. The current latest stable version of buildifier (from the bazelbuild/buildtools repository) is 8.0.1. Using a non-existent version will cause installation failures in tool managers like mise.

version = "8.0.1"

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented Apr 30, 2026

Greptile Summary

This PR adds buildifier_format and buildifier_lint built-ins for formatting and linting Starlark/Bazel files, modeled after the existing buf_format/buf_lint pattern. Commands, exit codes, glob patterns, and test fixtures are all consistent with buildifier's documented behavior (exit 4 for both formatting needs and lint warnings in -lint=warn mode).

Confidence Score: 5/5

Safe to merge — no logic errors or behavioral bugs found.

All commands match buildifier's documented interface, exit codes in tests are correct (4 for both formatting and lint issues in warn mode), and the implementation cleanly mirrors the established buf_format/buf_lint pattern.

No files require special attention.

Important Files Changed

Filename Overview
pkl/builtins/buildifier_format.pkl New format step for buildifier: correctly uses -mode=check for check and bare buildifier for fix, exit code 4 in tests matches buildifier's documented "needs reformatting" signal.
pkl/builtins/buildifier_lint.pkl New lint step for buildifier: uses -mode=check -lint=warn for check and -lint=fix for fix; exit code 4 is correct per buildifier docs (lint warnings in warn mode also trigger exit 4).
test/builtin_tool_stubs/buildifier Standard mise tool-stub for buildifier tests, pinned to version 8.5.1; consistent with other stubs in the directory.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Changed Starlark files\n BUILD / .bzl / .star etc.] --> B{Step type}
    B -->|buildifier_format check| C["buildifier -mode=check {{ files }}"]
    B -->|buildifier_format fix| D["buildifier {{ files }}"]
    B -->|buildifier_lint check| E["buildifier -mode=check -lint=warn {{ files }}"]
    B -->|buildifier_lint fix| F["buildifier -lint=fix {{ files }}"]
    C -->|exit 0| G[Files already formatted ✓]
    C -->|exit 4| H[Formatting needed ✗]
    D -->|exit 0| I[Files reformatted ✓]
    E -->|exit 0| J[No format or lint issues ✓]
    E -->|exit 4| K[Format or lint issues ✗]
    F -->|exit 0| L[Lint issues fixed ✓]
Loading

Reviews (2): Last reviewed commit: "[autofix.ci] apply automated fixes" | Re-trigger Greptile

Comment thread pkl/builtins/buildifier_lint.pkl
@jdx jdx merged commit d3a73e4 into jdx:main Apr 30, 2026
28 checks passed
@jdx jdx mentioned this pull request Apr 30, 2026
jdx added a commit that referenced this pull request May 5, 2026
### 🚀 Features

- **(builtins)** add `buildifier` format and lint built-ins by
[@plx](https://github.com/plx) in
[#896](#896)

### 🐛 Bug Fixes

- **(step)** only auto-batch when rendered command exceeds ARG_MAX by
[@jdx](https://github.com/jdx) in
[#901](#901)

### 📚 Documentation

- thank Namespace for GitHub Actions runner support by
[@jdx](https://github.com/jdx) in
[#895](#895)

### 🔍 Other Changes

- **(ci)** use !cancelled() instead of always() for final job by
[@jdx](https://github.com/jdx) in
[#906](#906)
- **(docs)** remove shrill.en.dev analytics script by
[@jdx](https://github.com/jdx) in
[#903](#903)
- remove rust-cache from release jobs by [@jdx](https://github.com/jdx)
in [#893](#893)
- invert CLAUDE.md/AGENTS.md so AGENTS.md is canonical by
[@jdx](https://github.com/jdx) in
[#905](#905)
- set dev profile debug to 1 by [@jdx](https://github.com/jdx) in
[#907](#907)

### 📦️ Dependency Updates

- update anthropics/claude-code-action digest to fefa07e by
[@renovate[bot]](https://github.com/renovate[bot]) in
[#897](#897)
- update jdx/mise-action digest to 1648a78 by
[@renovate[bot]](https://github.com/renovate[bot]) in
[#898](#898)
- update apple-actions/import-codesign-certs action to v7 by
[@renovate[bot]](https://github.com/renovate[bot]) in
[#900](#900)
- update autofix-ci/action action to v1.3.4 by
[@renovate[bot]](https://github.com/renovate[bot]) in
[#899](#899)
- lock file maintenance by
[@renovate[bot]](https://github.com/renovate[bot]) in
[#908](#908)

### New Contributors

- @plx made their first contribution in
[#896](#896)

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Low risk release bookkeeping: primarily version string updates across
manifests and docs with no functional code changes in this diff.
> 
> **Overview**
> Updates the project for the `v1.45.0` release by bumping the crate/CLI
version (`Cargo.toml`, `Cargo.lock`, `hk.usage.kdl`, generated CLI docs)
and adding the `1.45.0` entry to `CHANGELOG.md`.
> 
> Refreshes documentation and example configs to reference the new
versioned Pkl package URLs (`docs/*.md`, `docs/public/*.pkl`,
`hk-example.pkl`).
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
cfe2da5. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

Co-authored-by: mise-en-dev <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants