Files
mrcharles 84ea6e931e feat(doorman): badge listener + decoder TDD + deploy scaffolding [#355]
Modern successor of the 2018 Perl doorman (snapshot in legacy/):
bash+coreutils HID decoder, HA webhook dispatch, systemd unit.
Offline decoder suite green (9 tests); shellcheck zero-warning.

Umbrella #345. Work item: https://projects.knownelement.com/issues/355
2026-09-02 21:11:13 -05:00

80 lines
2.2 KiB
Bash
Executable File

#!/usr/bin/env bash
#
# tests/shellcheck.sh — enforce shellcheck (via Docker) on all repo shell scripts
#
# Usage:
# bash tests/shellcheck.sh # lint every .sh in the repo
# bash tests/shellcheck.sh path/a.sh # lint specific files
#
# Uses the koalaman/shellcheck:stable image (no native binary required).
# Exits non-zero if ANY script emits a diagnostic.
#
set -uo pipefail
IMAGE="koalaman/shellcheck:stable"
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
mapfile -t FILES < <(
if [ "$#" -gt 0 ]; then
for f in "$@"; do
f_abs="$(cd "$(dirname "$f")" && pwd)/$(basename "$f")"
case "$f_abs" in
"$ROOT"/legacy/*) ;; # 2018 Perl snapshot, verbatim, not maintained
*) case "$f_abs" in *.sh) echo "$f_abs" ;; esac ;;
esac
done
else
while IFS= read -r f_abs; do
case "$f_abs" in
"$ROOT"/legacy/*) ;; # 2018 Perl snapshot, verbatim, not maintained
*) echo "$f_abs" ;;
esac
done < <(find "$ROOT" -type f -name '*.sh' \
-not -path '*/.git/*' -not -path "$ROOT/.crush/*")
fi
)
if [ "${#FILES[@]}" -eq 0 ]; then
echo "shellcheck.sh: no .sh files to check." >&2
exit 0
fi
# --- Filter out non-bash scripts (e.g. PHP with a .sh extension) --------------
BASH_FILES=()
for f in "${FILES[@]}"; do
shebang=$(head -c 64 "$f" 2>/dev/null | head -n1)
case "$shebang" in
\#!/usr/bin/php* | \#!/usr/bin/env\ php*) ;; # PHP, skip
*) BASH_FILES+=("$f") ;;
esac
done
if [ "${#BASH_FILES[@]}" -eq 0 ]; then
echo "shellcheck.sh: no bash scripts among targets." >&2
exit 0
fi
# shellcheck disable=SC2012 # basename loop is intentional
REL=()
for f in "${BASH_FILES[@]}"; do REL+=("${f#"$ROOT"/}"); done
# Intentional conventions of this codebase (not bugs):
# SC1090/SC1091 — awk program paths & dynamic sourcing not followable
DISABLES=(-e SC1090 -e SC1091)
echo "Checking ${#BASH_FILES[@]} script(s) with $IMAGE:"
printf ' %s\n' "${REL[@]}"
docker run --rm \
-v "$ROOT:/mnt:ro" \
-w /mnt \
"$IMAGE" -x "${DISABLES[@]}" "${REL[@]}"
rc=$?
if [ "$rc" -eq 0 ]; then
echo "shellcheck: PASS (${#BASH_FILES[@]} scripts clean)"
else
echo "shellcheck: FAIL (fix the findings above or add targeted disable directives)" >&2
fi
exit "$rc"