2022-10-17 08:40:09 +00:00
|
|
|
#!/bin/bash
|
2020-10-04 17:34:15 +00:00
|
|
|
|
2022-08-22 14:22:46 +00:00
|
|
|
# version v0.3.0
|
|
|
|
# executed by Make (during CI or manually)
|
2021-06-01 16:12:17 +00:00
|
|
|
# task checks files against linting targets
|
2020-10-04 17:34:15 +00:00
|
|
|
|
|
|
|
set -eEuo pipefail
|
2021-12-19 10:56:22 +00:00
|
|
|
shopt -s inherit_errexit
|
2020-10-04 17:34:15 +00:00
|
|
|
|
2022-08-22 14:22:46 +00:00
|
|
|
REPOSITORY_ROOT=$(realpath "$(dirname "$(readlink -f "${0}")")"/../../)
|
|
|
|
LOG_LEVEL=${LOG_LEVEL:-debug}
|
2023-05-28 20:48:11 +00:00
|
|
|
HADOLINT_VERSION='2.12.0'
|
2023-10-17 21:47:43 +00:00
|
|
|
ECLINT_VERSION='2.7.2'
|
2023-01-30 11:30:27 +00:00
|
|
|
SHELLCHECK_VERSION='0.9.0'
|
2020-10-04 17:34:15 +00:00
|
|
|
|
2022-08-22 14:22:46 +00:00
|
|
|
# shellcheck source=./../../target/scripts/helpers/log.sh
|
|
|
|
source "${REPOSITORY_ROOT}/target/scripts/helpers/log.sh"
|
2020-10-04 17:34:15 +00:00
|
|
|
|
2023-05-25 23:01:41 +00:00
|
|
|
function _eclint() {
|
2021-06-07 12:58:34 +00:00
|
|
|
if docker run --rm --tty \
|
2022-08-22 14:22:46 +00:00
|
|
|
--volume "${REPOSITORY_ROOT}:/ci:ro" \
|
|
|
|
--workdir "/ci" \
|
2023-01-25 08:16:22 +00:00
|
|
|
--name dms-test_eclint \
|
2022-08-22 14:22:46 +00:00
|
|
|
"mstruebing/editorconfig-checker:${ECLINT_VERSION}" ec -config "/ci/test/linting/.ecrc.json"
|
2020-10-04 17:34:15 +00:00
|
|
|
then
|
2022-08-22 14:22:46 +00:00
|
|
|
_log 'info' 'ECLint succeeded'
|
2020-10-04 17:34:15 +00:00
|
|
|
else
|
2022-08-22 14:22:46 +00:00
|
|
|
_log 'error' 'ECLint failed'
|
2020-12-10 09:30:39 +00:00
|
|
|
return 1
|
2020-10-04 17:34:15 +00:00
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2023-05-25 23:01:41 +00:00
|
|
|
function _hadolint() {
|
2021-06-07 12:58:34 +00:00
|
|
|
if docker run --rm --tty \
|
2022-08-22 14:22:46 +00:00
|
|
|
--volume "${REPOSITORY_ROOT}:/ci:ro" \
|
|
|
|
--workdir "/ci" \
|
2023-01-25 08:16:22 +00:00
|
|
|
--name dms-test_hadolint \
|
2023-09-08 21:35:57 +00:00
|
|
|
"hadolint/hadolint:v${HADOLINT_VERSION}-alpine" hadolint --config "/ci/test/linting/.hadolint.yml" Dockerfile
|
2020-10-04 17:34:15 +00:00
|
|
|
then
|
2022-08-22 14:22:46 +00:00
|
|
|
_log 'info' 'Hadolint succeeded'
|
2020-10-04 17:34:15 +00:00
|
|
|
else
|
2022-08-22 14:22:46 +00:00
|
|
|
_log 'error' 'Hadolint failed'
|
2020-12-10 09:30:39 +00:00
|
|
|
return 1
|
2020-10-04 17:34:15 +00:00
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2023-05-27 20:12:24 +00:00
|
|
|
# Create three arrays (F_SH, F_BIN, F_BATS) containing our BASH scripts
|
|
|
|
function _getBashScripts() {
|
2023-05-23 14:33:58 +00:00
|
|
|
readarray -d '' F_SH < <(find . -type f -iname '*.sh' \
|
2021-06-07 12:58:34 +00:00
|
|
|
-not -path './test/bats/*' \
|
2023-04-17 08:42:35 +00:00
|
|
|
-not -path './test/test_helper/*' \
|
2023-05-23 14:33:58 +00:00
|
|
|
-not -path './.git/*' \
|
|
|
|
-print0 \
|
2022-05-05 08:28:38 +00:00
|
|
|
)
|
2023-05-27 20:12:24 +00:00
|
|
|
|
2021-06-07 12:58:34 +00:00
|
|
|
# shellcheck disable=SC2248
|
2023-05-23 14:33:58 +00:00
|
|
|
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)
|
2023-05-27 20:12:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
# 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
|
|
|
|
}
|
2021-06-07 12:58:34 +00:00
|
|
|
|
2023-05-27 20:12:24 +00:00
|
|
|
function _shellcheck() {
|
2021-11-20 20:33:49 +00:00
|
|
|
# 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,
|
|
|
|
# all sourced scripts share the same SCRIPTDIR source-path of the original script being linted.
|
2023-05-23 14:33:58 +00:00
|
|
|
local CMD_SHELLCHECK=(shellcheck
|
2021-11-20 20:33:49 +00:00
|
|
|
--external-sources
|
2021-06-07 12:58:34 +00:00
|
|
|
--check-sourced
|
|
|
|
--severity=style
|
|
|
|
--color=auto
|
|
|
|
--wiki-link-count=50
|
|
|
|
--enable=all
|
|
|
|
--exclude=SC2154
|
2021-12-19 10:56:22 +00:00
|
|
|
--exclude=SC2310
|
|
|
|
--exclude=SC2311
|
|
|
|
--exclude=SC2312
|
2021-06-07 12:58:34 +00:00
|
|
|
--source-path=SCRIPTDIR
|
2023-05-23 14:33:58 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
local BATS_EXTRA_ARGS=(
|
|
|
|
--exclude=SC2030
|
|
|
|
--exclude=SC2031
|
|
|
|
--exclude=SC2034
|
|
|
|
--exclude=SC2155
|
2021-06-07 12:58:34 +00:00
|
|
|
)
|
2021-11-20 20:33:49 +00:00
|
|
|
|
|
|
|
# The linter can reference additional source-path values declared in scripts,
|
|
|
|
# which in our case rarely benefit from extending from `SCRIPTDIR` and instead
|
|
|
|
# should use a relative path from the project root (mounted at `/ci`), eg `target/scripts/`.
|
|
|
|
# Note that `SCRIPTDIR` will strip a prefix variable for a source path, which can be useful
|
|
|
|
# if `SCRIPTDIR` would always be the same value, and combined with relative path via another
|
|
|
|
# `source-path=SCRIPTDIR/relative/path/to/scripts` in the .sh file.
|
|
|
|
# These source-path values can apply to the entire file (and sourced files) if not wrapped in a function scope.
|
|
|
|
# Otherwise it only applies to the line below it. You can declare multiple source-paths, they don't override the previous.
|
|
|
|
# `source=relative/path/to/file.sh` will check the source value in each source-path as well.
|
2021-06-07 12:58:34 +00:00
|
|
|
# shellcheck disable=SC2068
|
2023-05-23 14:33:58 +00:00
|
|
|
local ERROR=0
|
|
|
|
|
|
|
|
docker run --rm --tty \
|
2022-08-22 14:22:46 +00:00
|
|
|
--volume "${REPOSITORY_ROOT}:/ci:ro" \
|
|
|
|
--workdir "/ci" \
|
2023-01-25 08:16:22 +00:00
|
|
|
--name dms-test_shellcheck \
|
2023-05-23 14:33:58 +00:00
|
|
|
"koalaman/shellcheck-alpine:v${SHELLCHECK_VERSION}" "${CMD_SHELLCHECK[@]}" "${F_SH[@]}" "${F_BIN[@]}" || ERROR=1
|
|
|
|
|
|
|
|
docker run --rm --tty \
|
|
|
|
--volume "${REPOSITORY_ROOT}:/ci:ro" \
|
|
|
|
--workdir "/ci" \
|
|
|
|
--name dms-test_shellcheck \
|
|
|
|
"koalaman/shellcheck-alpine:v${SHELLCHECK_VERSION}" "${CMD_SHELLCHECK[@]}" \
|
|
|
|
"${BATS_EXTRA_ARGS[@]}" "${F_BATS[@]}" || ERROR=1
|
|
|
|
|
2023-05-24 07:06:59 +00:00
|
|
|
if [[ ${ERROR} -eq 0 ]]; then
|
2022-08-22 14:22:46 +00:00
|
|
|
_log 'info' 'ShellCheck succeeded'
|
2021-06-07 12:58:34 +00:00
|
|
|
else
|
2022-08-22 14:22:46 +00:00
|
|
|
_log 'error' 'ShellCheck failed'
|
2021-06-07 12:58:34 +00:00
|
|
|
return 1
|
2020-10-04 17:34:15 +00:00
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2023-05-25 23:01:41 +00:00
|
|
|
function _main() {
|
2021-06-01 16:12:17 +00:00
|
|
|
case "${1:-}" in
|
2023-05-27 20:12:24 +00:00
|
|
|
( 'eclint' ) _eclint ;;
|
|
|
|
( 'hadolint' ) _hadolint ;;
|
|
|
|
( 'bashcheck' ) _getBashScripts; _bashcheck ;;
|
|
|
|
( 'shellcheck' ) _getBashScripts; _shellcheck ;;
|
2022-08-22 14:22:46 +00:00
|
|
|
( * )
|
|
|
|
_log 'error' "'${1:-}' is not a command nor an option"
|
2021-06-01 16:12:17 +00:00
|
|
|
return 3
|
2020-10-04 17:34:15 +00:00
|
|
|
;;
|
|
|
|
esac
|
|
|
|
}
|
|
|
|
|
2022-08-22 14:22:46 +00:00
|
|
|
_main "${@}" || exit ${?}
|