Bazel 执行路径的惯用检索
Idiomatic retrieval of the Bazel execution path
我正在研究我的第一个自定义 Bazel 规则。规则允许 运行 的 bats
命令行测试。
我在下面逐字记录了规则定义。到目前为止,我对它很满意,但有一部分感觉真的很丑陋且不标准。如果规则用户向规则添加二进制依赖项,那么我会确保二进制文件出现在 PATH
上,以便可以对其进行测试。目前我通过制作一个二进制路径列表,然后在它们后面附加 $PWD
来实现这一点,它在脚本内部扩展到完整的执行路径。这感觉很老套而且容易出错。
有没有更惯用的方法来做到这一点?我不相信我可以访问规则中的执行路径,因为它直到执行阶段才被创建。
感谢您的帮助!
BATS_REPOSITORY_BUILD_FILE = """
package(default_visibility = [ "//visibility:public" ])
sh_binary(
name = "bats",
srcs = ["libexec/bats"],
data = [
"libexec/bats-exec-suite",
"libexec/bats-exec-test",
"libexec/bats-format-tap-stream",
"libexec/bats-preprocess",
],
)
"""
def bats_repositories(version="v0.4.0"):
native.new_git_repository(
name = "bats",
remote = "https://github.com/sstephenson/bats",
tag = version,
build_file_content = BATS_REPOSITORY_BUILD_FILE
)
BASH_TEMPLATE = """
#!/usr/bin/env bash
set -e
export TMPDIR="$TEST_TMPDIR"
export PATH="{bats_bins_path}":$PATH
"{bats}" "{test_paths}"
"""
def _dirname(path):
prefix, _, _ = path.rpartition("/")
return prefix.rstrip("/")
def _bats_test_impl(ctx):
runfiles = ctx.runfiles(
files = ctx.files.srcs,
collect_data = True,
)
tests = [f.short_path for f in ctx.files.srcs]
path = ["$PWD/" + _dirname(b.short_path) for b in ctx.files.deps]
sep = ctx.configuration.host_path_separator
ctx.file_action(
output = ctx.outputs.executable,
executable = True,
content = BASH_TEMPLATE.format(
bats = ctx.executable._bats.short_path,
test_paths = " ".join(tests),
bats_bins_path = sep.join(path),
),
)
runfiles = runfiles.merge(ctx.attr._bats.default_runfiles)
return DefaultInfo(
runfiles = runfiles,
)
bats_test = rule(
attrs = {
"srcs": attr.label_list(
allow_files = True,
),
"deps": attr.label_list(),
"_bats": attr.label(
default = Label("@bats//:bats"),
executable = True,
cfg = "host",
),
},
test = True,
implementation = _bats_test_impl,
)
Bazel 0.8.0 将在大约 2 周内发布,这应该很容易支持。
在您的 skylark 实现中,您应该执行 ctx.expand_location(binary)
,其中 binary
应该类似于 $(execpath :some-label)
,因此您可能只想使用 $(execpath)
和 bazel 格式化从用户那里获得的标签将确保为您提供该标签的执行位置。
一些相关资源:
https://github.com/bazelbuild/bazel/issues/2475
https://github.com/bazelbuild/bazel/commit/cff0dc94f6a8e16492adf54c88d0b26abe903d4c
我正在研究我的第一个自定义 Bazel 规则。规则允许 运行 的 bats
命令行测试。
我在下面逐字记录了规则定义。到目前为止,我对它很满意,但有一部分感觉真的很丑陋且不标准。如果规则用户向规则添加二进制依赖项,那么我会确保二进制文件出现在 PATH
上,以便可以对其进行测试。目前我通过制作一个二进制路径列表,然后在它们后面附加 $PWD
来实现这一点,它在脚本内部扩展到完整的执行路径。这感觉很老套而且容易出错。
有没有更惯用的方法来做到这一点?我不相信我可以访问规则中的执行路径,因为它直到执行阶段才被创建。
感谢您的帮助!
BATS_REPOSITORY_BUILD_FILE = """
package(default_visibility = [ "//visibility:public" ])
sh_binary(
name = "bats",
srcs = ["libexec/bats"],
data = [
"libexec/bats-exec-suite",
"libexec/bats-exec-test",
"libexec/bats-format-tap-stream",
"libexec/bats-preprocess",
],
)
"""
def bats_repositories(version="v0.4.0"):
native.new_git_repository(
name = "bats",
remote = "https://github.com/sstephenson/bats",
tag = version,
build_file_content = BATS_REPOSITORY_BUILD_FILE
)
BASH_TEMPLATE = """
#!/usr/bin/env bash
set -e
export TMPDIR="$TEST_TMPDIR"
export PATH="{bats_bins_path}":$PATH
"{bats}" "{test_paths}"
"""
def _dirname(path):
prefix, _, _ = path.rpartition("/")
return prefix.rstrip("/")
def _bats_test_impl(ctx):
runfiles = ctx.runfiles(
files = ctx.files.srcs,
collect_data = True,
)
tests = [f.short_path for f in ctx.files.srcs]
path = ["$PWD/" + _dirname(b.short_path) for b in ctx.files.deps]
sep = ctx.configuration.host_path_separator
ctx.file_action(
output = ctx.outputs.executable,
executable = True,
content = BASH_TEMPLATE.format(
bats = ctx.executable._bats.short_path,
test_paths = " ".join(tests),
bats_bins_path = sep.join(path),
),
)
runfiles = runfiles.merge(ctx.attr._bats.default_runfiles)
return DefaultInfo(
runfiles = runfiles,
)
bats_test = rule(
attrs = {
"srcs": attr.label_list(
allow_files = True,
),
"deps": attr.label_list(),
"_bats": attr.label(
default = Label("@bats//:bats"),
executable = True,
cfg = "host",
),
},
test = True,
implementation = _bats_test_impl,
)
Bazel 0.8.0 将在大约 2 周内发布,这应该很容易支持。
在您的 skylark 实现中,您应该执行 ctx.expand_location(binary)
,其中 binary
应该类似于 $(execpath :some-label)
,因此您可能只想使用 $(execpath)
和 bazel 格式化从用户那里获得的标签将确保为您提供该标签的执行位置。
一些相关资源:
https://github.com/bazelbuild/bazel/issues/2475
https://github.com/bazelbuild/bazel/commit/cff0dc94f6a8e16492adf54c88d0b26abe903d4c