Repository navigation
Fix vendored berry revert restoring stale lock (#759) - #1464
Mikola Lysenko (mikolalysenko) merged 3 commits into
Conversation
Assisted-by: Claude Code:claude-opus-5-5
Undoing a vendored Yarn Berry package wrote back the yarn.lock entry exactly as recorded at vendor time. If the lock changed in between, every later `yarn install --immutable` failed with YN0028 while the revert reported success: - a yarn 4.0.x -> 4.1+ upgrade respells checksums as 10c0/<hex>, but the restored entry kept the old bare spelling; - a workspace member that started depending on the package while it was vendored was missing from the restored entry's key; - a member that stopped depending on it was still in the key. `vendor --revert`, `rollback` and `remove` now spell the restored checksum the way the lock does, and key the entry by the descriptors the lock still declares, adding new ones the restored version satisfies. A new descriptor it can't satisfy is reported with a `vendor_lock_descriptor_unlocked` warning that says to run `yarn install`. The declared-descriptor helpers the hosted restore uses for #1435 move to formats::yarn::berry_prune so both paths share them. Fixes #759 Assisted-by: Claude Code:claude-opus-5-5
Follow-ups to the #759 fix: - A package a user `resolutions` pin routes keeps its recorded key: yarn keys it by the pin's range, which no dependency map declares, so rebuilding it from the dependency maps broke an unchanged lock. - A second revert pass (after `--preserve-state`, or a revert whose package.json write failed) recognizes the rebuilt entry instead of reporting it removed or warning about pruned entries. - Checksums are only respelled when the lock shows a spelling, and a lock with mixed line endings is left to the byte splice so its CRLF lines are not flattened. - The range reader handles hyphen ranges, a space after an operator, a `v` prefix and exact prereleases. Adds real-yarn e2e tests that vendor, change the lock (member adds or removes the dependency, yarn 4.0.2 -> 4.18 upgrade), revert, and install a fresh checkout with `yarn install --immutable`. Refs #759 Assisted-by: Claude Code:claude-opus-5-5
|
BugBot review Generated by Claude Code |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 2cccdba. Configure here.
|
Labeled Ready for review by the burn-down agent.
Slack announcement not sent: no Slack send tool was available to this run. Generated by Claude Code |
Final review briefWhat it does: After a Yarn Berry package was vendored, Risk: low to medium. It touches the revert path only, and every uncertain case keeps the old behavior: a user Look here:
Verified:
Changes I made: none. Open questions (non-blocking): Auto-merge (squash) is armed, so approving sends it straight to the merge queue. Generated by Claude Code |
LLM Description written by Claude Code:claude-opus-5-5
Fixes #759
Summary
After a Yarn Berry package was vendored,
vendor --revert,rollbackandremovewrote theyarn.lockentry back exactly as it was recorded at vendor time. If the lock had changed since then, the revert still exited 0, but every lateryarn install --immutablefailed with YN0028. The restored entry is now rebuilt from the live lock.Root cause
revert_yarn_berry_opts→revert_recorded_blocksplices in the recorded pre-vendor block byte for byte. The issue reports three ways the lock can change in between:checksum:as10c0/<hex>, but the restored entry kept the old bare hex.left-pad: 1.3.0next to the root's^1.3.0). Theresolutionspin routes it to the vendored entry, so the restored key was missing it.yarn removedeleted from one workspace member, so everyyarn install --immutablefails YN0028 #1435.Fix
vendor_lock_descriptor_unlockedwarning telling the user to runyarn install. It is documented in CLI_CONTRACT.md.resolutionsselector routes the package (a pin vendoring took over, or any other selector): yarn keys that entry by the pin's range, which no dependency map declares.--preserve-state(or after a failed package.json write) recognizes the rebuilt entry and converges silently.declared_descriptorsanddescriptor_declaredmove from the hosted restore (patch/redirect/upstream/npm.rs, Hosted yarn berry rollback/remove put back a descriptor thatyarn removedeleted from one workspace member, so everyyarn install --immutablefails YN0028 #1435) toformats::yarn::berry_prune, so hosted and vendored use the same logic. Hosted behavior is unchanged.npm/,pypi/andgem/only dispatch to the binary, so nothing changes there.Per-issue checklist
#759 covers three symptoms, and each has its own regression test.
issue_759_revert_follows_a_checksum_respelling_since_vendoring(both directions)issue_759_revert_after_a_yarn_upgrade_respells_checksums(vendor on 4.0.2, install on 4.18, revert, fresh--immutable)issue_759_revert_keys_a_descriptor_added_since_vendoringissue_759_revert_after_a_member_adds_a_descriptorissue_759_revert_drops_a_descriptor_removed_since_vendoringissue_759_revert_after_a_member_removes_a_descriptorissue_759_revert_warns_about_a_descriptor_it_cannot_lockissue_759_taken_over_user_pin_keeps_its_keyissue_759_second_revert_pass_converges_on_a_rebased_entryissue_759_mixed_line_endings_are_not_flattenednpm_range_admits_reads_npm_semanticslock_checksum_spelling_tells_none_from_prefixedTest evidence
main's code with the exact wrong locks (bare checksum, stale key in each direction, no warning), and pass with the fix.main's core, all three e2e tests fail with the issue's YN0028 diffs:cargo fmt --all -- --check: clean.cargo clippy --workspace --all-features -- -D warnings: clean.cargo test --workspace --all-features --no-fail-fast: everything passes except 13 tests that fail only because of this sandbox, none of them in yarn code. The sandbox runs as root, so the chmod-based write-failure tests incovgap_commands_vendor,in_process_redirect,repairand the core lib can't make a write fail.e2e_bun_lockbneedspatches-api.socket.dev, which the sandbox can't reach.scripts/yarn-berry-vex-matrix.sh 4.18.0 4.0.2: all four berry suites pass on both releases. The yarn 2 legacy-refusal step can't fetch yarn 2 in this sandbox (it isn't on the npm registry), so it is left to CI./code-review high: ran on the first push. All seven findings were confirmed and fixed in 2cccdba: user-pin keys, second-pass convergence, range coverage, mixed endings, the dead quote filter, the shared spelling helper, and no-checksum locks.🤖 Generated with Claude Code
https://claude.ai/code/session_01Y2UkYZUR7BXEk3odB4mdSS
Generated by Claude Code