Bazel 执行路径的惯用检索

xoe*_*bus 1 bazel

我正在制定我的第一个自定义 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,
)
Run Code Online (Sandbox Code Playgroud)

Itt*_*tai 5

Bazel 0.8.0 将在大约 2 周内发布,这应该很容易支持。
在您的 skylark 实现中,您应该执行ctx.expand_location(binary)where binaryshould 类似的操作$(execpath :some-label),因此您可能只想使用 来格式化从用户那里获得的标签,并且$(execpath)bazel 将确保为您提供该标签的执行位置。

一些相关资源: Bazel 中的 $location 扩展
https://github.com/bazelbuild/bazel/issues/2475 https://github.com/bazelbuild/bazel/commit/cff0dc94f6a8e16492adf54c88d0b26abe903d4c