此页面适用于计划向他人提供规则的规则编写者。
我们建议您从模板代码库 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
WORKSPACE
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
WORKSPACE
在项目的 WORKSPACE 中,您应定义用户将用于引用规则的名称。如果您的规则属于
bazelbuild 组织,则必须使用
rules_<lang>(例如 rules_mockascript)。否则,您应将
代码库命名为 <org>_rules_<lang>(例如 build_stack_rules_proto)。如果您认为自己的规则应遵循
bazelbuild 组织中规则的惯例,请在 GitHub
上发起讨论串。
在以下部分中,假设代码库属于 bazelbuild 组织。
workspace(name = "rules_mockascript")
README
在顶层,应有一个 README,其中包含(至少)用户需要复制并粘贴到其 WORKSPACE 文件中才能使用您的规则的内容。
一般来说,这将是一个指向 GitHub 版本的 http_archive 和一个宏调用,用于下载/配置规则所需的任何工具。例如,
对于 Go
规则,它
看起来像这样:
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "rules_go",
urls = ["https://github.com/bazelbuild/rules_go/releases/download/0.18.5/rules_go-0.18.5.tar.gz"],
sha256 = "a82a352bffae6bee4e95f68a8d80a70e87f42c4741e6a448bec11998fcc82329",
)
load("@rules_go//go:deps.bzl", "go_rules_dependencies", "go_register_toolchains")
go_rules_dependencies()
go_register_toolchains()
如果您的规则依赖于另一个代码库的规则,请在
规则文档中指定这一点(例如,请参阅
依赖于 Sass 规则的 Skydoc 规则),并提供一个 WORKSPACE
宏,用于下载所有依赖项(请参阅上面的 rules_go)。
规则
您的代码库通常会提供多个规则。按语言创建一个目录,并提供一个入口点 - 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 文件中执行特定于平台的逻辑(例如,
使用 选择)。
借助自定义限制条件,您可以定义整个 Bazel 生态系统将使用的语言。
Runfiles 库
如果您的规则提供用于访问 runfiles 的标准库,则该规则应采用位于 //<LANG>/runfiles 的库目标的形式(//<LANG>/runfiles:runfiles 的缩写)。需要访问其数据依赖项的用户目标通常会将此目标添加到其 deps 属性中。
代码库规则
依赖项
您的规则可能具有外部依赖项。为了简化对规则的依赖,请提供一个 WORKSPACE 宏,用于声明对这些外部依赖项的依赖。请勿在此处声明测试的依赖项,而仅声明规则正常运行所需的依赖项。将开发依赖项放入 WORKSPACE 文件中。
创建一个名为 <LANG>/repositories.bzl 的文件,并提供一个名为 rules_<LANG>_dependencies 的入口点
宏。我们的目录将如下所示:
/
mockascript/
constraints/
BUILD
BUILD
defs.bzl
repositories.bzl
注册工具链
您的规则可能还会注册工具链。请提供一个单独的 WORKSPACE 宏来注册这些工具链。这样,用户就可以选择省略之前的宏并手动控制依赖项,同时仍然可以注册工具链。
因此,请将名为 rules_<LANG>_toolchains 的 WORKSPACE 宏添加到
<LANG>/repositories.bzl 文件中。
请注意,为了在分析阶段解析工具链,Bazel 需要分析所有已注册的 toolchain 目标。Bazel 不需要分析 toolchain.toolchain 属性引用的所有目标。如果为了注册工具链,您需要在代码库中执行复杂的计算,请考虑将包含 toolchain 目标的代码库与包含 <LANG>_toolchain 目标的代码库分开。前者将始终被提取,而
后者仅在用户实际需要构建 <LANG> 代码时才会被提取。
发布代码段
在发布公告中,提供一个代码段,供用户复制并粘贴到其 WORKSPACE 文件中。此代码段通常如下所示:
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "rules_<LANG>",
urls = ["<url_to_the_release.zip"],
sha256 = "4242424242",
)
load("@rules_<LANG>//<LANG>:repositories.bzl", "rules_<LANG>_dependencies", "rules_<LANG>_toolchains")
rules_<LANG>_dependencies()
rules_<LANG>_toolchains()
测试
应有测试来验证规则是否按预期运行。这可以位于规则所针对语言的标准位置,也可以位于顶层的 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/ 文件夹
展示了一种简单的方法,可确保在更新 Starlark 文件时,docs/ 文件夹中的 Markdown 内容始终处于最新状态。
常见问题解答
为什么我们无法将规则添加到主要的 Bazel GitHub 代码库?
我们希望尽可能将规则与 Bazel 版本分离。这样可以更清楚地了解谁拥有各个规则,从而减轻 Bazel 开发者的负担。对于我们的用户来说,分离可以更轻松地修改、升级、降级和替换规则。 贡献规则可能比贡献 Bazel 更轻松(具体取决于规则),包括对相应 GitHub 代码库的完整提交访问权限。获取对 Bazel 本身的提交访问权限是一个复杂得多的过程。
缺点是,对于我们的用户来说,一次性安装过程更加复杂:他们必须将规则复制并粘贴到其 WORKSPACE 文件中,如上文 README.md 部分所示。
我们过去将所有规则都放在 Bazel 代码库中(位于 //tools/build_rules 或 //tools/build_defs 下)。我们仍然在那里保留了一些规则,但我们正在努力将剩余的规则移出。