--- name: verify-module description: Use before committing any change to a module's install.sh or to bootstrap.sh, to prove the change actually works. Covers the idempotency re-run check, shellcheck with the right shell dialect, and testing against both RHEL- and Debian-family containers. --- # Verifying a module change Nothing here is verified by a test suite — the only proof a module works is running it. Three checks, cheapest first. ## 1. shellcheck Every script is POSIX `sh`, so tell shellcheck that. Its default assumes bash and will happily wave through `[[ ]]` and `local`, which break on a box where `/bin/sh` is dash. ```sh shellcheck -s sh bootstrap.sh */install.sh lib/*.sh ``` `lib/` is sourced, not executed, so keep the `# shellcheck source=../lib/fetch.sh` directives above each `.` line or shellcheck can't follow them. ## 2. Idempotency — the re-run check This is the one that catches real bugs. Run the module twice: ```sh .//install.sh # does the work .//install.sh # must SKIP, not redo it ``` The second run has to say "already installed" / "already present". If it re-downloads, the guard is broken — most often a pinned `ver=` that doesn't match the string stamped in `~/.local/bin/.versions/` (`v1.2.3` vs `1.2.3`). That failure is silent: everything still works, it just refetches on every bootstrap forever. Guards must check the tool **runs**, not that a path exists. A Kasm redeploy leaves broken trees behind, and an existence check will happily skip past one. ## 3. Both distro families `lib/os-detect.sh` branches on dnf/yum vs apt. If your change touches `pkg_install` or anything OS-conditional, exercise both: ```sh docker run --rm -v "$PWD:/repo" -w /repo debian:13 sh -c \ 'apt-get update -qq && apt-get install -y -qq sudo curl git >/dev/null && .//install.sh' docker run --rm -v "$PWD:/repo" -w /repo rockylinux:9 sh -c \ 'dnf install -y -q sudo curl git >/dev/null && .//install.sh' ``` Run each container's command twice in the same shell to get the idempotency check on both families at once. Note this runs as root in a container, which is *not* how a real box runs it — it won't catch a missing-sudo problem. It's a portability check, not a faithful rehearsal. ## Non-systemd hosts Kasm has no systemd and no rootful Docker. Anything that would `systemctl` must no-op rather than abort — you can't fully rehearse this in a container, so read the code path and confirm the guard exists (`docker/install.sh` and `docker-rootless-cgroup/install.sh` are the references). ## Full run Finally, `./bootstrap.sh` end to end. It runs modules in a deliberate order and `set -eu` means any module's failure aborts the rest — a module that passes standalone can still break the chain if it was inserted at the wrong point. ## Report honestly If you only ran shellcheck and the re-run check, say that. Don't describe a change as verified on both distro families unless you actually ran both.