From 3d6260adf854a22ed7d5752218514368c76499b2 Mon Sep 17 00:00:00 2001 From: Casper Date: Sat, 27 May 2023 22:12:24 +0200 Subject: [PATCH] Add BASH syntax check to linter (#3369) --- Makefile | 5 ++++- test/linting/lint.sh | 32 +++++++++++++++++++++++++------- 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/Makefile b/Makefile index 2050da56..5732cc07 100644 --- a/Makefile +++ b/Makefile @@ -61,11 +61,14 @@ test/%: ALWAYS_RUN # --- Lints ------------------------------------- # ----------------------------------------------- -lint: ALWAYS_RUN eclint hadolint shellcheck +lint: ALWAYS_RUN eclint hadolint bashcheck shellcheck hadolint: ALWAYS_RUN @ ./test/linting/lint.sh hadolint +bashcheck: ALWAYS_RUN + @ ./test/linting/lint.sh bashcheck + shellcheck: ALWAYS_RUN @ ./test/linting/lint.sh shellcheck diff --git a/test/linting/lint.sh b/test/linting/lint.sh index 3bcb04cd..a056b02c 100755 --- a/test/linting/lint.sh +++ b/test/linting/lint.sh @@ -44,20 +44,37 @@ function _hadolint() { fi } -function _shellcheck() { - local F_SH F_BIN F_BATS - - # File paths for shellcheck: +# Create three arrays (F_SH, F_BIN, F_BATS) containing our BASH scripts +function _getBashScripts() { readarray -d '' F_SH < <(find . -type f -iname '*.sh' \ -not -path './test/bats/*' \ -not -path './test/test_helper/*' \ -not -path './.git/*' \ -print0 \ ) + # shellcheck disable=SC2248 readarray -d '' F_BIN < <(find 'target/bin' -type f -not -name '*.py' -print0) readarray -d '' F_BATS < <(find 'test/tests/' -type f -iname '*.bats' -print0) +} +# Check BASH files for correct syntax +function _bashcheck() { + local ERROR=0 SCRIPT + # .bats files are excluded from the test below: Due to their custom syntax ( @test ), .bats files are not standard bash + for SCRIPT in "${F_SH[@]}" "${F_BIN[@]}"; do + bash -n "${SCRIPT}" || ERROR=1 + done + + if [[ ${ERROR} -eq 0 ]]; then + _log 'info' 'BASH syntax check succeeded' + else + _log 'error' 'BASH syntax check failed' + return 1 + fi +} + +function _shellcheck() { # This command is a bit easier to grok as multi-line. # There is a `.shellcheckrc` file, but it's only supports half of the options below, thus kept as CLI: # `SCRIPTDIR` is a special value that represents the path of the script being linted, @@ -118,9 +135,10 @@ function _shellcheck() { function _main() { case "${1:-}" in - ( 'eclint' ) _eclint ;; - ( 'hadolint' ) _hadolint ;; - ( 'shellcheck' ) _shellcheck ;; + ( 'eclint' ) _eclint ;; + ( 'hadolint' ) _hadolint ;; + ( 'bashcheck' ) _getBashScripts; _bashcheck ;; + ( 'shellcheck' ) _getBashScripts; _shellcheck ;; ( * ) _log 'error' "'${1:-}' is not a command nor an option" return 3