Skip to content

l10n: eight apps have bidirectional catalogue drift — .js and .json each hold keys the other lacks #558

Description

@rubenvdlinde

Found while rolling the generated browser catalogue across the fleet (#553, #556, #557 and the nine app PRs).

The nine apps that were fixed

They had no l10n/*.js at all. Nextcloud serves only the .js to a browser, so 8,137 Dutch translations never reached a user. Generating the .js from the .json was safe there: there was nothing to lose.

These eight are different, and must NOT be regenerated

Both halves exist and each holds keys the other does not:

app keys only in .js keys missing from .js stale values
opencatalogi 21,958 4,216 32
openconnector 5,240 18,463 183
procest / dossiq 631 54,646 4,248
launchpad 962 0 8,106
openregister 15 44,194 16,874
softwarecatalog / stackiq 4 2,046 0
docudesk / filinq 0 1,689 15
pipelinq 0 2,128 1,665

(measured 2026-08-23 across every locale pair in each repo)

Running build-l10n-js.js in these repos would delete every key in the first column — 21,958 of them in opencatalogi. I deliberately did not roll the generator into them, and removed the copies made while measuring.

Why this is not mechanically fixable

None of the eight has a .tx/config or a translation workflow, so the .js-only keys are not Transifex output that could simply be re-pulled — they are translations someone produced that the .json never received. Which half is authoritative is a per-app judgement, and getting it wrong silently deletes work.

Suggested disposition, per app

  1. Decide which half is authoritative (probably: union them, .json wins on conflict, since .json is what PHP $l->t() reads).
  2. Merge into the .json.
  3. Then adopt scripts/build-l10n-js.js + check:l10n-js as the nine did, so the pair cannot drift again.

Step 1 is the part that needs a human. Steps 2–3 are mechanical and already proven.

Related

  • Generator + check:l10n-js, shipped to 9 apps
  • check:schema-l10n ratchet, shipped to 18 apps — 30,459 untranslated schema strings measured and frozen
  • Per-app e2e l10n-browser-catalogue.spec.ts — asserts from the browser that the catalogue is served and t() resolves through it

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions