Skip to content

cli: render OpTracker as plain lines on non-interactive stderr#2421

Open
dstotijn wants to merge 1 commit intoencoredev:mainfrom
dstotijn:optracker-non-interactive
Open

cli: render OpTracker as plain lines on non-interactive stderr#2421
dstotijn wants to merge 1 commit intoencoredev:mainfrom
dstotijn:optracker-non-interactive

Conversation

@dstotijn
Copy link
Copy Markdown

Summary

The build-progress UI (Building Encore application graph..., Analyzing service topology..., etc.) is rendered by internal/optracker.OpTracker, which uses ANSI cursor save/restore for in-place spinner updates. That works on a TTY, but when stderr is piped — mise run, log aggregators, CI, tee, Docker logs — every 100ms refresh becomes a new line and floods the output.

Fix

  • New proto field non_interactive on RunRequest, ExecScriptRequest, ExecSpecRequest. Defaults to false → existing behavior, fully backwards compatible.
  • The CLI auto-sets it from !term.IsTerminal(int(os.Stderr.Fd())).
  • optracker.New gains an interactive bool parameter. In interactive mode rendering is unchanged. In non-interactive mode the spinner goroutine is skipped, ANSI cursor manipulation is dropped, and the tracker emits one plain line per state transition (start / done / failed / canceled) — no duplicates across refresh calls.

Example non-interactive output:

  Building Encore application graph...
  Analyzing service topology...
  ✔ Building Encore application graph: Done
  ✔ Analyzing service topology: Done
  Compiling application source code...
  ✔ Compiling application source code: Done
  Starting Encore application...
  ✔ Starting Encore application: Done

Alternatives considered

  • --quiet flag / ENCORE_QUIET env var — rejected. The flooding is an output-format bug, not a verbosity preference; surfacing it as user config asks people to opt out of broken behavior.
  • Total suppression when non-TTY — rejected. Users still want to see what's happening; they only want to stop the spinner spam.

Test plan

  • Interactive: encore run from a TTY shows the spinner UI as before.
  • Non-interactive: encore run 2>&1 | cat produces plain one-line-per-event output, no spinner / cursor escapes.
  • Same for encore exec (Go and TS apps).
  • Existing tests still pass: go test ./internal/optracker/... ./cli/daemon/... ./cli/cmd/encore/...

The build progress UI uses ANSI cursor save/restore for in-place spinner
updates, which only works on a TTY. When stderr is piped into mise, a
log aggregator, or CI, every 100ms refresh becomes a new line and floods
the output.

Detect the CLI's stderr TTY state and pass it through to the daemon as a
new non_interactive bool on RunRequest, ExecScriptRequest, and
ExecSpecRequest. The OpTracker now renders one plain line per state
transition (start / done / failed) instead of the spinner when
interactive is false.
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