Skip to content

Leave unchanged JSON locale files alone and keep their trailing newline - #124

Merged
arvida merged 1 commit into
mainfrom
fix/859-json-write-noise
Oct 9, 2026
Merged

arvida merged 1 commit into
mainfrom
fix/859-json-write-noise

Conversation

@arvida

@arvida arvida commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

Bug

Every JSON write re-serialised the whole file with JSON.stringify(x, null, 2) and no trailing newline, even when nothing changed. In a sync the source-language cells are part of the payload, so a hand-formatted en.json was rewritten on every sync: inline arrays and one-line objects got exploded, and git showed \ No newline at end of file (newsroom-demo PR #19). The delete path had the same problem on a larger scale: pull calls it for every translation file when keys were deleted, and each JSON file was rewritten even when it held none of those keys.

Change

All in src/utils/translation-updater/json-handler.ts:

  • updateJsonFile skips the write when the merged content serialises exactly like what was read (compact JSON.stringify on both, so key order counts too). The skip only happens when a write would have changed nothing but whitespace. A file that is new or unparseable is always written.
  • deleteKeysFromJsonFile returns without writing when none of the keys were in the file.
  • When a file is written, it keeps its trailing newline if it had one. New files get one. A file without one keeps none.
  • Return values are unchanged (updatedKeys, created, deleted keys), so counts and summaries stay the same.

Not changed: indentation is still 2 spaces, and a file that really does change still has inline arrays expanded. Keeping those would need a splicer like yaml-splicer.ts.

Plan with a caller audit (translate, ci sync in git and signed-commit mode, pull update and delete, source alignment, multi-language files, new files): dev-docs/specs/859-json-write-noise.md in the monorepo. Codex reviewed the plan and found no blockers.

Verified

  • New tests in tests/utils/translation-updater/json-write-noise.test.ts were written first: 6 of the 7 failed on main's code. The 7th covers a file without a trailing newline, which main already left alone. They cover a byte-identical hand-formatted file with unchanged values, a byte-identical multi-language file, the newline kept after a real change, no newline added to a file without one, a new file ending in a newline, a delete leaving a file without those keys untouched, and a delete keeping the newline.
  • npm test: 83 suites, 1502 tests pass. npx tsc --noEmit and npx eslint 'src/**/*.ts' are clean.
  • Built dist and ran updateTranslationFile on a copy of newsroom-demo's apps/editor en.json with its own values, which is what a sync does. The file stayed byte-identical (34 lines in, 34 out). A real change to sv.json updated the value and kept the newline.
  • Codex review of the diff: no findings. A separate code-reviewer pass: no blockers.

Known edge case, not a blocker: a file with a duplicated key is no longer cleaned up by a no-op write, since the write is skipped.

Fixes localheroai/localhero-ai#859

- Skip the write when the merged content equals what was read, so a sync no longer reformats the source file
- Skip the delete-path write when none of the keys were in the file
- Keep the trailing newline when the file had one; new files end with one
- Fixes localheroai/localhero-ai#859
@arvida
arvida merged commit 3b484d1 into main Oct 9, 2026
1 check passed
This was referenced Oct 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant