fix(providers): guard the statusline's unguarded array expansion

`parts` is seeded empty and all seven appends are conditional, so
"${parts[@]}" at the join loop can expand an empty array. install.sh
deploys this file to every user machine.

Two things had to both hold for the bare form to be safe: this file
enabling no `set -u`, and the shell being bash 4.4+, which stopped
treating an empty-array expansion as unbound. On bash 3.2 -- macOS's
system bash, an explicit repo target -- adding `set -u` aborts here.
That is also why the hazard is unreproducible on a modern dev box and
why the enforcement is a static scan rather than a runtime test.

Adds the `providers` glob to test-vale-wrap.sh's bash-3.2 scan, which
excluded it precisely because of this defect. Floor is 1 rather than
"count minus slack": the glob holds one file, so any slack at all
means a floor of 0, which passes vacuously on a renamed directory.

Also adds case 27, the regression test for the stale `shellcheck
source=` directives fixed in the next commit (#97 item 2). It lives in
this file because that is where the exemption it guards lives.

Closes #96
Refs #97

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01X7GvKuJfy2WrdBmUttV4DT
This commit is contained in:
2026-08-14 08:03:17 +00:00
parent 55d956b298
commit 49d21bcb4d
2 changed files with 124 additions and 13 deletions

View File

@@ -92,8 +92,17 @@ parts=()
[ -n "$vim_mode" ] && parts+=("${COLOR_MAGENTA}${vim_mode}${COLOR_RESET}")
# --- Join with ' · ' separator and print ---
# `parts` is seeded empty above and every append is conditional, so all seven can
# be false and the array can reach here with no elements. Two things had to both
# stay true for bare "${parts[@]}" to be safe: this file enabling no `set -u`
# (house style in every other script here is `set -euo pipefail`), and the shell
# being bash 4.4+, which stopped treating an empty-array expansion as unbound.
# On bash 3.2 -- macOS's system bash, and an explicit repo target -- adding
# `set -u` aborts here. The guarded form removes the tripwire instead of relying
# on both conditions holding. install.sh deploys this file to every user
# machine. See issue #96.
output=""
for part in "${parts[@]}"; do
for part in ${parts[@]+"${parts[@]}"}; do
[ -z "$output" ] && output="$part" || output="${output} · ${part}"
done