Skip to content
Snippets Groups Projects
Unverified Commit fd7227d4 authored by aeschylus's avatar aeschylus Committed by GitHub
Browse files

Merge pull request #2116 from ProjectMirador/simple-i18n-lint

Add a simple i18n lint that prints warnings during our build
parents 02538e09 c012edcf
No related branches found
No related tags found
No related merge requests found
......@@ -2,10 +2,10 @@
"translation": {
"aboutThisItem": "Über dieses Element",
"add": "Hinzufügen",
"addedFromUrl": "(via URL hinzugefügt)",
"addManifestUrl": "Ort der Ressource",
"addManifestUrlHelp": "Die URL einer IIIF-Ressource",
"addResource": "Ressource hinzufügen",
"addedFromUrl": "(via URL hinzugefügt)",
"annotations": "Annotationen",
"book": "Buch",
"bottom": "Unten",
......@@ -13,9 +13,9 @@
"canvasIndex": "Index",
"closeAddResourceMenu": "Resourcenliste schließen",
"closeAnnotationCompanionWindow": "Annotationsfenster schließen",
"closeCanvasNavigationCompanionWindow": "Hilfsfenster für die Leinwandnavigation schließen",
"closeCompanionWindow": "Hilfsfenster schließen",
"closeInfoCompanionWindow": "Informationshilfsfenster schließen",
"closeCanvasNavigationCompanionWindow": "Hilfsfenster für die Leinwandnavigation schließen",
"closeWindow": "Fenster schließen",
"closeWindowMenu": "Fenstermenü schließen",
"currentItem": "Objekt",
......@@ -37,22 +37,22 @@
"numItems": "{{number}} Elemente",
"off": "Keine",
"openAnnotationCompanionWindow": "Annotationsfenster öffnen",
"openInfoCompanionWindow": "Informationshilfsfenster",
"openCanvasNavigationCompanionWindow": "Hilfsfenster für die Leinwandnavigation schließen",
"openWindows": "Fenster öffnen",
"openInCompanionWindow": "In Hilfsfenster öffnen",
"openInfoCompanionWindow": "Informationshilfsfenster",
"openWindows": "Fenster öffnen",
"position": "Position",
"previewWindowTitle": "Mirador",
"previousCanvas": "Vorherigen Objekt",
"resource": "Ressource",
"right": "Rechts",
"single": "Einzeln",
"settings": "Einstellungen",
"showZoomControls": "Zoomsteuerung anzeigen",
"showingNumAnnotations": "{{number}} Annotationen werden angezeigt",
"showZoomControls": "Zoomsteuerung anzeigen",
"single": "Einzeln",
"theme": "Farbschema",
"thumbnails": "Miniaturansicht",
"thumbnailNavigation": "Miniaturansicht",
"thumbnails": "Miniaturansicht",
"toggleWindowSideBar": "Seitenleiste umschalten",
"tryAgain": "Wiederholen",
"untitled": "[Unbenannt]",
......
......@@ -2,10 +2,10 @@
"translation": {
"aboutThisItem": "About this item",
"add": "Add",
"addedFromUrl": "(Added from URL)",
"addManifestUrl": "Resource location",
"addManifestUrlHelp": "The URL of a IIIF resource",
"addResource": "Add resource",
"addedFromUrl": "(Added from URL)",
"annotations": "Annotations",
"book": "Book",
"bottom": "Bottom",
......@@ -13,9 +13,9 @@
"canvasIndex": "Index",
"closeAddResourceMenu": "Close add resource panel",
"closeAnnotationCompanionWindow": "Close annotation companion window",
"closeCanvasNavigationCompanionWindow": "Close canvas navigation companion window",
"closeCompanionWindow": "Close this companion window",
"closeInfoCompanionWindow": "Close information companion window",
"closeCanvasNavigationCompanionWindow": "Close canvas navigation companion window",
"closeWindow": "Close window",
"closeWindowMenu": "Close window options menu",
"currentItem": "Current item",
......@@ -32,31 +32,31 @@
"light": "Light",
"listAllOpenWindows": "List all open windows",
"manifestError": "The resource cannot be added:",
"menu": "Menu",
"miradorResources": "Mirador resources",
"miradorViewer": "Mirador viewer",
"nextCanvas": "Next item",
"menu": "Menu",
"mosaic": "Mosaic",
"nextCanvas": "Next item",
"numItems": "{{number}} items",
"off": "Off",
"openAnnotationCompanionWindow": "Open annotation companion window",
"openInfoCompanionWindow": "Open information companion window",
"openCanvasNavigationCompanionWindow": "Open canvas navigation companion window",
"openWindows": "Open windows",
"openInCompanionWindow": "Open in companion window",
"openInfoCompanionWindow": "Open information companion window",
"openWindows": "Open windows",
"position": "Position",
"previewWindowTitle": "Mirador",
"previousCanvas": "Previous item",
"resource": "Resource",
"right": "Right",
"single": "Single",
"selectWorkspaceMenu": "Select workspace type",
"settings": "Settings",
"showZoomControls": "Show Zoom Controls",
"showingNumAnnotations": "Showing {{number}} annotations",
"selectWorkspaceMenu": "Select workspace type",
"showZoomControls": "Show Zoom Controls",
"single": "Single",
"theme": "Theme",
"thumbnails": "Thumbnails",
"thumbnailNavigation": "Thumbnail carousel",
"thumbnails": "Thumbnails",
"toggleWindowSideBar": "Toggle window sidebar",
"tryAgain": "Try again",
"untitled": "[Untitled]",
......@@ -64,10 +64,9 @@
"window": "Window: {{label}}",
"windowMenu": "Window menu",
"workspace": "Workspace",
"workspaceMenu": "Workspace menu",
"workspaceFullScreen": "Full Screen",
"workspaceMenu": "Workspace menu",
"workspaceSelectionTitle": "Select a workspace type",
"workspace": "Workspace",
"zoomIn": "Zoom in",
"zoomOut": "Zoom out",
"zoomReset": "Reset zoom"
......
......@@ -7,7 +7,7 @@
"dist"
],
"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",
"test": "npm run build && npm run lint && npm run size && jest -c jest.json",
"test:watch": "jest -c jest.json --watch",
......@@ -71,6 +71,7 @@
"babel-eslint": "10.0.1",
"babel-jest": "^24.1.0",
"babel-loader": "^8.0.4",
"chalk": "^2.4.2",
"codecov": "^3.1.0",
"concurrently": "^4.0.1",
"css-loader": "^2.1.0",
......@@ -85,6 +86,7 @@
"eslint-plugin-jest": "^22.2.2",
"eslint-plugin-jsx-a11y": "^6.2.0",
"eslint-plugin-react": "^7.12.4",
"glob": "^7.1.3",
"http-server": "^0.11.1",
"jest": "^24.1.0",
"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