Repository navigation
Fix gem eject dry run missing group-block refusal (#1761) - #1762
Conversation
Assisted-by: Claude Code:claude-opus-5-5
`socket-patch vendor --dry-run` on a hosted Bundler project whose patched gem sits inside a `group ... do` block reported the eject as planned (exit 0), while the real `vendor` refused the same gem with `gemfile_declaration_not_editable` and rolled back (exit 1). CI gating on the dry run was told an eject would succeed that never could. The eject now asks the gem takeover gate (manifest and Gemfile declaration checks) for each gem pin before planning, as `scan` and `get --mode vendored` already do. Dry and wet runs both refuse the eject whole with `eject_refused`, and the wet run no longer restores and rolls back first. Fixes #1761 Assisted-by: Claude Code:claude-opus-5-5
Move the #1761 fix to the gem vendored backend: its dry run now computes the Gemfile and lock edits the wet run would make and returns the same refusal (for example a declaration inside a `group` block). Every dry-run caller benefits, not just the eject: a plain `vendor --dry-run` and the takeover previews over restored text now report what the wet run would refuse. This replaces the eject-only gate added in the previous commit, which checked each gem pin against its own one-pin restore and hid earlier backend refusals. 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 01c0895. Configure here.
|
Burn-down agent: labeled Ready for review at head
Slack announcement not sent this run (Slack send unavailable to the burn-down agent); the next run will retry. Generated by Claude Code |
|
Burn-down agent: labeled Ready for review at head
Generated by Claude Code |
Final review briefWhat it does. Risk: low. An 8-line change in one dry-run branch. Look here
Verified
Changes I made: none. Open questions: none. Auto-merge is armed, so approving sends this straight to the merge queue. Generated by Claude Code |
|
BugBot review Generated by Claude Code |
Bugbot is paused — your team has an unpaid invoiceBugbot is paused because your team has an unpaid invoice. Pay it from the billing page in the Cursor dashboard and Bugbot resumes automatically. (requestId: 6ad00737-14f4-4a72-a4ac-27818feec8a1) |
LLM Description written by Claude Code:claude-opus-5-5
Fixes #1761
Root cause
socket-patch vendor(the hosted-pins eject,run_ejectincrates/socket-patch-cli/src/commands/vendor.rs) previews backendrefusals only through
takeover_dry_refusal, which stages the restoredtext and runs the vendored backend's dry run. The gem backend's dry run
does not evaluate the Gemfile declaration gate (a declaration inside a
groupblock, #775) or the manifest gate, so the preview reportseject_planned/ exit 0, while the wet run refuses withgemfile_declaration_not_editableand rolls back (exit 1).scan --mode vendored,get --mode vendoredand the per-purl takeoveralready consult
gem_takeover_refusalbefore the restore; the ejectpath never did.
Fix
The gem vendored backend (
vendor_gemincrates/socket-patch-core/src/vendor/gem.rs) now runs its pureGemfile/lock edit planner (
gem_edits) in dry runs too, for a gem notalready wired, and returns the same refusal the wet run would. The
eject's existing preview (
takeover_dry_refusal, which dispatches thebackend's dry run over the restored text) therefore sees the refusal,
and so does a plain
vendor --dry-run.A first commit special-cased the eject with
gem_takeover_refusals_for;/code-review highpointed out that it checked each gem against its ownone-pin restore and could hide earlier backend refusals, so the second
commit replaces it with the backend fix.
The wet eject is now refused up front too (
eject_refused, nothingwritten) instead of restoring, failing and rolling back.
Tests
vendor::gem::tests::test_dry_run_previews_declaration_refusal(unit, default
cargo test): dry and wet both refuse a group-blockdeclaration. Fails without the fix.
e2e_redirect_gem_build:gem_hosted_group_block_pin_survives_a_refused_vendored_takeovernow also ejects the CHECKSUMS lock with
vendor --dry-runandvendor, and the newgem_hosted_group_block_pin_survives_a_refused_eject_of_a_converged_lockcovers the lock converged by an unfrozen
bundle install(the issue'sother matrix rows). Both failed before the fix
(
status: success,eject_planned, exit 0) and pass with it onBundler 4.0.18 / Ruby 3.3.6.
Review follow-up (97d9a96)
A review pointed out that the dry hosted→vendored takeover in
vendor_records_reusingalso previews the backend over the files ondisk. For a gem, the Gemfile there still wraps the declaration in the
hosted
source … doblock, so the new dry-run edit check could refuseit as indented. Gems now stop after the restored-text preview
(
takeover_dry_refusal), as bun and sbt already do. No CLI path reachedthat branch with a hosted gem in my tests (
vendorejects whenever ahosted pin is in scope); the guard is defensive.
New e2e:
gem_hosted_pin_previews_and_runs_a_clean_eject. A top-levelhosted gem previews
eject_planned(exit 0, nothing written), and thewet eject then wires the vendored copy.
Local evidence
cargo fmt --all -- --check,cargo clippy --workspace --all-features -- -D warnings: clean.cargo test -p socket-patch-cli --all-features --test e2e_redirect_gem_build --test e2e_vendor_gem_build --test vendor_eject_fresh_checkout -- --ignored: all pass (35 + 9 capstones), Bundler 4.0.18 / Ruby 3.3.6.cargo test --workspace --all-features --no-fail-fast: everything passes except 12 tests that also need a non-root user or CI's pinned bun (write-failure tests thatchmoda file read-only, which root ignores;e2e_bun_lockbon local bun 1.4.4). None touches gem code; CI runs them in its own environment.in_process_vendor,in_process_vendor_bun_takeover, CLIvendorunit tests: pass.npm/,pypi/,gem/only dispatch to the binary).Per-issue checklist
vendor --dry-runeject previewseject_planned(exit 0) for a hosted gem declared in agroupblock, but the realvendorrefusesgemfile_declaration_not_editable(exit 1) #1761:test_dry_run_previews_declaration_refusal(unit), plus the twoe2e_redirect_gem_buildeject checks above (CHECKSUMS lock, and converged lock).https://claude.ai/code/session_011f9aeS3X2GZTkmFRmgCiSv
Generated by Claude Code