utils/check-package: prepare to run external tools

Some file formats have well-established syntax checkers.
One example of this is the tool 'shellcheck' that can analyse shell
scripts for common mistakes.

There is no reason to reimplement such tools in check-package, when we
can just call them.

Add the ability to check-package to call external tools that will run
once for each file to be analysed.
For simplicity, when the tool generated one or more warnings, count it
as a single warning from check-package, that can display something like
this:

|$ ./utils/check-package  package/unscd/S46unscd
|package/unscd/S46unscd:0: run 'shellcheck' and fix the warnings
|25 lines processed
|1 warnings generated

|$ ./utils/check-package -vvvvvvvvvvvvvvvv package/unscd/S46unscd
|package/unscd/S46unscd:0: run 'shellcheck' and fix the warnings
|In package/unscd/S46unscd line 9:
|        printf "Starting ${NAME}: "
|               ^------------------^ SC2059: Don't use variables in the printf format string. Use printf "..%s.." "$foo".
|In package/unscd/S46unscd line 11:
|        [ $? -eq 0 ] && echo "OK" || echo "FAIL"
|          ^-- SC2181: Check exit code directly with e.g. 'if mycmd;', not indirectly with $?.
|In package/unscd/S46unscd line 14:
|        printf "Stopping ${NAME}: "
|               ^------------------^ SC2059: Don't use variables in the printf format string. Use printf "..%s.." "$foo".
|In package/unscd/S46unscd line 16:
|        [ $? -eq 0 ] && echo "OK" || echo "FAIL"
|          ^-- SC2181: Check exit code directly with e.g. 'if mycmd;', not indirectly with $?.
|For more information:
|  https://www.shellcheck.net/wiki/SC2059 -- Don't use variables in the printf...
|  https://www.shellcheck.net/wiki/SC2181 -- Check exit code directly with e.g...
|25 lines processed
|1 warnings generated

In this first commit, add only the ability for check-package to call
external tools and not an example of such tool, as adding each tool to
call may need update to the docker image and can lead to it's own
discussion on how to implement.

Signed-off-by: Ricardo Martincoski <ricardo.martincoski@gmail.com>
Signed-off-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
This commit is contained in:
Ricardo Martincoski 2021-12-26 15:49:15 -03:00 committed by Arnout Vandecappelle (Essensium/Mind)
parent 4fe33a1b47
commit 1734127e59
2 changed files with 36 additions and 6 deletions

View File

@ -8,6 +8,7 @@ import re
import six
import sys
import checkpackagelib.base
import checkpackagelib.lib_config
import checkpackagelib.lib_hash
import checkpackagelib.lib_mk
@ -87,9 +88,7 @@ def get_lib_from_filename(fname):
return None
def is_a_check_function(m):
if not inspect.isclass(m):
return False
def common_inspect_rules(m):
# do not call the base class
if m.__name__.startswith("_"):
return False
@ -100,6 +99,22 @@ def is_a_check_function(m):
return True
def is_a_check_function(m):
if not inspect.isclass(m):
return False
if not issubclass(m, checkpackagelib.base._CheckFunction):
return False
return common_inspect_rules(m)
def is_external_tool(m):
if not inspect.isclass(m):
return False
if not issubclass(m, checkpackagelib.base._Tool):
return False
return common_inspect_rules(m)
def print_warnings(warnings):
# Avoid the need to use 'return []' at the end of every check function.
if warnings is None:
@ -121,14 +136,16 @@ def check_file_using_lib(fname):
if flags.verbose >= VERBOSE_LEVEL_TO_SHOW_IGNORED_FILES:
print("{}: ignored".format(fname))
return nwarnings, nlines
classes = inspect.getmembers(lib, is_a_check_function)
internal_functions = inspect.getmembers(lib, is_a_check_function)
external_tools = inspect.getmembers(lib, is_external_tool)
all_checks = internal_functions + external_tools
if flags.dry_run:
functions_to_run = [c[0] for c in classes]
functions_to_run = [c[0] for c in all_checks]
print("{}: would run: {}".format(fname, functions_to_run))
return nwarnings, nlines
objects = [c[1](fname, flags.manual_url) for c in classes]
objects = [c[1](fname, flags.manual_url) for c in internal_functions]
for cf in objects:
nwarnings += print_warnings(cf.before())
@ -148,6 +165,11 @@ def check_file_using_lib(fname):
for cf in objects:
nwarnings += print_warnings(cf.after())
tools = [c[1](fname) for c in external_tools]
for tool in tools:
nwarnings += print_warnings(tool.run())
return nwarnings, nlines

View File

@ -16,3 +16,11 @@ class _CheckFunction(object):
def after(self):
pass
class _Tool(object):
def __init__(self, filename):
self.filename = filename
def run(self):
pass