diff options
Diffstat (limited to 'rules/lint')
-rw-r--r-- | rules/lint/RULES | 292 | ||||
-rw-r--r-- | rules/lint/TARGETS | 3 | ||||
-rwxr-xr-x | rules/lint/call_lint | 45 | ||||
-rwxr-xr-x | rules/lint/call_summary | 36 |
4 files changed, 376 insertions, 0 deletions
diff --git a/rules/lint/RULES b/rules/lint/RULES new file mode 100644 index 0000000..add3cdb --- /dev/null +++ b/rules/lint/RULES @@ -0,0 +1,292 @@ +{ "defaults": + { "doc": + [ "A rule to provide default paths common to all lint targets." + , "" + , "While lint targets bring their own host directory via the" + , "field \"config\", it can still be necessary to bring some" + , "default paths, e.g., for finding the compiler, or the interpreter" + , "for the runner." + ] + , "string_fields": ["PATH"] + , "target_fields": ["base"] + , "field_doc": + { "base": ["Other targets to inherit values from."] + , "PATH": + [ "Paths for looking up system tools." + , "Specifying this field extends values from \"base\"." + ] + } + , "imports": {"base-provides-++": ["CC", "defaults-base-provides-++"]} + , "expression": + { "type": "let*" + , "bindings": + [ [ "PATH" + , { "type": "nub_left" + , "$1": + { "type": "++" + , "$1": + [ {"type": "FIELD", "name": "PATH"} + , { "type": "let*" + , "bindings": [["provider", "PATH"]] + , "body": + {"type": "CALL_EXPRESSION", "name": "base-provides-++"} + } + ] + } + } + ] + ] + , "body": {"type": "RESULT", "provides": {"type": "env", "vars": ["PATH"]}} + } + } +, "targets": + { "doc": + [ "Run a given linter on the lint information provided by the given targets." + ] + , "target_fields": ["linter", "config", "summarizer", "targets"] + , "string_fields": ["name"] + , "tainted": ["lint"] + , "field_doc": + { "linter": + [ "Single artifact running the lint checks." + , "" + , "This program is invoked with" + , "- argv[1] the file to lint, and" + , "- argv[2:] the original command line." + , "This invocation happens in an environment with" + , "- CONFIG pointing to the directory with all the artifacts given" + , " by the field \"config\", and" + , "- OUT pointing to a directory to which files with the lint result" + , " can be written." + , "- META pointing to a json file containing" + , " - at key \"direct deps artifact names\" a list of all input" + , " artifacts that come from the target itself or are runfiles of a" + , " direct dependency." + , " - at key \"extra outs\" a list of extra output artifacts that the" + , " command might produce, such as DWARF objects if debug fission is" + , " enabled." + , "- TMPDIR pointing to a directory location that can be used to" + , " create additional temporary files." + , "It is supposed to indicate by the exit code whether the file to lint" + , "complies with the given linting policy, with 0 meaning" + , "compliant." + , "Stdout and stderr, as well as the directory ${OUT} can be used to" + , "provide additional information." + ] + , "config": ["Any configuration or other files needed by the linter."] + , "summarizer": + [ "Single artifact generating a summary of the individual lint results." + , "It will be called in a directory where all subdirectories" + , "except . and .. represent the results of the individual lint" + , "actions. Those are given as" + , " - a file \"result\" with content \"PASS\" if and only if the lint" + , " action exited 0," + , " - files \"stdout\" and \"stderr\" with stdout and stderr of the lint" + , " action, and" + , " - a directory \"out\" with the additional information provided by the" + , " lint action." + , "The summarizer is required to indicate the overall result by the exit" + , "code, produce a human-readable summary on stdout, and optionally" + , "additional information in the directory ${OUT}." + ] + , "call_lint": ["Launcher for the linter"] + , "call_summary": ["Launcher for the summarizer"] + , "name": + [ "Name of the kind of lint check performed, to be reported" + , "when an action is failing." + ] + } + , "implicit": + { "defaults": ["defaults"] + , "call_lint": ["call_lint"] + , "call_summary": ["call_summary"] + } + , "config_transitions": {"targets": [{"type": "'", "$1": {"LINT": true}}]} + , "anonymous": + {"lint": {"target": "targets", "provider": "lint", "rule_map": {}}} + , "imports": + { "stage": ["", "stage_singleton_field"] + , "artifacts": ["", "field_artifacts"] + , "default-PATH": ["CC", "default-PATH"] + } + , "expression": + { "type": "let*" + , "bindings": + [ [ "linter" + , { "type": "let*" + , "bindings": [["fieldname", "linter"], ["location", "linter"]] + , "body": {"type": "CALL_EXPRESSION", "name": "stage"} + } + ] + , [ "runner" + , { "type": "let*" + , "bindings": [["fieldname", "call_lint"], ["location", "runner"]] + , "body": {"type": "CALL_EXPRESSION", "name": "stage"} + } + ] + , [ "config" + , { "type": "let*" + , "bindings": [["fieldname", "config"]] + , "body": {"type": "CALL_EXPRESSION", "name": "artifacts"} + } + ] + , [ "PATH" + , { "type": "join" + , "separator": ":" + , "$1": {"type": "CALL_EXPRESSION", "name": "default-PATH"} + } + ] + , ["name", {"type": "join", "$1": {"type": "FIELD", "name": "name"}}] + , [ "lint results" + , { "type": "foreach" + , "range": {"type": "FIELD", "name": "lint"} + , "body": + { "type": "let*" + , "bindings": + [ [ "src" + , { "type": "DEP_PROVIDES" + , "dep": {"type": "var", "name": "_"} + , "provider": "src" + } + ] + , [ "cmd" + , { "type": "DEP_PROVIDES" + , "dep": {"type": "var", "name": "_"} + , "provider": "cmd" + } + ] + , [ "src input" + , { "type": "DEP_ARTIFACTS" + , "dep": {"type": "var", "name": "_"} + } + ] + , [ "direct deps artifact names" + , { "type": "DEP_PROVIDES" + , "dep": {"type": "var", "name": "_"} + , "provider": "direct deps artifact names" + } + ] + , [ "extra outs" + , { "type": "DEP_PROVIDES" + , "dep": {"type": "var", "name": "_"} + , "provider": "extra outs" + } + ] + ] + , "body": + { "type": "TREE" + , "$1": + { "type": "ACTION" + , "inputs": + { "type": "map_union" + , "$1": + [ {"type": "var", "name": "runner"} + , {"type": "var", "name": "linter"} + , { "type": "to_subdir" + , "subdir": "work" + , "$1": {"type": "var", "name": "src input"} + } + , { "type": "to_subdir" + , "subdir": "config" + , "$1": {"type": "var", "name": "config"} + } + , { "type": "singleton_map" + , "key": "meta.json" + , "value": + { "type": "BLOB" + , "data": + { "type": "json_encode" + , "$1": + { "type": "env" + , "vars": + ["direct deps artifact names", "extra outs"] + } + } + } + } + ] + } + , "cmd": + { "type": "++" + , "$1": + [ ["./runner", {"type": "var", "name": "src"}] + , {"type": "var", "name": "cmd"} + ] + } + , "env": {"type": "env", "vars": ["PATH"]} + , "outs": ["stdout", "stderr", "result"] + , "out_dirs": ["out"] + , "may_fail": ["lint"] + , "fail_message": + { "type": "join" + , "$1": + [ "lint " + , {"type": "var", "name": "name"} + , { "type": "if" + , "cond": {"type": "var", "name": "name"} + , "then": " failed for " + , "else": "failed for " + } + , {"type": "var", "name": "src"} + ] + } + } + } + } + } + ] + , [ "lint results" + , {"type": "nub_right", "$1": {"type": "var", "name": "lint results"}} + ] + , [ "summary input" + , {"type": "enumerate", "$1": {"type": "var", "name": "lint results"}} + ] + , [ "summarizer" + , { "type": "let*" + , "bindings": + [["fieldname", "summarizer"], ["location", "summarizer"]] + , "body": {"type": "CALL_EXPRESSION", "name": "stage"} + } + ] + , [ "runner" + , { "type": "let*" + , "bindings": [["fieldname", "call_summary"], ["location", "runner"]] + , "body": {"type": "CALL_EXPRESSION", "name": "stage"} + } + ] + , [ "summary" + , { "type": "ACTION" + , "inputs": + { "type": "map_union" + , "$1": + [ {"type": "var", "name": "runner"} + , {"type": "var", "name": "summarizer"} + , { "type": "to_subdir" + , "subdir": "work" + , "$1": {"type": "var", "name": "summary input"} + } + ] + } + , "cmd": ["./runner"] + , "outs": ["report", "result"] + , "out_dirs": ["out"] + } + ] + ] + , "body": + { "type": "RESULT" + , "artifacts": + { "type": "map_union" + , "$1": + [ {"type": "var", "name": "summary"} + , { "type": "singleton_map" + , "key": "work" + , "value": + {"type": "TREE", "$1": {"type": "var", "name": "summary input"}} + } + ] + } + } + } + } +} diff --git a/rules/lint/TARGETS b/rules/lint/TARGETS new file mode 100644 index 0000000..de52b00 --- /dev/null +++ b/rules/lint/TARGETS @@ -0,0 +1,3 @@ +{ "defaults": + {"type": "defaults", "base": [["CC", "defaults"], ["shell", "defaults"]]} +} diff --git a/rules/lint/call_lint b/rules/lint/call_lint new file mode 100755 index 0000000..850812e --- /dev/null +++ b/rules/lint/call_lint @@ -0,0 +1,45 @@ +#!/bin/sh +# Copyright 2024 Huawei Cloud Computing Technology Co., Ltd. +# +# 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. + + +# ensure all required outputs are present +touch stdout +touch stderr +RESULT=UNKNOWN +echo "${RESULT}" > result + +mkdir -p out +export OUT="$(pwd)/out" +mkdir -p config +export CONFIG="$(pwd)/config" +export META="$(pwd)/meta.json" +mkdir scratch +export TMPDIR=$(realpath scratch) + +cd work + +if ../linter "$@" > ../stdout 2> ../stderr +then + RESULT=PASS +else + RESULT=FAIL +fi + +echo "${RESULT}" > ../result + +if [ "${RESULT}" '!=' PASS ] +then + exit 1; +fi diff --git a/rules/lint/call_summary b/rules/lint/call_summary new file mode 100755 index 0000000..9686d0a --- /dev/null +++ b/rules/lint/call_summary @@ -0,0 +1,36 @@ +#!/bin/sh +# Copyright 2024 Huawei Cloud Computing Technology Co., Ltd. +# +# 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. + + +# ensure all required outputs are present +touch report +RESULT=UNKNOWN +echo "${RESULT}" > result + +mkdir -p out +export OUT="$(pwd)/out" + +cd work + +if ../summarizer > ../report +then + RESULT=PASS +else + RESULT=FAIL +fi + +echo "${RESULT}" > ../result + +exit 0 |