Skip to content

run: collapse a silent successful script to one line in the --filter renderer - #41197

Closed
robobun wants to merge 2 commits into
mainfrom
robobun/861e0a34/filter-collapse-silent-success
Closed

robobun wants to merge 2 commits into
mainfrom
robobun/861e0a34/filter-collapse-silent-success

Conversation

@robobun

@robobun robobun commented Sep 2, 2026 •

Copy link
Copy Markdown
Collaborator

Problem

  • Fixes Make bun run --filter output more concise for scripts with no output #41196. With bun run --filter, every successful script takes two lines in the terminal renderer, even when it prints nothing: dep0 script $ exit 0 plus └─ Done in 1 ms. In a monorepo with many packages, an incremental build fills the screen with these pairs.
  • The renderer (State::redraw() in src/runtime/cli/filter_run.rs) always writes the header and footer, with no case for a script that produced no output.

Fix

  • When a script has exited with code 0 and its output buffer is empty, redraw() now renders one line: dep0 script · Done in 1 ms. Scripts with any output, and scripts that fail, keep the expanded header, body, and footer.
  • The change is limited to the interactive terminal renderer. The non-TTY streaming path is untouched.
  • The Done in N ms timing block is extracted into a write_done helper, used by both the collapsed and the expanded form.
  • Verified: test/cli/run/filter-workspace.test.ts (one updated test plus two new ones, the collapse test fails on stock bun). The whole file passes with the debug build (88 pass).

Background

