Skip to content
Snippets Groups Projects
Commit 0463d429 authored by Jessie Keck's avatar Jessie Keck
Browse files

Add a basic i18n lint implementation that will warn us about missing and unsorted keys

parent ecad5306
No related branches found
No related tags found
No related merge requests found
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
"dist" "dist"
], ],
"scripts": { "scripts": {
"lint": "node_modules/.bin/eslint ./ && node_modules/.bin/sass-lint -v ./src/styles/**/*", "lint": "node_modules/.bin/eslint ./ && node_modules/.bin/sass-lint -v ./src/styles/**/* && node ./scripts/i18n-lint.js",
"server": "node_modules/.bin/http-server", "server": "node_modules/.bin/http-server",
"test": "npm run build && npm run lint && npm run size && jest -c jest.json", "test": "npm run build && npm run lint && npm run size && jest -c jest.json",
"test:watch": "jest -c jest.json --watch", "test:watch": "jest -c jest.json --watch",
...@@ -71,6 +71,7 @@ ...@@ -71,6 +71,7 @@
"babel-eslint": "10.0.1", "babel-eslint": "10.0.1",
"babel-jest": "^24.1.0", "babel-jest": "^24.1.0",
"babel-loader": "^8.0.4", "babel-loader": "^8.0.4",
"chalk": "^2.4.2",
"codecov": "^3.1.0", "codecov": "^3.1.0",
"concurrently": "^4.0.1", "concurrently": "^4.0.1",
"css-loader": "^2.1.0", "css-loader": "^2.1.0",
...@@ -85,6 +86,7 @@ ...@@ -85,6 +86,7 @@
"eslint-plugin-jest": "^22.2.2", "eslint-plugin-jest": "^22.2.2",
"eslint-plugin-jsx-a11y": "^6.2.0", "eslint-plugin-jsx-a11y": "^6.2.0",
"eslint-plugin-react": "^7.12.4", "eslint-plugin-react": "^7.12.4",
"glob": "^7.1.3",
"http-server": "^0.11.1", "http-server": "^0.11.1",
"jest": "^24.1.0", "jest": "^24.1.0",
"jest-fetch-mock": "^2.1.1", "jest-fetch-mock": "^2.1.1",
......
const glob = require('glob'); // eslint-disable-line import/no-extraneous-dependencies
const fs = require('fs');
const chalk = require('chalk'); // eslint-disable-line import/no-extraneous-dependencies
const { log } = console;
const globOpts = { cwd: 'locales' };
const defaultLocaleFile = 'en/translation.json';
const files = glob.sync('**/translation.json', globOpts);
const normalizedFiles = {};
const errors = {};
/**
* Return a new copy of the array lowercased and sorted
*/
function lowerCaseSortedArray(arr) {
return arr.slice().map(v => v.toLowerCase()).sort();
}
/**
* Return the keys in an array that are not sorted (not considering case in sort)
*/
function unsortedKeys(arr) {
const sortedArray = lowerCaseSortedArray(arr);
return arr.filter((v, i) => v.toLowerCase() !== sortedArray[i]);
}
/**
* Return any keys in array 2 that are not in array 1
* (values will be sorted and downcased for comparison)
*/
function missingKeys(arr1, arr2) {
const sortedDonwcasedLeftHandArray = lowerCaseSortedArray(arr1);
const sortedDonwcasedRightHandArray = lowerCaseSortedArray(arr2);
return sortedDonwcasedLeftHandArray.filter((v, i) => v !== sortedDonwcasedRightHandArray[i]);
}
files.forEach((fileName) => {
const fileContent = fs.readFileSync(`locales/${fileName}`);
normalizedFiles[fileName] = Object.keys(JSON.parse(fileContent.toString()).translation);
});
const completeKeys = normalizedFiles[defaultLocaleFile].slice().sort();
Object.keys(normalizedFiles).forEach((fileName) => {
const unsorted = unsortedKeys(normalizedFiles[fileName]);
const missing = missingKeys(completeKeys, normalizedFiles[fileName]);
if (unsorted.length) {
errors[fileName] = errors[fileName] || [];
errors[fileName].push('Keys are not sorted properly');
errors[fileName].push(
`\tSorting starts to be incorrect around: ${unsorted[0]}`,
);
}
if (missing.length) {
errors[fileName] = errors[fileName] || [];
errors[fileName].push('Some keys from the default locale file are missing');
errors[fileName].push(
`\tMissing keys: ${missing.join(', ')}`,
);
}
});
Object.keys(errors).forEach((errorFileName) => {
log(chalk.red(`${chalk.inverse.bold(errorFileName)} has ${chalk.underline.bold('internationalization')} errors`));
errors[errorFileName].forEach((error) => {
log(`\t${chalk.yellow(error)}`);
});
});
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment