Conversation
|
Updated 6:13 PM PT - Aug 20th, 2026
✅ @robobun, your commit 18a490702c76d3496d20f8817355f10383abd6ca passed in 🧪 To try this PR locally: bunx bun-pr 29509That installs a local version of the PR into your bun-29509 --bun |
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
WalkthroughAdds a new Changes
🚥 Pre-merge checks | ✅ 2✅ Passed checks (2 passed)
Comment |
|
Found 2 issues this PR may fix:
🤖 Generated with Claude Code |
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/cli/pm_fetch_command.zig`:
- Around line 73-85: The current dep-edge lookup inside the dep_id: block
repeatedly scans lockfile.buffers.resolutions (via dep_resolutions and pkg_id)
for each package, making the algorithm quadratic; precompute a reverse index
once before the package loop (e.g., map from resolution package id to array/list
of dependency indices) and then replace the inner scan in the dep_id: block to
O(1) access into that index (referencing lockfile.buffers.resolutions,
dep_resolutions, pkg_id, and lockfile.buffers.dependencies.items); ensure the
index honors the same priority logic (preferred required edge else first
optional) so the subsequent logic that checks deps[id].behavior.isRequired() and
the first optional selection remains identical.
- Around line 100-105: The InvalidURL branch in the fetch error handler
currently just logs via Output.warn and continue, allowing cold-cache runs to
exit 0 despite missing packages; instead, in the catch |err| switch (err) for
the fetch logic (the block that calls bun.outOfMemory()), replace the simple
warn+continue behavior for error.InvalidURL with a concrete failure or fallback:
either enqueue the package using the manifest tarball path (fallback to
manifest-resolved URL) or record an install error via your install-error
reporting API (e.g., call the same error-recording mechanism used elsewhere) and
propagate a non-success status so the run fails; make the same change for the
other identical branches referenced (the blocks around the same switch at the
other locations mentioned).
- Around line 54-65: The switch in pm_fetch_command.zig incorrectly treats the
.calc_patch_hash case as already cached; change the switch handling so that
.calc_patch_hash is removed from the .apply_patch group and instead handled like
.extract (i.e., do not increment already_cached or continue for
.calc_patch_hash). Keep .done behavior the same, keep .apply_patch grouped with
the behavior that really implies the tarball is present, and ensure
pm.determinePreinstallState’s .calc_patch_hash falls through to the
extraction/fetch path so missing tarballs are fetched.
In `@test/cli/install/bun-pm-fetch.test.ts`:
- Line 52: The test defines a snake_case variable cache_dir; rename it to
camelCase cacheDir throughout test/cli/install/bun-pm-fetch.test.ts (including
the other occurrences referenced) and update every reference/usage (assignments,
joins, and any assertions) to use cacheDir so the file follows the repo's
TypeScript camelCase naming convention.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 7e65a253-de5c-4043-95eb-5237f6a42d20
📒 Files selected for processing (3)
src/cli/pm_fetch_command.zigsrc/install/PackageManager/runTasks.zigtest/cli/install/bun-pm-fetch.test.ts
|
✅ No merge conflicts detected when merging into Your branch is good to go! |
3 similar comments
|
✅ No merge conflicts detected when merging into Your branch is good to go! |
|
✅ No merge conflicts detected when merging into Your branch is good to go! |
|
✅ No merge conflicts detected when merging into Your branch is good to go! |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/cli/pm_fetch_command.zig`:
- Around line 88-96: The code currently silently continues when encountering
states like .calc_patch_hash (and
.calcing_patch_hash/.unknown/.extracting/.applying_patch) which can hide
unexpected cache-miss cases; update the match branch that currently does "=>
continue" to emit a diagnostic (debug or warning) when state == .calc_patch_hash
(and similarly for the other unexpected states) including identifying info
(package name or id and pass number) using the existing logger in scope (the
same logger used elsewhere in pm_fetch_command.zig / installWithManager), then
continue as before so the behavior is unchanged but diagnosable.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: b102f3b5-cbab-44bc-b819-a6eb04709012
📒 Files selected for processing (1)
src/cli/pm_fetch_command.zig
d623496 to
fe626ca
Compare
fe626ca to
b88c15c
Compare
2619307 to
82d83d7
Compare
StatusRebased onto current main (3ecf625), plus bfa1ffc (review fixes: idempotent Verified locally on the rebased branch:
Review threads: all resolved; the automated review of 8574446 found nothing further and asks for a human look at the design (the two points are summarized in the comment below). Rebased again onto current main (now 89a620a; Earlier CI history (pre-rebase builds)On the previous revision (88d1bc9), builds #64919 and #64929 were red only on the macOS aarch64 test lanes: a |
e570e6e to
a96ab71
Compare
a96ab71 to
359779d
Compare
|
Rebased onto main (359779d). This one was non-trivial: main removed every The PR now contains only:
Two API renames on main were picked up: Verified: |
|
Pushed 88d1bc9 addressing both review findings:
|
|
Pushed bfa1ffc for the two review findings on 3ecf625:
Both threads are resolved; the PR description's verification section is updated. Locally: 6/6 tests, clippy and fmt clean. |
|
Pushed 95d7313 for the docs/completions finding:
All review threads are resolved; PR description updated. The branch is now |
|
Pushed 7d02031 for the two findings on 95d7313:
Threads resolved, description updated. Locally 8/8 tests, clippy and fmt clean. |
|
Pushed 46737f3 for the lockfile finding on 95d7313 / 7d02031. It turned out to be a real behavior bug rather than a docs wording issue, and wider than the reported case:
Thread resolved, description updated. Locally: bun-pm-fetch 10/10, migrate.test.ts 21/21, clippy and fmt clean. |
|
Pushed 8574446 for the |
There was a problem hiding this comment.
I reviewed this revision and the automated bug hunt found nothing new — all earlier inline findings (docs/completions, --no-summary, the lockfile format-migration write, --lockfile-only) are addressed with tests. Because this adds a new user-facing bun pm subcommand and changes shared bun install --dry-run behavior (the !dry_run gate on should_save_lockfile's migration branch), a human look at the API/design would still be worthwhile.
What was reviewed:
PopulatePackageCache.rs: dependency-edge mapping, preinstall-state handling, and theForTarballErrorarms — the enqueue paths mirror the installer's and errors surface viamanager.log/any_failed_to_install.install_with_manager.rs: the new!dry_rungate only affects the binary→text migration disjunct;--frozen-lockfilestill migrates (it doesn't setdry_run).runTasks.rs: the addedextracted_count += 1on git checkout also fires during regularbun install;extracted_countis otherwise only read for the progress bar total, so no summary regression.setup_global_diridempotency:global_bin_dirstartsFd::INVALIDand is only assigned here, so the early return is sound.
Extended reasoning...
Overview
This PR adds bun pm fetch, a new subcommand that resolves dependencies and downloads them into the install cache without touching node_modules, lifecycle scripts, package.json, or the lockfile. It spans 16 files: two new Rust files (PopulatePackageCache.rs in bun_install, pm_fetch_command.rs in the CLI), edits to install_with_manager.rs / runTasks.rs / PackageManagerDirectories.rs / PackageManagerOptions.rs, help text in two places, docs, four completion files, and ~300 lines of new tests. It also fixes a pre-existing bug where bun install --dry-run wrote bun.lock when migrating from package-lock.json.
Security risks
None identified. The command reuses the existing install_with_manager resolve/download machinery and the same enqueue functions the installer uses; no new parsing of untrusted input, no new filesystem paths derived from user data. The unsafe block reading ROOT_PACKAGE_JSON_PATH follows the same pattern as other bun pm subcommands and has a SAFETY comment.
Level of scrutiny
High. This is new user-facing CLI surface in the package manager (a critical, widely-exercised subsystem), and it changes behavior in shared code:
install_with_manager.rsnow gates the lockfile format-migration write on!dry_run, which changesbun install --dry-runsemantics for projects withpackage-lock.jsonorbun.lockb+saveTextLockfile. This is arguably a bug fix, but it's a behavior change to an existing command that a maintainer should confirm.runTasks.rsnow incrementsextracted_countand callsanalytics::Features::extracted_packages_inc()on the git-checkout success path, which affects everybun install(progress bar totals and analytics), not justbun pm fetch.- The design decision to skip already-pinned
git:dependencies (with a printed note) rather than implementing a checkout-into-cache path is a UX/scope call a maintainer should weigh in on.
Other factors
The PR went through five rounds of review feedback, each surfacing an edge case (missing docs/completions, --no-summary not honored, lockfile written on the migration path, lockfile written on bun.lockb + saveTextLockfile, --lockfile-only bypass). All were fixed with dedicated tests, and this run's bug hunt found nothing further. Test coverage is thorough for the paths exercised (fresh project, existing lockfile, warm cache, package-lock.json migration, bun.lockb migration, --lockfile-only, --no-summary/--silent, -g, help text). The iteration history and the scope of shared-code changes are exactly why a human should sign off on the final shape rather than an automated approval.
|
Automated review is clean as of 8574446 (all earlier findings fixed with tests). For whoever picks this up, the two judgment calls in the diff that are worth a deliberate look, since the rest is mechanical:
|
8574446 to
89a620a
Compare
|
Rebased onto current main (89a620a). Conflicts were all adjacency with #38333 ( Two things from main that this PR picks up without code changes: Rebuilt and re-ran: |
There was a problem hiding this comment.
I reviewed this PR again after the fixes for the earlier findings and found no new issues. Because it adds a new user-facing bun pm subcommand and changes bun install --dry-run behavior (the format-migration branch of should_save_lockfile is now gated on !dry_run), a human sign-off on the two judgment calls the author flagged — skipping already-pinned git dependencies, and the --dry-run migration change — would still be worthwhile.
What was reviewed:
- The three lockfile-write paths in
install_with_manager(normal save, format migration,--lockfile-only) — each now covered by a directory-listing test. setup_global_diridempotency and thebun pm -g fetchdouble-call path.--no-summary/--silentgating and theextracted_countincrement on git checkout inrunTasks.rs.- Test file: every spawn drains stdout/stderr/exit concurrently, uses the local dummy registry, and asserts full snapshots.
Extended reasoning...
Overview
This PR adds bun pm fetch, a new user-facing subcommand that downloads all dependencies into Bun's install cache without writing node_modules, running scripts, or touching package.json / the lockfile. It consists of two new files (pm_fetch_command.rs, ~96 lines; PopulatePackageCache.rs, ~180 lines), small edits to five shared install files, docs, four completion files, and a ~290-line test file plus one test in migrate.test.ts.
The shared-code changes are: (1) install_with_manager.rs — the format-migration disjunct of should_save_lockfile is now additionally gated on !options.dry_run, and wait_for_everything_except_peers becomes pub(crate); (2) runTasks.rs — a successful git checkout now increments extracted_count and the analytics counter, mirroring the npm extract path; (3) PackageManagerDirectories.rs — setup_global_dir returns early if global_bin_dir is already open; (4) PackageManagerOptions.rs — lockfile_only widened from pub(crate) to pub.
Security risks
None identified. The command reuses the existing resolve and download machinery unchanged; the new code enqueues tarballs by the URLs already stored in the lockfile via the same enqueue_* helpers bun install uses, and does no new parsing of untrusted input. The visibility widenings (lockfile_only to pub, wait_for_everything_except_peers to pub(crate)) don't expose anything security-relevant.
Level of scrutiny
Medium-high. This is a new user-facing CLI surface (name, semantics, output format, and the documented git-dependency caveat are all API decisions), and one of the shared-code edits changes the behavior of an existing command: bun install --dry-run on a project with only a package-lock.json (or a bun.lockb with saveTextLockfile = true) previously wrote a bun.lock and now does not. That change is defensible and has a test in migrate.test.ts, but it is a user-visible behavior change to bun install riding in on a feature PR, and --frozen-lockfile is deliberately unaffected — a maintainer should confirm that split is intended.
Other factors
The PR went through several rounds of automated review; every earlier finding (setup_global_dir double-open, undrained pipes, --no-summary, the format-migration and --lockfile-only lockfile-write bypasses, the AlreadyFailed comment) was fixed with a test that fails on the prior revision. Test coverage is thorough for the happy paths and the specific edge cases raised. The author's own closing comment explicitly flags two judgment calls for a human: skipping already-pinned git: dependencies rather than teaching run_tasks a checkout-only mode, and the --dry-run gate on the migration branch. Given those open design questions and the size of the new surface, deferring to a human reviewer rather than auto-approving.
|
Rebased onto current main (8326d1b). The only conflicts were the two insertion points Unrelated observation while resolving: #39229 added |
89a620a to
f087da3
Compare
There was a problem hiding this comment.
Automated review is clean on this revision — no new findings. This adds a new user-facing bun pm subcommand and changes bun install --dry-run behavior around lockfile migration, so a human sign-off on the two design calls the author flagged (skipping already-pinned git dependencies, and the !dry_run gate on saves_migrated_lockfile) is still worth having.
What was reviewed:
PopulatePackageCache.rs: dependency-edge indexing, preinstall-state handling, enqueue paths per resolution tag, and thewait_for_everything_except_peersreuse.pm_fetch_command.rs: all three lockfile-write bypasses (Do::SAVE_LOCKFILE, format migration viadry_run,--lockfile-only) are now closed and covered by directory-listing tests.setup_global_diridempotence and therunTasks.rsgit-checkoutextracted_countincrement — both look correct.- Tests drain stdout/stderr/exit concurrently, use a local registry, and snapshot full stdout.
Extended reasoning...
Overview
This PR adds bun pm fetch, a new subcommand that resolves dependencies and downloads them into the install cache without touching node_modules, lifecycle scripts, package.json, or the lockfile. It touches 16 files: two new Rust files (PopulatePackageCache.rs ~180 lines, pm_fetch_command.rs ~96 lines), small edits to five existing package-manager Rust files, docs, four completion files, and two test files (~290 new test lines, one new case in migrate.test.ts).
The changes to existing code are: (1) install_with_manager.rs gates the saves_migrated_lockfile branch of should_save_lockfile on !dry_run, which also changes bun install --dry-run (previously wrote a bun.lock when migrating from package-lock.json); (2) wait_for_everything_except_peers becomes pub(crate); (3) runTasks.rs increments extracted_count on git checkout success (mirrors the npm extract path); (4) setup_global_dir is now idempotent; (5) lockfile_only becomes pub; (6) help text, docs, and completions gain the new subcommand.
Security risks
None identified. The command reuses the existing bun install resolve/download machinery and lockfile URLs; it introduces no new network parsing, no new user-controlled path handling, and no auth changes. unsafe in pm_fetch_command.rs reads a static written once during PackageManager::init on the same thread, with a SAFETY comment.
Level of scrutiny
Medium-high. This is new user-facing API surface in the package manager (a critical subsystem), and it changes behavior of an existing command (bun install --dry-run no longer writes a migrated lockfile). The author explicitly flagged two design decisions for a maintainer: whether skipping already-pinned git dependencies (with a printed note) is acceptable, and whether the !dry_run gate on the migration branch is the right layering. Per the repo's review guidance on API design and on fixing at the layer that owns the invariant, both deserve a deliberate human look rather than an automated approval.
Other factors
This PR has been through many automated review rounds; every prior finding (subprocess pipe draining, --no-summary handling, the three lockfile-write bypasses, docs/completions coverage, the AlreadyFailed comment) was fixed with a test. Test coverage is thorough: fresh project, existing lockfile + cold cache, warm cache, package-lock.json migration, lockb+saveTextLockfile, --lockfile-only, --no-summary/--silent, -g, and both help copies. The bug hunting system found nothing on this revision. All review threads are resolved. The remaining reason to defer is the scope (new subcommand + behavior change to --dry-run), not any specific concern with the implementation.
Downloads every dependency into the global cache without installing anything into node_modules, running lifecycle scripts, or writing package.json / the lockfile. Useful for warming the cache in CI images and for preparing offline installs. The command runs the normal resolve phase with `Do::INSTALL_PACKAGES` (and the other write/side-effect flags) cleared, which also downloads any package that was not already pinned by the lockfile. It then runs `populate_package_cache`, which walks the lockfile and downloads the packages the resolve phase skipped because they were already resolved, reusing the same enqueue functions and wait loop as `bun install`. `git:` dependencies that are already pinned are left to `bun install`: outside of the package installer a finished clone is only used as a resolve result, so there is no checkout step to populate the cache. Successful git checkouts now count toward `extracted_count`, matching the npm extract path, so git packages fetched during the resolve phase show up in the summary. `bun pm --help` and a bare `bun pm` print separate copies of the subcommand list; both now list `fetch`.
`bun pm -g fetch` reaches setup_global_dir twice (the `bun pm` dispatcher and install_with_manager), and each call opened a fresh bin directory fd while orphaning the previous one. Return early once global_bin_dir is set. The banner is now followed by a blank line like `bun install`'s. Tests drain stdout/stderr concurrently, snapshot the full stdout, assert the exact stderr of the lockfile and warm-cache runs, and cover `-g`.
Adds a `## fetch` section to docs/pm/cli/pm.mdx and the subcommand to bun-cli.json (the entry the generator produces; a full regeneration would rewrite ~1300 unrelated lines) and to the bash/fish/zsh lists. The fresh-fetch test now also runs `bun install` afterwards and checks it makes no registry requests.
The banner already went through should_print_command_name(), which is off under both --silent and --no-summary, but the "Fetched ..." and "Cache: ..." lines only checked for --silent. Use the same answer for both, captured before the Do flags are cleared for the resolve pass. Also split the AlreadyFailed arm off with an accurate comment: packages whose download failed during the resolve pass stay in the Extracting state and are skipped before anything is enqueued, so that error is not how pass 1 failures reach this code.
Clearing Do::SAVE_LOCKFILE is not enough to keep install_with_manager from writing a lockfile: the format-migration branch of should_save_lockfile (binary or migrated lockfile loaded, text format to be saved) ignores that flag on purpose so --frozen-lockfile still migrates. `bun pm fetch` in a project with only a package-lock.json therefore wrote a bun.lock, and with a bun.lockb plus saveTextLockfile=true it replaced the lockb with bun.lock. `bun install --dry-run` had the same problem in the package-lock.json case. Gate that branch on !dry_run and mark fetch as a dry run, which is what it is. Tests cover both fetch cases and the --dry-run case; all three fail without the change.
--lockfile-only is a shared `bun pm` flag and install_with_manager acts on it before looking at the Do flags, so `bun pm --lockfile-only fetch` wrote a lockfile. Clear it like the other install side effects; the packages it would have skipped prefetching are picked up by the second pass anyway.
|
Rebased onto current main (18a4907). One conflict: #39770 replaced the |
f087da3 to
18a4907
Compare
There was a problem hiding this comment.
I reviewed this PR and the automated pass found no bugs; all earlier findings (lockfile-write bypasses via format migration and --lockfile-only, --no-summary, double setup_global_dir, docs/completions) have been fixed with tests. Because it adds a new user-facing subcommand, changes bun install --dry-run behavior via the !dry_run gate on saves_migrated_lockfile, and skips already-pinned git dependencies by design, a human look at those two calls is still worthwhile.
What was reviewed:
PopulatePackageCache.rs: dependency-edge mapping, preinstall-state gating, enqueue error handling, and the wait loop reuse — matchesinstall_with_manager's shape.pm_fetch_command.rs: every lockfile-write path in pass 1 (Do::SAVE_LOCKFILE, migration branch,--lockfile-only) is closed and covered by a directory-listing test.runTasks.rsgit-checkoutextracted_countincrement mirrors the npm extract path; only affects the progress total for regular installs.setup_global_diridempotency guard checked against its only other caller.
Extended reasoning...
Overview
Adds bun pm fetch (analogue of pnpm fetch): resolve + download all dependencies into the install cache without writing node_modules, lifecycle scripts, package.json, or the lockfile. 16 files: two new (PopulatePackageCache.rs, pm_fetch_command.rs), edits to install_with_manager.rs / runTasks.rs / PackageManagerDirectories.rs / PackageManagerOptions.rs, help text in two places, docs, four completion files, and two test files (11 new tests plus one --dry-run migration test).
Security risks
None identified. No new parsing of untrusted input; downloads go through the existing enqueue helpers keyed by lockfile URLs. No auth/crypto/permissions code touched.
Level of scrutiny
High — this is new user-facing API surface in the package manager, and it makes a small behavior change to an existing command: install_with_manager's should_save_lockfile migration branch is now gated on !options.dry_run, so bun install --dry-run no longer writes a bun.lock when migrating from package-lock.json or a binary lockfile. That is arguably a bug fix, and it has a test in migrate.test.ts, but it is a shared-path change a maintainer should sign off on. The author also flagged the decision to skip already-pinned git: dependencies (with a printed note) rather than teaching run_tasks a checkout-only mode.
Other factors
Every earlier automated finding on this PR was addressed with a failing-then-passing test; the test file covers fresh project, existing lockfile + cold cache, warm cache, package-lock.json migration, bun.lockb + saveTextLockfile, --lockfile-only, --no-summary/--silent, -g, and both help copies. The three rebases since the last review round were adjacency-only (bun pm licenses, bun pm diff, and the has_on_extract refactor). The lockfile_only field visibility widened from pub(crate) to pub so the CLI shim in bun_runtime can clear it — consistent with the neighboring dry_run field. The setup_global_dir early-return is safe: the only other caller is install_with_manager, and global_bin_dir starts at Fd::INVALID.
Given the new API surface and the two author-flagged design calls, deferring to a human rather than approving.
What
Adds
bun pm fetch, a new subcommand that resolves all dependencies and downloads them into Bun's install cache without writingnode_modules, running lifecycle scripts, or writingpackage.json/ the lockfile.Why
Useful for:
node_modulesSimilar to
pnpm fetch.How
Two passes, both reusing the
bun installmachinery:src/runtime/cli/pm_fetch_command.rs(the CLI shim) clearsDo::INSTALL_PACKAGES,RUN_SCRIPTS,WRITE_PACKAGE_JSON,SAVE_LOCKFILE,SAVE_YARN_LOCKandSUMMARY, then runs the normalinstall_with_manager. The resolve phase already downloads the tarball of every package it resolves for the first time, so this pass covers everything that was not pinned by the lockfile yet. The shim also marks the run as a dry run:should_save_lockfileininstall_with_managerhas a lockfile format-migration branch (saves_migrated_lockfile: binary or migrated lockfile loaded, text lockfile to be written) that deliberately ignoresDo::SAVE_LOCKFILEso--frozen-lockfilestill migrates. Without this,bun pm fetchwrote abun.lockin projects that only have apackage-lock.json, and replaced abun.lockbwithbun.lockwhensaveTextLockfileis set. That branch is now gated on!dry_run, which also fixesbun install --dry-runwriting abun.lockin the package-lock.json case.--lockfile-only(also a sharedbun pmflag, acted on before theDoflags) is cleared as well.src/install/PackageManager/PopulatePackageCache.rs(populate_package_cache, next to the existingPopulateManifestCache.rs) walks the lockfile and enqueues a download for every package whosedetermine_preinstall_stateisExtract(npm / github / remote tarball / local tarball), using the URLs stored in the lockfile (no manifest round-trips), then waits with the samewait_for_everything_except_peersloopbun installuses. It returns a smallSummary(fetched,already_cached,skipped_git) that the shim prints. Living insidebun_installmeans it uses the crate-internal enqueue APIs directly; the only visibility change iswait_for_everything_except_peersbecomingpub(crate).Packages are mapped back to a dependency edge (preferring a required edge) because the enqueue functions and the download-failure reporting are keyed by dependency, not package.
git:dependencies that are already pinned are skipped with a note: outside of the package installer a finished clone is only used as a resolve result, so there is no checkout step that would populate the cache. Git dependencies resolved for the first time are still cached by pass 1.runTasks.rsnow incrementsextracted_counton a successful git checkout, mirroring the npm extract path, so git packages fetched during pass 1 are reflected in the summary (extracted_countis otherwise only used for the progress bar total).bun pm --helpand a barebun pmprint separate copies of the subcommand list (src/install/PackageManager.rsandsrc/runtime/cli/package_manager_command.rs); both now listfetch.setup_global_dirnow returns early once the bin directory is open:bun pm -g fetchis the firstbun pmsubcommand to reachinstall_with_manager, which calls it a second time after thebun pmdispatcher already did, and each call used to open a fresh directory fd.Docs: new
## fetchsection indocs/pm/cli/pm.mdx. Completions: the subcommand is added tocompletions/bun-cli.json(the entry the generator emits; a full regeneration rewrites ~1300 unrelated lines) and to the bash/fish/zshbun pmlists.Verification
test/cli/install/bun-pm-fetch.test.ts(every spawn drains stdout/stderr/exit concurrently; stdout is compared against an inline snapshot):node_modules, nobun.lock/bun.lockbwritten; abun installrun afterwards makes zero registry requestsFetching packages(only the second pass ran), nonode_modulespackage-lock.json: fetches from the migrated lockfile's URL and leaves the directory listing unchanged (nobun.lock)bun.lockbplussaveTextLockfile = true: directory listing unchanged (the lockb is not migrated)--lockfile-only: ignored; directory listing unchanged, package still fetched--no-summaryand--silent: nothing on stdout (and nothing on stderr for--silent), but the fetch still happensbun pm -g fetch: fetches the global install's dependencies (exercises bothsetup_global_dircall sites), leaves the global directory untouchedbun pmandbun pm --helplist the commandtest/cli/install/migration/migrate.test.tsgains abun install --dry-runcase for the package-lock.json migration (nobun.lockwritten).All of them fail on a bun without this change (
fetchis an unknownbun pmsubcommand; the--dry-runtest fails because abun.lockis written) and pass on this branch. Also run locally:bun-pm.test.ts(18/18),test/internal/source-lints(98/98),cargo clippy -p bun_install -p bun_runtime,cargo fmt --check.Related to #6353
Related to #7956
no test proof · iteration 22 · Platform-specific test(s) that do not run on this machine. Deferring to CI, which covers all platforms: test/cli/install/migration/migrate.test.ts