From 521890638575ee8f7dce020b8dc43cc01279ba08 Mon Sep 17 00:00:00 2001 From: Jeff Avallone Date: Thu, 15 Feb 2018 21:19:25 -0500 Subject: [PATCH] Adding script to scrub locale files For any keys in en/translation.yaml and missing in /translation.yaml, this tool will add the key to /missing.yaml. This is to facilitate translation of keys that have been added to the app. This also serves as a lint-like tool for translation files since they will all be re-written when running. --- package.json | 2 ++ script/i18n-scrub.js | 80 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 script/i18n-scrub.js diff --git a/package.json b/package.json index 6bca144..fb47568 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "test:unit": "jest", "test:lint": "eslint --ignore-path .gitignore .", "test:watch": "yarn test:unit --watch", + "i18n:scrub": "node ./script/i18n-scrub.js", "precommit": "run-s test:lint" }, "browserslist": [ @@ -161,6 +162,7 @@ "devDependencies": { "http-server": "^0.11.1", "husky": "^0.14.3", + "js-yaml": "^3.10.0", "webpack-dev-server": "^2.11.1" } } diff --git a/script/i18n-scrub.js b/script/i18n-scrub.js new file mode 100644 index 0000000..ad1e8eb --- /dev/null +++ b/script/i18n-scrub.js @@ -0,0 +1,80 @@ +const util = require('util'); +const path = require('path'); +const fs = require('fs'); +const yaml = require('js-yaml'); + +const readdir = util.promisify(fs.readdir); +const readFile = util.promisify(fs.readFile); +const writeFile = util.promisify(fs.writeFile); + +const localesDir = path.resolve(__dirname, '../src/locales'); + +const loadLocales = async () => { + const languages = (await readdir(localesDir)).filter(name => name !== 'index.js'); + + let localeData = {}; + + await Promise.all(languages.map(async lang => { + const langDir = path.resolve(localesDir, lang); + const namespaces = (await readdir(langDir)) + .filter(file => /\.yaml$/.test(file)); + + localeData[lang] = {}; + + await Promise.all(namespaces.map(async ns => { + const nsFile = path.resolve(langDir, ns); + localeData[lang][ns.replace('.yaml', '')] = yaml.safeLoad(await readFile(nsFile)); + })); + })); + + return localeData; +}; + +const saveLocales = async locales => { + await Promise.all(Object.keys(locales).map(async langName => { + const lang = locales[langName]; + + await Promise.all(Object.keys(lang).map(async nsName => { + const nsFile = path.resolve(localesDir, langName, `${ nsName }.yaml`); + const yamlDump = yaml.safeDump(lang[nsName], { + sortKeys: true + }); + await writeFile(nsFile, yamlDump); + })); + })); +}; + +loadLocales() + .then(async locales => { + const requiredKeys = Object.keys(locales.en.translation); + const languages = Object.keys(locales).filter(lang => lang !== 'en'); + + languages.forEach(langName => { + const lang = locales[langName]; + const presentKeys = Object.keys(lang.translation || {}); + + if (!lang.translation) { + lang.translation = {}; + } + + if (!lang.missing) { + lang.missing = {}; + } + + requiredKeys.forEach(key => { + if (!presentKeys.includes(key)) { + console.log(`es needs translation for "${ key }"`); // eslint-disable-line no-console + lang.missing[key] = locales.en.translation[key]; + } + }); + }); + + await saveLocales(locales); + }) + .then(() => { + console.log('Done updating locales'); // eslint-disable-line no-console + }) + .catch(e => { + console.log(e.toString()); // eslint-disable-line no-console + process.exit(1); + });