Skip to content

Pick the line terminator for spliced lines through one line_endings::terminator #815

Description

[agent] Filed by the scheduled architecture audit routine (ecosystems and formats). Register: register comment.

Kind: refactor. Source: review 4.4 and 5.4 (CRLF policies); register E16. Child 1 of tracking #814.

Problem

Writers that insert or append lines pick the terminator with three hand-written rules (main @ 045d7ec):

Drift, proved by execution. A throwaway unit probe on main, run twice, gave:

  • for "a\nb\r\nc\r\n": detect_eol and pypi_uv::newline_of → CRLF, gradle::newline_of → LF, majority_terminator → CRLF;
  • for "a\r\nb\nc\n": the first two → CRLF, gradle::newline_of → CRLF, majority_terminator → LF.

On a uniform file all three agree.

Symptoms

None filed for these sites specifically. The same disagreement produced #467 and #695 in other writers (see #814).

Impact

Low risk, small. The rules differ only on mixed CRLF/LF files, where a new line comes out in a style that depends on which copy the writer was pasted from.

Proposed change

Size and scope

About 15 files, roughly −60/+40 production lines, plus unit tests. Out of scope: preserve_line_endings and crlf_to_lf (child 2), yarn classic's mixed-file posture (child 3, #467), the pnpm CRLF refusal (review 4.7 G) and the Poetry/PDM rule (PR #703).

Acceptance criteria

  • rg 'contains\("\\r\\n"\) \{ "\\r\\n"' crates/socket-patch-core/src finds no production hits; detect_eol and both newline_of functions are gone.
  • New unit tests in utils/line_endings.rs for terminator: LF, CRLF, None, and mixed with a CRLF majority, an LF majority and a tie.
  • A regression test on one append-and-revert writer (for example go_sum_edit or Gradle append_line) over a mixed file: forward then revert is byte-exact.
  • These stay green: crlf_go_sum_preserves_line_endings, test_crlf_go_mod_preserves_line_endings, rewrites_hash_pinned_continuation_and_preserves_crlf, transitive_append_crlf_root_without_trailing_newline, crlf_pyproject_and_lock_round_trip_byte_exact, kotlin_settings_crlf_and_missing_newline_are_preserved, crlf_and_tabs_are_preserved (maven_reactor), gem_crlf_lock_checksum_pinned_preserving_crlf, gem_crlf_lock_checksums_header_gains_crlf_entry, gemfile_rerun_on_crlf_checkout_never_nests, and the full cargo test -p socket-patch-core.

Dependencies

Blocked by nothing. It touches gradle.rs and maven_reactor.rs lines that #715's children also edit, so rebase whichever lands second. It unblocks children 2–4 of #814.

Activity

added
arch-auditFiled by a scheduled architecture audit routine (see the architecture review discussion)
refactorStructural change: duplicated code or logic, missing abstraction, layering, dead code
on Oct 5, 2026

mikolalysenko commented on Oct 5, 2026

@mikolalysenko
CollaboratorAuthor

[agent] Triaged: priority:p3 (a cross-cutting refactor). This is child 1 of tracking issue #814. Confirmed on main: common::detect_eol, pypi_uv::newline_of and gradle::newline_of (which follows a different rule) all still exist. Not a duplicate, and no open PR covers it.


Generated by Claude Code

mikolalysenko commented on Oct 8, 2026

@mikolalysenko
CollaboratorAuthor

[agent] Claiming this issue for the architecture refactor routine (highest leverage: the only refactor slice left whose files no open PR changes; it collapses 8 copies of the "any \r\n → CRLF" rule into one line_endings::terminator). Branch: arch-refactor/815-line-terminator. Claim-ID: 2026-10-08T03:56:03Z-4c3126

Slice taken (slice 1): add utils::line_endings::terminator and route the copies in files no open PR touches: formats/gem/hosted.rs, redirect/upstream/{composer,gem,pypi}.rs, redirect/pipenv.rs, utils/python_script.rs and vendor/go_mod_edit.rs (2 sites). Remaining (slice 2, after the open PRs that change those files land): vendor::common::detect_eol and its callers, pypi_uv::newline_of, maven_reactor.rs ×2, redirect/mod.rs, the crlf flags in upstream/cargo.rs/npmrc.rs/pypi_pipenv.rs, and the Gradle newline_of.


Generated by Claude Code

mikolalysenko commented on Oct 8, 2026

@mikolalysenko
CollaboratorAuthor

[agent] Draft PR for slice 1: #1108.


Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    agent:claimedagent:triagedarch-auditFiled by a scheduled architecture audit routine (see the architecture review discussion)priority:p3refactorStructural change: duplicated code or logic, missing abstraction, layering, dead code

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions