From 78bae7166cae1197184108af3a862813429ab467 Mon Sep 17 00:00:00 2001 From: albailey Date: Tue, 25 May 2021 11:07:50 -0500 Subject: [PATCH] Calling an additional shell lint command from zuul The '.sh' files are examined by bashate but now the linters command will also run a shellcheck on them. The majority of the shellcheck errors that are failing have been suppressed, and can be updated and fixed by subsequent submissions. Shell scripts that do not end in .sh will also be examined by bashate and shellcheck. Story: 2008943 Task: 42561 Signed-off-by: albailey Change-Id: I735e62bfd25434e0a3dfbbec7f80d59074f2ecc0 --- test-requirements.txt | 1 + tox.ini | 72 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+) diff --git a/test-requirements.txt b/test-requirements.txt index 9d356e23..ec28eb63 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -2,3 +2,4 @@ hacking < 4.0.1 bashate >= 0.2 bandit!=1.6.0,>=1.1.0,<2.0.0;python_version>="3.0" # GPLv2 +shellcheck-py;python_version>="3.0" # MIT diff --git a/tox.ini b/tox.ini index 61b3db7f..6230f578 100644 --- a/tox.ini +++ b/tox.ini @@ -18,10 +18,68 @@ deps = whitelist_externals = bash +[testenv:shellcheck] +basepython = python3 +# The following are currently suppressed: +# SC1083: This '{' or '}' is literal. Check expression (missing ;/\n?) or quote it. +# SC2002: Useless cat. Consider 'cmd < file | ..' or 'cmd file | ..' instead. +# SC2004: $/${} is unnecessary on arithmetic variables. +# SC2005: Useless echo? Instead of 'echo $(cmd)', just use 'cmd'. +# SC2006: Use $(...) notation instead of legacy backticked `...`. +# SC2012: Use find instead of ls to better handle non-alphanumeric filenames. +# SC2034: variable appears unused. Verify use (or export if used externally). +# SC2044: For loops over find output are fragile. Use find -exec or a while read loop. +# SC2046: Quote this to prevent word splitting +# SC2068: Double quote array expansions to avoid re-splitting elements. +# SC2076: Remove quotes from right-hand side of =~ to match as a regex rather than literally. +# SC2086: Double quote to prevent globbing and word splitting +# SC2091: Remove surrounding $() to avoid executing output (or use eval if intentional). +# SC2115: Use "${var:?}" to ensure this never expands to /* . +# SC2148: Tips depend on target shell and yours is unknown. Add a shebang or a 'shell' directive. +# SC2154: i is referenced but not assigned. +# SC2155: Declare and assign separately to avoid masking return values. +# SC2162: read without -r will mangle backslashes +# SC2166: Prefer [ p ] || [ q ] as [ p -o q ] is not well defined. +# SC2181: Check exit code directly with e.g. if mycmd; not indirectly with $? +# SC2199: Arrays implicitly concatenate in [[ ]]. Use a loop (or explicit * instead of @). +# SC2206: Quote to prevent word splitting/globbing, or use mapfile or read -a. +# SC2207: Prefer mapfile or read -a to split command output (or quote to avoid splitting) +# SC2219: Instead of 'let expr', prefer (( expr )) +# SC2254: Quote expansions in case patterns to match literally rather than as a glob. + +# shellcheck is called twice, to handle shell scripts that do not end in .sh +commands = + bash -c "find {toxinidir} \ + -not \( -type d -name .?\* -prune \) \ + -type f \ + -not -name \*~ \ + -not -name \*.md \ + -name \*.sh \ + -print0 | xargs -r -n 1 -0 shellcheck \ + -eSC1083 -eSC2002 -eSC2004 -eSC2005 -eSC2006 -eSC2012 -eSC2034 \ + -eSC2044 -eSC2046 -eSC2068 -eSC2076 -eSC2086 -eSC2091 -eSC2115 \ + -eSC2148 -eSC2154 -eSC2155 -eSC2162 -eSC2166 -eSC2181 -eSC2199 \ + -eSC2206 -eSC2207 -eSC2219 -eSC2254" + bash -c "find {toxinidir} \ + -not \( -type d -name .?\* -prune \) \ + -type f \ + -not -name \*~ \ + -not -name \*.md \ + \( -exec bash -c 'file \{\} | grep -q shell' \; \ + -a ! -name '*.sh' \) \ + -print0 | xargs -r -n 1 -0 shellcheck \ + -eSC1083 -eSC2002 -eSC2004 -eSC2005 -eSC2006 -eSC2012 -eSC2034 \ + -eSC2044 -eSC2046 -eSC2068 -eSC2076 -eSC2086 -eSC2091 -eSC2115 \ + -eSC2148 -eSC2154 -eSC2155 -eSC2162 -eSC2166 -eSC2181 -eSC2199 \ + -eSC2206 -eSC2207 -eSC2219 -eSC2254" + [testenv:bashate] # Treat all E* codes as Errors rather than warnings using: -e 'E*' # The following codes are being suppressed: # E006 Line too long +# E011 Then keyword is not on same line as if or elif keyword +# bashate is called twice, to handle shell scripts that do not end in .sh +# the suppression lists are different (eventually nothing will be suppressed) commands = bash -c "find {toxinidir} \ -not \( -type d -name .?\* -prune \) \ @@ -32,6 +90,18 @@ commands = -print0 | xargs -r -n 1 -0 bashate -v \ -i E006 \ -e 'E*'" + bash -c "find {toxinidir} \ + -not \( -type d -name .?\* -prune \) \ + -type f \ + -not -name \*~ \ + -not -name \*.md \ + -not -name \*.ldif \ + \( -exec bash -c 'file \{\} | grep -q shell' \; \ + -a ! -name '*.sh' \) \ + -print0 | xargs -r -n 1 -0 bashate -v \ + -i E006,E011 \ + -e 'E*'" + [testenv:bindep] # Do not install any requirements. We want this to be fast and work even if @@ -42,6 +112,7 @@ deps = bindep commands = bindep test [testenv:linters] +basepython = python3 # Note: centos developer env requires ruby-devel # Ubuntu developer env requires ruby-dev whitelist_externals = @@ -59,6 +130,7 @@ commands = -name \*.pp -print0 \ | xargs -0 puppet-lint --fail-on-warnings {[testenv:linters]skip_tests}" {[testenv:bashate]commands} + {[testenv:shellcheck]commands} [testenv:pep8] basepython = python3