从规则中获取 git 元数据git_repository



在此提交之前(首次包含在 0.17.0 中(,我能够使用genrule从外部 git 存储库收集 git 元数据。

它实际上看起来像这样:

genrule(
name = "git-describe-foo",
# We can't dep all of @foo, so we pick a file
srcs = ["@foo//:SOME_FILE"],
outs = ["my_version"],
# Do a git describe and strip off the leading "v"
cmd = "git -C $$(dirname $(location @foo//:SOME_FILE)) describe --tags | cut -c 2- > $@",
# I don't know if this is strictly necessary
stamp = True,
# This is required or bazel will sandbox us with just SOME_FILE
local = True,
output_to_bindir = True,
)

但是,这不再有效,因为.git/目录现已被删除。我知道这样做是为了提高可重现性,但 git SHA(以及理论上的 git 历史(实际上不应该影响构建的可重现性。

我最初的方法是尝试以某种方式通过--workspace_status_command传入我需要的 git SHA 和 git 元数据,但随后我还必须使用该 git SHA 来克隆git_repository,我认为这是不可能的。

有没有其他方法可以收集这些信息?

首先,您对genrule的使用通常会被破坏,因为它依赖于声明的输入之外的更多。正如您自己所注意到的,沙盒会检测这些未声明(因此未被bazel跟踪(输入。

作为git_repository规则的一部分删除.git子目录的原因是,外部存储库的可重现内容以计算机可验证的形式存在。但是,存储库规则的所有部分(包括patch_cmds(都会在删除.git子目录之前执行。因此,您可以将元数据创建为存储库本身的一部分,例如,如下所示。

load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
git_repository(
remote = "...",
...
patch_cmds = [
"git log -n 1 --format=%H > VERSION",
],
)

有两件事要记住。

  • 为了可重现,元数据应完全由提交本身确定。

  • 确保将添加的元数据文件导出,例如,通过将exports_files(["VERSION"])修补到外部存储库的BUILD文件中。

最新更新