shout/CLAUDE.md

2.7 KiB

shout

Transcript-based shell integration test runner. Bun + TypeScript.

Commands

  • bun test — run unit tests
  • bunx tsc --noEmit — type check
  • bun run src/cli/index.ts test [files...] — run shout CLI
    • -u, --update — rewrite .shout files with actual output
    • -k, --keep — keep temp directories after run
    • --clean-env — start with empty environment
    • --path <path> — prepend to $PATH (repeatable)
    • --timeout <dur> — per-command timeout (default 10s)
    • -v, --verbose — print each command as it runs
    • --port-from <n> — auto-assign $PORT starting from n (default 5400)
    • --parallel — run files in parallel

Architecture

  • src/parse.ts — parses .shout files into ShoutFile (list of Command)
  • src/run.ts — executes commands via Bun.spawn(["/bin/sh"], { detached: true }), captures output with sentinels
  • src/match.ts — wildcard-aware output matching and diff generation
  • src/format.ts — evaluates pass/fail, formats failures and summary
  • src/update.ts — rewrites .shout files with actual output (--update mode)
  • src/duration.ts — parses duration strings (10s, 500ms, 1m)
  • src/cli/index.ts — CLI entry point via commander
  • src/index.ts — barrel exports
  • web/index.html — web documentation page

.shout file format

  • $ prefix = command to execute
  • Lines between commands = expected output (stdout+stderr merged)
  • ... on its own line = multi-line wildcard (matches zero or more lines)
  • ... inline = matches any characters on that line
  • [N] on last line of expected output = assert exit code N
  • [*] = assert any non-zero exit code; default expects 0
  • # after a command = comment (stripped); # in expected output is literal
  • @env KEY=VALUE before first command = set environment variable
  • @setup path.shout before first command = prepend commands (and @env) from another file
    • Setup files use a plain format: each line is a command (no $ prefix), # lines are comments, blank lines ignored
    • Setup files can contain @env directives but not @setup (no nesting)
    • User file @env overrides setup file @env
    • Setup command failures abort the test with an error
  • Each file runs in a fresh temp dir with a single /bin/sh session
  • $HOME and $SHOUT_DIR are set to the temp dir automatically
  • $SHOUT_SOURCE_DIR is set to the directory containing the .shout file
  • $SHOUT_PROJECT_DIR is set to cwd where shout was invoked
  • stdout and stderr are merged (exec 2>&1)

Style

  • Strict TypeScript, Bun runtime
  • No classes — plain functions and types
  • Tests in src/*.test.ts, example .shout files in test/