install: make bun update re-resolve root peerDependencies

Closed
RO
10d ago
+69-19

Fixes #13509.

Repro

mkdir app && cd app
echo '{"name":"repro","peerDependencies":{"typescript":"5.5.2"}}' > package.json
bun install
echo '{"name":"repro","peerDependencies":{"typescript":"^5.5.2"}}' > package.json
bun install
bun update                      # "no changes"
bun update typescript           # "installed typescript@5.5.2"

bun outdated sees the newer version but bun update never moves it.

Cause

Peer dependencies are resolved in a deferred second pass with install_peer = true. get_or_put_resolved_package has a peer-reuse path that scans package_index for any existing entry whose resolution satisfies the requested range and short-circuits to it. That is correct for transitive peers (they piggyback on whatever sibling already provides the package) but the stale lockfile entry for typescript@5.5.2 is still in the index, satisfies ^5.5.2, and wins.

The should_update gate that forces a fresh resolve for update targets already existed in get_or_put_resolved_package_with_find_result, but that runs after the peer-reuse short-circuit, so it was never consulted for peers.

Fix

Extract the existing check into should_update_dependency() and use it to skip the peer-reuse path when the dependency is a direct update target (root-level, and either bun update was run without args or the name matches an explicit request). Transitive peers are unaffected because is_root_dependency is false for them.

Verification

New tests in the update describe block of bun-install-registry.test.ts seed the lockfile with a-dep@1.0.1, widen to ^1.0.1, then run each of bun update, bun update a-dep, and bun update --latest. All three now land on 1.0.10 and rewrite peerDependencies in package.json. The first two fail on main (stay at 1.0.1).

Existing update and peer test groups in bun-install-registry.test.ts, plus bun-lock.test.ts -t peer and catalogs.test.ts -t update, continue to pass.


no test proof · iteration 0 · Platform-specific test(s) that do not run on this machine. Deferring to CI, which covers all platforms: test/cli/install/bun-install-registry.test.ts