首页 > 解决方案 > Bazel WORKSPACE 有条件地定义了两个`git_repository`s之一

问题描述

我正在维护两个 Python 库 A 和 B,每个库都部分使用 Bazel 来构建非 Python 代码。库 B 在 Bazel 方面依赖于 A,因此 B 需要 A 的远程存储库。

git_repository(
  name = "A",
  commit = "...",
  remote = "https://github.com/foo/A",
)
git_repository(
  name = "A",
  branch = "master",
  remote = "https://github.com/foo/B",
)

我想使用其中之一。经过一些研究,我发现没有可以在 WORKSPACE 级别使用的“条件分支”方法(从命令行标志或环境变量提供)。我正在询问我找不到的任何选项。


以下是我搜索过的替代方案,但不是 100% 满意。

# WORKSPACE
git_repository(name = "A", ...)
git_repository(name = "A_master", ...)

# BUILD
config_setting(name = "use_master", ...)
alias(
  name = "A_pkg_label",  # There are too many targets to declare
  actual = select({
    ":use_master": "@A_master/pkg:label",
    "//conditions:default": "@A/pkg:label",
  })
)

标签: bazel

解决方案


虽然您一般不能重用其他存储库规则,但实际上其中许多规则是用 Starlark 编写的,并且易于重用。例如,git_repository的实现如下所示

def _git_repository_implementation(ctx):
    update = _clone_or_update(ctx)
    patch(ctx)
    ctx.delete(ctx.path(".git"))
    return _update_git_attrs(ctx.attr, _common_attrs.keys(), update)

如果您只使用基本功能,或者可能load来自您自己的 starlark 代码,那么大多数这些实用程序功能要么是 NOP。你可以用这个来做一个准系统替换:

load("@bazel_tools//tools/build_defs/repo:git_worker.bzl", "git_repo")
def _my_git_repository_implementation(ctx):
    directory = str(ctx.path("."))
    git_repo(ctx, directory)
    ctx.delete(ctx.path(".git"))

推荐阅读