Check step in bazel

I am looking for a good recipe for running a “check” or “check” of steps in Bazel, for example go vet , gofmt , pylint , cppcheck . These steps do not create any output file. The only thing that matters is a return code (like a test).

Now I am using the following recipe:

 sh_test( name = "verify-pylint", srcs = ["verify-pylint.sh"], data = ["//:all-srcs"], ) 

And verify-pylint.sh looks like this:

 find . -name '*.py' | xargs pylint 

This has two problems:

  • Validation logic is shared between the shell script and the BUILD file. Ideally, I would like to have both in one place (in the BUILD file).
  • Anytime one of the source files changes (in //:all-srcs ), bazel test verify-pylint re-runs pylint for each individual file (and this can be expensive / slow).

What is the idiomatic way to run these steps?

+5
source share
2 answers

There are several solutions.

The cleanest way is to perform validation during build: you create a genrule for each file (or batch of files) that you want to verify, and if the verification succeeds, genrule outputs something, if that fails, then the rule does not output anything, which automatically also leads to a build failure.

Since the success of the check depends on the contents of the file, and the same input should give the same result, genrules should create an output file that depends on the contents of the input (s). The most convenient thing is to write the digest of the file (s) to the output if the verification is successful, and there is no output if the verification failed.

To re-validate with a verifier, you can create a Skylark macro and use it in all of your packages.

To put it all together, you should write something like the following.

Contents //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, ) 

Contents //tools:build_test.sh :

 #!/bin/true # If the test rule dependencies could be built, # then all files were successfully verified at # build time, so this test can merely return true. 

Contents //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"], ) 

The contents of any package that wants to check files:

 load("//tools:py_verify_test.bzl", "py_verify_test") py_verify_test( name = "verify", srcs = glob(["**/*.py"]), ) 
+3
source

A simple solution.

In your BUILD file:

 load(":gofmt.bzl", "gofmt_test") gofmt_test( name = "format_test", srcs = glob(["*.go"]), ) 

In gofmt.bzl :

 def gofmt_test(name, srcs): cmd = """ export TMPDIR=. out=$$(gofmt -d $(SRCS)) if [ -n "$$out" ]; then echo "gmfmt failed:" echo "$$out" exit 1 fi touch $@ """ native.genrule( name = name, cmd = cmd, srcs = srcs, outs = [name + ".out"], tools = ["gofmt.sh"], ) 

Some notes:

  • If your wrapper script grows, you should put it in a separate .sh file.
  • In the genrule command, we need $$ instead of $ due to escaping (see documentation )
  • gofmt_test is not really a test and will work with bazel build :all . If you really need a test, see the Laszlo example and the sh_test call.
  • I call touch to create the file because genrule requires the result to be successful.
  • export TMPDIR=. necessary because by default the sandbox prevents writing to other directories.

In order to cache the results for each file (and not double-check the file that has not changed), you need to create several actions. See Loop Laszlo for .

To simplify the code, we could provide a general rule. Perhaps this is what we should put in the standard library.

+1
source

Source: https://habr.com/ru/post/1266032/


All Articles