Skip to content

Integrate 'black' Formatter with Bazel for Code Formatting` #226

@EricRahm

Description

@EricRahm

Motivation

To ensure a consistent Python code style across the project and automate a manual, error-prone process, we should integrate the black code formatter directly into our Bazel build system. We already use black in our CI pipeline, but don't expose it for local usage.

Below is a proposed approach, but we're open to do thing this other ways.

Proposed Solution

We will implement two separate Bazel targets to achieve this:

  1. A bazel run Target for Fixing:

    • A target named black_fix will be created.
    • Running bazel run //:black_fix -- . will execute black on the entire workspace, reformatting any non-compliant Python files in-place.
  2. A bazel test Target for Checking (Optional):

    • A target named black_check will be created.
    • Running bazel test //:black_check (or as part of bazel test //...) will execute black --check --diff.
    • This test will pass if all files are correctly formatted and fail otherwise, printing a diff of the required changes. This is ideal for CI integration.

Implementation Plan

  1. Add black as a Bazel Dependency:

    • Modify MODULE.bazel to use the pip.parse extension from rules_python.
    • Create a requirements.txt file to declare a dependency on black==24.8.0 and its necessary transitive dependencies.
  2. Create a py_binary for the Formatter:

    • In the root BUILD file, define a py_binary target named black_binary.
    • This target will use the entry_point attribute set to "black" to directly use the black command-line tool provided by the pip package.
  3. Implement the "Fix" Command:

    • Create a sh_binary named black_fix that simply calls the black_binary target with the provided arguments (e.g., . to format the whole project). This will be the user-facing command run with bazel run.
  4. Implement the "Check" Test:

    • Create a sh_test named black_check.
    • This test will execute the black_binary target with the --check and --diff flags. The test will succeed only if black returns a zero exit code (indicating no changes are needed).

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions