Skip to content

fix: per-file fix reporting, BOM-safe contents insertion, stale-offset guard - #419

Merged
MaximeGaudin merged 9 commits into
mainfrom
fix/issue-227-fix-cluster
Aug 29, 2026
Merged

fix: per-file fix reporting, BOM-safe contents insertion, stale-offset guard#419
MaximeGaudin merged 9 commits into
mainfrom
fix/issue-227-fix-cluster

Conversation

@MaximeGaudin

Copy link
Copy Markdown
Owner

Summary

A cluster of correctness/atomicity fixes around --fix:

Fixes #227
Fixes #230
Fixes #234
Fixes #247
Fixes #277

Test plan

Note: a_later_path_with_its_own_config_is_named_when_the_first_path_governs is a pre-existing flake reproducible on origin/main (XDG_CONFIG_HOME env mutation racing parallel tests); it is unrelated to this diff.

A write failure partway through a multi-file run used to return before the
report was rendered, leaving the files fixed before it on disk and nothing
but a bare error line behind. apply() now records a per-file failure and
continues with the remaining files; the CLI turns each failure into a note
on the report and exits with the failed code, so the reader sees exactly
which files changed and which did not.

Fixes #227
with_contents() read the file's first line as the literal text with the
mark, so a UTF-8 BOM kept the title line from matching and the Contents
block was spliced in above the mark and the title it belongs under. The
first line is now scanned past the mark — the same tolerance the parser
applies to frontmatter — and the mark's bytes stay on disk untouched.

Fixes #230
A fix is a byte range into the text it was measured against, but
apply_to_file() re-read the file and trusted the offsets blindly — a file
rewritten between the lint pass and the fix pass, even to the same length,
had the fix spliced into bytes nobody measured. The report now records a
fingerprint (length plus a cheap hash) of every fixable file's text when it
is read, and apply() re-checks the file against it before writing: a
mismatch skips that file with a note saying why, the same channel the
failed-write report speaks through.

Fixes #234
Fixes #247
Pins both halves of the behaviour: a read-only file is still fixable,
because the replacement asks the directory for room rather than the file
for permission and keeps the mode it had; and when the directory refuses
too, the run reports the failed write and still fixes the other files.

Red at c226adf (before the per-file failure reporting), green at HEAD.
@MaximeGaudin
MaximeGaudin merged commit 7f6f3ea into main Aug 29, 2026
4 of 8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment