Repository navigation
Fix gem revert of a commented Gemfile line (#988) - #1406
Conversation
Assisted-by: Claude Code:claude-opus-5-5
Regression tests for #988: a comment added to the vendored Gemfile line must not stop the revert, and a truly drifted Gemfile line must leave both the Gemfile and Gemfile.lock untouched instead of restoring the lock alone. These fail until the fix lands. Assisted-by: Claude Code:claude-opus-5-5
A comment added to the vendored Gemfile line made revert treat the line as drifted, while vendor still saw it as wired. Revert then restored Gemfile.lock to rubygems.org but left the Gemfile path: line, a pair bundle install --frozen refuses, and every later revert kept failing the same way (#988). Revert now finds the wired line by its gem name and path:, puts the original back, and keeps the user's comment. It also plans every record in memory first and writes nothing when one has drifted, so the Gemfile and lock are reverted together or not at all. A lock with no CHECKSUMS section now counts as already reverted instead of blocking the rest. Assisted-by: Claude Code:claude-opus-5-5
Revert now only puts the original back over a wired line whose code is unchanged, so an option the user added (require: false) is never silently dropped. A Gemfile that still names the vendored copy, or points the gem at another source, keeps both files as they are; one the user already moved back to the registry lets the lock follow it. An edited managed block no longer counts as removed, and a failed Gemfile write puts the lock back as it was. 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 f2a11a3. Configure here.
|
Ready for review (burn-down agent)
Generated by Claude Code |
|
Final review brief (final reviewer agent) What it does. Risk: medium. The fix is narrow and well tested, but it changes what revert, remove and rollback write for every gem entry. It also reclassifies three cases, all disclosed in the PR body:
Look here
Verified
Changes I made: none. Open questions (non-blocking, could be follow-ups)
Auto-merge is armed, so approving sends this straight to the merge queue. Generated by Claude Code |
LLM Description written by Claude Code:claude-opus-5-5
Fixes #988
Summary
Vendored gem
vendor --revert(andremove/rollback) no longerhalf-reverts when the user has commented the wired Gemfile line. Before,
the lock went back to rubygems.org while the Gemfile kept its
path: ".socket/vendor/gem/<uuid>/…"line, a pairbundle install --frozenrefuses, and every later revert drift-kept again.Root cause
Vendor's in-sync check treats the Gemfile as wired when it contains the
copy path, but
revert_gemfile_recordonly accepted the recorded linebyte for byte. Records were also reverted and written one at a time
(lock first), so a drifted Gemfile record did not stop the lock from
being restored.
Fix (
crates/socket-patch-core/src/vendor/gem.rs)code equals what vendor wrote matches whatever its trailing comment
says. The original line is put back, carrying the user's comment when
they added or changed one. CRLF endings follow the original line.
Lines whose code changed (for example
, require: falseadded) arenot rewritten, so a user edit is never silently dropped.
against in-memory text (
RevertFiles). When any known record drifts,nothing is written and the artifact is kept. If the Gemfile write fails
after the lock was written, the lock's original bytes are put back.
a Gemfile that still contains the copy path, or that points the gem at
another
path:/source, counts as drift. A Gemfile that declares thegem from the registry again (a hand restore, even with a different
constraint) has converged, so the lock follows it back. An edited
managed block that still names the copy is now drift instead of "already
removed". A lock with no CHECKSUMS section at all now counts as
converged for the checksum record. Without that, the all-or-nothing rule
would wedge that case forever.
formats::gem::gemfile::code_ofis nowpub(crate)(a quote-awarecomment splitter).
Existing tests whose expectations changed
They pinned the old per-record partial revert, which is the behavior
#988 reports:
test_checksums_revert_drift_warningandrevert_missing_dep_pin_leaves_both_files_alone(renamed): a driftedlock record now leaves both files exactly as found.
revert_checksums_section_gone_is_converged(renamed): no CHECKSUMSsection counts as converged, so the artifact is removed.
RevertFilesinstead of passing a path.Test evidence
New tests failed on
mainbefore the fix (red run:cargo test -p socket-patch-core --lib vendor::gem::tests::revert_→4 failed:
revert_commented_gemfile_line_restores_both_files,revert_edited_carried_comment_keeps_the_users_comment,revert_commented_gemfile_line_keeps_crlf,revert_drifted_gemfile_line_writes_neither_file). All pass after it.Per-issue checklist (#988 acceptance criteria):
registry form, comment kept, artifact removed:
revert_commented_gemfile_line_restores_both_files(plus…edited_carried_comment…and…keeps_crlf).kept, and the same on a second revert:
revert_drifted_gemfile_line_writes_neither_file,revert_still_wired_but_edited_gemfile_writes_neither_file.test_revert_round_trip_*,test_revert_converged_files_are_silent_and_still_removeand thelegacy-ledger fixtures stay green.
Commands run locally:
cargo fmt --all -- --check: okcargo clippy --workspace --all-features -- -D warnings: okcargo test -p socket-patch-core --all-features: 6324 passed. The 4failures are chmod-based write-failure tests in copy_tree, vlt_heal,
pypi_poetry and pypi_requirements, which can't trigger as root in this
sandbox. None is in gem code, and CI runs them as non-root.
cargo test -p socket-patch-cli --all-features --test e2e_vendor_gem_build --test e2e_redirect_gem_build --test in_process_vendor -- --include-ignored(ruby 3.3.6, bundler 4.0.18): 41 + 49 + 132 passed.
remaining suites.
/code-review high: findings not fixed
the forward compatibility that
revert_unrecognized_wiring_kind_warns_and_continuespins, and theartifact is still kept.
groupblock or split across lines is drift(nothing written) rather than rewritten. Revert won't rewrite indented
or multi-line declarations, the same rule the forward path refuses on.
Follow-ups (not in this PR)
CRLF Gemfile (seen while writing the CRLF test). This is part of the
line-ending tracking in Tracking: classify line endings in one place instead of five drifting rules #814.
# socket-patch vendor:comment:vendor --revertdrift-keeps forever (exit 0), and the suggested "re-vendor" remedy is a no-op or adds a duplicate line #977).🤖 Generated with Claude Code
https://claude.ai/code/session_01QFoDP1VMMeczUdpPaToVKx
Note
Medium Risk
Changes gem vendor revert semantics for Gemfile/Gemfile.lock pairing; behavior is narrower (no partial writes) but affects frozen
bundle installif revert logic is wrong.Overview
Fixes #988: vendored gem revert no longer leaves Gemfile and Gemfile.lock in a mismatched state (e.g. registry lock with a
path:line still in the Gemfile).Gemfile matching now treats a wired line as the same when only the trailing
#comment differs from what vendor recorded, using quote-awarecode_of(nowpub(crate)). Revert restores the original declaration while keeping the user’s comment (and CRLF where applicable). Lines whose code changed (extra options, reformats) are not rewritten and count as drift.All-or-nothing revert: wiring records are applied against in-memory
RevertFiles; disk writes happen only if no record drifted. Any drift leaves both files untouched, updates warnings to say neither file changed, and keeps the artifact. Failed writes roll back an already-written lock. Convergence rules are tightened so a hand-restored registry gem can still revert the lock, a missing CHECKSUMS section is converged (not drift), and edited managed blocks that still point at the copy are drift.Tests add #988 scenarios and update expectations that previously allowed partial lock-only reverts.
Reviewed by Cursor Bugbot for commit f2a11a3. Configure here.
Generated by Claude Code