Add shellcheck lint and bats tests

make lint runs shellcheck on every tracked bash script, make test runs
the bats suite in tests/, and make check runs both. The tests cover the
update orchestrator (hook isolation, failure reporting, pull and
free-space handling) and utils.sh (migrations, package install and
removal, services, initramfs build check), using stub commands so they
never touch the real system.

Fixes from the first lint run: 20-aur.sh stops if a cd fails rather
than building or deleting in the wrong directory, and
80-gnome-extensions.sh refuses to rm -rf with an empty path. The rest
are false positives, silenced in .shellcheckrc or per line.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-30 16:15:12 -06:00
co-authored by Claude Opus 5.5
parent 7e08a048ca
commit d9da8208dd
16 changed files with 464 additions and 12 deletions
+49
View File
@@ -0,0 +1,49 @@
#!/bin/bash
# Shared setup for the bats tests. Each test gets its own HOME and a bin dir at
# the front of PATH where it can put fake versions of pacman, yay, sudo, etc.
REPO="$(cd "$BATS_TEST_DIRNAME/.." && pwd)"
common_setup() {
export HOME="$BATS_TEST_TMPDIR/home"
export STUB_BIN="$BATS_TEST_TMPDIR/bin"
export STUB_LOG="$BATS_TEST_TMPDIR/stub.log"
mkdir -p "$HOME" "$STUB_BIN"
: > "$STUB_LOG"
export PATH="$STUB_BIN:$PATH"
unset COREDESKTOP
}
# A test file that needs more setup defines its own setup that calls this first
setup() {
common_setup
}
# stub NAME [BODY]: put a fake NAME on PATH that appends "NAME args..." to
# $STUB_LOG and then runs BODY, a bash snippet that sees the args as "$@"
stub() {
local name="$1" body="${2:-}"
cat > "$STUB_BIN/$name" << EOF
#!/bin/bash
echo "$name \$*" >> "\$STUB_LOG"
$body
EOF
chmod +x "$STUB_BIN/$name"
}
# called NAME ARGS...: true if the stub log has exactly the line "NAME ARGS..."
called() {
grep -qxF "$*" "$STUB_LOG"
}
# not_called NAME: true if the stub NAME never ran
not_called() {
! grep -q "^$1 " "$STUB_LOG"
}
# uncalled NAME ARGS...: the opposite of called. (A bare "! called ..." would
# not fail the test: bats, like set -e, ignores the status of a ! command.)
uncalled() {
! called "$@"
}