# Buildifier buildifier is a tool for formatting bazel BUILD and .bzl files with a standard convention. ## Setup Build the tool: * Checkout the repo and then either via `go install` or `bazel build //buildifier` * If you already have 'go' installed, then build a binary via: `go install github.com/bazelbuild/buildtools/buildifier@latest` ## Usage Use buildifier to create standardized formatting for BUILD and .bzl files in the same way that clang-format is used for source files. $ buildifier path/to/file You can also process multiple files at once: $ buildifier path/to/file1 path/to/file2 You can make buildifier automatically find all Starlark files (i.e. BUILD, WORKSPACE, .bzl, or .sky) in a directory recursively: $ buildifier -r path/to/dir Buildifier supports the following file types: `BUILD`, `WORKSPACE`, `.bzl`, and default, the latter is reserved for Starlark files buildifier doesn't know about (e.g. configuration files for third-party projects that use Starlark). The formatting rules for WORKSPACE files are the same as for BUILD files (both are declarative and have stricter formatting rules), and default files are formatted similarly to .bzl files, allowing more flexibility. Different linter warnings may be limited to any subset of these file types, e.g. a certain warning may be only relevant to Bazel files (i.e. `BUILD`, `WORKSPACE`, and `.bzl`) or to non-WORKSPACE files. Buildifier automatically detects the file type by its filename, taking into account optional prefixes and suffixes, e.g. `BUILD`, `BUILD.oss`, or `BUILD.bazel` will be detected as BUILD files, and `build_defs.bzl.oss` is a .bzl file. Files with unknown names (e.g. `foo.bar`) or files passed via stdin will be treated as default file type. To override the automatic file type detection use the `--type` flag explicitly: $ cat foo.bar | buildifier --type=build $ cat foo.bar | buildifier --type=bzl $ cat foo.bar | buildifier --type=workspace $ cat foo.bar | buildifier --type=default $ cat foo.bar | buildifier --type=module ## Linter Buildifier has an integrated linter that can point out and in some cases automatically fix various issues. To use it launch one of the following commands to show and to fix the issues correspondingly (note that some issues cannot be fixed automatically): buildifier --lint=warn path/to/file buildifier --lint=fix path/to/file By default, the linter searches for all known issues relevant for the given file type except those that are marked with "[Disabled by default](../WARNINGS.md)" in the documentation. You can specify the categories using the `--warnings` flag either by providing the categories explicitly: buildifier --lint=warn --warnings=positional-args,duplicated-name or by modifying the default warnings set by using `+` or `-` modifiers before each warning category: buildifier --lint=warn --warnings=-positional-args,+unsorted-dict-items It's also possible to provide `--warnings=all` to use all supported warnings categories (they will still be limited to relevant warnings for the given file type). See also the [full list](../WARNINGS.md) or the supported warnings. ## Setup and usage via Bazel You can also invoke buildifier via the Bazel rule. `WORKSPACE` file: ```bzl load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") # buildifier is written in Go and hence needs rules_go to be built. # See https://github.com/bazelbuild/rules_go for the up to date setup instructions. http_archive( name = "io_bazel_rules_go", sha256 = "6dc2da7ab4cf5d7bfc7c949776b1b7c733f05e56edc4bcd9022bb249d2e2a996", urls = [ "https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.39.1/rules_go-v0.39.1.zip", "https://github.com/bazelbuild/rules_go/releases/download/v0.39.1/rules_go-v0.39.1.zip", ], ) load("@io_bazel_rules_go//go:deps.bzl", "go_rules_dependencies") go_rules_dependencies() load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains") go_register_toolchains(version = "1.20.3") http_archive( name = "bazel_gazelle", sha256 = "727f3e4edd96ea20c29e8c2ca9e8d2af724d8c7778e7923a854b2c80952bc405", urls = [ "https://mirror.bazel.build/github.com/bazelbuild/bazel-gazelle/releases/download/v0.30.0/bazel-gazelle-v0.30.0.tar.gz", "https://github.com/bazelbuild/bazel-gazelle/releases/download/v0.30.0/bazel-gazelle-v0.30.0.tar.gz", ], ) load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies") # If you use WORKSPACE.bazel, use the following line instead of the bare gazelle_dependencies(): # gazelle_dependencies(go_repository_default_config = "@//:WORKSPACE.bazel") gazelle_dependencies() http_archive( name = "com_google_protobuf", sha256 = "3bd7828aa5af4b13b99c191e8b1e884ebfa9ad371b0ce264605d347f135d2568", strip_prefix = "protobuf-3.19.4", urls = [ "https://github.com/protocolbuffers/protobuf/archive/v3.19.4.tar.gz", ], ) load("@com_google_protobuf//:protobuf_deps.bzl", "protobuf_deps") protobuf_deps() http_archive( name = "com_github_bazelbuild_buildtools", sha256 = "ae34c344514e08c23e90da0e2d6cb700fcd28e80c02e23e4d5715dddcb42f7b3", strip_prefix = "buildtools-4.2.2", urls = [ "https://github.com/bazelbuild/buildtools/archive/refs/tags/4.2.2.tar.gz", ], ) ``` `BUILD.bazel` typically in the workspace root: ```bzl load("@com_github_bazelbuild_buildtools//buildifier:def.bzl", "buildifier") buildifier( name = "buildifier", ) ``` Invoke with ```bash bazel run //:buildifier ``` ## File diagnostics in json Buildifier supports diagnostics output in machine-readable format (json), triggered by `--format=json` (only works in combination with `--mode=check`). If used in combination with `-v`, the output json will be indented for better readability. The output format is the following: ```jsonc { "success": false, // true if all files are formatted and generate no warnings, false otherwise "files": [ // list of all files processed by buildifier { "filename": "file_1.bzl", "formatted": true, // whether the file is correctly formatted "valid": true, // whether the file is a valid Starlark file. Can only be false if formatted = false "warnings": [ // a list of warnings { "start": { "line": 1, "column": 5 }, "end": { "line": 1, "column": 10 }, "category": "integer-division", "actionable": true, "autoFixable": true, "message": "The \"/\" operator for integer division is deprecated in favor of \"//\".", "url": "https://github.com/bazelbuild/buildtools/blob/master/WARNINGS.md#integer-division" } ] }, { "filename": "file_2.bzl", "formatted": false, "valid": true, "warnings": [], "rewrites": { // technical information, a list of rewrites buildifier applies during reformatting "editoctal": 1 } }, { "filename": "file_3.bzl", "formatted": true, "valid": true, "warnings": [] }, { "filename": "file_4.not_bzl", "formatted": false, "valid": false, "warnings": [] } ] } ``` When the `--format` flag is provided, buildifier always returns `0` unless there are internal failures or wrong input parameters, this means the output can be parsed as JSON, and its `success` field should be used to determine whether the diagnostics result is positive.