Skip to content

cli(test): make --coverage/--coverage-reporter/--coverage-dir override bunfig - #36669

Closed
robobun wants to merge 4 commits into
mainfrom
farm/71602ccb/coverage-cli-over-bunfig
Closed

robobun wants to merge 4 commits into
mainfrom
farm/71602ccb/coverage-cli-over-bunfig

Conversation

@robobun

@robobun robobun commented Aug 1, 2026 •

Copy link
Copy Markdown
Collaborator

Repro

# bunfig.toml
[test]
coverage = false
bun test --coverage   # no coverage table printed

Cause

parse_test_command_options (CLI flags) runs before load_config_with_cmd_args (bunfig). The bunfig loader then wrote [test] coverage / coverageReporter / coverageDir into ctx.test_options unconditionally, so the config value clobbered an explicit CLI flag. The if !ctx.test_options.coverage.enabled guard on the CLI side was dead because bunfig had not loaded yet.

Fix

Record whether each of --coverage / --coverage-reporter / --coverage-dir was passed on the CLI (same pattern the codebase already uses for path_ignore_patterns_from_cli) and have the bunfig loader skip the assignment when the corresponding CLI flag was seen.

Scope

This PR covers the coverage-family keys from #12216. The same clobber mechanism also applies to other [test] keys (onlyFailures, reporter.dots, randomize, rerunEach, retry, seed); those are pre-existing and intentionally deferred to a follow-up to keep this change reviewable.

Verification

USE_SYSTEM_BUN=1 bun test test/cli/test/coverage.test.ts -t "overrides bunfig"   # 3 fail
bun bd test test/cli/test/coverage.test.ts                                       # 16 pass
bun bd test test/cli/bunfig-test-options.test.ts                                 # 5 pass

Supersedes the coverage half of #28547 (stale, conflicting, bundles an unrelated fix).

Closes #12216


[review] gate passed · iteration 2 · 4 files touched

fails on main (without fix)
ASAN without fix: 3 FAILED
$ BUN_DEBUG_QUIET_LOGS=1 bun scripts/build.ts --profile=debug --quiet test "--reporter=junit" "--reporter-outfile=/tmp/mechgate.xml" test/cli/test/coverage.test.ts
bun test v1.4.1 (4448a2e21)

test/cli/test/coverage.test.ts:
bun test v1.4.1 (4448a2e21)

demo.test.ts:
--------------|---------|---------|-------------------
File          | % Funcs | % Lines | Uncovered Line #s
--------------|---------|---------|-------------------
All files     |    0.00 |   66.67 |
 demo.test.ts |    0.00 |   66.67 | 
--------------|---------|---------|-------------------

 0 pass
 0 fail
Ran 0 tests across 1 file. [311.00ms]
(pass) coverage crash [436.53ms]
bun test v1.4.1 (4448a2e21)

demo2.ts:

 0 pass
 0 fail
Ran 0 tests across 1 file. [244.00ms]
(pass) lcov coverage reporter [307.73ms]
(pass) coverage excludes node_modules directory [407.55ms]
(pass) coveragePathIgnorePatterns - single pattern string [381.01ms]
(pass) coveragePathIgnorePatterns - partial coverage without nan [388.17ms]
(pass) coveragePathIgnorePatterns - array of patterns [452.25ms]
(pass) coveragePathIgnorePatterns - glob patterns [484.10ms]
(pass) coveragePathIgnorePatterns - lcov reporter [405.01ms]
(pass) cov
... (truncated)

release without fix: 4 FAILED
bun test v1.4.0-canary.1 (4448a2e21)

test/cli/test/coverage.test.ts:
bun test v1.4.0-canary.1 (4448a2e21)

demo.test.ts:

 0 pass
 0 fail
Ran 0 tests across 1 file. [5.00ms]
(pass) coverage crash [16.45ms]
bun test v1.4.0-canary.1 (4448a2e21)

demo2.ts:

 0 pass
 0 fail
