fix(install): use includePrerelease semantics for peer dep validation#27085
fix(install): use includePrerelease semantics for peer dep validation#27085ramonclaudio wants to merge 2 commits into
Conversation
WalkthroughAdds include-prerelease satisfaction logic to enable prerelease versions to satisfy version ranges without prerelease tags. Modifies npm/npm dependency satisfaction in PackageManagerEnqueue and introduces two new satisfiesIncludePrerelease methods in SemverQuery for List and Group. Changes
🚥 Pre-merge checks | ✅ 2✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
ef50df4 to
2f70d05
Compare
|
Newest first ✅ 016c3 — Looks good! Reviewed 2 files across Previous reviewsCode ReviewNewest first ✅ 2f70d — Looks good! Reviewed 4 files across Powered by Claude Code Review |
f4edb5f to
611167a
Compare
fb8590b to
8341f70
Compare
Prerelease versions like `56.0.0-canary-20260212-4f61309` incorrectly trigger "incorrect peer dependency" warnings when checked against ranges like `>=14.0.4` or `*`. The strict semver `pre_matched` gate in `List.satisfiesPre` requires comparators to share the same major.minor.patch with a prerelease tag, which fails for ranges without prerelease comparators. Yarn v1 fixed the same issue in 2017 (yarnpkg/yarn#3361) via `satisfiesWithPrereleases`. node-semver exposes `{ includePrerelease: true }` as a built-in option. npm/rfcs#397 has been open since 2021 proposing similar semantics. Add `satisfiesIncludePrerelease` methods to `List` and `Group` in `SemverQuery.zig` that skip the `pre_matched` gate, then call from `resolutionSatisfiesDependency` which is exclusively used for peer dependency validation. Strict semver resolution path stays strict. Fixes oven-sh#29444 Relates to oven-sh#26076, oven-sh#15711
8341f70 to
bb637d7
Compare
… versions Removes the install_peer && behavior.is_peer() block from get_or_put_resolved_package (PackageManagerEnqueue.rs) and the resolution_satisfies_dependency helper that only that block called. Peers now flow through findBestVersion; dedup and the 'incorrect peer dependency' warning live in Tree::hoist_dependency where placement is deterministic. Adds satisfies_include_prerelease on Group and List in SemverQuery.rs — the strict-semver siblings of satisfies_pre without the pre_matched gate. Wired into the peer paths in Tree::hoist_dependency so prerelease resolutions like 5.0.0-alpha.150 are accepted against ranges like >=1.0.0 (node-semver includePrerelease / yarn v1 satisfiesWithPrereleases semantics). The strict resolver path is untouched; Bun.semver.satisfies() keeps current behavior. Combines oven-sh#29804 (Dylan Conway, Zig-era refactor) with oven-sh#27085 (prerelease semver fix). Both were stuck pre-rewrite and don't apply to the Rust tree. Fixes oven-sh#29444.
… versions Removes the install_peer && behavior.is_peer() block from get_or_put_resolved_package (PackageManagerEnqueue.rs) and the resolution_satisfies_dependency helper that only that block called. Peers now flow through findBestVersion. Dedup and the "incorrect peer dependency" warning live in Tree::hoist_dependency where placement is deterministic. Adds satisfies_include_prerelease on Group and List in SemverQuery.rs, the strict-semver siblings of satisfies_pre without the pre_matched gate. Wired into the peer paths in Tree::hoist_dependency so prerelease resolutions like 5.0.0-alpha.150 are accepted against ranges like >=1.0.0 (node-semver includePrerelease, yarn v1 satisfiesWithPrereleases semantics). The strict resolver path is untouched. Bun.semver.satisfies() keeps current behavior. Combines oven-sh#29804 (Dylan Conway, Zig-era refactor) with oven-sh#27085 (prerelease semver fix). Both were stuck pre-rewrite and don't apply to the Rust tree. Fixes oven-sh#29444.
… versions Removes the install_peer && behavior.is_peer() block from get_or_put_resolved_package (PackageManagerEnqueue.rs) and the resolution_satisfies_dependency helper that only that block called. Peers now flow through findBestVersion. Dedup and the "incorrect peer dependency" warning live in Tree::hoist_dependency where placement is deterministic. Adds satisfies_include_prerelease on Group and List in SemverQuery.rs, the strict-semver siblings of satisfies_pre without the pre_matched gate. Wired into the peer paths in Tree::hoist_dependency so prerelease resolutions like 5.0.0-alpha.150 are accepted against ranges like >=1.0.0 (node-semver includePrerelease, yarn v1 satisfiesWithPrereleases semantics). The strict resolver path is untouched. Bun.semver.satisfies() keeps current behavior. Combines oven-sh#29804 (Dylan Conway, Zig-era refactor) with oven-sh#27085 (prerelease semver fix). Both were stuck pre-rewrite and don't apply to the Rust tree. Fixes oven-sh#29444.
… versions Removes the install_peer && behavior.is_peer() block from get_or_put_resolved_package (PackageManagerEnqueue.rs) and the resolution_satisfies_dependency helper that only that block called. Peers now flow through findBestVersion. Dedup and the "incorrect peer dependency" warning live in Tree::hoist_dependency where placement is deterministic. Adds satisfies_include_prerelease on Group and List in SemverQuery.rs, the strict-semver siblings of satisfies_pre without the pre_matched gate. Wired into the peer paths in Tree::hoist_dependency so prerelease resolutions like 5.0.0-alpha.150 are accepted against ranges like >=1.0.0 (node-semver includePrerelease, yarn v1 satisfiesWithPrereleases semantics). The strict resolver path is untouched. Bun.semver.satisfies() keeps current behavior. Combines oven-sh#29804 (Dylan Conway, Zig-era refactor) with oven-sh#27085 (prerelease semver fix). Both were stuck pre-rewrite and don't apply to the Rust tree. Fixes oven-sh#29444.
… versions Removes the install_peer && behavior.is_peer() block from get_or_put_resolved_package (PackageManagerEnqueue.rs) and the resolution_satisfies_dependency helper that only that block called. Peers now flow through findBestVersion. Dedup and the "incorrect peer dependency" warning live in Tree::hoist_dependency where placement is deterministic. Adds satisfies_include_prerelease on Group and List in SemverQuery.rs, the strict-semver siblings of satisfies_pre without the pre_matched gate. Wired into the peer paths in Tree::hoist_dependency so prerelease resolutions like 5.0.0-alpha.150 are accepted against ranges like >=1.0.0 (node-semver includePrerelease, yarn v1 satisfiesWithPrereleases semantics). The strict resolver path is untouched. Bun.semver.satisfies() keeps current behavior. Combines oven-sh#29804 (Dylan Conway, Zig-era refactor) with oven-sh#27085 (prerelease semver fix). Both were stuck pre-rewrite and don't apply to the Rust tree. Fixes oven-sh#29444.
… versions Removes the install_peer && behavior.is_peer() block from get_or_put_resolved_package (PackageManagerEnqueue.rs) and the resolution_satisfies_dependency helper that only that block called. Peers now flow through findBestVersion. Dedup and the "incorrect peer dependency" warning live in Tree::hoist_dependency where placement is deterministic. Adds satisfies_include_prerelease on Group and List in SemverQuery.rs, the strict-semver siblings of satisfies_pre without the pre_matched gate. Wired into the peer paths in Tree::hoist_dependency so prerelease resolutions like 5.0.0-alpha.150 are accepted against ranges like >=1.0.0 (node-semver includePrerelease, yarn v1 satisfiesWithPrereleases semantics). The strict resolver path is untouched. Bun.semver.satisfies() keeps current behavior. Combines oven-sh#29804 (Dylan Conway, Zig-era refactor) with oven-sh#27085 (prerelease semver fix). Both were stuck pre-rewrite and don't apply to the Rust tree. Fixes oven-sh#29444.
… versions Removes the install_peer && behavior.is_peer() block from get_or_put_resolved_package (PackageManagerEnqueue.rs) and the resolution_satisfies_dependency helper that only that block called. Peers now flow through findBestVersion. Dedup and the "incorrect peer dependency" warning live in Tree::hoist_dependency where placement is deterministic. Adds satisfies_include_prerelease on Group and List in SemverQuery.rs, the strict-semver siblings of satisfies_pre without the pre_matched gate. Wired into the peer paths in Tree::hoist_dependency so prerelease resolutions like 5.0.0-alpha.150 are accepted against ranges like >=1.0.0 (node-semver includePrerelease, yarn v1 satisfiesWithPrereleases semantics). The strict resolver path is untouched. Bun.semver.satisfies() keeps current behavior. Combines oven-sh#29804 (Dylan Conway, Zig-era refactor) with oven-sh#27085 (prerelease semver fix). Both were stuck pre-rewrite and don't apply to the Rust tree. Fixes oven-sh#29444.
… versions Removes the install_peer && behavior.is_peer() block from get_or_put_resolved_package (PackageManagerEnqueue.rs) and the resolution_satisfies_dependency helper that only that block called. Peers now flow through findBestVersion. Dedup and the "incorrect peer dependency" warning live in Tree::hoist_dependency where placement is deterministic. Adds satisfies_include_prerelease on Group and List in SemverQuery.rs, the strict-semver siblings of satisfies_pre without the pre_matched gate. Wired into the peer paths in Tree::hoist_dependency so prerelease resolutions like 5.0.0-alpha.150 are accepted against ranges like >=1.0.0 (node-semver includePrerelease, yarn v1 satisfiesWithPrereleases semantics). The strict resolver path is untouched. Bun.semver.satisfies() keeps current behavior. Combines oven-sh#29804 (Dylan Conway, Zig-era refactor) with oven-sh#27085 (prerelease semver fix). Both were stuck pre-rewrite and don't apply to the Rust tree. Fixes oven-sh#29444.
|
Superseded by the Rust port. The order-determinism half (Dylan's #29804) is in #30855, and the prerelease-semver fix that originally lived here follows in a separate Rust PR once that lands. The fix code is preserved on |
What does this PR do?
Fixes #29444.
Bun warns
incorrect peer dependencyfor any prerelease version validated against a peer range with no prerelease comparator on the same major.minor.patch. Hits every package on a-canary/-rc/-nextchannel: expo canary, react-native nightlies, anything shipping prereleases to users.List.satisfiesPreinsrc/semver/SemverQuery.ziggates on apre_matchedflag that only flips when a range comparator carries a prerelease tag on the same major.minor.patch.56.0.0-canaryfails against>=14.0.4because the range has no prerelease comparator, even though 56 > 14. Same for*(desugars to>=0.0.0).yarn v1 fixed this in 2017 (
satisfiesWithPrereleases, yarnpkg/yarn#3361).node-semverhas{ includePrerelease: true }built in. npm/rfcs#397 open since 2021. Bun auto-installs peer deps, so users hit this with no escape hatch.Fix adds
List.satisfiesIncludePrereleaseandGroup.satisfiesIncludePrereleasealongside the existingsatisfiesPre, skipping thepre_matchedgate.resolutionSatisfiesDependencyswitches to the new method. ExistingsatisfiesPresignature is untouched, strict semver resolution path is unchanged.Scope check:
resolutionSatisfiesDependencyhas two callers, both insideif (install_peer and behavior.isPeer()). Change is confined to peer-dep validation. Regular version resolution stays strict.before:
after:
How did you verify your code works?
test/cli/install/bun-install-registry.test.ts: a local package declarespeerDependencies: { "prereleases-3": ">=1.0.0" }, installs alongsideprereleases-3@5.0.0-alpha.150. Asserts the warning does not fire.test/cli/install/semver.test.ts: locksBun.semver.satisfiesto strict semver so the fix does not leakincludePrereleasesemantics into general resolution.oven-sh/bunclone: baseline binary reproduces the warning, patched binary does not. Same test file, same test runner, only the binary differs.bun add expo@canary react-native@nightly react@19.3.0-canary-3e319a94-20260126fires 21incorrect peer dependencywarnings onoven-sh/bun@main, 0 with this patch applied.bun-install-registry.test.tspass unchanged.Relates to #26076, #15711.