Fix Portuguese Portugal upload code and document local alias boundaries

Map pt-PT to pt_PT and upload the shared target once. Verify that canonical alias targets are registered and loaded while retaining local variant wording. Offline upload and language-loader checks pass; no uploads were run.

Thanks to xet7 !
This commit is contained in:
Lauri Ojansivu committed 2026-09-13 18:35:42 +03:00
1 parent 38e7cf81a4
commit 0c0adb48b9
4 files changed
+18 -4

No files matched your search

+1 -1
View File
@@ -1,6 +1,6 @@
[main]
host = https://www.transifex.com
lang_map = te_IN: te-IN, es_AR: es-AR, es_CO: es-CO, es_419: es-LA, es_TX: es-TX, he_IL: he-IL, zh_CN: zh-CN, ar_EG: ar-EG, cs_CZ: cs-CZ, fa_IR: fa-IR, ms_MY: ms-MY, nl_NL: nl-NL, de_CH: de-CH, en_IT: en-IT, uz_UZ: uz-UZ, fr_CH: fr-CH, fr_BE: fr-BE, fr_CA: fr-CA, km_KH: km-KH, gug_PY: gn, hi_IN: hi-IN, et_EE: et-EE, es_PE: es-PE, es_MX: es-MX, gl_ES: gl-ES, mn_MN: mn, zh_TW: zh-TW, ast_ES: ast-ES, es_CL: es-CL, ja_JP: ja-JP, lv_LV: lv, ro_RO: ro-RO, az_AZ: az-AZ, cy_GB: cy-GB, gu_IN: gu-IN, pl_PL: pl-PL, vep: ve-PP, en_BR: en-BR, en@ysv: en-YS, hu_HU: hu, ko_KR: ko-KR, pt_BR: pt-BR, zh_HK: zh-HK, zu_ZA: zu-ZA, en_MY: en-MY, ja-Hira: ja-HI, fi_FI: fi, vec: ve-CC, vi_VN: vi-VN, fr_FR: fr-FR, id_ID: id, zh_Hans: zh-Hans, en_DE: en-DE, en_GB: en-GB, el_GR: el-GR, uk_UA: uk-UA, az@latin: az-LA, de_AT: de-AT, uz@Latn: uz-LA, vls: vl-SS, ar_DZ: ar-DZ, bg_BG: bg, es_PY: es-PY, fy_NL: fy-NL, uz@Arab: uz-AR, ru_UA: ru-UA, war: wa-RR, zh_CN.GB2312: zh-GB
lang_map = te_IN: te-IN, es_AR: es-AR, es_CO: es-CO, es_419: es-LA, es_TX: es-TX, he_IL: he-IL, zh_CN: zh-CN, ar_EG: ar-EG, cs_CZ: cs-CZ, fa_IR: fa-IR, ms_MY: ms-MY, nl_NL: nl-NL, de_CH: de-CH, en_IT: en-IT, uz_UZ: uz-UZ, fr_CH: fr-CH, fr_BE: fr-BE, fr_CA: fr-CA, km_KH: km-KH, gug_PY: gn, hi_IN: hi-IN, et_EE: et-EE, es_PE: es-PE, es_MX: es-MX, gl_ES: gl-ES, mn_MN: mn, zh_TW: zh-TW, ast_ES: ast-ES, es_CL: es-CL, ja_JP: ja-JP, lv_LV: lv, ro_RO: ro-RO, az_AZ: az-AZ, cy_GB: cy-GB, gu_IN: gu-IN, pl_PL: pl-PL, vep: ve-PP, en_BR: en-BR, en@ysv: en-YS, hu_HU: hu, ko_KR: ko-KR, pt_BR: pt-BR, pt_PT: pt-PT, zh_HK: zh-HK, zu_ZA: zu-ZA, en_MY: en-MY, ja-Hira: ja-HI, fi_FI: fi, vec: ve-CC, vi_VN: vi-VN, fr_FR: fr-FR, id_ID: id, zh_Hans: zh-Hans, en_DE: en-DE, en_GB: en-GB, el_GR: el-GR, uk_UA: uk-UA, az@latin: az-LA, de_AT: de-AT, uz@Latn: uz-LA, vls: vl-SS, ar_DZ: ar-DZ, bg_BG: bg, es_PY: es-PY, fy_NL: fy-NL, uz@Arab: uz-AR, ru_UA: ru-UA, war: wa-RR, zh_CN.GB2312: zh-GB
[o:wekan:p:wekan:r:application]
file_filter = imports/i18n/data/<lang>.i18n.json
+6 -1
View File
@@ -54,7 +54,7 @@ of that remote target. The explicit mapping selects `es-CO.i18n.json`, and the
script reports the alias instead of uploading the same target twice. Both local
files remain available; all nine differences were reviewed, with three erroneous values repaired and
seven valid wording alternatives retained.
The offline dry run reports 243 distinct targets and the English source.
The offline dry run reports 242 distinct targets and the English source.
French Belgium/Canada use `fr_BE`/`fr_CA`, Khmer Cambodia uses `km_KH`,
and Guarani uses Transifex's `gug_PY`. The Khmer hyphen/underscore files
@@ -62,3 +62,8 @@ share one target. Transifex's public catalogue currently lists no Manx (`gv`)
or Ladin (`lld`); these failures remain visible. Ladin must not be mapped to
Ladino (`lad`), which is a different language. Catalogue reference:
https://explore.transifex.com/languages/
Portuguese Portugal maps `pt-PT.i18n.json` to `pt_PT`; the local underscore
variant shares the remote target and is reported as an alias. Local variants
keep their wording; only the explicitly mapped canonical file round-trips
through Transifex. The canonical file remains registered and loaded.
+9
View File
@@ -172,6 +172,15 @@ test('a Transifex pull writes the file the app loads, for every language', () =>
for (const [, tag, file] of entries) {
const written = mapping[tag] || tag;
if (written === file) continue;
// Deliberate local variants share one remote target. The canonical mapped
// file MUST have its own registered loader; the alias keeps valid local
// wording and is not claimed to round-trip independently through Transifex.
const localVariants = { es_CO: 'es-CO', pt_PT: 'pt-PT' };
if (localVariants[tag] === written && file === tag) {
assert.ok(entries.some(([, , loadedFile]) => loadedFile === written),
`canonical variant ${written} receives the pull and is loaded`);
continue;
}
const a = real(written);
// Only a real, separate file proves the pull lands somewhere unread. A
// symlink makes both names the same file, and a name with no file at all
+2 -2
View File
@@ -17,7 +17,7 @@ const root = path.resolve(__dirname, '..');
assert.equal(colombian[0].file, 'es-CO', 'explicit mapping chooses canonical local file');
assert.deepEqual(colombian[0].aliases, ['es_CO']);
assert.ok(!localLanguages(config).some(row => row.code === 'es-CO'), 'never register an unsupported hyphenated code');
for (const [file, code] of [['fr-BE','fr_BE'], ['fr-CA','fr_CA'], ['km-KH','km_KH'], ['gn','gug_PY']]) {
for (const [file, code] of [['fr-BE','fr_BE'], ['fr-CA','fr_CA'], ['km-KH','km_KH'], ['gn','gug_PY'], ['pt-PT','pt_PT']]) {
assert.equal(localLanguages(config).find(row => row.file === file).code, code);
assert.ok(!localLanguages(config).some(row => row.code === file));
}
@@ -75,6 +75,6 @@ const root = path.resolve(__dirname, '..');
assert.equal(network, 0, 'pagination cannot send credentials to another origin');
const dry = cp.spawnSync('sh', [path.join(root, 'releases/translations/push-all-translations.sh'), '--dry-run'], { cwd: path.join(root, '.tools/tmp'), env: { ...process.env, NODE_BIN: process.execPath }, encoding: 'utf8' });
assert.equal(dry.status, 0, dry.stderr);
assert.match(dry.stdout, /243 targets and source en; no network requests/);
assert.match(dry.stdout, /242 targets and source en; no network requests/);
console.log('transifexForcePush: full uploads, polling, mapped languages, additive registration, failure continuation and summary, token origin boundary and offline wrapper passed');
})().catch(error => { console.error(error); process.exitCode = 1; });