Ran 0 tests across 1 file. [11.00ms]
(pass) lcov coverage reporter [18.24ms]
(pass) coverage excludes node_modules directory [13.55ms]
(pass) coveragePathIgnorePatterns - single pattern string [11.72ms]
(pass) coveragePathIgnorePatterns - partial coverage without nan [16.52ms]
(pass) coveragePathIgnorePatterns - array of patterns [15.64ms]
(pass) coveragePathIgnorePatterns - glob patterns [20.12ms]
(pass) coveragePathIgnorePatterns - lcov reporter [15.99ms]
(pass) coveragePathIgnorePatterns - invalid config type [8.88ms]
(pass) coveragePathIgnorePatterns - invalid array item [4.50ms]
(pass) coveragePathIgnorePatterns - empty array [13.40ms]
(pass) coveragePathIgnorePatterns - ignore all files [20.54ms]
633 | 
634 |   const lcov = readFileSync(path.join(String(dir), "coverage", "lcov.info"), "utf-8");
635 |   const record = lcov.split("end_of_record").find(r => r.includes("SF:subject.ts"));
636 |   e
... (truncated)
passes on PR (with fix)
ASAN with fix: all passed
$ BUN_DEBUG_QUIET_LOGS=1 bun scripts/build.ts --profile=debug --quiet test "--reporter=junit" "--reporter-outfile=/tmp/mechgate.xml" test/cli/test/coverage.test.ts
bun test v1.4.1 (4448a2e21)

test/cli/test/coverage.test.ts:
bun test v1.4.1 (4448a2e21)

demo.test.ts:
--------------|---------|---------|-------------------
File          | % Funcs | % Lines | Uncovered Line #s
--------------|---------|---------|-------------------
All files     |    0.00 |   66.67 |
 demo.test.ts |    0.00 |   66.67 | 
--------------|---------|---------|-------------------

 0 pass
 0 fail
Ran 0 tests across 1 file. [290.00ms]
(pass) coverage crash [388.37ms]
bun test v1.4.1 (4448a2e21)

demo2.ts:

 0 pass
 0 fail
Ran 0 tests across 1 file. [299.00ms]
(pass) lcov coverage reporter [364.89ms]
(pass) coverage excludes node_modules directory [262.13ms]
(pass) coveragePathIgnorePatterns - single pattern string [309.11ms]
(pass) coveragePathIgnorePatterns - partial coverage without nan [300.46ms]
(pass) coveragePathIgnorePatterns - array of patterns [307.65ms]
(pass) coveragePathIgnorePatterns - glob patterns [326.78ms]
(pass) coveragePathIgnorePatterns - lcov reporter [384.55ms]
(pass) cov
... (truncated)

release with fix: all passed
$ bun scripts/build.ts --profile=release
[configured] bun-profile → bun (stripped)
  target       linux-x64-gnu
  build type   Release
  build dir    ./build/release
  revision     9b5abba46e
  features     baseline

23 deps, 129 codegen, 1172 objects in 741ms

