kumquat-buildroot/utils/check-package

317 lines
10 KiB
Plaintext
Raw Normal View History

#!/usr/bin/env python3
# See utils/checkpackagelib/readme.txt before editing this file.
import argparse
import inspect
import magic
check-package: prepare to extend to other directories Currently the script only checks files inside the package/ directory. Upcoming patches will enable it for other directories. In order to reliably test for file names, i.e. the Config.in in the base directory, normalize the path of files to check to a relative path to the base directory. Rename the variable that holds the compiled regexp to better represent its content and rearrange how it is declared to make easy to later add new directories to check. As a consequence the files that declare package infra types would not be ignored anymore, so create a new variable to list the files intree to be ignored during the check. The same variable will be used by upcoming patches to ignore other files. Ignore pkg-*.mk and doc-asciidoc.mk since they are package infra files. In order to not produce weird results when used for files outside the tree (i.e. in a private br2-external) add an explicit command line option (-b) that bypasses any checks that would make a file be ignored by the path that contains it. When in this out-of-tree mode, the user is responsible for providing a list of files to check that do not contain files the script does not understand, e.g. package infra files. As a result of this patch, besides the known use: $ ./utils/check-package package/new-package/* someone with the utils/ directory in the path can now also run: $ cd package/new-package/ $ check-package * or $ check-package -b /path/to/br2-ext-tree/package/staging-package/* Signed-off-by: Ricardo Martincoski <ricardo.martincoski@gmail.com> Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
2018-04-01 07:08:14 +02:00
import os
import re
import sys
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>
2021-12-26 19:49:15 +01:00
import checkpackagelib.base
import checkpackagelib.lib_config
import checkpackagelib.lib_hash
import checkpackagelib.lib_ignore
import checkpackagelib.lib_mk
import checkpackagelib.lib_patch
import checkpackagelib.lib_python
import checkpackagelib.lib_shellscript
import checkpackagelib.lib_sysv
VERBOSE_LEVEL_TO_SHOW_IGNORED_FILES = 3
flags = None # Command line arguments.
# There are two Python packages called 'magic':
# https://pypi.org/project/file-magic/
# https://pypi.org/project/python-magic/
# Both allow to return a MIME file type, but with a slightly different
# interface. Detect which one of the two we have based on one of the
# attributes.
if hasattr(magic, 'FileMagic'):
# https://pypi.org/project/file-magic/
def get_filetype(fname):
return magic.detect_from_filename(fname).mime_type
else:
# https://pypi.org/project/python-magic/
def get_filetype(fname):
return magic.from_file(fname, mime=True)
utils/check-package: decouple adding rules from fixing all intree files When a new check_function is added to check-package, often there are files in the tree that would generate warnings. An example is the Sob check_function for patch files: | $ ./utils/check-package --i Sob $(git ls-files) >/dev/null | 369301 lines processed | 46 warnings generated Currently these warnings are listed when calling check-package directly, and also at the output of pkg-stats, but the check_function does not run on 'make check-package' (that is used to catch regressions on GitLab CI 'check-package' job) until all warnings in the tree are fixed. This (theoretically) allows new .patch files be added without SoB, without the GitLab CI catching it. So add a way to check-package itself ignore current warnings, while still catching new files that do not follow that new check_function. Add a file named .checkpackageignore to the buildroot topdir. It contains the list of check_functions that are expected to fail for each given intree file tested by check-package. Each entries is in the format: <filename> <check_function> [<check_function> ...] These are 2 examples of possible entries: package/initscripts/init.d/rcK ConsecutiveEmptyLines EmptyLastLine Shellcheck utils/test-pkg Shellcheck Keeping such a list allows us to have fine-grained control over which warning to ignore. In order to avoid this list to grow indefinitely, containing entries for files that are already fixed, make each entry an 'expected to fail' instead of just an 'ignore', and generate a warning if a check_function that was expect to fail for a given files does not generate that warning. Unfortunately one case that do not generate warning is an entry for a file that is deleted in a later commit. By default, all checks are applied. The --ignore-list option allows to specify a file that contains the list of warnings that should be ignored. The paths in the ignore file must be relative to the location of the ignore file itself, which means: - in the main Buildroot tree, the paths in the ignore file are relative to the root of the main Buildroot tree - in a BR2_EXTERNAL tree, if the ignore file is at the root of the BR2_EXTERNAL, the paths it contains must be relative to that root of the BR2_EXTERNAL This is one more step towards standardizing the use of just 'make check-package' before submitting patches to the list. Cc: Sen Hastings <sen@phobosdpl.com> Signed-off-by: Ricardo Martincoski <ricardo.martincoski@gmail.com> Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
2022-07-31 21:35:08 +02:00
def get_ignored_parsers_per_file(intree_only, ignore_filename):
ignored = dict()
entry_base_dir = ''
if not ignore_filename:
return ignored
filename = os.path.abspath(ignore_filename)
entry_base_dir = os.path.join(os.path.dirname(filename))
with open(filename, "r") as f:
for line in f.readlines():
filename, warnings_str = line.split(' ', 1)
warnings = warnings_str.split()
ignored[os.path.join(entry_base_dir, filename)] = warnings
return ignored
def parse_args():
parser = argparse.ArgumentParser()
# Do not use argparse.FileType("r") here because only files with known
# format will be open based on the filename.
parser.add_argument("files", metavar="F", type=str, nargs="*",
help="list of files")
check-package: prepare to extend to other directories Currently the script only checks files inside the package/ directory. Upcoming patches will enable it for other directories. In order to reliably test for file names, i.e. the Config.in in the base directory, normalize the path of files to check to a relative path to the base directory. Rename the variable that holds the compiled regexp to better represent its content and rearrange how it is declared to make easy to later add new directories to check. As a consequence the files that declare package infra types would not be ignored anymore, so create a new variable to list the files intree to be ignored during the check. The same variable will be used by upcoming patches to ignore other files. Ignore pkg-*.mk and doc-asciidoc.mk since they are package infra files. In order to not produce weird results when used for files outside the tree (i.e. in a private br2-external) add an explicit command line option (-b) that bypasses any checks that would make a file be ignored by the path that contains it. When in this out-of-tree mode, the user is responsible for providing a list of files to check that do not contain files the script does not understand, e.g. package infra files. As a result of this patch, besides the known use: $ ./utils/check-package package/new-package/* someone with the utils/ directory in the path can now also run: $ cd package/new-package/ $ check-package * or $ check-package -b /path/to/br2-ext-tree/package/staging-package/* Signed-off-by: Ricardo Martincoski <ricardo.martincoski@gmail.com> Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
2018-04-01 07:08:14 +02:00
parser.add_argument("--br2-external", "-b", dest='intree_only', action="store_false",
help="do not apply the pathname filters used for intree files")
utils/check-package: decouple adding rules from fixing all intree files When a new check_function is added to check-package, often there are files in the tree that would generate warnings. An example is the Sob check_function for patch files: | $ ./utils/check-package --i Sob $(git ls-files) >/dev/null | 369301 lines processed | 46 warnings generated Currently these warnings are listed when calling check-package directly, and also at the output of pkg-stats, but the check_function does not run on 'make check-package' (that is used to catch regressions on GitLab CI 'check-package' job) until all warnings in the tree are fixed. This (theoretically) allows new .patch files be added without SoB, without the GitLab CI catching it. So add a way to check-package itself ignore current warnings, while still catching new files that do not follow that new check_function. Add a file named .checkpackageignore to the buildroot topdir. It contains the list of check_functions that are expected to fail for each given intree file tested by check-package. Each entries is in the format: <filename> <check_function> [<check_function> ...] These are 2 examples of possible entries: package/initscripts/init.d/rcK ConsecutiveEmptyLines EmptyLastLine Shellcheck utils/test-pkg Shellcheck Keeping such a list allows us to have fine-grained control over which warning to ignore. In order to avoid this list to grow indefinitely, containing entries for files that are already fixed, make each entry an 'expected to fail' instead of just an 'ignore', and generate a warning if a check_function that was expect to fail for a given files does not generate that warning. Unfortunately one case that do not generate warning is an entry for a file that is deleted in a later commit. By default, all checks are applied. The --ignore-list option allows to specify a file that contains the list of warnings that should be ignored. The paths in the ignore file must be relative to the location of the ignore file itself, which means: - in the main Buildroot tree, the paths in the ignore file are relative to the root of the main Buildroot tree - in a BR2_EXTERNAL tree, if the ignore file is at the root of the BR2_EXTERNAL, the paths it contains must be relative to that root of the BR2_EXTERNAL This is one more step towards standardizing the use of just 'make check-package' before submitting patches to the list. Cc: Sen Hastings <sen@phobosdpl.com> Signed-off-by: Ricardo Martincoski <ricardo.martincoski@gmail.com> Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
2022-07-31 21:35:08 +02:00
parser.add_argument("--ignore-list", dest='ignore_filename', action="store",
help='override the default list of ignored warnings')
check-package: prepare to extend to other directories Currently the script only checks files inside the package/ directory. Upcoming patches will enable it for other directories. In order to reliably test for file names, i.e. the Config.in in the base directory, normalize the path of files to check to a relative path to the base directory. Rename the variable that holds the compiled regexp to better represent its content and rearrange how it is declared to make easy to later add new directories to check. As a consequence the files that declare package infra types would not be ignored anymore, so create a new variable to list the files intree to be ignored during the check. The same variable will be used by upcoming patches to ignore other files. Ignore pkg-*.mk and doc-asciidoc.mk since they are package infra files. In order to not produce weird results when used for files outside the tree (i.e. in a private br2-external) add an explicit command line option (-b) that bypasses any checks that would make a file be ignored by the path that contains it. When in this out-of-tree mode, the user is responsible for providing a list of files to check that do not contain files the script does not understand, e.g. package infra files. As a result of this patch, besides the known use: $ ./utils/check-package package/new-package/* someone with the utils/ directory in the path can now also run: $ cd package/new-package/ $ check-package * or $ check-package -b /path/to/br2-ext-tree/package/staging-package/* Signed-off-by: Ricardo Martincoski <ricardo.martincoski@gmail.com> Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
2018-04-01 07:08:14 +02:00
parser.add_argument("--manual-url", action="store",
default="https://nightly.buildroot.org/",
help="default: %(default)s")
parser.add_argument("--verbose", "-v", action="count", default=0)
parser.add_argument("--quiet", "-q", action="count", default=0)
# Now the debug options in the order they are processed.
parser.add_argument("--include-only", dest="include_list", action="append",
help="run only the specified functions (debug)")
parser.add_argument("--exclude", dest="exclude_list", action="append",
help="do not run the specified functions (debug)")
parser.add_argument("--dry-run", action="store_true", help="print the "
"functions that would be called for each file (debug)")
parser.add_argument("--failed-only", action="store_true", help="print only"
" the name of the functions that failed (debug)")
utils/check-package: decouple adding rules from fixing all intree files When a new check_function is added to check-package, often there are files in the tree that would generate warnings. An example is the Sob check_function for patch files: | $ ./utils/check-package --i Sob $(git ls-files) >/dev/null | 369301 lines processed | 46 warnings generated Currently these warnings are listed when calling check-package directly, and also at the output of pkg-stats, but the check_function does not run on 'make check-package' (that is used to catch regressions on GitLab CI 'check-package' job) until all warnings in the tree are fixed. This (theoretically) allows new .patch files be added without SoB, without the GitLab CI catching it. So add a way to check-package itself ignore current warnings, while still catching new files that do not follow that new check_function. Add a file named .checkpackageignore to the buildroot topdir. It contains the list of check_functions that are expected to fail for each given intree file tested by check-package. Each entries is in the format: <filename> <check_function> [<check_function> ...] These are 2 examples of possible entries: package/initscripts/init.d/rcK ConsecutiveEmptyLines EmptyLastLine Shellcheck utils/test-pkg Shellcheck Keeping such a list allows us to have fine-grained control over which warning to ignore. In order to avoid this list to grow indefinitely, containing entries for files that are already fixed, make each entry an 'expected to fail' instead of just an 'ignore', and generate a warning if a check_function that was expect to fail for a given files does not generate that warning. Unfortunately one case that do not generate warning is an entry for a file that is deleted in a later commit. By default, all checks are applied. The --ignore-list option allows to specify a file that contains the list of warnings that should be ignored. The paths in the ignore file must be relative to the location of the ignore file itself, which means: - in the main Buildroot tree, the paths in the ignore file are relative to the root of the main Buildroot tree - in a BR2_EXTERNAL tree, if the ignore file is at the root of the BR2_EXTERNAL, the paths it contains must be relative to that root of the BR2_EXTERNAL This is one more step towards standardizing the use of just 'make check-package' before submitting patches to the list. Cc: Sen Hastings <sen@phobosdpl.com> Signed-off-by: Ricardo Martincoski <ricardo.martincoski@gmail.com> Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
2022-07-31 21:35:08 +02:00
flags = parser.parse_args()
flags.ignore_list = get_ignored_parsers_per_file(flags.intree_only, flags.ignore_filename)
if flags.failed_only:
flags.dry_run = False
flags.verbose = -1
utils/check-package: decouple adding rules from fixing all intree files When a new check_function is added to check-package, often there are files in the tree that would generate warnings. An example is the Sob check_function for patch files: | $ ./utils/check-package --i Sob $(git ls-files) >/dev/null | 369301 lines processed | 46 warnings generated Currently these warnings are listed when calling check-package directly, and also at the output of pkg-stats, but the check_function does not run on 'make check-package' (that is used to catch regressions on GitLab CI 'check-package' job) until all warnings in the tree are fixed. This (theoretically) allows new .patch files be added without SoB, without the GitLab CI catching it. So add a way to check-package itself ignore current warnings, while still catching new files that do not follow that new check_function. Add a file named .checkpackageignore to the buildroot topdir. It contains the list of check_functions that are expected to fail for each given intree file tested by check-package. Each entries is in the format: <filename> <check_function> [<check_function> ...] These are 2 examples of possible entries: package/initscripts/init.d/rcK ConsecutiveEmptyLines EmptyLastLine Shellcheck utils/test-pkg Shellcheck Keeping such a list allows us to have fine-grained control over which warning to ignore. In order to avoid this list to grow indefinitely, containing entries for files that are already fixed, make each entry an 'expected to fail' instead of just an 'ignore', and generate a warning if a check_function that was expect to fail for a given files does not generate that warning. Unfortunately one case that do not generate warning is an entry for a file that is deleted in a later commit. By default, all checks are applied. The --ignore-list option allows to specify a file that contains the list of warnings that should be ignored. The paths in the ignore file must be relative to the location of the ignore file itself, which means: - in the main Buildroot tree, the paths in the ignore file are relative to the root of the main Buildroot tree - in a BR2_EXTERNAL tree, if the ignore file is at the root of the BR2_EXTERNAL, the paths it contains must be relative to that root of the BR2_EXTERNAL This is one more step towards standardizing the use of just 'make check-package' before submitting patches to the list. Cc: Sen Hastings <sen@phobosdpl.com> Signed-off-by: Ricardo Martincoski <ricardo.martincoski@gmail.com> Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
2022-07-31 21:35:08 +02:00
return flags
def get_lib_from_filetype(fname):
if not os.path.isfile(fname):
return None
filetype = get_filetype(fname)
if filetype == "text/x-shellscript":
return checkpackagelib.lib_shellscript
if filetype in ["text/x-python", "text/x-script.python"]:
return checkpackagelib.lib_python
return None
CONFIG_IN_FILENAME = re.compile(r"Config\.\S*$")
DO_CHECK_INTREE = re.compile(r"|".join([
r".checkpackageignore",
r"Config.in",
r"arch/",
r"board/",
r"boot/",
r"fs/",
r"linux/",
r"package/",
r"support/",
r"system/",
r"toolchain/",
r"utils/",
check-package: prepare to extend to other directories Currently the script only checks files inside the package/ directory. Upcoming patches will enable it for other directories. In order to reliably test for file names, i.e. the Config.in in the base directory, normalize the path of files to check to a relative path to the base directory. Rename the variable that holds the compiled regexp to better represent its content and rearrange how it is declared to make easy to later add new directories to check. As a consequence the files that declare package infra types would not be ignored anymore, so create a new variable to list the files intree to be ignored during the check. The same variable will be used by upcoming patches to ignore other files. Ignore pkg-*.mk and doc-asciidoc.mk since they are package infra files. In order to not produce weird results when used for files outside the tree (i.e. in a private br2-external) add an explicit command line option (-b) that bypasses any checks that would make a file be ignored by the path that contains it. When in this out-of-tree mode, the user is responsible for providing a list of files to check that do not contain files the script does not understand, e.g. package infra files. As a result of this patch, besides the known use: $ ./utils/check-package package/new-package/* someone with the utils/ directory in the path can now also run: $ cd package/new-package/ $ check-package * or $ check-package -b /path/to/br2-ext-tree/package/staging-package/* Signed-off-by: Ricardo Martincoski <ricardo.martincoski@gmail.com> Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
2018-04-01 07:08:14 +02:00
]))
DO_NOT_CHECK_INTREE = re.compile(r"|".join([
r"boot/barebox/barebox\.mk$",
r"fs/common\.mk$",
r"package/doc-asciidoc\.mk$",
r"package/pkg-\S*\.mk$",
r"support/dependencies/[^/]+\.mk$",
r"support/gnuconfig/config\.",
r"support/kconfig/",
r"support/misc/[^/]+\.mk$",
r"support/testing/tests/.*br2-external/",
r"toolchain/helpers\.mk$",
r"toolchain/toolchain-external/pkg-toolchain-external\.mk$",
check-package: prepare to extend to other directories Currently the script only checks files inside the package/ directory. Upcoming patches will enable it for other directories. In order to reliably test for file names, i.e. the Config.in in the base directory, normalize the path of files to check to a relative path to the base directory. Rename the variable that holds the compiled regexp to better represent its content and rearrange how it is declared to make easy to later add new directories to check. As a consequence the files that declare package infra types would not be ignored anymore, so create a new variable to list the files intree to be ignored during the check. The same variable will be used by upcoming patches to ignore other files. Ignore pkg-*.mk and doc-asciidoc.mk since they are package infra files. In order to not produce weird results when used for files outside the tree (i.e. in a private br2-external) add an explicit command line option (-b) that bypasses any checks that would make a file be ignored by the path that contains it. When in this out-of-tree mode, the user is responsible for providing a list of files to check that do not contain files the script does not understand, e.g. package infra files. As a result of this patch, besides the known use: $ ./utils/check-package package/new-package/* someone with the utils/ directory in the path can now also run: $ cd package/new-package/ $ check-package * or $ check-package -b /path/to/br2-ext-tree/package/staging-package/* Signed-off-by: Ricardo Martincoski <ricardo.martincoski@gmail.com> Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
2018-04-01 07:08:14 +02:00
]))
SYSV_INIT_SCRIPT_FILENAME = re.compile(r"/S\d\d[^/]+$")
def get_lib_from_filename(fname):
check-package: prepare to extend to other directories Currently the script only checks files inside the package/ directory. Upcoming patches will enable it for other directories. In order to reliably test for file names, i.e. the Config.in in the base directory, normalize the path of files to check to a relative path to the base directory. Rename the variable that holds the compiled regexp to better represent its content and rearrange how it is declared to make easy to later add new directories to check. As a consequence the files that declare package infra types would not be ignored anymore, so create a new variable to list the files intree to be ignored during the check. The same variable will be used by upcoming patches to ignore other files. Ignore pkg-*.mk and doc-asciidoc.mk since they are package infra files. In order to not produce weird results when used for files outside the tree (i.e. in a private br2-external) add an explicit command line option (-b) that bypasses any checks that would make a file be ignored by the path that contains it. When in this out-of-tree mode, the user is responsible for providing a list of files to check that do not contain files the script does not understand, e.g. package infra files. As a result of this patch, besides the known use: $ ./utils/check-package package/new-package/* someone with the utils/ directory in the path can now also run: $ cd package/new-package/ $ check-package * or $ check-package -b /path/to/br2-ext-tree/package/staging-package/* Signed-off-by: Ricardo Martincoski <ricardo.martincoski@gmail.com> Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
2018-04-01 07:08:14 +02:00
if flags.intree_only:
if DO_CHECK_INTREE.match(fname) is None:
return None
if DO_NOT_CHECK_INTREE.match(fname):
return None
else:
if os.path.basename(fname) == "external.mk" and \
os.path.exists(fname[:-2] + "desc"):
return None
if fname == ".checkpackageignore":
return checkpackagelib.lib_ignore
if CONFIG_IN_FILENAME.search(fname):
return checkpackagelib.lib_config
if fname.endswith(".hash"):
return checkpackagelib.lib_hash
if fname.endswith(".mk"):
return checkpackagelib.lib_mk
if fname.endswith(".patch"):
return checkpackagelib.lib_patch
if SYSV_INIT_SCRIPT_FILENAME.search(fname):
return checkpackagelib.lib_sysv
return get_lib_from_filetype(fname)
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>
2021-12-26 19:49:15 +01:00
def common_inspect_rules(m):
# do not call the base class
if m.__name__.startswith("_"):
return False
if flags.include_list and m.__name__ not in flags.include_list:
return False
if flags.exclude_list and m.__name__ in flags.exclude_list:
return False
return True
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>
2021-12-26 19:49:15 +01:00
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)
utils/check-package: decouple adding rules from fixing all intree files When a new check_function is added to check-package, often there are files in the tree that would generate warnings. An example is the Sob check_function for patch files: | $ ./utils/check-package --i Sob $(git ls-files) >/dev/null | 369301 lines processed | 46 warnings generated Currently these warnings are listed when calling check-package directly, and also at the output of pkg-stats, but the check_function does not run on 'make check-package' (that is used to catch regressions on GitLab CI 'check-package' job) until all warnings in the tree are fixed. This (theoretically) allows new .patch files be added without SoB, without the GitLab CI catching it. So add a way to check-package itself ignore current warnings, while still catching new files that do not follow that new check_function. Add a file named .checkpackageignore to the buildroot topdir. It contains the list of check_functions that are expected to fail for each given intree file tested by check-package. Each entries is in the format: <filename> <check_function> [<check_function> ...] These are 2 examples of possible entries: package/initscripts/init.d/rcK ConsecutiveEmptyLines EmptyLastLine Shellcheck utils/test-pkg Shellcheck Keeping such a list allows us to have fine-grained control over which warning to ignore. In order to avoid this list to grow indefinitely, containing entries for files that are already fixed, make each entry an 'expected to fail' instead of just an 'ignore', and generate a warning if a check_function that was expect to fail for a given files does not generate that warning. Unfortunately one case that do not generate warning is an entry for a file that is deleted in a later commit. By default, all checks are applied. The --ignore-list option allows to specify a file that contains the list of warnings that should be ignored. The paths in the ignore file must be relative to the location of the ignore file itself, which means: - in the main Buildroot tree, the paths in the ignore file are relative to the root of the main Buildroot tree - in a BR2_EXTERNAL tree, if the ignore file is at the root of the BR2_EXTERNAL, the paths it contains must be relative to that root of the BR2_EXTERNAL This is one more step towards standardizing the use of just 'make check-package' before submitting patches to the list. Cc: Sen Hastings <sen@phobosdpl.com> Signed-off-by: Ricardo Martincoski <ricardo.martincoski@gmail.com> Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
2022-07-31 21:35:08 +02:00
def print_warnings(warnings, xfail):
# Avoid the need to use 'return []' at the end of every check function.
if warnings is None:
utils/check-package: decouple adding rules from fixing all intree files When a new check_function is added to check-package, often there are files in the tree that would generate warnings. An example is the Sob check_function for patch files: | $ ./utils/check-package --i Sob $(git ls-files) >/dev/null | 369301 lines processed | 46 warnings generated Currently these warnings are listed when calling check-package directly, and also at the output of pkg-stats, but the check_function does not run on 'make check-package' (that is used to catch regressions on GitLab CI 'check-package' job) until all warnings in the tree are fixed. This (theoretically) allows new .patch files be added without SoB, without the GitLab CI catching it. So add a way to check-package itself ignore current warnings, while still catching new files that do not follow that new check_function. Add a file named .checkpackageignore to the buildroot topdir. It contains the list of check_functions that are expected to fail for each given intree file tested by check-package. Each entries is in the format: <filename> <check_function> [<check_function> ...] These are 2 examples of possible entries: package/initscripts/init.d/rcK ConsecutiveEmptyLines EmptyLastLine Shellcheck utils/test-pkg Shellcheck Keeping such a list allows us to have fine-grained control over which warning to ignore. In order to avoid this list to grow indefinitely, containing entries for files that are already fixed, make each entry an 'expected to fail' instead of just an 'ignore', and generate a warning if a check_function that was expect to fail for a given files does not generate that warning. Unfortunately one case that do not generate warning is an entry for a file that is deleted in a later commit. By default, all checks are applied. The --ignore-list option allows to specify a file that contains the list of warnings that should be ignored. The paths in the ignore file must be relative to the location of the ignore file itself, which means: - in the main Buildroot tree, the paths in the ignore file are relative to the root of the main Buildroot tree - in a BR2_EXTERNAL tree, if the ignore file is at the root of the BR2_EXTERNAL, the paths it contains must be relative to that root of the BR2_EXTERNAL This is one more step towards standardizing the use of just 'make check-package' before submitting patches to the list. Cc: Sen Hastings <sen@phobosdpl.com> Signed-off-by: Ricardo Martincoski <ricardo.martincoski@gmail.com> Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
2022-07-31 21:35:08 +02:00
return 0, 0 # No warning generated.
utils/check-package: decouple adding rules from fixing all intree files When a new check_function is added to check-package, often there are files in the tree that would generate warnings. An example is the Sob check_function for patch files: | $ ./utils/check-package --i Sob $(git ls-files) >/dev/null | 369301 lines processed | 46 warnings generated Currently these warnings are listed when calling check-package directly, and also at the output of pkg-stats, but the check_function does not run on 'make check-package' (that is used to catch regressions on GitLab CI 'check-package' job) until all warnings in the tree are fixed. This (theoretically) allows new .patch files be added without SoB, without the GitLab CI catching it. So add a way to check-package itself ignore current warnings, while still catching new files that do not follow that new check_function. Add a file named .checkpackageignore to the buildroot topdir. It contains the list of check_functions that are expected to fail for each given intree file tested by check-package. Each entries is in the format: <filename> <check_function> [<check_function> ...] These are 2 examples of possible entries: package/initscripts/init.d/rcK ConsecutiveEmptyLines EmptyLastLine Shellcheck utils/test-pkg Shellcheck Keeping such a list allows us to have fine-grained control over which warning to ignore. In order to avoid this list to grow indefinitely, containing entries for files that are already fixed, make each entry an 'expected to fail' instead of just an 'ignore', and generate a warning if a check_function that was expect to fail for a given files does not generate that warning. Unfortunately one case that do not generate warning is an entry for a file that is deleted in a later commit. By default, all checks are applied. The --ignore-list option allows to specify a file that contains the list of warnings that should be ignored. The paths in the ignore file must be relative to the location of the ignore file itself, which means: - in the main Buildroot tree, the paths in the ignore file are relative to the root of the main Buildroot tree - in a BR2_EXTERNAL tree, if the ignore file is at the root of the BR2_EXTERNAL, the paths it contains must be relative to that root of the BR2_EXTERNAL This is one more step towards standardizing the use of just 'make check-package' before submitting patches to the list. Cc: Sen Hastings <sen@phobosdpl.com> Signed-off-by: Ricardo Martincoski <ricardo.martincoski@gmail.com> Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
2022-07-31 21:35:08 +02:00
if xfail:
return 0, 1 # Warning not generated, fail expected for this file.
for level, message in enumerate(warnings):
if flags.verbose >= level:
print(message.replace("\t", "< tab >").rstrip())
utils/check-package: decouple adding rules from fixing all intree files When a new check_function is added to check-package, often there are files in the tree that would generate warnings. An example is the Sob check_function for patch files: | $ ./utils/check-package --i Sob $(git ls-files) >/dev/null | 369301 lines processed | 46 warnings generated Currently these warnings are listed when calling check-package directly, and also at the output of pkg-stats, but the check_function does not run on 'make check-package' (that is used to catch regressions on GitLab CI 'check-package' job) until all warnings in the tree are fixed. This (theoretically) allows new .patch files be added without SoB, without the GitLab CI catching it. So add a way to check-package itself ignore current warnings, while still catching new files that do not follow that new check_function. Add a file named .checkpackageignore to the buildroot topdir. It contains the list of check_functions that are expected to fail for each given intree file tested by check-package. Each entries is in the format: <filename> <check_function> [<check_function> ...] These are 2 examples of possible entries: package/initscripts/init.d/rcK ConsecutiveEmptyLines EmptyLastLine Shellcheck utils/test-pkg Shellcheck Keeping such a list allows us to have fine-grained control over which warning to ignore. In order to avoid this list to grow indefinitely, containing entries for files that are already fixed, make each entry an 'expected to fail' instead of just an 'ignore', and generate a warning if a check_function that was expect to fail for a given files does not generate that warning. Unfortunately one case that do not generate warning is an entry for a file that is deleted in a later commit. By default, all checks are applied. The --ignore-list option allows to specify a file that contains the list of warnings that should be ignored. The paths in the ignore file must be relative to the location of the ignore file itself, which means: - in the main Buildroot tree, the paths in the ignore file are relative to the root of the main Buildroot tree - in a BR2_EXTERNAL tree, if the ignore file is at the root of the BR2_EXTERNAL, the paths it contains must be relative to that root of the BR2_EXTERNAL This is one more step towards standardizing the use of just 'make check-package' before submitting patches to the list. Cc: Sen Hastings <sen@phobosdpl.com> Signed-off-by: Ricardo Martincoski <ricardo.martincoski@gmail.com> Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
2022-07-31 21:35:08 +02:00
return 1, 1 # One more warning to count.
def check_file_using_lib(fname):
# Count number of warnings generated and lines processed.
nwarnings = 0
nlines = 0
utils/check-package: decouple adding rules from fixing all intree files When a new check_function is added to check-package, often there are files in the tree that would generate warnings. An example is the Sob check_function for patch files: | $ ./utils/check-package --i Sob $(git ls-files) >/dev/null | 369301 lines processed | 46 warnings generated Currently these warnings are listed when calling check-package directly, and also at the output of pkg-stats, but the check_function does not run on 'make check-package' (that is used to catch regressions on GitLab CI 'check-package' job) until all warnings in the tree are fixed. This (theoretically) allows new .patch files be added without SoB, without the GitLab CI catching it. So add a way to check-package itself ignore current warnings, while still catching new files that do not follow that new check_function. Add a file named .checkpackageignore to the buildroot topdir. It contains the list of check_functions that are expected to fail for each given intree file tested by check-package. Each entries is in the format: <filename> <check_function> [<check_function> ...] These are 2 examples of possible entries: package/initscripts/init.d/rcK ConsecutiveEmptyLines EmptyLastLine Shellcheck utils/test-pkg Shellcheck Keeping such a list allows us to have fine-grained control over which warning to ignore. In order to avoid this list to grow indefinitely, containing entries for files that are already fixed, make each entry an 'expected to fail' instead of just an 'ignore', and generate a warning if a check_function that was expect to fail for a given files does not generate that warning. Unfortunately one case that do not generate warning is an entry for a file that is deleted in a later commit. By default, all checks are applied. The --ignore-list option allows to specify a file that contains the list of warnings that should be ignored. The paths in the ignore file must be relative to the location of the ignore file itself, which means: - in the main Buildroot tree, the paths in the ignore file are relative to the root of the main Buildroot tree - in a BR2_EXTERNAL tree, if the ignore file is at the root of the BR2_EXTERNAL, the paths it contains must be relative to that root of the BR2_EXTERNAL This is one more step towards standardizing the use of just 'make check-package' before submitting patches to the list. Cc: Sen Hastings <sen@phobosdpl.com> Signed-off-by: Ricardo Martincoski <ricardo.martincoski@gmail.com> Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
2022-07-31 21:35:08 +02:00
xfail = flags.ignore_list.get(os.path.abspath(fname), [])
failed = set()
lib = get_lib_from_filename(fname)
if not lib:
if flags.verbose >= VERBOSE_LEVEL_TO_SHOW_IGNORED_FILES:
print("{}: ignored".format(fname))
return nwarnings, nlines
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>
2021-12-26 19:49:15 +01:00
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:
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>
2021-12-26 19:49:15 +01:00
functions_to_run = [c[0] for c in all_checks]
print("{}: would run: {}".format(fname, functions_to_run))
return nwarnings, nlines
objects = [[f"{lib.__name__[16:]}.{c[0]}", c[1](fname, flags.manual_url)] for c in internal_functions]
utils/check-package: decouple adding rules from fixing all intree files When a new check_function is added to check-package, often there are files in the tree that would generate warnings. An example is the Sob check_function for patch files: | $ ./utils/check-package --i Sob $(git ls-files) >/dev/null | 369301 lines processed | 46 warnings generated Currently these warnings are listed when calling check-package directly, and also at the output of pkg-stats, but the check_function does not run on 'make check-package' (that is used to catch regressions on GitLab CI 'check-package' job) until all warnings in the tree are fixed. This (theoretically) allows new .patch files be added without SoB, without the GitLab CI catching it. So add a way to check-package itself ignore current warnings, while still catching new files that do not follow that new check_function. Add a file named .checkpackageignore to the buildroot topdir. It contains the list of check_functions that are expected to fail for each given intree file tested by check-package. Each entries is in the format: <filename> <check_function> [<check_function> ...] These are 2 examples of possible entries: package/initscripts/init.d/rcK ConsecutiveEmptyLines EmptyLastLine Shellcheck utils/test-pkg Shellcheck Keeping such a list allows us to have fine-grained control over which warning to ignore. In order to avoid this list to grow indefinitely, containing entries for files that are already fixed, make each entry an 'expected to fail' instead of just an 'ignore', and generate a warning if a check_function that was expect to fail for a given files does not generate that warning. Unfortunately one case that do not generate warning is an entry for a file that is deleted in a later commit. By default, all checks are applied. The --ignore-list option allows to specify a file that contains the list of warnings that should be ignored. The paths in the ignore file must be relative to the location of the ignore file itself, which means: - in the main Buildroot tree, the paths in the ignore file are relative to the root of the main Buildroot tree - in a BR2_EXTERNAL tree, if the ignore file is at the root of the BR2_EXTERNAL, the paths it contains must be relative to that root of the BR2_EXTERNAL This is one more step towards standardizing the use of just 'make check-package' before submitting patches to the list. Cc: Sen Hastings <sen@phobosdpl.com> Signed-off-by: Ricardo Martincoski <ricardo.martincoski@gmail.com> Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
2022-07-31 21:35:08 +02:00
for name, cf in objects:
warn, fail = print_warnings(cf.before(), name in xfail)
if fail > 0:
failed.add(name)
nwarnings += warn
lastline = ""
with open(fname, "r", errors="surrogateescape") as f:
for lineno, text in enumerate(f):
nlines += 1
for name, cf in objects:
if cf.disable.search(lastline):
continue
line_sts = cf.check_line(lineno + 1, text)
warn, fail = print_warnings(line_sts, name in xfail)
if fail > 0:
failed.add(name)
nwarnings += warn
lastline = text
utils/check-package: decouple adding rules from fixing all intree files When a new check_function is added to check-package, often there are files in the tree that would generate warnings. An example is the Sob check_function for patch files: | $ ./utils/check-package --i Sob $(git ls-files) >/dev/null | 369301 lines processed | 46 warnings generated Currently these warnings are listed when calling check-package directly, and also at the output of pkg-stats, but the check_function does not run on 'make check-package' (that is used to catch regressions on GitLab CI 'check-package' job) until all warnings in the tree are fixed. This (theoretically) allows new .patch files be added without SoB, without the GitLab CI catching it. So add a way to check-package itself ignore current warnings, while still catching new files that do not follow that new check_function. Add a file named .checkpackageignore to the buildroot topdir. It contains the list of check_functions that are expected to fail for each given intree file tested by check-package. Each entries is in the format: <filename> <check_function> [<check_function> ...] These are 2 examples of possible entries: package/initscripts/init.d/rcK ConsecutiveEmptyLines EmptyLastLine Shellcheck utils/test-pkg Shellcheck Keeping such a list allows us to have fine-grained control over which warning to ignore. In order to avoid this list to grow indefinitely, containing entries for files that are already fixed, make each entry an 'expected to fail' instead of just an 'ignore', and generate a warning if a check_function that was expect to fail for a given files does not generate that warning. Unfortunately one case that do not generate warning is an entry for a file that is deleted in a later commit. By default, all checks are applied. The --ignore-list option allows to specify a file that contains the list of warnings that should be ignored. The paths in the ignore file must be relative to the location of the ignore file itself, which means: - in the main Buildroot tree, the paths in the ignore file are relative to the root of the main Buildroot tree - in a BR2_EXTERNAL tree, if the ignore file is at the root of the BR2_EXTERNAL, the paths it contains must be relative to that root of the BR2_EXTERNAL This is one more step towards standardizing the use of just 'make check-package' before submitting patches to the list. Cc: Sen Hastings <sen@phobosdpl.com> Signed-off-by: Ricardo Martincoski <ricardo.martincoski@gmail.com> Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
2022-07-31 21:35:08 +02:00
for name, cf in objects:
warn, fail = print_warnings(cf.after(), name in xfail)
if fail > 0:
failed.add(name)
nwarnings += warn
tools = [[c[0], c[1](fname)] for c in external_tools]
for name, tool in tools:
warn, fail = print_warnings(tool.run(), name in xfail)
if fail > 0:
failed.add(name)
nwarnings += warn
for should_fail in xfail:
if should_fail not in failed:
print("{}:0: {} was expected to fail, did you fix the file and forget to update {}?"
utils/check-package: decouple adding rules from fixing all intree files When a new check_function is added to check-package, often there are files in the tree that would generate warnings. An example is the Sob check_function for patch files: | $ ./utils/check-package --i Sob $(git ls-files) >/dev/null | 369301 lines processed | 46 warnings generated Currently these warnings are listed when calling check-package directly, and also at the output of pkg-stats, but the check_function does not run on 'make check-package' (that is used to catch regressions on GitLab CI 'check-package' job) until all warnings in the tree are fixed. This (theoretically) allows new .patch files be added without SoB, without the GitLab CI catching it. So add a way to check-package itself ignore current warnings, while still catching new files that do not follow that new check_function. Add a file named .checkpackageignore to the buildroot topdir. It contains the list of check_functions that are expected to fail for each given intree file tested by check-package. Each entries is in the format: <filename> <check_function> [<check_function> ...] These are 2 examples of possible entries: package/initscripts/init.d/rcK ConsecutiveEmptyLines EmptyLastLine Shellcheck utils/test-pkg Shellcheck Keeping such a list allows us to have fine-grained control over which warning to ignore. In order to avoid this list to grow indefinitely, containing entries for files that are already fixed, make each entry an 'expected to fail' instead of just an 'ignore', and generate a warning if a check_function that was expect to fail for a given files does not generate that warning. Unfortunately one case that do not generate warning is an entry for a file that is deleted in a later commit. By default, all checks are applied. The --ignore-list option allows to specify a file that contains the list of warnings that should be ignored. The paths in the ignore file must be relative to the location of the ignore file itself, which means: - in the main Buildroot tree, the paths in the ignore file are relative to the root of the main Buildroot tree - in a BR2_EXTERNAL tree, if the ignore file is at the root of the BR2_EXTERNAL, the paths it contains must be relative to that root of the BR2_EXTERNAL This is one more step towards standardizing the use of just 'make check-package' before submitting patches to the list. Cc: Sen Hastings <sen@phobosdpl.com> Signed-off-by: Ricardo Martincoski <ricardo.martincoski@gmail.com> Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
2022-07-31 21:35:08 +02:00
.format(fname, should_fail, flags.ignore_filename))
nwarnings += 1
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>
2021-12-26 19:49:15 +01:00
if flags.failed_only:
if len(failed) > 0:
f = " ".join(sorted(failed))
print("{} {}".format(fname, f))
return nwarnings, nlines
def __main__():
global flags
flags = parse_args()
check-package: prepare to extend to other directories Currently the script only checks files inside the package/ directory. Upcoming patches will enable it for other directories. In order to reliably test for file names, i.e. the Config.in in the base directory, normalize the path of files to check to a relative path to the base directory. Rename the variable that holds the compiled regexp to better represent its content and rearrange how it is declared to make easy to later add new directories to check. As a consequence the files that declare package infra types would not be ignored anymore, so create a new variable to list the files intree to be ignored during the check. The same variable will be used by upcoming patches to ignore other files. Ignore pkg-*.mk and doc-asciidoc.mk since they are package infra files. In order to not produce weird results when used for files outside the tree (i.e. in a private br2-external) add an explicit command line option (-b) that bypasses any checks that would make a file be ignored by the path that contains it. When in this out-of-tree mode, the user is responsible for providing a list of files to check that do not contain files the script does not understand, e.g. package infra files. As a result of this patch, besides the known use: $ ./utils/check-package package/new-package/* someone with the utils/ directory in the path can now also run: $ cd package/new-package/ $ check-package * or $ check-package -b /path/to/br2-ext-tree/package/staging-package/* Signed-off-by: Ricardo Martincoski <ricardo.martincoski@gmail.com> Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
2018-04-01 07:08:14 +02:00
if flags.intree_only:
# change all paths received to be relative to the base dir
base_dir = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
check-package: prepare to extend to other directories Currently the script only checks files inside the package/ directory. Upcoming patches will enable it for other directories. In order to reliably test for file names, i.e. the Config.in in the base directory, normalize the path of files to check to a relative path to the base directory. Rename the variable that holds the compiled regexp to better represent its content and rearrange how it is declared to make easy to later add new directories to check. As a consequence the files that declare package infra types would not be ignored anymore, so create a new variable to list the files intree to be ignored during the check. The same variable will be used by upcoming patches to ignore other files. Ignore pkg-*.mk and doc-asciidoc.mk since they are package infra files. In order to not produce weird results when used for files outside the tree (i.e. in a private br2-external) add an explicit command line option (-b) that bypasses any checks that would make a file be ignored by the path that contains it. When in this out-of-tree mode, the user is responsible for providing a list of files to check that do not contain files the script does not understand, e.g. package infra files. As a result of this patch, besides the known use: $ ./utils/check-package package/new-package/* someone with the utils/ directory in the path can now also run: $ cd package/new-package/ $ check-package * or $ check-package -b /path/to/br2-ext-tree/package/staging-package/* Signed-off-by: Ricardo Martincoski <ricardo.martincoski@gmail.com> Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
2018-04-01 07:08:14 +02:00
files_to_check = [os.path.relpath(os.path.abspath(f), base_dir) for f in flags.files]
# move current dir so the script find the files
os.chdir(base_dir)
else:
files_to_check = flags.files
if len(files_to_check) == 0:
print("No files to check style")
sys.exit(1)
# Accumulate number of warnings generated and lines processed.
total_warnings = 0
total_lines = 0
check-package: prepare to extend to other directories Currently the script only checks files inside the package/ directory. Upcoming patches will enable it for other directories. In order to reliably test for file names, i.e. the Config.in in the base directory, normalize the path of files to check to a relative path to the base directory. Rename the variable that holds the compiled regexp to better represent its content and rearrange how it is declared to make easy to later add new directories to check. As a consequence the files that declare package infra types would not be ignored anymore, so create a new variable to list the files intree to be ignored during the check. The same variable will be used by upcoming patches to ignore other files. Ignore pkg-*.mk and doc-asciidoc.mk since they are package infra files. In order to not produce weird results when used for files outside the tree (i.e. in a private br2-external) add an explicit command line option (-b) that bypasses any checks that would make a file be ignored by the path that contains it. When in this out-of-tree mode, the user is responsible for providing a list of files to check that do not contain files the script does not understand, e.g. package infra files. As a result of this patch, besides the known use: $ ./utils/check-package package/new-package/* someone with the utils/ directory in the path can now also run: $ cd package/new-package/ $ check-package * or $ check-package -b /path/to/br2-ext-tree/package/staging-package/* Signed-off-by: Ricardo Martincoski <ricardo.martincoski@gmail.com> Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
2018-04-01 07:08:14 +02:00
for fname in files_to_check:
nwarnings, nlines = check_file_using_lib(fname)
total_warnings += nwarnings
total_lines += nlines
# The warning messages are printed to stdout and can be post-processed
# (e.g. counted by 'wc'), so for stats use stderr. Wait all warnings are
# printed, for the case there are many of them, before printing stats.
sys.stdout.flush()
if not flags.quiet:
print("{} lines processed".format(total_lines), file=sys.stderr)
print("{} warnings generated".format(total_warnings), file=sys.stderr)
if total_warnings > 0 and not flags.failed_only:
sys.exit(1)
__main__()