Notes
  • The collapse keys on handle.buffer.is_empty() plus Status::Exited with code 0. In the pretty path the buffer is append-only during the run, so a script that printed anything can never collapse.
  • The tests assert on the final repaint frame: the renderer repaints the whole display per event inside synchronized-update markers (\x1b[?2026h / \x1b[?2026l), so the test splits on the end marker, takes the last frame, and strips ANSI escapes.
  • Suites run: bun bd test test/cli/run/filter-workspace.test.ts (88 pass, 2 skip). cargo check -p bun_runtime clean.
  • Self-reviewed: the surviving concerns were all about the test-file overlap with test(filter-workspace): run the cases concurrently and assert the exact output #41033, none about the code change.

no test proof · iteration 1 · platform-specific test(s) that do not run on this machine, deferring to CI, which covers all platforms: test/cli/run/filter-workspace.test.ts

@coderabbitai

coderabbitai Bot commented Sep 2, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Essentials

Run ID: f8ff0a63-0175-4737-9534-ef5cf2a057d0

📥 Commits

Reviewing files that changed from the base of the PR and between d6af50f and e4a596b.

📒 Files selected for processing (2)
  • src/runtime/cli/filter_run.rs
  • test/cli/run/filter-workspace.test.ts

Included review availability: Your plan provides up to 10 included reviews per hour; 8 remain after this review.


Walkthrough

The filtered workspace runner centralizes successful completion timing output. Silent successful scripts now render as one compact line. Tests cover compact success, expanded success with output, and expanded failure cases.

Changes

Filtered run output

Layer / File(s) Summary
Centralized completion timing
src/runtime/cli/filter_run.rs
The private write_done helper formats elapsed durations and provides a fallback completion message. Successful-exit rendering now uses this helper.
Compact successful rendering and terminal validation
src/runtime/cli/filter_run.rs, test/cli/run/filter-workspace.test.ts
Successful scripts without output render on one line. Tests parse final terminal frames and verify compact success, expanded success with output, expanded failure, and exit codes.

Suggested reviewers: dylan-conway, jarred-sumner

Merge Risk: ⚪ Minimal · up to e4a59

This localized renderer change collapses only silent successful scripts while preserving output and failure rendering; no actionable merge-blocking risk remains, so it is merge-ready after normal checks.

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The changes satisfy the primary collapse objective in issue #41196. Silent successful scripts use a compact single-line form, scripts with output and failed scripts retain expanded output, and non-TTY…
Out of Scope Changes check ✅ Passed The code and test changes remain within issue #41196. They update only the interactive --filter renderer, centralize completion formatting, and add coverage for the affected success and failure cases.
Title check ✅ Passed The title clearly and concisely describes the main change: collapsing silent successful scripts to one line in the --filter renderer.
Description check ✅ Passed The description explains the problem, fix, scope, test coverage, verification results, and known limitations. It does not use the exact template headings, but it provides the required information and …
Full details: Linked Issues check

Explanation

The changes satisfy the primary collapse objective in issue #41196. Silent successful scripts use a compact single-line form, scripts with output and failed scripts retain expanded output, and non-TTY behavior remains unchanged. The optional --hide-silent proposal is explicitly excluded from this PR.

Full details: Description check

Explanation

The description explains the problem, fix, scope, test coverage, verification results, and known limitations. It does not use the exact template headings, but it provides the required information and is mostly complete.


Comment @coderabbitai help to get the list of available commands.

@claude claude Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM — small, focused renderer tweak with the right test coverage.

What was reviewed:

  • write_done is a pure extraction, byte-identical to the removed inline block; both call sites wired.
  • Collapsed path gates on buffer.is_empty() + Status::Exited + code == 0 and continues — the is_abort branch below is unaffected (nothing to expand when the buffer is empty anyway).
  • Tests anchor the whole final frame (^…$) for all three variants (silent-success, noisy-success, silent-fail), assert frame before exit code, and reuse the file's existing spawnSync + FORCE_COLOR/skipIf(isWindows) pattern.
Extended reasoning...

Overview

This PR touches two files: src/runtime/cli/filter_run.rs (the interactive terminal renderer for bun run --filter) and test/cli/run/filter-workspace.test.ts. The Rust change extracts the existing "Done in N ms/s" formatting into a write_done associated function and adds an early continue in the per-handle redraw loop that renders a compact one-line form (pkg script · Done in N ms) when a script exited with code 0 and produced no output. The expanded box form (header + │ body + └─ footer) is unchanged for scripts with output or nonzero exit. The test change replaces a single loose toMatch(/Done in .../) assertion with a runTerminalRenderTest helper plus lastTerminalFrame (split on the synchronized-update end marker, strip ANSI), and asserts the exact final frame for three cases.

Security risks

None. This is display-only formatting in the pretty terminal renderer — no input parsing, no filesystem/network operations, no unsafe blocks, no user-controlled data reaching a trust boundary. The only inputs are the already-captured package/script names and the process's own output buffer, both handled identically to the surrounding code.

Level of scrutiny

Low. The write_done extraction is byte-for-byte identical to the removed inline block (same fmt! strings, same ms/s threshold, same end_time.is_none() fallback). The new collapsed branch is a narrow additive guard that only fires on buffer.is_empty() && Status::Exited && code == 0, uses the same fmt!/bstr::BStr idioms and ? propagation as the neighboring header write, and continues cleanly. I checked that skipping the is_abort-driven elide_lines = None path is harmless here since an empty buffer has nothing to elide. No CODEOWNERS cover these paths.

Other factors

Test quality is good per REVIEW.md: the new tests anchor the entire final frame with ^…$ (strongest invariant, not toContain), cover the three-way variant matrix (collapsed vs. two expanded forms), assert output before exit code, use tempDir/bunExe/bunEnv, and follow the file's existing spawnSync + FORCE_COLOR: "1" + test.skipIf(isWindows) convention already used by runElideLinesTest in the same file. The ANSI-stripping regex /\x1b\[[0-9;?]*[a-zA-Z]/g correctly handles both color/cursor CSI sequences and the ?2026h start marker. The PR description states the collapse test fails on stock bun and the full file passes on the debug build. Bug hunt exited on dry_streak with no findings and no ruled-out candidates.

@robobun

robobun commented Sep 4, 2026

Copy link
Copy Markdown
Collaborator Author

Closing in favor of #41325. That PR rewrites the same renderer and puts the status on the header line. A script that exits 0 with no output then takes one line, for example quiet build $ true [2 ms]. I checked this with a debug build of #41325 in a pty, both while another script still runs and in the final output. The --hide-silent flag from #41196 is not part of either PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Make bun run --filter output more concise for scripts with no output

1 participant