我可以查询一组标签吗?

Nat*_*rot 2 bazel

我想运行一组 Bazel 目标。我的BUILD文件看起来像这样

load("@rules_java//java:defs.bzl", "java_binary")

java_binary(
    name = "run_me",
    srcs = glob(["src1/main/java/com/example/*.java"]),
    tags = ["java", "good"],
)

java_binary(
    name = "me_also",
    srcs = glob(["src2/main/java/com/example/*.java"]),
    tags = ["java", "good"],
)

java_binary(
    name = "do_not_run_me",
    srcs = glob(["src3/main/java/com/example/*.java"]),
    tags = ["java", "bad"],
)
Run Code Online (Sandbox Code Playgroud)

我想运行所有标记为“好”的目标。我希望能够做类似的事情

bazel query 'tags(["good"], //...)'
Run Code Online (Sandbox Code Playgroud)

我在文档中没有看到查询标签的功能。我明白了attr,所以我尝试了

bazel query 'attr(tags, "\[good\]", //...)'
Run Code Online (Sandbox Code Playgroud)

但这是行不通的。我认为因为

列表类型的属性(如 srcs、data 等)会转换为 [value1, ..., valuen] 形式的字符串,以 [ 括号开头,以 ] 括号结尾,并使用“,”(逗号、空格) ) 分隔多个值

我能够使其完全匹配地工作,

bazel query 'attr(tags, "\[good, java\]", //...)'
Run Code Online (Sandbox Code Playgroud)

但是,请注意

  1. 交换列表的顺序("\[java, good\]")没有得到任何结果)。我不确定它是按字母顺序排列还是将它们放入哈希集中。但这意味着订购不可靠。
  2. 我不想列出所有标签。我希望能够运行所有“好”目标,即使有些目标也被标记为“慢”或“本地”。

我可以使用标签来完成此任务吗?标签真的只是用于测试吗?(这test_suite就是我首先考虑使用标签的原因。)

ahu*_*sky 7

如果您的意思是“运行一组 Bazel 目标” bazel run,则可以使用--build_tag_filters以下命令:

https://docs.bazel.build/versions/3.2.0/command-line-reference.html#flag--build_tag_filters

但请注意,bazel run一次仅支持运行 1 个可执行目标。

如果您想在一次调用中运行多个二进制文件,则需要继续追求bazel query.

过滤attr()器接受正则表达式,因此为了解决标签任意顺序的问题,您可以执行以下操作:

bazel query "attr(tags, '\\bgood\\b', //...)"

(其中\b是单词边界匹配器)

如果您有多个标签,您可以使用intersect

bazel query "attr(tags, '\\bgood\\b', //...) intersect attr(tags, '\\balso-good\\b', //...)"

这将为您提供要运行的目标列表,然后您可以执行以下操作:

targets=$(bazel query "attr(tags, '\\bgood\\b', //...)")

bazel build ${targets[@]}

for target in ${targets[@]}; do
  bazel run $target &
done
Run Code Online (Sandbox Code Playgroud)

bazel run将在运行目标之前构建目标,并且 bazel 将等待同一工作区中先前对其自身的调用[1]。因此,为了让二进制文件并行运行(如果这是您想要的),该示例在运行它们之前构建所有目标。(一旦二进制文件运行,bazel 就不会阻止其自身的后续调用)

还有另一个看起来更好的想法,那就是让一个sh_binarywhich 依赖于您想要运行的所有二进制文件,并且sh_binary脚本只需运行它们即可。然后您就可以bazel run在该单曲上进行操作sh_binary。问题是您必须在 的data属性中列出要运行的每个二进制文件sh_binary,因为不可能使用查询在 BUILD 文件中创建依赖项(尽管有一条genquery规则 - 只输出结果对文件的查询)。

[1] 除非您有用于--output_base不同调用的单独输出基础