Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tool/unused i18n token finder #457

Closed
wants to merge 8 commits into from
Clean up and document unused i18n token finder script
  • Loading branch information
wlycdgr committed Oct 3, 2019
commit 9064846375e7c7f26938bd4a0f220413afc9edc3
@@ -0,0 +1,118 @@
/**
* Possibly Unused i18n Token Finder
* Key word: POSSIBLY
*
* Looks for i18n tokens that MAY be unused by the code
* Since some tokens are generated dynamically, the list generated by this script
* should ALWAYS be verified manually before removing any of the tokens in it
*
* Ghostery Browser Extension
* http://www.ghostery.com/
*
* Copyright 2019 Ghostery, Inc. All rights reserved.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0
*/

// eslint-disable-next-line import/no-extraneous-dependencies
const fs = require('fs');
// eslint-disable-next-line import/no-extraneous-dependencies
const jsonfile = require('jsonfile');

// Constants
const DEFAULT_LOCALE_TOKENS_FILE = './_locales/en/messages.json';
const UNUSED_TOKENS_FILE = './tools/i18n_results/unused_tokens.txt';

function saveListOfUnusedTokensToFile(filepath, unusedTokens) {
fs.writeFileSync(
filepath,
unusedTokens.join('\n')
);
}

function findUnusedTokens(tokens, filepaths) {
tokens = tokens.map(token => ({ value: token, isUsed: false }));

filepaths.forEach((filepath) => {
const fileContents = fs.readFileSync(filepath, 'utf8');
tokens.forEach((token) => {
if (token.isUsed) { return; }

// THE TEST
if (fileContents.includes(`t('${token.value}`)) {
token.isUsed = true;
}
});
});

const unusedTokens =
(tokens.filter(token => token.isUsed === false))
.map(token => token.value);

return unusedTokens;
}

/**
* Recursively collect the filepaths of files that
* satisfy the supplied extension and file system location conditions
* @param [Array|object] whereToLookAndForWhatExtensions
* @param [string Array] filepaths The matching filepaths
* @returns [string Array] filepaths The matching filepaths
*/
function getFilepaths(whereToLookAndForWhatExtensions, filepaths = []) {
const target = whereToLookAndForWhatExtensions;

if (Array.isArray(target)) {
target.forEach((t) => {
filepaths = getFilepaths(t, filepaths);
});
} else {
const dirEntries = fs.readdirSync(target.dir, { withFileTypes: true });

dirEntries.forEach((dirEntry) => {
if (dirEntry.isDirectory()) {
filepaths = getFilepaths({
dir: `${target.dir}/${dirEntry.name}`,
extensions: target.extensions
}, filepaths);
} else if (dirEntry.isFile()) {
if (target.extensions.some(extension => dirEntry.name.endsWith(extension))) {
filepaths.push(`${target.dir}/${dirEntry.name}`);
}
}
});

return filepaths;
}

return filepaths;
}

function getJSONKeys(filepath) {
const json = jsonfile.readFileSync(filepath);
return Object.keys(json);
}

saveListOfUnusedTokensToFile(
UNUSED_TOKENS_FILE,
findUnusedTokens(
getJSONKeys(DEFAULT_LOCALE_TOKENS_FILE),
getFilepaths(
[
// Overly broad, but we favor simplicity since there is no compelling reason here to favor performance / efficiency
// Also, we prefer that unused tokens be incorrectly reported as used than vice versa
{ dir: './app', extensions: ['.jsx', '.js'] },
{ dir: './src', extensions: ['.js'] },
]
)
)
);

console.log('\nPLEASE NOTE:');
console.log('Since some i18n tokens are generated dynamically,')
console.log('and since some others are formatted in a non-standard way,');
console.log('the list generated by this script should ALWAYS');
console.log('be verified manually before removing any of the tokens in it.');
console.log('\nThe results are in ./tools/i18n_results/unused_tokens.txt');

This file was deleted.

ProTip! Use n and p to navigate between commits in a pull request.