From 5723f6477524084f5ff6065ab201b616ae68e592 Mon Sep 17 00:00:00 2001 From: Claude Code Bot Date: Sun, 16 Aug 2026 18:52:58 -0700 Subject: [PATCH] fix(install): fail fast on Bash < 4.0 instead of crashing on mapfile MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit install.sh uses the `mapfile` builtin (5 call sites), which requires Bash 4.0+. The shebang is `#!/usr/bin/env bash` and stock macOS ships Bash 3.2.57 at /bin/bash, so a user on stock macOS hits a cryptic "mapfile: command not found" partway through the run — after the script has already done real filesystem work under `set -euo pipefail`. Add an early version guard immediately after `set -euo pipefail`, before any side effects. It checks ${BASH_VERSINFO[0]} (guarding against the variable being unset), writes an actionable message to stderr naming the macOS 3.2 default and the `brew install bash` remedy, and exits 1. Also correct the "Requires:" header, which omitted the Bash 4.0 requirement entirely. Verified: `/bin/bash ./install.sh --help` now prints the guard message and exits 1; `/opt/homebrew/bin/bash ./install.sh --help` prints usage and exits 0. shellcheck -S info reports only pre-existing SC2312 infos. --- install.sh | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/install.sh b/install.sh index ab357ce..c425f9a 100755 --- a/install.sh +++ b/install.sh @@ -11,11 +11,29 @@ # The script is idempotent: re-running it adds missing entries, updates changed # entries, and removes entries for domains no longer in the mirrors list. # -# Requires: macOS, curl (for network operations), python3 (bundled on macOS) +# Requires: macOS, Bash 4.0+ (stock macOS /bin/bash is 3.2 — see guard below), +# curl (for network operations), python3 (bundled on macOS) # Root is required only for install/uninstall, not for --update-mirrors. set -euo pipefail +# --------------------------------------------------------------------------- +# Bash version guard — must run before any side effects. +# This script uses `mapfile`, a Bash 4.0+ builtin. macOS ships Bash 3.2.57 at +# /bin/bash, so without this guard a stock-macOS run fails mid-execution with a +# cryptic "mapfile: command not found" after filesystem changes have started. +# `error()`/`fatal()` are defined further down, so emit plainly here. +# --------------------------------------------------------------------------- +if [[ -z "${BASH_VERSINFO[0]:-}" || "${BASH_VERSINFO[0]}" -lt 4 ]]; then + echo "[error] archive-resolver requires Bash 4.0 or newer (found: ${BASH_VERSION:-unknown})." >&2 + echo "[error] macOS ships Bash 3.2 at /bin/bash, which lacks the 'mapfile' builtin this script uses." >&2 + echo "[error] Remedy: install a newer Bash and run the script with it, e.g." >&2 + echo "[error] brew install bash" >&2 + echo "[error] /opt/homebrew/bin/bash ./install.sh # Apple silicon" >&2 + echo "[error] /usr/local/bin/bash ./install.sh # Intel" >&2 + exit 1 +fi + # --------------------------------------------------------------------------- # Constants # ---------------------------------------------------------------------------