diff --git a/.claude/skills/find-missing-translations/SKILL.md b/.claude/skills/find-missing-translations/SKILL.md index 3e195b7088..02a2a4b1ca 100644 --- a/.claude/skills/find-missing-translations/SKILL.md +++ b/.claude/skills/find-missing-translations/SKILL.md @@ -38,11 +38,17 @@ The default set of locales (unless the user specifies otherwise): | Locale | Language | Directory | |--------|----------|-----------| -| `cs-rCZ` | Czech | `values-cs-rCZ` | +| `cs` | Czech | `values-cs` | | `pt-rBR` | Brazilian Portuguese | `values-pt-rBR` | | `sv-rSE` | Swedish | `values-sv-rSE` | | `de-rDE` | German | `values-de-rDE` | +> Czech was consolidated onto the base qualifier (PR #3461, 2026-07-03): a +> `cs: cs` `languages_mapping` entry in `crowdin.yml` makes Crowdin export to +> `values-cs`, and `values-cs-rCZ` no longer exists. The other locales still +> use Crowdin's default region-qualified `androidCode` until they are +> consolidated the same way — update this table as each one moves. + ## Technique ### 1. Identify files @@ -52,9 +58,9 @@ Default: amethyst/src/main/res/values/strings.xml Target: amethyst/src/main/res/values-/strings.xml ``` -### 2. Find missing keys using cs-rCZ as reference +### 2. Find missing keys using cs as reference -Always diff against `cs-rCZ` first — it is the most complete locale and serves as the reference. Any keys missing in `cs-rCZ` will also be missing in the other target locales. +Always diff against `cs` first — it is the most complete locale and serves as the reference. Any keys missing in `cs` will also be missing in the other target locales. You MUST diff **both** `` in the source will never appear in a `` diff. Forgetting `` is the most common silent failure of this skill (it misses things like `music_playlist_track_count`, `notification_count_more`, etc.). @@ -65,7 +71,7 @@ comm -23 \ <(grep ' ===" comm -23 \ <(grep '` translations need the per-locale CLDR category set (see Step 5 → "Plurals: handle with care"). -Crowdin can asymmetrically strip keys across locales (each translator independently chose source-identical for different keys), so **cs-rCZ is not a reliable upper bound**. Diff **every** target locale and union the results — don't assume the cs-rCZ set covers the others. A quick per-locale count is a useful sanity check against the Crowdin UI's "N untranslated": +Crowdin can asymmetrically strip keys across locales (each translator independently chose source-identical for different keys), so **cs is not a reliable upper bound**. Diff **every** target locale and union the results — don't assume the cs set covers the others. A quick per-locale count is a useful sanity check against the Crowdin UI's "N untranslated": ```bash -for locale in cs-rCZ de-rDE sv-rSE pt-rBR; do +for locale in cs de-rDE sv-rSE pt-rBR; do ns=$(comm -23 \ <(grep ': extract the multi-line block (opening tag through ) @@ -124,7 +130,7 @@ while IFS= read -r key; do done < <(comm -23 \ <(grep '` is a separate resource type; a source `` missing from a locale will never show up in a `` diff. Always run the diff twice (once per resource type) as shown in Step 2. The same goes for `` if the project uses it. - **Trusting a git "sync-timestamp" heuristic to pre-filter the list** — this skill used to skip keys added before the last `New Crowdin translations` commit, on the theory that Crowdin had already "decided" them. It was dropped: a key added shortly before an export that translators hadn't reached yet is genuinely missing, so the heuristic silently dropped real work. Use the raw on-disk diff and reconcile against the Crowdin web UI's untranslated count instead. - **Adding source-identical fallbacks locally** — they get overwritten on the next Crowdin sync. Android falls back to `values/strings.xml` at runtime anyway, so a key intentionally kept as English already renders correctly. Skip these by inspection (brand terms, loanwords, `v%1$s`-style strings); don't translate them to an identical value. -- **Skipping per-locale diffs when only diffing cs-rCZ** — Crowdin can strip different keys in different locales (each translator's choice), so cs-rCZ is not a reliable upper bound. Diff each target locale and union the results. +- **Skipping per-locale diffs when only diffing cs** — Crowdin can strip different keys in different locales (each translator's choice), so cs is not a reliable upper bound. Diff each target locale and union the results. - **Inserting strings in a specific position** — always append at the bottom; ordering is handled separately - **Hardcoding `"1"` in a `` `quantity="one"` item** — always use the count placeholder; otherwise non-English `one` categories produce wrong text - **Copying English's `one`/`other` set into every locale** — each language must include all CLDR plural categories it uses (e.g. Czech needs `one`, `few`, `many`, `other`)