Skip to content

fix(cli): don't hang on ci explain with no --log in a terminal - #366

Merged
PabloCodes7 merged 1 commit into
mainfrom
fix/cli-interactive-stdin-no-hang
Jul 15, 2026
Merged

PabloCodes7 merged 1 commit into
mainfrom
fix/cli-interactive-stdin-no-hang

Conversation

@PabloCodes7

Copy link
Copy Markdown
Contributor

Problem

When --log is omitted, PatchRail reads the log from stdin — correct for the documented one-liner:

gh run view <run-id> --log-failed | patchrail ci explain

But a first-timer who just runs patchrail ci explain in a terminal — forgetting --log, with nothing piped in — hit a blocking sys.stdin.read() that waited forever with zero output. The program looked frozen or crashed, with no hint that it wanted input. Reproduced against the published 0.7.2 wheel (hangs >6s, no output, on a pty stdin).

Fix

_read_log now detects an interactive terminal on stdin (isatty()) with no --log and raises LogReadError with an actionable hint instead of blocking. explain, classify, pilot-pack and redact print it to stderr and exit 2 — the same clean contract as the other bad-input cases (missing file, directory, unreadable file, empty input):

patchrail ci explain: no log to read from stdin: pass --log <file>, or pipe a CI log in (e.g. `gh run view <run-id> --log-failed | patchrail ci explain`)

A real pipe or file redirect is untouched (its stdin is not a TTY), so the documented one-liner and every scripted use keep working exactly as before.

Tests

  • +3 tests (explain/classify/redact): an interactive-TTY stdin with no --log exits 2, emits the hint, and leaks no traceback.
  • Existing empty-stdin / missing-file / directory / unreadable tests unchanged and green (they model a pipe, isatty()→False).
  • Full suite: 941 passed + 70 subtests (Python 3.12). ruff + format + mypy clean. Benchmark top-1 = 1.0 over 223 fixtures (no classifier/fixture change).

When --log is omitted the log is read from stdin, which is right for the
piped one-liner (`gh run view <id> --log-failed | patchrail ci explain`).
But running `patchrail ci explain` interactively with nothing piped hit a
blocking stdin.read() that waited forever with zero output -- a first-timer
who forgot --log just saw a frozen screen.

_read_log now detects an interactive terminal on stdin (isatty) and raises
LogReadError with an actionable hint; explain/classify/pilot-pack/redact
print it to stderr and exit 2, the same contract as the other bad-input
cases. A real pipe or file redirect is untouched, so the documented
one-liner keeps working.
@PabloCodes7
PabloCodes7 merged commit 1be7ac5 into main Jul 15, 2026
5 checks passed
@PabloCodes7
PabloCodes7 deleted the fix/cli-interactive-stdin-no-hang branch July 15, 2026 21:07
@PabloCodes7 PabloCodes7 mentioned this pull request Jul 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant