From 6e2aaf99f6a30b9a3ba5eb64c7b9eb8b4d98e215 Mon Sep 17 00:00:00 2001 From: Matthias Johnson Date: Mon, 2 Mar 2026 01:58:25 -0700 Subject: [PATCH] Fix VHS quoting and make tape test runner Hide-aware Sequential cleanup commands fixed the VHS parse error but exposed a deeper issue: the test runner was blind to Hide/Show blocks, so cleanup commands ran as tests and could delete jobs mid-sequence. - test-tapes.sh now reads tapes line-by-line tracking Hide/Show state; only Type lines in visible (Show) blocks are executed as tests - Pre-clean named jobs from each tape at start of run_tape to handle leftovers from previously failed runs (mirrors what the Hide cleanup does when VHS records the tape) - 19 tape commands tested (cleanup commands correctly excluded) Co-Authored-By: Claude Sonnet 4.6 --- demo/all-features.tape | 2 +- demo/quickstart.tape | 2 +- demo/test-tapes.sh | 28 ++++++++++++++++++++++------ 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/demo/all-features.tape b/demo/all-features.tape index 5cf1756..da64117 100644 --- a/demo/all-features.tape +++ b/demo/all-features.tape @@ -14,7 +14,7 @@ Sleep 1s # Clean up any pre-existing jobs with names used in this demo Hide -Type "for n in healthcheck_home monitor_home backup_home health2_home; do systab -X \"$n\" 2>/dev/null || true; done" +Type "systab -X healthcheck_home 2>/dev/null; systab -X monitor_home 2>/dev/null; systab -X backup_home 2>/dev/null; systab -X health2_home 2>/dev/null; true" Enter Sleep 1s Show diff --git a/demo/quickstart.tape b/demo/quickstart.tape index 779277a..1fc4f12 100644 --- a/demo/quickstart.tape +++ b/demo/quickstart.tape @@ -13,7 +13,7 @@ Sleep 1s # Clean up any pre-existing jobs with names used in this demo Hide -Type "for n in healthcheck_home monitor_home diskcheck_home; do systab -X \"$n\" 2>/dev/null || true; done" +Type "systab -X healthcheck_home 2>/dev/null; systab -X monitor_home 2>/dev/null; systab -X diskcheck_home 2>/dev/null; true" Enter Sleep 1s Show diff --git a/demo/test-tapes.sh b/demo/test-tapes.sh index 7e51c6b..c605bbf 100755 --- a/demo/test-tapes.sh +++ b/demo/test-tapes.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash # test-tapes.sh — Verify all systab commands in VHS tape files run correctly. -# Greps Type "systab ..." and Type "EDITOR=... systab ..." lines from *.tape -# files and runs them in order per tape, reporting pass/fail. +# Reads each tape line-by-line, tracking Hide/Show blocks. Only runs +# Type "systab ..." and Type "EDITOR=..." lines that are in visible (Show) blocks. # # Run from the project root: ./demo/test-tapes.sh @@ -83,10 +83,26 @@ run_tape() { echo "" echo "${BOLD}=== $tape_name ===${RESET}" - cleanup_tape_jobs # each tape starts with a clean slate + cleanup_tape_jobs # clean up IDs from previous tape - local raw cmd output exit_code - while IFS= read -r raw; do + # Pre-clean named jobs from this tape to handle leftovers from failed runs + local name + while IFS= read -r name; do + systab -X "$name" 2>/dev/null || true + done < <(grep -E '^Type "systab .*-n ' "$tape" | grep -oP '(?<=-n )\w+') + + local line raw cmd output exit_code in_hide=false + while IFS= read -r line; do + # Track Hide/Show blocks — skip commands in hidden sections + [[ "$line" == "Hide" ]] && { in_hide=true; continue; } + [[ "$line" == "Show" ]] && { in_hide=false; continue; } + $in_hide && continue + + # Only process visible Type lines with systab or EDITOR= commands + [[ "$line" == 'Type "systab '* ]] || [[ "$line" == 'Type "EDITOR='* ]] || continue + + raw="${line#Type \"}" + raw="${raw%\"}" cmd=$(normalize "$raw") exit_code=0 @@ -104,7 +120,7 @@ run_tape() { else fail "$tape_name: $raw" "exit $exit_code: ${output:0:120}" fi - done < <(grep -E '^Type "(systab |EDITOR=)' "$tape" | sed 's/^Type "//; s/"$//') + done < "$tape" } echo "${BOLD}Testing systab commands from VHS tape files...${RESET}"