# @bazel/buildozer 中文文档

规范地址：https://npmcn.com/package/%40bazel/buildozer/

版本：8\.2\.1
npm 元数据更新时间：2025-06-10T13:34:03.729Z
中文译文更新时间：2026-11-07T18:43:00.154Z
软件包许可：Apache-2\.0

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40bazel/buildozer
原文对照：https://npmcn.com/package/%40bazel/buildozer/?lang=original
项目主页：https://github.com/bazelbuild/buildtools#readme
源码仓库：https://github.com/bazelbuild/buildtools

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：44.8 MB，11 个文件
- TypeScript 类型：未声明
- 运行依赖：0 个
- 首次发布：2019-05-24T16:12:20.432Z
- 最新版本发布：2025-06-10T13:34:03.469Z
- 近 30 天下载量：19625（2026-10-08 至 2026-11-06，npm 官方下载统计）
- 已发布版本数：39（近 12 个月 0 个）

## 中文简介

一个使用标准命令重写多个 BUILD 文件的命令行工具

## 安装

```sh
npm install @bazel/buildozer
```

也可以使用：`pnpm add @bazel/buildozer`、`yarn add @bazel/buildozer`、`bun add @bazel/buildozer`

## README

# 构建器

Buildozer 是重写多行的命令行工具 [巴泽尔](https://github.com/bazelbuild/bazel) 使用 BUILD 文件 标准命令.

## 安装

1.  构建二进制并把它放入您的 $GOPATH/ bin :

```bash
go install github.com/bazelbuild/buildtools/buildozer@latest
```

## 使用量

```shell
buildozer [OPTIONS] ['command arg...'...|-f FILE] [label]...
```

这里, `label...` 是Bazel标签的(空格分隔,可能为空)列表, 比如说 `//path/to/pkg1:rule1 relative/path/to/pkg2:rule2`。除此之外 指定软件包的 Bazel 标签语法, Buildozer 也允许 包件部分以引用类似 BUILD 的文件, 例如 `//WORKSPACE:all` 或者说 `toolchains/BUILD.tpl:host_toolchain`。 。 。 .

Builder 命令作为单一位置参数传递,因此必须 引出(或以其他方式逃脱)。 多个命令和多个标签可以是 通过了。 Buildoze将对所有目标执行所有命令. (所以如果你没有) 指定至少一个命令和一个目标,不会发生任何事。 ) 命令为 按顺序执行,文件会平行处理.

何时 `-f FILE` 使用文字命令, 构建者读取命令 从 `FILE`。 。 。 . `FILE` 可能会是 `-`,在此情况下,命令从 标准输入.

命令文件的格式如下: 空行和行起始 与 `#` 忽略(包括主白空间)。 非无标志行由 联 合 国 `|`\- 分离的命令和标签:

```shell
command arg arg...|command arg arg...|...|label|label|...
```

(事实上,命令和标签可以任意地出现互放. ) `|` 命令中的字符可以像 `\|`双空字节 (单位:千美元)`\x00\x00`)在命令文件中无效。 特别处理 允许从标准输入读取的标签。 当命令文件中的行 使用“\*”的单标签,然后将命令适用于所有元素 名单 `label...` 从命令行.

### 目标

目标看起来像Bazel标签, 但可能存在一些差异 宏.

-   使用标签标记指代一条规则: `//buildtools/buildozer:edit`
-   使用 `__pkg__` 引用软件包声明的后缀 : `//buildtools/buildozer:__pkg__`
-   使用星号指代文件中的所有规则 : `//pkg:*`
-   使用 `...` 以指代目录中所有后裔 BUILD 文件: `//pkg/...:*`
-   用%来指代所有某种规则: `//pkg:%java_library`
-   使用百分数和数来指代一条从某一行开始的规则: `//pkg:%123`。 。 。 .
-   使用特殊软件包名称 `-` 从标准读取 BUILD 文件 输入而不是从软件包目录中的本地文件 : `-:all_tests`。 。 。 . (据推测,两者使用a和b均无用。) `-` 软件包名称并使用 `-f -` 从标准输入读取命令的旗帜。 )

### 选项

备选办法包括:

-   `-stdout` : 将更改的 BUILD 文件写入 stdout
-   `-buildifier` : 使用特定的建构二进制格式输出。 如果为空, 则使用内置内容 .
-   `-k` : 应用所有命令, 即使有失败
-   `-quiet` : 压制信息信息
-   `-shorten_labels` : 将所添加的标签转换为短窗形, 例如 //foo: bar qq: bar
-   `-types`:过滤目标,只保留指定类型的目标,例如. `buildozer -types go_library,go_binary 'print rule' '//buildtools/buildozer:*'`
-   `-eol-comments=false`:在添加新评论时,将其放入单独一行.

见 `buildozer -help` 完整名单.

### 编辑命令

Buildozer 支持以下命令 (`'command args'`:

-   `add <attr> <value(s)>`: 向规则的列表属性添加值。 如果有的话 值已经存在于列表中,而不是添加.
-   `new_load <path> <[to=]from(s)>`: 为给定路径添加负载语句, 导入符号。 之后,考虑运行 `buildozer 'fix unusedLoads'`。 。 。 .
-   `replace_load <path> <[to=]from(s)>`: 类似 `new_load`,但删除 在添加新负载之前,已有对请求符号的加载语句.
-   `substitute_load <old_regexp> <new_template>` 替换负载的模块 匹配 `old_regexp` 根据 `new_template`。正则表达式必须 跟着 [RE2 语法](https://github.com/google/re2/wiki/Syntax)。 。 。 . `new_template` 可能是简单的替换字符串,但它也可能扩展 使用 `$0` 或者说 `$x`。 。 。 .
-   `comment <attr>? <value>? <comment>`: 在规则、属性中添加一个注释, 或列表中的特定值。 注释中的空格应当与 后鞭击.
-   `print_comment <attr>? <value>?`
-   `delete`: 删除一条规则.
-   `fix <fix(es)>?`: 应用固定.
-   `move <old_attr> <new_attr> <value(s)>`: 移动 `value(s)` 从列表中 `old_attr` 列表中 `new_attr`。通配符 `*` 匹配所有值.
-   `new <rule_kind> <rule_name> [(before|after) <relative_rule_name>]`: 添加一个 bUILD 文件结尾处的新规则( 前后) `<relative_rule>`) (中文(简体) ). 这个 标识符 `__pkg__` 可用于定位相对于包()的规则.
-   `print <attr(s)>`
-   `remove <attr>`: 删除属性 `attr`。通配符 `*` 全部匹配 属性除外 `name`。 。 。 .
-   `remove <attr> <value(s)>`: 删除 `value(s)` 从列表中 `attr`编辑 通配符 `*` 匹配所有属性。 列表中无 `value(s)` 为: 未修改.
-   `remove_comment <attr>? <value>?`: 删除该规则所附带的评论, 属性,或列表中的特定值.
-   `remove_if_equal <attr> <value>`: 删除属性 `attr` 如果其价值 等于 `value`。 。 。 .
-   `rename <old_attr> <new_attr>`: 重命名为 `old_attr` 改为 `new_attr` 必须 尚不存在.
-   `replace <attr> <old_value> <new_value>`: 替换 `old_value` 与 `new_value` 列表中 `attr`。通配符 `*` 匹配所有属性。 不包含 `old_value` 未修改.
-   `substitute <attr> <old_regexp> <new_template>`: 替换字符串 匹配 `old_regexp` 列表中 `attr` 根据 `new_template`。通配符 `*` 匹配所有属性。 正则表达式必须遵循 [RE2 语法](https://github.com/google/re2/wiki/Syntax)。 。 。 . `new_template` 可能 是一个简单的替换字符串,但它也可能扩展编号或命名 使用 `$0` 或者说 `$x`。没有匹配字符串的列表 `old_regexp` 未修改.
-   `set <attr> <value(s)>`:设置属性的值。 如果属性 它的旧值已被替换.
-   `set_if_absent <attr> <value(s)>`:设置属性的值。 如果 属性已经存在,没有采取任何行动.
-   `set kind <value>`: 设定目标类型为值.
-   `set_select <attr> <key_1> <value_1> <key_n> <value_n>`
-   `copy <attr> <from_rule>`: 复制值 `attr` 在规则之间 如果是 存在于 `to_rule`它将被覆盖.
-   `copy_no_overwrite <attr> <from_rule>`: 复制值 `attr` 介于 规则。 如果它存在于 `to_rule`,不采取行动.
-   `dict_add <attr> <(key:value)(s)>`: 设置命令键的值 属性 `attr`。如果键已经存在,它将 _没有_ 被覆盖. 科隆字符可以包含在密钥中,而从":"中逃出的价值.
-   `dict_set <attr> <(key:value)(s)>`: 设置命令键的值 属性 `attr`。如果密钥已经存在,则其旧值将被替换. 科隆字符可以包含在密钥中,而从":"中逃出的价值.
-   `dict_remove <attr> <key(s)>`: 删除 dict 属性的密钥 `attr`。 。 。 .
-   `dict_replace_if_equal <attr> <key> <old_value> <new_value>`: 替换 `old_value` 与 `new_value` 键 `key` 在字典属性中 `attr`。 。 。 . 如果字典中没有键, 或者没有值 `old_value`,它会 _没有_ 更新.
-   `dict_list_add <attr> <key> <value(s)>`: 将数值添加到列表中 dict 属性 `attr`。 。 。 .
-   `format`: 强迫所有文件格式化,即使这些文件没有被更改 其他命令.

这里, `<attr>` 代表属性( 存在) `add`编/`rename`(单位:千美元)`delete`(d等), 例如: `srcs`, (中文(简体) ), `<value(s)>` 代表属性等值. A '?' 表示前面的论点是可选的.

对所有符合条件的修补应用没有指定固定的固定命令. 使用 `//path/to/pkg:__pkg__` 作为文件级别更改的标签, 如 `new_load` 财务报告和审定财务报表 `new`。 。 。 . 通过使用 `%rule_kind` 在标签末尾(见下文示例).

以下命令仅适用于 `MODULE.bazel` 文件(例如目标) `//MODULE.bazel:all`:

-   `use_repo_add <use_extension variable name> <repo(s)>`数字 : 确保通过 `use_repo` 联 合 国 扩展名,其中指定的顶级变量包含返回值 页:1 `use_extension` 电话.
-   `use_repo_remove <use_extension variable name> <repo(s)>`数字 : 确保给定的寄存器 _没有_ 通过 `use_repo` 页:1 上一级变量包含返回的扩展名 数值 a `use_extension` 电话.
-   `use_repo_add [dev] <extension .bzl file> <extension name> <repo(s)>`数字 : 确保指定扩展生成的给定寄存器 通过 `use_repo`如果 `dev` 参数,扩展用法 与 `dev_dependency = True` 将被考虑。 扩展用途 与 `isolated = True` 被忽略.
-   `use_repo_remove [dev] <extension .bzl file> <extension name> <repo(s)>`数字 : 确保指定扩展生成的给定寄存器 _没有_ 通过 `use_repo`如果 `dev` 参数,扩展名 用法为 `dev_dependency = True` 将被考虑。 延长 用法为 `isolated = True` 被忽略.

#### 实例

```bash
# Edit //pkg:rule and //pkg:rule2, and add a dependency on //base
buildozer 'add deps //base' //pkg:rule //pkg:rule2

# A load for a skylark file in //pkg
buildozer 'new_load //tools/build_rules:build_test.bzl build_test' //pkg:__pkg__

# Replaces existing loads for build_test in //pkg
buildozer 'replace_load @rules_build//build:defs.bzl build_test' //pkg:__pkg__

# Replaces modules of loads using regular expressions.
#
# In this example
#     load("@rules_foo//foo:defs.bzl", "foo_library", "foo_test")
# will be replaced with
#     load("//third_party/build_defs/rules_foo/foo:defs.bzl", "foo_library", "foo_test")
buildozer 'substitute_load ^@([^/]*)//([^:].*)$ //third_party/build_defs/${1}/${2}' //pkg:__pkg__

# Change the default_visibility to public for the package //pkg
buildozer 'set default_visibility //visibility:public' //pkg:__pkg__

# Change all gwt_module targets to java_library in the package //pkg
buildozer 'set kind java_library' //pkg:%gwt_module

# Replace the dependency on pkg_v1 with a dependency on pkg_v2
buildozer 'replace deps //pkg_v1 //pkg_v2' //pkg:rule

# Replace all dependencies using regular expressions.
buildozer 'substitute deps //old/(.*) //new/${1}' //pkg:rule

# Delete the dependency on foo in every cc_library in the package
buildozer 'remove deps foo' //pkg:%cc_library

# Delete the testonly attribute in every rule in the package
buildozer 'remove testonly' '//pkg:*'

# Add a comment to the timeout attribute of //pkg:rule_test
buildozer 'comment timeout Delete\ this\ after\ 2015-12-31.' //pkg:rule_test

# Add a new rule at the end of the file
buildozer 'new java_library foo' //pkg:__pkg__

# Add a cc_binary rule named new_bin before the rule named tests
buildozer 'new cc_binary new_bin before tests' //:__pkg__

# Copy an attribute from `protolib` to `py_protolib`.
buildozer 'copy testonly protolib' //pkg:py_protolib

# Set two attributes in the same rule
buildozer 'set compile 1' 'set srcmap 1' //pkg:rule

# Make a default explicit in all soy_js rules in a package
buildozer 'set_if_absent allowv1syntax 1' //pkg:%soy_js

# Add an attribute new_attr with value "def_val" to all cc_binary rules
# Note that special characters will automatically be escaped in the string
buildozer 'add new_attr def_val' //:%cc_binary
```

### 打印命令

这些命令没有修改文件, 构建器在成功后返回 0 执行.

-   `print <attribute(s)>`: 对于每个目标,打印属性值 (见下文).
-   `print_comment <attr>? <value>?`: 打印与规则相关的注释, 列表中的属性或特定值.

打印命令打印属性的值。 如果目标没有 属性,在 stderr 上打印出警告.

有一些特殊的属性 `print` 命令 :

-   `kind`: 显示函数的名称
-   `attrs`: 显示规则的属性名称
-   `label`: 完全合格的标签
-   `rule`: 整个规则定义
-   `startline`: 规则在 BUILD 文件开始的行号
-   `endline`: 规则以 BUILD 文件结尾的行号
-   `path`: 包含规则的 BUILD 文件的绝对路径

#### 实例

```shell
# Print the kind of a target
buildozer 'print kind' base  # output: cc_library

# Print the name of all cc_library in //base
buildozer 'print name' base:%cc_library

# Get the default visibility of the //base package
buildozer 'print default_visibility' base:%package

# Print labels of cc_library targets in //base that have a deps attribute
buildozer 'print label deps' base:%cc_library 2>/dev/null | cut -d' ' -f1

# Print the list of labels in //base that explicitly set the testonly attribute:
buildozer 'print label testonly' 'base:*' 2>/dev/null

# Print the entire definition (including comments) of the //base:heapcheck rule:
buildozer 'print rule' //base:heapcheck
```

## 转换标签

Buildoze在语法层面工作. 它不评价BUILD文件. 狦 需要查询 Bazel 拥有的信息, 请使用 `bazel query`。如果你有一个 bazel 标签列表, 有可能其中一部分是由 BUILD 生成的 扩展。 Budozer的标签与Bazel的标签略有不同. Bazel 关心生成的代码, 而 Buildoze 则查看 BUILD 文件 在宏观扩张之前.

要查看扩展的 BUILD 文件, 请尝试:

```shell
bazel query --output=build //path/to/BUILD
```

## 一次做多个更改

使用 `buildozer -f <file>` 从文件中装入命令和标签列表(参见 [使用量](https://npmcn.com/package/%40bazel/buildozer/#readme-usage) (见上文).

```shell
$ cat /tmp/cmds
# a comment
new cc_library foo|//buildtools/buildozer/BUILD
add deps //base //strings|add srcs foo.cc|//buildtools/buildozer:foo
add deps :foo|//buildtools/buildozer

$ buildozer -f /tmp/cmds
fixed //buildtools/buildozer/BUILD
```

命令列表一般会生成并可以大. 这是 效率 : 将命令分组, 这样每个文件都会被修改一次 。 文件为 平行处理.

或者,BUILD文件可以从标准输入读取并写入到 通过使用 `-` 软件包名称 :

```shell
$ cat /tmp/cmds
add deps //base //strings|-:foo|-:bar

$ cat some/path/BUILD | buildozer -f /tmp/cmds
```

此处写入更新结果 `:foo` 财务报告和审定财务报表 `:bar` 输入中的目标 BUILD 文件到标准输出.

Buildozer 命令也可以通过 shebang 线执行:

```shell
#!/usr/bin/env -S buildozer -f
#
# Adds //base and //string dependencies to :foo and :bar.

add deps //base //strings|-:foo|-:bar
```

## 使用 Buildozer 在记忆中

Builder 的一些客户端需要执行内存中的 builder 动作 (由于无法进入其文件系统的服务环境). 这可以使用, `edit.ExecuteCommandsOnInlineFile`,接受 命令和 BUILD 文件内容作为字节,应用更改并返回 原始文件内容 . 详情及执行情况见 [`/edit/buildozer.go`](https://npmcn.com/package/%40bazel/edit/buildozer.go)

运行 Buildoze in-memory 的一些警告:

-   该功能假定(并在一定程度上验证)所有命令都适用于 如果命令影响不同的文件, 则返回错误 路径.
-   当引用目标时,该功能将无法可靠地确定目标是否 是本地或远程的。 因此,可在 输出. `add dep //package/path:bar|//package/path:foo` 将添加代码( d) `//package/path:bar` 而不是仅仅 `:bar`) (中文(简体) ).

## 错误代码

返回代码为:

-   `0` ,如果修改或只执行只读命令
-   `1` 当出现使用错误时
-   `2` 当至少一个命令失败时
-   `3` 在无变化的情况下

## 源结构

-   `buildozer/main.go` : 构建器二进制的条目点
-   `edit/buildozer.go` : 执行建设者命令的功能
-   `edit/edit.go`: 执行ASTs上各种操作的图书馆功能. 这些
-   函数由 builder.go 中的 impl 函数调用
-   `edit/fix.go`: 各项修正的功能 `buildozer 'fix <fix(es)>'` 命令,如清理未用载荷,将标签更改为标语等.
-   `edit/types.go`: 属性信息类型

## 常见问题

### @bazel/buildozer 是什么？

一个使用标准命令重写多个 BUILD 文件的命令行工具

### 如何安装 @bazel/buildozer？

在项目目录运行 npm install @bazel/buildozer，或使用 pnpm add / yarn add / bun add。它还提供命令行工具 buildozer，可以用 npx buildozer 直接运行。

### @bazel/buildozer 支持 TypeScript 吗？

该包的 package\.json 没有声明类型入口。需要类型提示时，可以在 npm 上查找社区维护的 @types/bazel\_\_buildozer 是否存在。

### @bazel/buildozer 可以商用吗？

@bazel/buildozer 使用 Apache-2\.0 许可。宽松许可：允许商业使用、修改和再分发，并附带明确的专利授权；分发时需保留许可与 NOTICE 文件，修改过的文件要注明改动。以上为概括，不构成法律意见，请以许可原文为准。

### @bazel/buildozer 的下载量有多少？

根据 npm 官方下载统计，@bazel/buildozer 在 2026/10/08 – 2026/11/06 这 30 天内被下载 19,625 次，日均约 654 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @bazel/buildozer 还在维护吗？

最新版本 8\.2\.1 发布于 2025/06/10（1\.4 年前）；至今共发布 39 个版本，其中过去 12 个月发布了 0 个；首次发布于 2019/05/25。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

