解决方案不止一种。
最干净的方法是在构建时进行验证:为要验证的每个文件(或一批文件)创建一个genrule,如果验证成功,则 genrule 会输出一些内容,如果失败,则该规则不输出任何内容,这也会自动使构建失败。
由于验证的成功取决于文件的内容,并且相同的输入应该产生相同的输出,所以 genrules 应该产生一个依赖于输入内容的输出文件。最方便的方法是验证成功时将文件的摘要写入输出,验证失败则不输出。
要使验证器可重用,您可以创建一个Skylark macro 并在您的所有包中使用它。
要将所有这些放在一起,您可以编写如下内容。
//tools:py_verify_test.bzl的内容:
def py_verify_test(name, srcs, visibility = None):
rules = {"%s-file%d" % (name, hash(s)): s for s in srcs}
for rulename, src in rules.items():
native.genrule(
name = rulename,
srcs = [s],
outs = ["%s.md5" % rulename],
cmd = "$(location //tools:py_verifier) $< && md5sum $< > $@",
tools = ["//tools:py_verifier"],
visibility = ["//visibility:private"],
)
native.sh_test(
name = name,
srcs = ["//tools:build_test.sh"],
data = rules.keys(),
visibility = visibility,
)
//tools:build_test.sh的内容:
#!/bin/true
# If the test rule's dependencies could be built,
# then all files were successfully verified at
# build time, so this test can merely return true.
//tools:BUILD的内容:
# I just use sh_binary as an example, this could
# be a more complicated rule of course.
sh_binary(
name = "py_verifier",
srcs = ["py_verifier.sh"],
visibility = ["//visibility:public"],
)
任何想要验证文件的包的内容:
load("//tools:py_verify_test.bzl", "py_verify_test")
py_verify_test(
name = "verify",
srcs = glob(["**/*.py"]),
)