GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Fix hosted gem block mixing CRLF Gemfile endings (#1831) by mikolalysenko · Pull Request #1841 · SocketDev/socket-patch

Conversation

@mikolalysenko

@mikolalysenko Mikola Lysenko (mikolalysenko) commented Oct 29, 2026 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Collaborator

LLM Description written by Claude Code:claude-opus-5-5

Fixes #1831

Summary

scan --mode hosted / get --mode hosted over a CRLF Gemfile (a Windows checkout, or core.autocrlf=true) wrote the Socket source "…" do … end block with bare LF endings, so the committed Gemfile ended up with mixed line endings. Now:

  • In-place rewrite of a gem line (plain, with options, parenthesized, inside the user's own source … do block): the block takes the ending of the line it replaces. The line's CR goes back at the end of the block, not inside it. An unterminated last line takes the file's ending, and a lone trailing CR at EOF is no longer read as a line ending.
  • Appended block for a transitive gem: takes the file's ending (line_endings::terminator, so the majority wins on a mixed file), for both the separator and the block.
  • Rollback / remove (upstream/gem.rs restore_manifest) now restores the declaration with the block's own ending. Before, it used CRLF whenever the file held any CRLF line. An LF block (the only spelling written before this PR) takes the ending of the lines around it, so existing redirected projects restore the same as before.

This is the hosted-mode twin of #1821 / #1822 (vendored mode).

Root cause

rewrite_gem in crates/socket-patch-core/src/patch/redirect/mod.rs built the block from a literal with hard-coded \n in both arms (in-place and append). The in-place arm's gem_line_re match also ran up to the line's CR, so the CR was dropped and the block ended in the original line's bare LF.

The recognizers already accept \r?\n: the re-run idempotency guard, gem_spelling_residue, the restore's socket_blocks, and VEX's parse_source_blocks (via str::lines). So a CRLF block is recognized everywhere, and the e2e test below confirms that against real bundler.

No wrapper changes: npm/, pypi/ and gem/ only dispatch to the binary.

Tests (red → green)

Issue facet Test Without fix With fix
#1831 single-line decl, decl with options + comment, gem(…), decl inside a user source … do block, unterminated last line, lone trailing CR, transitive append (terminated and not), plus a re-run no-op for each core patch::redirect::tests::gemfile_source_block_keeps_crlf_line_endings FAIL: mixed line endings: "…\r\nsource \"https://patch.test/…\" do\n gem …\nend\n" pass
LF Gemfile stays LF; an LF line in a CRLF file keeps its LF core gemfile_source_block_keeps_lf_line_endings pass (guard) pass
#1831 real bundler: CRLF Gemfile (both the issue's Driver::ScanVex and Driver::ScanVexSourceBlock shapes) stays CRLF after hosted scan, converging bundle install passes, re-scan is byte-identical, rollback gives back a CRLF Gemfile that declares the gem cli e2e_redirect_gem_build::gem_hosted_redirect_keeps_a_crlf_gemfile_crlf (--ignored, bundler 4.0.18 / Ruby 3.3.6 locally; runs in the gem e2e CI legs) FAIL: crlf-gemfile: the redirected Gemfile mixes line endings: "source \"http://127.0.0.1:…/upstream\"\r\nsource \"…/patch-registry/gem/…\" do\n gem \"vuln-gem\", \"1.0.0\"\nend\n" pass

One existing test changed its expectation: gemfile_single_line_declaration_lookalikes_still_rewrite has a CRLF declaration in an LF file (gem "vuln-gem", require: false\r). It pinned the old LF block and now expects that line's CRLF. That is the intended rule: the block takes the ending of the line it replaces.

Commands run locally:

  • cargo fmt --all -- --check: clean
  • cargo clippy --workspace --all-features -- -D warnings: clean
  • cargo test -p socket-patch-core --lib: 6992 passed, 4 failed. All 4 are the known permission-denial tests that can't fail a write as root in this sandbox (copy_tree::relax_loop_must_not_traverse_symlinked_root, vlt_heal::an_unremovable_hidden_lock_keeps_every_store_entry, pypi_poetry::wire_write_failure_…, pypi_requirements::wire_failure_rolls_back_…). None touch gem code.
  • cargo test -p socket-patch-cli --all-features --test e2e_redirect_gem_build --test e2e_vendor_gem_build (--ignored): 38 + 11 passed. Without --ignored: 21 + 35 passed.
  • I couldn't finish the full cargo test --workspace --all-features: the sandbox ran out of disk while linking the CLI test binaries. CI is the full-suite gate.

Per-issue checklist

  • Hosted gem redirect writes the Socket source … do block with LF endings into a CRLF Gemfile, leaving it with mixed line endings #1831 single-line declaration, CRLF Gemfile with LF or CRLF lock: gemfile_source_block_keeps_crlf_line_endings, gem_hosted_redirect_keeps_a_crlf_gemfile_crlf (crlf-gemfile)
  • Hosted gem redirect writes the Socket source … do block with LF endings into a CRLF Gemfile, leaving it with mixed line endings #1831 declaration inside a user source … do block: same unit test, and e2e (crlf-gemfile-source-block)
  • Hosted gem redirect writes the Socket source … do block with LF endings into a CRLF Gemfile, leaving it with mixed line endings #1831 append arm (transitive gem): gemfile_source_block_keeps_crlf_line_endings (puma → rails cases)
  • Hosted gem redirect writes the Socket source … do block with LF endings into a CRLF Gemfile, leaving it with mixed line endings #1831 converging install, re-scan no-op, rollback in CRLF: gem_hosted_redirect_keeps_a_crlf_gemfile_crlf

/code-review high

Fixed:

  • Rollback chose its ending by "any CRLF in the file" while the forward pass now keeps the replaced line's ending. Rollback now follows the block's own ending.
  • The recorded FileEdit.new left out the CR that was actually written. It now records the exact spliced text.
  • A lone trailing CR at EOF was treated as a CRLF ending and left a stray CR. Now covered by a test.
  • Stale "the rewriter emits LF" comments are updated, and the unit test uses LineEndings::of instead of a hand-rolled counter.

Not changed:

  • Excluding the CR in gem_line_re itself instead of stripping it after the match. That is equivalent, and keeping the regex unchanged leaves the swallowed-whitespace behaviour that rollback depends on (Gem hosted rollback / remove turn a redirected transitive gem into a top-level exact pin, because the restore looks for a blank line the rewriter never writes #457) untouched.
  • On a mixed-ending file, rollback can't tell an LF block written before this PR apart from one written for an LF line, so it uses the ending of the surrounding lines. That's the same as main for every pre-existing project.

https://claude.ai/code/session_011f9aeRvMuTRkgqjmDvPu3j


Generated by Claude Code

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@claude
Start fix for #1831
ef3218d
Assisted-by: Claude Code:claude-opus-5-5
@mikolalysenko Mikola Lysenko (mikolalysenko) mentioned this pull request Oct 29, 2026
Hosted gem redirect writes the Socket source … do block with LF endings into a CRLF Gemfile, leaving it with mixed line endings #1831
Closed
@claude
Keep CRLF Gemfiles CRLF on hosted gem redirect
89d5c1d
A hosted scan or get over a CRLF Gemfile (a Windows checkout, or
core.autocrlf=true) wrote the Socket `source ... do` block with bare
LF endings, so the committed Gemfile ended up with mixed line endings
and churned under editors and .gitattributes normalization.

The rewritten block now takes the ending of the gem line it replaces
(the file's ending for an unterminated last line), and the block
appended for a transitive gem takes the file's ending. This matches
what vendored mode does since #1822.

Fixes #1831

Assisted-by: Claude Code:claude-opus-5-5
@mikolalysenko Mikola Lysenko (mikolalysenko) mentioned this pull request Oct 29, 2026
Swarm health manager log #1382
Open
Claude (claude) added 2 commits October 29, 2026 17:05
@claude
Match gem rollback to the block's line ending
0ea0db3
Rollback restored a hosted gem declaration with CRLF whenever the
Gemfile held any CRLF line. It now takes the ending of the Socket block
it replaces, which the redirect writes in the ending of the original
line, so a mixed-ending Gemfile round-trips. A gem line that ends in a
lone CR at end of file no longer leaves a stray CR, and the recorded
edit now shows exactly what was written.

Assisted-by: Claude Code:claude-opus-5-5
@claude
Test a lone trailing CR in a hosted Gemfile
210c955
Assisted-by: Claude Code:claude-opus-5-5
@mikolalysenko
Mikola Lysenko (mikolalysenko) marked this pull request as ready for review October 29, 2026 17:09
@mikolalysenko

Mikola Lysenko (mikolalysenko) commented Oct 29, 2026

Copy link
Copy Markdown
Collaborator Author

BugBot review


Generated by Claude Code

cursor[bot] reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

cursor[bot]
cursor Bot reviewed Oct 29, 2026
View reviewed changes

@cursor cursor Bot left a comment

Copy link
Copy Markdown

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ 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 210c955. Configure here.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@mikolalysenko Mikola Lysenko (mikolalysenko) added the Ready for review Agent-verified: mergeable, CI green, Bugbot clean — awaiting human review label Oct 29, 2026
@mikolalysenko

Mikola Lysenko (mikolalysenko) commented Oct 29, 2026

Copy link
Copy Markdown
Collaborator Author

Burn-down agent: labeled Ready for review at 210c955b (full: see head).

  • CI: 32/32 run checks green or neutral (50 skipped by path filters); mergeable, no conflicts. The one neutral row is a cancelled Bugbot run; the re-requested Bugbot review on this head reported no issues.
  • Bugbot: reviewed 210c955, no findings.
  • For the reviewer: rollback now picks the Socket block's line ending from the block itself; on mixed-ending Gemfiles it follows the surrounding lines (see "Not changed" in the description).
  • Slack announcement not sent this run (Slack send unavailable); the next run retries.

Generated by Claude Code

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@mikolalysenko

Mikola Lysenko (mikolalysenko) commented Oct 29, 2026

Copy link
Copy Markdown
Collaborator Author

Final review brief (210c955)

What it does. A hosted gem redirect over a CRLF Gemfile (Windows checkout, core.autocrlf=true) wrote the Socket source "…" do … end block in bare LF, leaving a mixed-ending Gemfile. Now the block takes the ending of the gem line it replaces (or the file's ending when appended for a transitive gem), and rollback restores the declaration with the block's own ending. Hosted-mode twin of #1821/#1822. Fixes #1831.

Risk: low. Only the line endings of text the rewriter writes change. Every recognizer already accepted \r?\n, and an LF block written by an older release restores exactly as before.

Look here

  • redirect/mod.rs:8016: picking the ending for an in-place rewrite. The line's CR moves to the end of the block; an unterminated last line (a lone trailing CR included) takes the file's ending.
  • redirect/mod.rs:8111: splicing the block, and the recorded FileEdit.new now includes the CR.
  • redirect/mod.rs:8156: the append arm now uses the majority ending (line_endings::terminator). Before, any CRLF in the file picked CRLF. The two only differ on a mixed file.
  • upstream/gem.rs:1180:`` restore_manifest uses the block's ending, falling back to the surrounding text's.
  • Tests: mod.rs:18049 (8 CRLF shapes, each with a re-run no-op) and the real-bundler e2e e2e_redirect_gem_build.rs:4781.```

Verified

  • Read the full diff.
  • cargo test -p socket-patch-core --lib -- gemfile gem:: line_endings: 334/334 pass.
  • CI on 210c955: 82 check runs, 0 failing (31 success, 50 skipped, 1 neutral, which is the Bugbot check).
  • Cursor Bugbot reviewed 210c955 and found no issues; there are no review threads.
  • CHANGELOG.md is untouched.

Changes I made: none.

Open questions: none blocking. One small note: a lone CR at the very end of the file is dropped by the rewrite, and rollback doesn't put it back. That's intended and pinned by a test.

Auto-merge is armed, so approving sends this straight to the merge queue.


Generated by Claude Code

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@mikolalysenko
Mikola Lysenko (mikolalysenko) enabled auto-merge October 29, 2026 19:03
This was referenced Nov 2, 2026
Share one copy_tree across the test suites #1988
Merged
Sweep core utils/python_{lock,script}.rs #1990
Merged
Wenxin-Jiang
Wenxin Jiang (Wenxin-Jiang) approved these changes Nov 2, 2026
View reviewed changes
@mikolalysenko
Mikola Lysenko (mikolalysenko) added this pull request to the merge queue Nov 2, 2026
Wenxin-Jiang
Wenxin Jiang (Wenxin-Jiang) approved these changes Nov 2, 2026
View reviewed changes

@Wenxin-Jiang Wenxin Jiang (Wenxin-Jiang) left a comment

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[agent] Reviewed 210c955b3813d9b5c0d4a3916b0a9c66e3a819ea. Checked CRLF in-place/appended Gemfile blocks and restore line-ending handling. No major correctness issues found. Validation: source and regression-test review plus the available exact-head CI checks; no local test pass is claimed.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Merged via the queue into main with commit 3595c58 Nov 2, 2026
82 checks passed

Uh oh!

There was an error while loading. Please reload this page.

@mikolalysenko
Mikola Lysenko (mikolalysenko) deleted the agent/fix-hosted-gemfile-crlf-block branch November 2, 2026 15:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@cursor cursor[bot] cursor[bot] left review comments
@Wenxin-Jiang Wenxin Jiang (Wenxin-Jiang) Wenxin-Jiang approved these changes

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

Ready for review Agent-verified: mergeable, CI green, Bugbot clean — awaiting human review

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Hosted gem redirect writes the Socket source … do block with LF endings into a CRLF Gemfile, leaving it with mixed line endings

Uh oh!

There was an error while loading. Please reload this page.

3 participants

@mikolalysenko @Wenxin-Jiang @claude
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402520 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.