ninja: Entering directory `/workspace/bun/build/release'
[1/1244] install /workspace/bun
bun install v1.4.0-canary.1 (4448a2e21)

Checked 26 installs across 63 packages (no changes) [6.00ms]
[2/1244] install /workspace/bun/packages/bun-error
bun install v1.4.0-canary.1 (4448a2e21)

Checked 1 install across 2 packages (no changes) [1.00ms]
[3/1244] gen ErrorCode+*.h
[4/1244] install /workspace/bun/src/node-fallbacks
bun install v1.4.0-canary.1 (4448a2e21)

Checked 111 installs across 104 packages (no changes) [5.00ms]
[5/1244] gen node-fallbacks/react-refresh.js
Bundled 1 module in 9ms

  react-refresh.js  4.81 KB  (entry point)

[6/1244] gen bindgenv2
[7/1244] fetch tinycc
[tinycc] up to date
[8/1243] fetch libjpeg-turbo
[libjpeg-turbo] up to date
[9/1216] fetch zlib
[zlib] up to date
[10/1216] gen .bind.ts → GeneratedBindings.cpp
[11/1216] gen ProcessBindingConstants.lut.h
Generating /workspace/bun/build
... (truncated)
diff hotspot
src/bunfig/bunfig.rs           | 25 +++++++----
 src/options_types/context.rs   |  6 +++
 src/runtime/cli/Arguments.rs   |  7 +++-
 test/cli/test/coverage.test.ts | 95 +++++++++++++++++++++++++++++++++++++++++-
 4 files changed, 121 insertions(+), 12 deletions(-)

gate history · 2 passed · 0 rejected · iteration 2

evidence per changed file
file                            reads  edits  tests
src/bunfig/bunfig.rs                2      3      0
src/options_types/context.rs        1      2      0
src/runtime/cli/Arguments.rs        2      2      0
test/cli/test/coverage.test.ts      3      6      0

@robobun

robobun commented Aug 1, 2026 •

Copy link
Copy Markdown
Collaborator Author

Status: superseded by #40348. Closing this one.

#40348 moves the bun test flag parse below the bunfig load in Arguments::parse, so every [test] key is overridden by its flag with no per-key guard. That covers coverage, coverageReporter and coverageDir (this PR), plus the sibling keys this PR deferred (onlyFailures, reporter.dots, randomize, rerunEach, retry, seed), and it removes the path_ignore_patterns_from_cli idiom this PR adds three more of. The two cannot both merge.

If the reorder in #40348 is not wanted, this PR is a rebased, green, narrow alternative and can be reopened.

Reproduced with:

printf '[test]\ncoverage = false\n' > bunfig.toml
bun test --coverage   # no coverage table

@coderabbitai

coderabbitai Bot commented Aug 1, 2026 •

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

  • Run on-demand review

On-demand reviews are free for the next 27 days. After that, they cost $0.25 per reviewed file.

Or wait 20 minutes for your next included review.

View limit details

Limit details: You’ve used all 5 included reviews currently available.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: a556e3e2-396a-4601-963a-5957eabca8a2

📥 Commits

Reviewing files that changed from the base of the PR and between b746c07 and 9b5abba.

📒 Files selected for processing (4)
  • src/bunfig/bunfig.rs
  • src/options_types/context.rs
  • src/runtime/cli/Arguments.rs
  • test/cli/test/coverage.test.ts

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

@github-actions github-actions Bot added the claude label Aug 1, 2026
@robobun

robobun commented Aug 1, 2026 •

Copy link
Copy Markdown
Collaborator Author
Updated 11:31 AM PT - Aug 24th, 2026

@robobun, your commit 9b5abba is building: #105000

@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

This PR may be a duplicate of:

  1. Fix object loader missing default export and coverage CLI flag override #28547 - Also fixes Values in bunfig.toml take precedence over command line args #12216 by making CLI coverage flags (--coverage, --coverage-reporter, --coverage-dir) override bunfig.toml settings; touches the same three files (context.rs, Arguments.rs, bunfig.rs)

🤖 Generated with Claude Code

@robobun

robobun commented Aug 1, 2026

Copy link
Copy Markdown
Collaborator Author

Yes, known: #28547 is stale (March, now conflicting) and bundles an unrelated ObjectModule fix. This PR is a fresh, focused change for #12216 only and supersedes the coverage portion of that PR.

Comment thread src/bunfig/bunfig.rs
Comment thread src/bunfig/bunfig.rs
Comment thread test/regression/issue/12216.test.ts Outdated

@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 — thanks for addressing the three notes (Scope section, description tweak, and moving the tests into coverage.test.ts).

What was reviewed:

  • The three *_from_cli guards mirror the existing path_ignore_patterns_from_cli pattern; bunfig-only path (coverage = true with no CLI flag) still applies since the flags default to false.
  • --coverage CLI change: the removed if !ctx.test_options.coverage.enabled guard was dead (bunfig loads after CLI parsing), so switching to if args.flag(...) is behavior-preserving.
  • New tests cover all three flags plus the bunfig-only sanity case; each drains stdout/stderr concurrently and uses tempDir/bunEnv per harness conventions.
Extended reasoning...

Overview

Fixes #12216: --coverage, --coverage-reporter, and --coverage-dir were being clobbered by [test] bunfig values because CLI parsing runs before bunfig loading and the bunfig loader wrote unconditionally. The fix adds three bool fields to TestOptions (coverage_from_cli, coverage_reporter_from_cli, coverage_dir_from_cli), sets them in parse_test_command_options when the corresponding flag is present, and guards the three bunfig assignments on those flags. Four tests are added to test/cli/test/coverage.test.ts.

Security risks

None. This is CLI/bunfig option-precedence plumbing for the test runner's coverage settings; no untrusted input parsing, network, or filesystem-path handling changes.

Level of scrutiny

Low-to-moderate. The change is small (~30 net lines of Rust, ~90 lines of tests), mechanical, and copies the established path_ignore_patterns_from_cli pattern already in the same file/struct. The old if !ctx.test_options.coverage.enabled guard on the CLI side was provably dead (default is false and bunfig hasn't loaded yet), so replacing it with if args.flag(b"--coverage") is behavior-preserving for the CLI-only case. --coverage is a presence-only flag (no --no-coverage), so setting coverage_from_cli only when the flag is present is correct.

Other factors

All three prior review comments are resolved: the sibling [test] keys (onlyFailures, reporter.dots, randomize, rerunEach, retry, seed) are explicitly named in the PR description's Scope section as an intentional deferral; the stale description sentence about type validation was dropped; and the tests were moved from test/regression/issue/12216.test.ts into test/cli/test/coverage.test.ts per the test-organization convention. No CODEOWNERS-gated paths are touched. Tests follow harness conventions (tempDir, bunEnv, await using, concurrent stdout/stderr/exited drain, exit-code asserted last, test.concurrent for independent subprocess spawns).

@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 — all three prior review nits (sibling-key scope note, description wording, test file placement) have been addressed.

What was reviewed:

  • The three *_from_cli guards mirror the existing path_ignore_patterns_from_cli pattern; bunfig type validation still runs for coverage/coverageDir before the guard.
  • Confirmed the removed if !ctx.test_options.coverage.enabled CLI-side guard was dead (bunfig loads after CLI parsing), so dropping it doesn't change behavior when --coverage is absent.
  • New tests drain all pipes concurrently, assert output before exitCode, and include the negative control (coverage = true in bunfig with no CLI flag still enables coverage).
Extended reasoning...

Overview

The PR fixes #12216: bun test --coverage was clobbered by [test] coverage = false in bunfig because CLI flags are parsed before bunfig loads and the bunfig loader wrote unconditionally. The fix adds three boolean *_from_cli markers on TestOptions (coverage_from_cli, coverage_reporter_from_cli, coverage_dir_from_cli), sets them in parse_test_command_options when the corresponding flag is present, and gates the bunfig writes on them. Four subprocess tests are added to test/cli/test/coverage.test.ts. Total: ~30 lines of Rust across three files plus ~90 lines of tests.

Security risks

None. This is CLI/config precedence logic for the test runner's coverage reporting; no untrusted-input parsing paths, allocation sizes, or privileged operations are touched.

Level of scrutiny

Low-to-medium. The change is mechanical, follows an existing in-tree pattern (path_ignore_patterns_from_cli in the same struct/same bunfig block), and is confined to option plumbing. The one non-obvious edit — replacing if !ctx.test_options.coverage.enabled { ... = args.flag(...) } with if args.flag(...) { ... = true } — is safe because the old guard was always true at that point (bunfig hadn't loaded yet, so enabled was still its default false), so the flag-absent path is unchanged.

Other factors

I previously left three non-blocking comments on this PR; all were addressed: the PR description now has a Scope section deferring the sibling [test] keys, the inaccurate validation sentence was dropped, and the tests were moved from test/regression/issue/12216.test.ts into test/cli/test/coverage.test.ts. The new tests follow harness conventions (tempDir, bunEnv, test.concurrent, Promise.all on stdout/stderr/exited) and include a negative control confirming bunfig-only coverage = true still works. Verification section shows the tests fail under USE_SYSTEM_BUN=1 and pass under the debug build.

@robobun

robobun commented Aug 24, 2026

Copy link
Copy Markdown
Collaborator Author

#40348 moves the bun test flag parse below the bunfig load in Arguments::parse, so every [test] key (including coverage, coverageReporter and coverageDir) is overridden by its flag without a per-key guard. If that lands, the _from_cli flags here are not needed.

robobun and others added 4 commits August 24, 2026 18:27
…e bunfig

CLI test options are parsed before bunfig.toml is loaded, and the bunfig
loader was writing the [test] coverage/coverageReporter/coverageDir values
unconditionally, so an explicit CLI flag was clobbered by the config value.

Track whether each of these came from the CLI (same pattern as
path_ignore_patterns_from_cli) and skip the bunfig assignment when so.

Fixes #12216
Not a true regression (never worked), so per convention these belong next
to the other coverage CLI tests rather than under test/regression/issue/.
@robobun
robobun force-pushed the farm/71602ccb/coverage-cli-over-bunfig branch from 0114802 to 9b5abba Compare August 24, 2026 18:31

@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 fix that mirrors the existing path_ignore_patterns_from_cli pattern; all earlier nits have been addressed.

What was reviewed:

  • Confirmed the three *_from_cli guards match the established pathIgnorePatterns shape and that the removed if !coverage.enabled guard was dead (bunfig loads after CLI parse).
  • Checked that --coverage remains a set-true-only flag (no behavior change when the flag is absent) and that bunfig type validation still runs for coverage/coverageDir.
  • The four new tests cover CLI-overrides-bunfig for each flag plus the negative case (bunfig coverage = true still works with no CLI flag).
  • Noted the author's own heads-up about #40348; that's a possible follow-up simplification, not a blocker for this fix.
Extended reasoning...

Overview

The PR fixes #12216: --coverage, --coverage-reporter, and --coverage-dir were being clobbered by [test] bunfig values because CLI flag parsing runs before bunfig loading and the bunfig loader wrote unconditionally. The fix adds three *_from_cli booleans to TestOptions (src/options_types/context.rs), sets them in parse_test_command_options (src/runtime/cli/Arguments.rs), and guards the corresponding assignments in bunfig.rs. Four test.concurrent cases are added to test/cli/test/coverage.test.ts.

Security risks

None. This is CLI/bunfig option-precedence plumbing; no untrusted input parsing, auth, crypto, or filesystem-path handling is touched.

Level of scrutiny

Low-to-moderate. The change is ~30 src lines and mechanically copies the codebase's existing path_ignore_patterns_from_cli pattern (same struct, adjacent bunfig block). The removed if !ctx.test_options.coverage.enabled guard was provably dead — at that point in parse_test_command_options, bunfig has not loaded and coverage.enabled is always its default false, so the branch was always taken; replacing it with if args.flag(b"--coverage") is behavior-preserving for the no-flag case and correct for the flag case.

Other factors

  • All three prior inline nits from earlier runs were addressed: a Scope section now names the deferred sibling keys (onlyFailures, reporter.dots, randomize, rerunEach, retry, seed); the inaccurate description sentence about coverageReporter type validation was dropped; and the tests were moved from test/regression/issue/12216.test.ts into test/cli/test/coverage.test.ts.
  • Tests follow harness conventions (tempDir, bunEnv, concurrent pipe-drain, using, exit-code asserted last) and include a negative case verifying bunfig still applies when no CLI flag is passed.
  • The PR body's evidence shows the new tests fail on main (both ASAN and release) and pass with the fix.
  • No CODEOWNERS entries match the touched paths.
  • The author's note about #40348 (reordering flag parse after bunfig load) is a potential future simplification; it does not change the correctness of this fix and can remove the _from_cli flags later if it lands.

@robobun

robobun commented Aug 24, 2026

Copy link
Copy Markdown
Collaborator Author

Closing in favor of #40348, which fixes the CLI-vs-bunfig ordering for all [test] keys rather than guarding three of them. Reopen if the narrow fix is preferred.

@robobun robobun closed this Aug 24, 2026
@robobun

robobun commented Aug 24, 2026 •

Copy link
Copy Markdown
Collaborator Author

The three "overrides bunfig" coverage cases from this PR (--coverage, --coverage-reporter, --coverage-dir) pass on the #40348 branch and are now part of its test file, test/cli/bunfig-test-options.test.ts.

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.

Values in bunfig.toml take precedence over command line args

2 participants