Refuse bash older than 4.4 with one clear error when sourced.
commit 703211b0e1a33c252c7d15380d76ffdabfe83ffb · parent 7be6f95327
· browse this tree
Ximianth, 2026-10-23 13:35:03 UTC
Before, macOS's /bin/bash (3.2) printed "declare: -g: invalid option" three times and sourcing still succeeded; the failures came later, from inside testmark_parse. The check is in syntax 3.2 runs, and makes `source` return 1. tests/test-old-bash.sh runs the check under bash 3.2 and 4.3 builds, if present, and skips each missing one with a note.
diff --git a/lib/testmark.bash b/lib/testmark.bash index c747d56..5e80e44 100644 --- a/lib/testmark.bash +++ b/lib/testmark.bash @@ -1,10 +1,17 @@ ## testmark.bash: read testmark documents (data hunks embedded in markdown) from bash. ## ## Source this file, by a path containing a slash; it sources the rest of the library from beside itself. +## Needs bash 4.4 or later; on older ones, sourcing fails. ## Every public function is a shim over a private `_testmark_*` implementation, run through `_testmark_call`. ## Data comes out on stdout as exact bytes; errors go to stderr as "testmark: ...", with a nonzero status. ## Documents are addressed by a handle the caller picks at parse time; handles match `[A-Za-z0-9_]+`. +# Checked first, in syntax bash 3.2 (macOS's /bin/bash) still runs, so an old bash gets one clear error. +if ((BASH_VERSINFO[0] < 4 || (BASH_VERSINFO[0] == 4 && BASH_VERSINFO[1] < 4))); then + >&2 echo "testmark: needs bash 4.4 or later; this is $BASH_VERSION" + return 1 +fi + # shellcheck source=lib/testmark/document.bash source "${BASH_SOURCE[0]%/*}/testmark/document.bash" diff --git a/tests/test-old-bash.sh b/tests/test-old-bash.sh new file mode 100755 index 0000000..22547d1 --- /dev/null +++ b/tests/test-old-bash.sh @@ -0,0 +1,20 @@ +#!/bin/bash +## Sourcing under a bash older than 4.4 fails with one clear line. +## Uses the builds in BASH_VERSIONS_DIR (default /tmp/bash-versions), from the research's build-bash-versions.sh; +## each one that's missing is skipped with a note. +set -euo pipefail +cd "$(dirname "$0")" +# shellcheck source=tests/lib.sh +source ./lib.sh + +for v in 3.2 4.3; do + b=${BASH_VERSIONS_DIR:-/tmp/bash-versions}/bin/bash-$v + if [ ! -x "$b" ]; then + echo "SKIP bash $v: no $b" + continue + fi + got=$("$b" -c 'source "$1" 2>&1 || echo "rc=$?"' _ "$ROOT/lib/testmark.bash") + expect_eq "bash $v refuses" "$got" "testmark: needs bash 4.4 or later; this is $("$b" -c 'echo "$BASH_VERSION"')"$'\n'"rc=1" +done + +exit "$RESULT"