我正在寻找一个好的食谱运行"检查"或巴泽尔"验证"的步骤,如go vet
,gofmt
,pylint
,cppcheck
.这些步骤不会创建任何输出文件.唯一重要的是返回代码(如测试).
现在我正在使用以下配方:
sh_test(
name = "verify-pylint",
srcs = ["verify-pylint.sh"],
data = ["//:all-srcs"],
)
Run Code Online (Sandbox Code Playgroud)
而且verify-pylint.sh
看起来是这样的:
find . -name '*.py' | xargs pylint
Run Code Online (Sandbox Code Playgroud)
这有两个问题:
//:all-srcs
),就会在每个文件上bazel test verify-pylint
重新运行pylint
(这可能很昂贵/很慢).在bazel运行这些步骤的惯用方法是什么?
解决方案不止一种。
最简洁的方法是在构建时进行验证:genrule
为要验证的每个文件(或一批文件)创建一个,如果验证成功,则 genrule 输出一些内容,如果失败,则规则不输出任何内容,这构建也会自动失败。
由于验证的成功取决于文件的内容,并且相同的输入应该产生相同的输出,因此genrules应该生成一个依赖于输入内容的输出文件。最方便的方法是,如果验证成功,则将文件的摘要写入输出,如果验证失败,则不输出。
为了使验证器可重用,您可以创建一个Skylark 宏并在所有包中使用它。
为了将所有这些放在一起,您可以编写如下内容。
内容//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,
)
Run Code Online (Sandbox Code Playgroud)
内容//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.
Run Code Online (Sandbox Code Playgroud)
内容//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"],
)
Run Code Online (Sandbox Code Playgroud)
任何想要验证文件的包的内容:
load("//tools:py_verify_test.bzl", "py_verify_test")
py_verify_test(
name = "verify",
srcs = glob(["**/*.py"]),
)
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
391 次 |
最近记录: |