Repository navigation
Fix CRLF .npmrc append with no final newline (#1196) - #1417
Mikola Lysenko (mikolalysenko) wants to merge 3 commits into
Conversation
Assisted-by: Claude Code:claude-opus-5-5
A hosted npm scan that appended allow-remote=all to a CRLF .npmrc whose last line had no terminator wrote ...\nallow-remote=all\r: the old last line lost its CR and the file ended in a lone CR, a shape socket-patch itself refuses to edit later. The old last line now gets the file's terminator and the new line keeps the no-final-newline shape. LF files are unchanged. Fixes #1196 Assisted-by: Claude Code:claude-opus-5-5
Derive the spliced line's ending from one terminator, skip BOM-only lines when choosing where the line goes (npm reads them as blank), update the docs for the terminated last line, and have the CLI test re-run scan to show the written file is read back, not refused. Refs #1196 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 758f53a. Configure here.
|
Ready for review (burn-down agent)
Generated by Claude Code |
Final review briefWhat it does. Fixes #1196. A hosted npm scan that appended Risk: low. One planner function. The only output that changes is the unterminated-last-line case. For mixed files the CR decision is the same as before ( Look here
Verified. Read the full diff and the helpers it uses ( Changes I made. None. Open questions. None. Auto-merge 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 #1196
Summary
A hosted npm scan that appended
allow-remote=allto a CRLF project.npmrcwhose last line had no terminator (a common Windows editor save) wrote…audit=false\nallow-remote=all\r. The old last line lost its CR and the file ended in a lone CR, which the planner itself refuses (Unsupported, CR-only) on any later run. It now writes…audit=false\r\nallow-remote=all. LF files and files that end in a newline produce the same output as before.Root cause
plan_npmrc_allow_remote_with(crates/socket-patch-core/src/patch/redirect/npmrc.rs) splits the file on\n, insertsallow-remote=all\r(CRLF files) after the last non-empty top-level line, and joins with\n. The baked-in\rassumes a\nfrom the join follows it. When the anchor is past an unterminated last line, the new line becomes the tail: nothing follows it, and the old last line gets the join's bare\n.Fix
line_endings::terminator) and then the line, keeping the no-final-newline shape.js_trim(npm's whitespace, which includes U+FEFF) rather thanstr::trim, so a stray BOM-only line counts as blank, the way npm reads it.NpmrcPlan::Appendand planner docs. The appended line has no unwind path: a user-owned.npmrcis never edited by rollback (npm_allow_remote_left), so terminating the old last line doesn't affect any revert.Tests
npmrc::tests::append_after_an_unterminated_last_line_keeps_its_terminator(CRLF, BOM+CRLF, LF, one line, BOM-only tail; re-plan isAlreadyAll)"fund=false\r\naudit=false\nallow-remote=all\r"vendorsuite:crlf_npmrc_without_final_newline_keeps_crlf_on_append(the issue's repro throughscan --mode hosted, then a second scan shows no CR-only refusal and no rewrite)Local runs:
cargo fmt --all -- --check: cleancargo clippy --workspace --all-features -- -D warnings: cleancargo test -p socket-patch-core --all-features --lib: 6334 passed, 4 failed. All 4 failures are chmod-0555 permission tests (vlt_heal,copy_tree,pypi_poetry,pypi_requirements) that can't fail as root, and the sandbox runs as uid 0. None of them touch this code.cargo test -p socket-patch-cli --all-features --test vendor: 94 passedcargo test --workspace --all-featuresran out of this sandbox's disk allowance while linking test binaries, so I couldn't finish it locally. CI runs the full set.npm/,pypi/andgem/have no.npmrclogic.Review notes (/code-review high)
Fixed: stale docs, the duplicated terminator decision,
trimvsjs_trim, and the missing second-scan check. Not done: the reviewer suggested folding the end-of-file case into the general splice instead of an early return. The early return is the one place where the inserted line has nothing after it, and the comment explains why, so I kept it.🤖 Generated with Claude Code
https://claude.ai/code/session_01MLrkKwvWmW2Zmi46c1dRCT
Generated by Claude Code