mirror of
https://github.com/wekan/wekan.git
synced 2026-11-05 01:20:07 -05:00
Fix Colombian Spanish Transifex mapping and duplicate target uploads
Map es-CO to supported es_CO and prefer explicit local mappings when a legacy alias shares the remote code. Report skipped aliases rather than overwriting one target twice. Offline force-upload tests pass; no remote upload was run. Nine local alias differences still need reconciliation. Thanks to xet7 !
This commit is contained in:
1 parent
46a8b785f8
commit
27a566a0d5
5 files changed
+33
-7
No files matched your search
+1
-1
@@ -1,6 +1,6 @@
|
||||
[main]
|
||||
host = https://www.transifex.com
|
||||
lang_map = te_IN: te-IN, es_AR: es-AR, 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, 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, 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
|
||||
|
||||
[o:wekan:p:wekan:r:application]
|
||||
file_filter = imports/i18n/data/<lang>.i18n.json
|
||||
|
||||
@@ -6,7 +6,7 @@ Run the explicit upload operation from any directory:
|
||||
releases/translations/push-all-translations.sh
|
||||
```
|
||||
|
||||
It uploads the English source and every other local language file, including
|
||||
It uploads the English source and every distinct remote target language, including
|
||||
regional English variants. Local translation values replace the corresponding
|
||||
remote values, irrespective of file or remote modification times. Source strings
|
||||
edited remotely are also replaced by the local source. This operation publishes
|
||||
@@ -47,3 +47,10 @@ The upload implementation follows the [Transifex API v3 documentation](https://t
|
||||
It bypasses the CLI's timestamp skip rather than using an undocumented force
|
||||
attribute. The [CLI documentation](https://developers.transifex.com/docs/cli)
|
||||
describes `--force` as disabling that timestamp skip.
|
||||
|
||||
Colombian Spanish maps `es-CO.i18n.json` to Transifex `es_CO`; `es-CO`
|
||||
is not a supported Transifex code. The legacy `es_CO.i18n.json` file is an alias
|
||||
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; their nine differing values still require reconciliation.
|
||||
The offline dry run reports 244 distinct targets and the English source.
|
||||
@@ -130,6 +130,11 @@ async function main() {
|
||||
const config = readConfig();
|
||||
if (!config.sourceFile) throw new Error('Missing source_file in .tx/config');
|
||||
const languages = localLanguages(config);
|
||||
for (const language of languages) {
|
||||
for (const alias of language.aliases || []) {
|
||||
console.log(`[tx] alias ${alias}.i18n.json -> ${language.code}; using mapped ${language.file}.i18n.json`);
|
||||
}
|
||||
}
|
||||
const source = JSON.parse(fs.readFileSync(config.sourceFile, 'utf8'));
|
||||
if (args.includes('--dry-run')) {
|
||||
const failures = [];
|
||||
|
||||
@@ -61,12 +61,21 @@ export function readConfig() {
|
||||
// Every language WeKan ships, as the code Transifex knows it by. English is the
|
||||
// SOURCE language, so it is not a target and is left out.
|
||||
export function localLanguages({ localToTx, sourceLanguage = 'en' }) {
|
||||
return readdirSync(DATA_DIR)
|
||||
const targets = new Map();
|
||||
const files = readdirSync(DATA_DIR)
|
||||
.filter(f => f.endsWith('.i18n.json'))
|
||||
.map(f => f.replace('.i18n.json', ''))
|
||||
.filter(name => name !== sourceLanguage)
|
||||
.map(name => ({ file: name, code: localToTx.get(name) || name }))
|
||||
.sort((a, b) => a.code.localeCompare(b.code));
|
||||
.filter(name => name !== sourceLanguage);
|
||||
// Explicit filename mappings win over a second file named after the same
|
||||
// remote code. One remote language cannot retain two different uploads.
|
||||
files.sort((a, b) => Number(localToTx.has(b)) - Number(localToTx.has(a)) || a.localeCompare(b));
|
||||
for (const file of files) {
|
||||
const code = localToTx.get(file) || file;
|
||||
const target = targets.get(code);
|
||||
if (target) (target.aliases ||= []).push(file);
|
||||
else targets.set(code, { file, code });
|
||||
}
|
||||
return [...targets.values()].sort((a, b) => a.code.localeCompare(b.code));
|
||||
}
|
||||
|
||||
// ── the token ───────────────────────────────────────────────────────────────
|
||||
|
||||
@@ -12,6 +12,11 @@ const root = path.resolve(__dirname, '..');
|
||||
assert.ok(localLanguages(config).some(row => row.file === 've-PP' && row.code === 'vep'));
|
||||
assert.ok(localLanguages(config).some(row => row.file === 'en-GB' && row.code === 'en_GB'));
|
||||
assert.ok(!localLanguages(config).some(row => row.file === 'en'));
|
||||
const colombian = localLanguages(config).filter(row => row.code === 'es_CO');
|
||||
assert.equal(colombian.length, 1, 'upload each remote language only once');
|
||||
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');
|
||||
const content = JSON.stringify({ title: 'Title __card__', empty: '' });
|
||||
const source = JSON.parse(content);
|
||||
assert.doesNotThrow(() => validateTranslation(content, source), 'intentional empty source strings are valid');
|
||||
@@ -66,6 +71,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, /245 targets and source en; no network requests/);
|
||||
assert.match(dry.stdout, /244 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; });
|
||||
Reference in new issue
Block a user