本页内容面向计划向他人提供规则的规则编写者。
我们建议您从模板代码库开始创建新的规则集:https://github.com/bazel-contrib/rules-template 该模板遵循以下建议,并包含 API 文档生成功能,还设置了 CI/CD 流水线,可轻松分发您的规则集。
托管和命名规则
新规则应放入组织下自己的 GitHub 代码库中。 如果您认为自己的规则应归入 bazelbuild 组织,请在 GitHub 上发起讨论串。
Bazel 规则的代码库名称采用以下标准化格式:
$ORGANIZATION/rules_$NAME
。
请参阅 GitHub 上的示例。
为保持一致性,您在发布 Bazel 规则时应遵循相同的格式。
请务必使用描述性 GitHub 代码库说明和 README.md
标题,例如:
- 代码库名称:
bazelbuild/rules_go
- 代码库说明:适用于 Bazel 的 Go 规则
- 代码库标记:
golang
、bazel
README.md
标题:适用于 Bazel 的 Go 规则(请注意指向 https://bazel.build 的链接,该链接会将不熟悉 Bazel 的用户引导至正确的位置)
规则可以按语言(例如 Scala)、运行时平台(例如 Android)或框架(例如 Spring)进行分组。
代码库内容
每个规则代码库都应具有特定的布局,以便用户快速了解新规则。
例如,在为(虚构的)mockascript
语言编写新规则时,规则代码库将具有以下结构:
/
LICENSE
README
MODULE.bazel
mockascript/
constraints/
BUILD
runfiles/
BUILD
runfiles.mocs
BUILD
defs.bzl
tests/
BUILD
some_test.sh
another_test.py
examples/
BUILD
bin.mocs
lib.mocs
test.mocs
MODULE.bazel
在项目的 MODULE.bazel
中,您应定义用户将用于引用规则的名称。如果您的规则属于 bazelbuild 组织,则必须使用 rules_<lang>
(例如 rules_mockascript
)。否则,您应将代码库命名为 <org>_rules_<lang>
(例如 build_stack_rules_proto
)。如果您认为自己的规则应遵循 bazelbuild 组织中规则的惯例,请在 GitHub 上发起讨论串。
在以下部分中,假设代码库属于 bazelbuild 组织。
module(name = "rules_mockascript")
自述文件
在顶层,应有一个 README
,其中包含规则集的简要说明以及 API 用户应预期的内容。
规则
您的代码库通常会提供多条规则。创建一个以语言命名的目录,并提供一个导出所有规则的入口点 - defs.bzl
文件(还包含一个 BUILD
文件,以便该目录成为一个软件包)。对于 rules_mockascript
,这意味着将有一个名为 mockascript
的目录,其中包含 BUILD
文件和 defs.bzl
文件:
/
mockascript/
BUILD
defs.bzl
限制条件
如果您的规则定义了工具链规则,则可能需要定义自定义 constraint_setting
和/或 constraint_value
。将这些内容放入 //<LANG>/constraints
软件包中。您的目录结构将如下所示:
/
mockascript/
constraints/
BUILD
BUILD
defs.bzl
请访问 github.com/bazelbuild/platforms,了解最佳实践并查看已有的限制条件,如果您的限制条件与语言无关,请考虑在此处贡献您的限制条件。
请注意引入自定义限制,规则的所有用户都将使用这些限制在其 BUILD
文件中执行平台特定逻辑(例如,使用 selects)。借助自定义限制条件,您可以定义整个 Bazel 生态系统将使用的语言。
Runfiles 库
如果您的规则提供用于访问 runfile 的标准库,则该库应采用位于 //<LANG>/runfiles
(//<LANG>/runfiles:runfiles
的缩写)的库目标的形式。需要访问其数据依赖项的用户目标通常会将此目标添加到其 deps
属性。
代码库规则
依赖项
您的规则可能具有外部依赖项,您需要在 MODULE.bazel 文件中指定这些依赖项。
注册工具链
您的规则可能还会注册工具链,您也可以在 MODULE.bazel 文件中指定这些工具链。
请注意,为了在分析阶段解析工具链,Bazel 需要分析所有已注册的 toolchain
目标。Bazel 将无需分析 toolchain.toolchain
属性引用的所有目标。如果为了注册工具链,您需要在代码库中执行复杂的计算,请考虑将包含 toolchain
目标的代码库与包含 <LANG>_toolchain
目标的代码库分开。前者将始终被提取,而后者仅在用户实际需要构建 <LANG>
代码时才会被提取。
发布代码段
在发布公告中,提供一个代码段,供用户复制并粘贴到其 MODULE.bazel
文件中。此代码段一般如下所示:
bazel_dep(name = "rules_<LANG>", version = "<VERSION>")
测试
应有测试来验证规则是否按预期运行。该文件可以位于相应语言的规则的标准位置,也可以位于顶层的 tests/
目录中。
示例(可选)
对于用户来说,拥有一个 examples/
目录非常有用,该目录会向用户展示规则的几种基本使用方式。
CI/CD
许多规则集都使用 GitHub Actions。请参阅 rules-template 代码库中使用的配置,这些配置使用托管在 bazel-contrib 组织中的“可重用工作流”进行了简化。ci.yaml
会针对每个 PR 和 main
提交运行测试,而 release.yaml
会在您将标记推送到代码库时运行。如需了解详情,请参阅 rules-template 代码库中的注释。
如果您的代码库位于 bazelbuild 组织下,您可以申请将其添加到 ci.bazel.build。
文档
如需了解如何注释规则以自动生成文档,请参阅 Stardoc 文档。
rules-template 文档/ 文件夹展示了一种简单的方法,可确保 docs/
文件夹中的 Markdown 内容始终与 Starlark 文件保持同步。
常见问题解答
为什么我们无法将规则添加到主 Bazel GitHub 代码库?
我们希望尽可能将规则与 Bazel 版本分离。这样可以更清楚地了解各个规则的归属,从而减轻 Bazel 开发者的负担。对于用户来说,解耦可让您更轻松地修改、升级、降级和替换规则。 与贡献于 Bazel 相比,贡献于规则可能更轻量级(具体取决于规则),包括对相应 GitHub 代码库的完整提交访问权限。获取 Bazel 本身的提交访问权限是一个复杂得多的过程。
缺点是用户需要执行一次性安装,过程较为复杂:他们必须在 MODULE.bazel
文件中添加对您的规则集的依赖项。
我们以前将所有规则都放在 Bazel 代码库中(位于 //tools/build_rules
或 //tools/build_defs
下)。我们现在仍在那里保留了一些规则,但正在努力将剩余的规则移出。