diff --git a/context/test-evidence/tooling.md b/context/test-evidence/tooling.md index 32bc4846..cda31503 100644 --- a/context/test-evidence/tooling.md +++ b/context/test-evidence/tooling.md @@ -1048,3 +1048,33 @@ scanned" alone, so the deleted-file case is what stops the fix from over-refusing. The rival ran from an ignored copy inside the worktree. A copy under `/tmp` fails "the real tree does not pass against a silent bd" for a reason unrelated to the rival: there is no repository there. + +### Section 5b runs on a hermetic PATH — `scripts/checkers-test.sh` + +**What broke.** Every PR's "Knowledge base consistency" job went red at +`666de199` with "a bash 5.0 with no nix is exit 3, not 5.x (exit 1, wanted 3)" +and "a bash 5.1 is accepted (exit 1, wanted 0)". Neither PR alone was wrong. The +NixOS-runner change (`af44653f`) found that `/usr/bin:/bin` on NixOS holds only +`env` and `sh`, so the runner dies on `dirname` with exit 1. It fixed section 5 +by moving it to a `utilbin` of linked tools. #237 (`e45a9c42`) added section 5b +on its own branch, with the old `PATH=$work/fakebin:/usr/bin:/bin`. The two +merged with no conflict, and each had passed CI only on its own side. + +**Reproduced** on macOS by running both 5b invocations with `/usr/bin:/bin` +replaced by a directory holding only `env` and `sh`. Both exited 1 on +`dirname: command not found`. Those are the CI exits. + +**Fix.** 5b uses `utilbin` as well. `utilbin` gains `head` and `env`, because +the 5.1 control runs past the version check into `check_shebangs` and +`run_suite`. + +**Rivals**, each run in the suite: +- **`dirname` left out of `utilbin`** fails all three section-5 cases with the + exact CI pair: exit 1 where 3 was wanted, and exit 1 where 0 was wanted. The + NixOS failure now reproduces on any host, because no case reads the host's + `/usr/bin` any more. +- **`env` left out** fails "a bash 5.1 is accepted" alone. +- **`head` left out** fails nothing. `check_shebangs` calls `head` inside + `check_shebangs || rc=1`, where `set -e` is off. A missing `head` makes every + first line empty, and the shebang check then passes without checking + anything. That is a defect in `checkers.sh` and is not fixed here. diff --git a/scripts/checkers-test.sh b/scripts/checkers-test.sh index a3995f55..67a9b846 100755 --- a/scripts/checkers-test.sh +++ b/scripts/checkers-test.sh @@ -136,9 +136,10 @@ chmod +x "$work/fakebin/bash" # utilbin carries only the utilities the runner itself needs, and no nix, so # the fake bash is the only candidate and the nix fallback is absent. Linked # one by one rather than taking /usr/bin:/bin, which on NixOS hold only `env` -# and `sh` -- the runner died on `dirname` there, exit 1 instead of 3. +# and `sh` -- the runner died on `dirname` there, exit 1 instead of 3. `head` +# and `env` are for 5b's 5.1 control, which runs past the version check. mkdir -p "$work/utilbin" -for tool in dirname; do +for tool in dirname head env; do ln -sf "$(command -v "$tool")" "$work/utilbin/$tool" done env PATH="$work/fakebin:$work/utilbin" HOME="$HOME" \ @@ -154,7 +155,7 @@ for v in "5 0:3:a bash 5.0 with no nix is exit 3, not 5.x" \ printf '#!/bin/sh\ncase "$*" in *BASH_VERSINFO*) echo %s; exit 0 ;; esac\nexit 0\n' \ "${v%%:*}" > "$work/fakebin/bash" want="${v#*:}"; name="${want#*:}"; want="${want%%:*}" - env PATH="$work/fakebin:/usr/bin:/bin" HOME="$HOME" \ + env PATH="$work/fakebin:$work/utilbin" HOME="$HOME" \ "${BASH:-bash}" "$d/checkers.sh" any > "$work/out" 2>&1 got=$? [ "$got" = "$want" ] && ok "$name" || bad "$name" "exit $got, wanted $want"