Repository navigation
Share one lock_fragments driver for PDM and Poetry (#1844) - #1898
Conversation
Assisted-by: Claude Code:claude-opus-5-5
poetry.lock and pdm.lock each carried their own copy of the code that runs a lock rewrite: the one-dep rewrite, the batch rewrite and the step-by-step fallback. The copies had drifted: PDM refused an idempotent re-run whose edits could not be re-derived, while Poetry reported it as unchanged. The driver now lives once in lock_fragments behind a LockFormat trait. Each format only supplies its checks, its plan and its mutation. Fragment pairing goes through one helper instead of three copies. The batch-vs-steps equivalence check and the shape-change test each exist once. No change to any rewritten lock's bytes, edits or refusals. Assisted-by: Claude Code:claude-opus-5-5
Assisted-by: Claude Code:claude-opus-5-5
socket-patch-core is published, so rewrite_poetry_lock_in, rewrite_pdm_lock_in and their Parse/Rewrite type aliases stay public. They now forward to the shared driver instead of carrying their own copy, and the test-only duplicates are gone. Also names the format in the batch's pairing error and drops a second copy of Poetry's lowercased sha256. 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 41bb169. Configure here.
|
[burn-down agent] Labeled Ready for review at
Generated by Claude Code |
Final review briefWhat it does: Removes the duplicated PDM and Poetry lock-rewrite code. A Risk: low–medium. This is the core lock-rewrite path, but it's behavior-preserving for every step and batch result. The only observable difference is noted below. Look here:
Verified: Read the full diff, with an independent pass by a review subagent. Changes I made: none. Open questions (non-blocking): the version value returned by public
The doc comment matches the new behavior. The only caller ( Auto-merge is armed, so approving sends it straight to the merge queue. Generated by Claude Code |
Wenxin Jiang (Wenxin-Jiang)
left a comment
There was a problem hiding this comment.
[agent] Reviewed 41bb1690123ef6ee8adf674f1a1d1eddc270b443. Traced the shared LockFormat driver through PDM/Poetry planning, mutation, fallback, line-ending preservation and rollback fragment checks; inspected the batch/step equivalence coverage. No major correctness issues found. Validation: source and regression-test review plus the available exact-head CI checks; no local test pass is claimed.
LLM Description written by Claude Code:claude-opus-5-5
Fixes #1844
Root cause
utils/pdm_lock.rsandutils/poetry_lock.rseach had their own copy of the code that runs a lock rewrite aroundutils::lock_fragments:rewrite_*_lock_in);rewrite_*_lock_batch);rewrite_*_lock_steps).Their mirrored equivalence tests were copied too. The two
_stepsloops had already drifted: PDM calledrewrite.edits()?before its Unchanged check, and Poetry compared the text first. Insidelock_fragments, fragment pairing was also written three times (pair_fragments,finish,rewrite_batch), each with its own copy of the shape check.Change
One driver.
lock_fragmentsnow has aLockFormattrait. Each format supplies only:WHAT, its name in error messages;FRAGMENTS_IN, which reads a dep's fragments from the lock;check, the dep's own refusals, settled before the lock is read;plan, which reads the parsed lock and returns a refusal, not-found or a plan;mutate, which applies the plan.rewrite_in,rewrite_all,rewrite_stepsandrewrite_batchare written once against that trait.PdmandPoetryimplement it. Their batch/steps/closure glue is deleted.One pairing helper.
changed_pairschecks the shape and pairs the fragments, andsole_inchecks uniqueness.pair_fragments,finishandrewrite_batchall go through them. The batch keeps its one-pass overlappingsole_occurrencesscan on purpose: it is conservative and only ever hands a case back to the step-by-step rewrite.Tests, one copy each.
assert_batch_matches_steps::<F>inlock_fragments, which both formats' batch tests call.lock_fragments(it already ran for both format names). The two per-format copies are deleted.Public API unchanged.
rewrite_{poetry,pdm}_lock{,_with_edits,_in,_all},rewrite_poetry_lock_all_with_versionand the*LockParse/*LockRewritealiases all stay, becausesocket-patch-coreis published. Each is now a few lines that forward to the shared driver.FragmentRewrite.namebecame an ownedString, so a dep's lifetime no longer has to match the lock text's.Behavior
No change to any rewritten lock's bytes, edits or refusals. The golden tests
pdm_lock_reused_parseandpoetry_lock_reused_parseand every exact-bytes test pass unchanged. Two internal differences:Refused. It is nowUnchanged, which is also what the batch path already reported. The issue notes this case looks unreachable, and no test or fixture reaches it.rewrite_poetry_lock_all_with_version: it now also returns thelock_versionwhen it falls back to step-by-step. It is read insidePoetry::planfrom a parse the rewrite takes anyway. The only caller, the hosted Poetry redirect, uses it to skip a re-parse. The batch test checks that it matches the output lock's version.Review findings I didn't fix (from
/code-review high)lock_versionin the redirect viaparse_lock(original)instead of aOnceCellon the format: that would depend on the 2-slot parse memo still holding the original after the rewrite, and the hosted-scan parse-count tests pin those counts. TheOnceCellis the narrower change.lock_fragments. A per-format fragment-count regression is still caught by the exact-bytes, golden and batch-equivalence tests on every fixture.FragmentRewrite.nameallocates: one smallStringper dep, next to a whole-lock render and re-parse. That isn't measurable, and it decouples the dep's lifetime from the text's."missing PDM package"fallback inrewrite_pdm_lock_inis dead today: it is kept on purpose, so that if PDM's plan ever returnsNonethe single-dep API refuses instead of panicking.Test evidence
cargo fmt --all -- --check: clean.cargo clippy --workspace --all-features -- -D warnings: clean.cargo test -p socket-patch-core --all-features --lib: 6993 passed, 4 failed. The same 4 fail on unmodifiedmainin this sandbox, because it runs as root and root can write to the read-only dirs those tests rely on (same list as Build: share one test RNG across randomized tests (#1868) #1882 and Build: share one test env guard in core (#1889) #1891):copy_tree::relax_loop_must_not_traverse_symlinked_root,vlt_heal::an_unremovable_hidden_lock_keeps_every_store_entry,pypi_poetry::wire_write_failure_maps_error_and_leaves_lock_untouched,pypi_requirements::wire_failure_rolls_back_already_written_files.cargo test -p socket-patch-core --all-features --test '*': all pass.cargo test -p socket-patch-cli --all-features --test e2e_vex_lockfile: 354 passed.cargo test -p socket-patch-cli --all-features --test e2e_vex_build -- --ignored poetry:: pdm::with Poetry 2.4.3 and PDM 2.29.2: 6 passed.npm/,pypi/andgem/don't touch lock rewriting.https://claude.ai/code/session_011f9aePxc3X2mz1fi6wUwYS
Generated by Claude Code