#!/usr/bin/env bash # # scripts/doctor.sh contract (miss path): # 1. Exits non-zero. # 2. Each miss is followed by a `fix: ...` line. # 3. Emits a consolidated "Run the following to fix them" block. # 4. No raw ANSI escapes leak into non-TTY stderr. set -euo pipefail here="$(cd "$(dirname "$0")" && pwd -P)" repo="$(cd "$here/.." && pwd -P)" out="$(mktemp)" trap 'rm -f "$out"' EXIT # Strip tools from PATH so the miss branches execute. # /usr/bin/python3 is 3.10.x on Ubuntu 22.04; this exercises the # python>=3.11 miss branch and its fix+alt lines. if env -i HOME="$HOME" PATH="/usr/bin:/bin" bash "$repo/scripts/doctor.sh" >"$out" 2>&1; then echo "FAIL: doctor.sh exited 0 despite missing prerequisites" cat "$out" exit 1 fi fail=0 must_contain() { local needle="$1" if ! grep -Fq -- "$needle" "$out"; then echo "FAIL: expected to see: $needle" fail=1 fi } must_contain '[miss] just' must_contain '[miss] uv' must_contain '[miss] python>=3.11' must_contain 'fix: curl --proto "=https" --tlsv1.2 -LsSf https://just.systems/install.sh' must_contain 'fix: curl -LsSf https://astral.sh/uv/install.sh | sh' must_contain 'fix: uv python install 3.11' must_contain 'Run the following to fix them' # No raw ANSI sequences when stderr is redirected to a file. if grep -q $'\033\\[' "$out"; then echo "FAIL: raw ANSI escape leaked into non-TTY stderr" fail=1 fi # Each [miss] line is followed by a "fix:" line. `[miss]` is 6 chars # so %-6s adds no padding; the literal " %-12s" supplies one sep space. awk ' /^ \[miss\]/ { miss_line = NR; next } miss_line && NR == miss_line + 1 { if ($0 !~ /^ fix: /) { printf "FAIL: [miss] at line %d not followed by fix: (got: %s)\n", miss_line, $0 exit 1 } miss_line = 0 } ' "$out" || fail=1 if [ "$fail" -ne 0 ]; then echo "---- doctor.sh output ----" cat "$out" exit 1 fi echo "PASS: doctor.sh prints fix commands for every miss"