From d50170a4d86ed6cf22a3d1291f7a62a2c1f5c99b Mon Sep 17 00:00:00 2001 From: Naomi Carrigan Date: Tue, 19 Dec 2023 22:41:45 -0800 Subject: [PATCH] feat: manual i18n sync tool (#52637) --- package.json | 1 + tools/scripts/sync-i18n.ts | 44 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 tools/scripts/sync-i18n.ts diff --git a/package.json b/package.json index 115b8f6383a..3c8368df154 100644 --- a/package.json +++ b/package.json @@ -57,6 +57,7 @@ "format": "run-s format:eslint format:prettier", "format:eslint": "eslint . --fix", "format:prettier": "prettier --write .", + "i18n-sync": "ts-node ./tools/scripts/sync-i18n.ts", "knip": "npx -y knip@1 --include files", "knip:all": "npx -y knip@1", "prelint": "pnpm run -F=client predevelop", diff --git a/tools/scripts/sync-i18n.ts b/tools/scripts/sync-i18n.ts new file mode 100644 index 00000000000..23874a2dbe0 --- /dev/null +++ b/tools/scripts/sync-i18n.ts @@ -0,0 +1,44 @@ +import { exec } from 'child_process'; +import { readdir, stat } from 'fs/promises'; +import { join } from 'path'; +import { promisify } from 'util'; + +const asyncExec = promisify(exec); + +const loadDirectory = async (path: string): Promise => { + const files: string[] = []; + const status = await stat(path); + if (status.isDirectory()) { + const filesInDir = await readdir(path); + for (const file of filesInDir) { + files.push(...(await loadDirectory(join(path, file)))); + } + } else { + files.push(path); + } + return files; +}; + +const syncChallenges = async () => { + const ignore = ['.markdownlint.yaml', '_meta', 'english']; + const basePath = join(process.cwd(), 'curriculum', 'challenges'); + const allLangs = await readdir(basePath); + const filtered = allLangs.filter(lang => !ignore.includes(lang)); + // these will be paths + const english = await loadDirectory(join(basePath, 'english')); + for (const path of english) { + for (const lang of filtered) { + const targetPath = path.replace('english', lang); + // we swallow the error here to detect if the file doesn't exist + const status = await stat(targetPath).catch(() => null); + if (!status) { + console.log(`Syncing ${path.split('/english/')[1]}`); + await asyncExec(`mkdir -p ${targetPath} && cp ${path} ${targetPath}`); + } + } + } +}; + +void (async () => { + await syncChallenges(); +})();