从 git_repository 规则获取 git 元数据

Getting git metadata from git_repository rule

this 提交(首次包含在 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 子目录作为 git_repository 规则的一部分被删除的原因是在 machine-verifiable form 中具有外部存储库的可重现内容。但是,存储库规则的所有部分,包括 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 文件中。