diff options
-rw-r--r-- | tools/defs.bzl | 3 | ||||
-rw-r--r-- | tools/nogo/BUILD | 6 | ||||
-rw-r--r-- | tools/nogo/defs.bzl | 48 | ||||
-rwxr-xr-x | tools/nogo/gentest.sh | 47 |
4 files changed, 74 insertions, 30 deletions
diff --git a/tools/defs.bzl b/tools/defs.bzl index 64cacb27a..e2c72a1f6 100644 --- a/tools/defs.bzl +++ b/tools/defs.bzl @@ -72,6 +72,7 @@ def go_binary(name, nogo = True, pure = False, static = False, x_defs = None, ** ) nogo_test( name = name + "_nogo", + srcs = kwargs.get("srcs", []), library = ":" + name + "_nogo_library", ) @@ -203,6 +204,7 @@ def go_library(name, srcs, deps = [], imports = [], stateify = True, marshal = F if nogo: nogo_test( name = name + "_nogo", + srcs = all_srcs, library = ":" + name, ) @@ -239,6 +241,7 @@ def go_test(name, nogo = True, **kwargs): if nogo: nogo_test( name = name + "_nogo", + srcs = kwargs.get("srcs", []), library = ":" + name, ) diff --git a/tools/nogo/BUILD b/tools/nogo/BUILD index 313c56410..dd4b46f58 100644 --- a/tools/nogo/BUILD +++ b/tools/nogo/BUILD @@ -13,6 +13,12 @@ nogo_stdlib( visibility = ["//visibility:public"], ) +sh_binary( + name = "gentest", + srcs = ["gentest.sh"], + visibility = ["//visibility:public"], +) + go_library( name = "nogo", srcs = [ diff --git a/tools/nogo/defs.bzl b/tools/nogo/defs.bzl index e780a83e8..c6fcfd402 100644 --- a/tools/nogo/defs.bzl +++ b/tools/nogo/defs.bzl @@ -275,36 +275,19 @@ nogo_aspect = go_rule( def _nogo_test_impl(ctx): """Check nogo findings.""" - # Build a runner that checks for the existence of the facts file. Note that - # the actual build will fail in the case of a broken analysis. We things - # this way so that any test applied is effectively pushed down to all - # upstream dependencies through the aspect. - inputs = [] - findings = [] - runner = ctx.actions.declare_file("%s-executer" % ctx.label.name) - runner_content = ["#!/bin/bash"] - for dep in ctx.attr.deps: - # Extract the findings. - info = dep[NogoInfo] - inputs.append(info.findings) - findings.append(info.findings) - - # Include all source files, transitively. This will make this target - # "directly affected" for the purpose of build analysis. - inputs += info.srcs - - # If there are findings, dump them and fail. - runner_content.append("if [[ -s \"%s\" ]]; then cat \"%s\" && exit 1; fi" % ( - info.findings.short_path, - info.findings.short_path, - )) - - # Otherwise, draw a sweet unicode checkmark with the package name (in green). - runner_content.append("echo -e \"\\033[0;32m\\xE2\\x9C\\x94\\033[0;31m\\033[0m %s\"" % info.importpath) - runner_content.append("exit 0\n") - ctx.actions.write(runner, "\n".join(runner_content), is_executable = True) + # Build a runner that checks the facts files. + findings = [dep[NogoInfo].findings for dep in ctx.attr.deps] + runner = ctx.actions.declare_file(ctx.label.name) + ctx.actions.run( + inputs = findings + ctx.files.srcs, + outputs = [runner], + tools = depset(ctx.files._gentest), + executable = ctx.files._gentest[0], + mnemonic = "Gentest", + progress_message = "Generating %s" % ctx.label, + arguments = [runner.path] + [f.path for f in findings], + ) return [DefaultInfo( - runfiles = ctx.runfiles(files = inputs), executable = runner, )] @@ -313,14 +296,19 @@ _nogo_test = rule( attrs = { # deps should have only a single element. "deps": attr.label_list(aspects = [nogo_aspect]), + # srcs exist here only to ensure that this target is + # directly affected by changes to the source files. + "srcs": attr.label_list(allow_files = True), + "_gentest": attr.label(default = "//tools/nogo:gentest"), }, test = True, ) -def nogo_test(name, library, **kwargs): +def nogo_test(name, srcs, library, **kwargs): tags = kwargs.pop("tags", []) + ["nogo"] _nogo_test( name = name, + srcs = srcs, deps = [library], tags = tags, **kwargs diff --git a/tools/nogo/gentest.sh b/tools/nogo/gentest.sh new file mode 100755 index 000000000..033da11ad --- /dev/null +++ b/tools/nogo/gentest.sh @@ -0,0 +1,47 @@ +#!/bin/bash +# Copyright 2019 The gVisor Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -euo pipefail + +if [[ "$#" -lt 2 ]]; then + echo "usage: $0 <output> <findings...>" + exit 2 +fi +declare violations=0 +declare output=$1 +shift + +# Start the script. +echo "#!/bin/sh" > "${output}" + +# Read a list of findings files. +declare filename +declare line +for filename in "$@"; do + if [[ -z "${filename}" ]]; then + continue + fi + while read -r line; do + violations=$((${violations}+1)); + echo "echo -e '\\033[0;31m${line}\\033[0;31m\\033[0m'" >> "${output}" + done < "${filename}" +done + +# Show violations. +if [[ "${violations}" -eq 0 ]]; then + echo "echo -e '\\033[0;32mPASS\\033[0;31m\\033[0m'" >> "${output}" +else + echo "exit 1" >> "${output}" +fi |