Skip to content

Commit

Permalink
Merge pull request #481 from robinborst95/feature/addon-paths
Browse files Browse the repository at this point in the history
Add support for translations in actual addons
  • Loading branch information
Mikek2252 authored Apr 22, 2022
2 parents 7b61f00 + 33cb043 commit ddcf8b8
Show file tree
Hide file tree
Showing 13 changed files with 112 additions and 7 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ build/Release
node_modules/
jspm_packages/

# Include node modules used in tests
!fixtures/**/node_modules

# TypeScript v1 declaration files
typings/

Expand Down
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,26 @@ To prevent that from happening you can configure a `whitelist`, which accepts an
array of regular expressions that will be checked when looking for unused
translations.

### `externalPaths`

If your application uses translations provided by (external) addons, then those
translations will show up as missing by default. In order to include such translations,
you can define `externalPaths` in the configuration file as follows:

```js
export default {
externalPaths: ['my-addon'],
};
```

This example will try to find translation files in `node_modules/my-addon/translations`.
Patterns supported by [`globby`](https://www.npmjs.com/package/globby) are also
possible here, e.g. this:
```js
externalPaths: ['@*/*']
```
will look up translations in scoped addons like `node_modules/@company/scoped-addon/translations`.

### `--fix`
If your application has a lot of unused translations you can run the command with
the `--fix` to remove them. Remember to double check your translations as dynamic
Expand Down
16 changes: 16 additions & 0 deletions __snapshots__/test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,22 @@ exports[`Test Fixtures emblem 1`] = `

exports[`Test Fixtures emblem 2`] = `Map {}`;

exports[`Test Fixtures external-addon-translations 1`] = `
"[1/4] 🔍 Finding JS and HBS files...
[2/4] 🔍 Searching for translations keys in JS and HBS files...
[3/4] ⚙️ Checking for unused translations...
[4/4] ⚙️ Checking for missing translations...
👏 No unused translations were found!
⚠️ Found 1 missing translations!
- other-external-addon.used-by-app-translation (used in app/templates/application.hbs)
"
`;

exports[`Test Fixtures external-addon-translations 2`] = `Map {}`;

exports[`Test Fixtures in-repo-translations 1`] = `
"[1/4] 🔍 Finding JS and HBS files...
[2/4] 🔍 Searching for translations keys in JS and HBS files...
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import Controller from '@ember/controller';

export default class ApplicationController extends Controller {
get foo() {
return this.intl.t('js-translation');
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{{t "hbs-translation"}}
{{t "external-addon.used-by-app-translation"}}
{{t "other-external-addon.used-by-app-translation"}}
{{t "company.scoped-addon.used-by-app-translation"}}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions fixtures/external-addon-translations/translations/en.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
hbs-translation: HBS!
js-translation: JS!
49 changes: 42 additions & 7 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ async function run(rootDir, options = {}) {
const NUM_STEPS = 4;
const step = num => chalk.dim(`[${num}/${NUM_STEPS}]`);

let config = readConfig(rootDir);
let config = options.config || readConfig(rootDir);

log(`${step(1)} 🔍 Finding JS and HBS files...`);
let appFiles = await findAppFiles(rootDir);
Expand All @@ -37,12 +37,21 @@ async function run(rootDir, options = {}) {

log(`${step(3)} ⚙️ Checking for unused translations...`);

let translationFiles = await findTranslationFiles(rootDir);
let existingTranslationKeys = await analyzeTranslationFiles(rootDir, translationFiles);
let ownTranslationFiles = await findOwnTranslationFiles(rootDir);
let externalTranslationFiles = await findExternalTranslationFiles(rootDir, config);
let existingOwnTranslationKeys = await analyzeTranslationFiles(rootDir, ownTranslationFiles);
let existingExternalTranslationKeys = await analyzeTranslationFiles(
rootDir,
externalTranslationFiles
);
let existingTranslationKeys = mergeMaps(
existingOwnTranslationKeys,
existingExternalTranslationKeys
);
let whitelist = config.whitelist || [];

let unusedTranslations = findDifferenceInTranslations(
existingTranslationKeys,
existingOwnTranslationKeys,
usedTranslationKeys,
whitelist
);
Expand Down Expand Up @@ -82,7 +91,7 @@ async function run(rootDir, options = {}) {
let totalErrors = missingTranslations.size + unusedTranslations.size;

if (shouldFix) {
removeUnusedTranslations(writeToFile, rootDir, translationFiles, unusedTranslations);
removeUnusedTranslations(writeToFile, rootDir, ownTranslationFiles, unusedTranslations);
log();
log(' 👏 All unused translations were removed');
}
Expand Down Expand Up @@ -113,8 +122,19 @@ async function findInRepoFiles(cwd) {
return globby(joinPaths(inRepoFolders, ['**/*.js', '**/*.hbs', '**/*.emblem']), { cwd });
}

async function findTranslationFiles(cwd) {
let inputFolders = ['', ...findInRepoPaths(cwd)];
async function findOwnTranslationFiles(cwd) {
return findTranslationFiles(cwd, ['', ...findInRepoPaths(cwd)]);
}

async function findExternalTranslationFiles(cwd, config) {
if (!config.externalPaths) {
return [];
}

return findTranslationFiles(cwd, joinPaths('node_modules', config.externalPaths));
}

async function findTranslationFiles(cwd, inputFolders) {
let translationPaths = joinPaths(inputFolders, ['translations']);

return globby(joinPaths(translationPaths, ['**/*.json', '**/*.yaml', '**/*.yml']), {
Expand Down Expand Up @@ -388,4 +408,19 @@ function getNestedAttribute(parent, keys) {
return attribute;
}

function mergeMaps(mapA, mapB) {
let resultMap = new Map([...mapA]);

for (let [key, bFiles] of mapB) {
if (!resultMap.has(key)) {
resultMap.set(key, bFiles);
} else {
let aFiles = resultMap.get(key);
resultMap.set(key, new Set([...aFiles, ...bFiles]));
}
}

return resultMap;
}

module.exports = { run, generateFileList };
7 changes: 7 additions & 0 deletions test.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,14 @@ describe('Test Fixtures', () => {
'missing-translations',
'unused-translations',
'in-repo-translations',
'external-addon-translations',
];
let fixturesWithFix = ['remove-unused-translations', 'remove-unused-translations-nested'];
let fixturesWithConfig = {
'external-addon-translations': {
externalPaths: ['@*/*', 'external-addon'],
},
};

beforeEach(() => {
output = '';
Expand All @@ -34,6 +40,7 @@ describe('Test Fixtures', () => {
fix: fixturesWithFix.includes(fixture),
color: false,
writeToFile,
config: fixturesWithConfig[fixture],
});

let expectedReturnValue = fixturesWithErrors.includes(fixture) ? 1 : 0;
Expand Down

0 comments on commit ddcf8b8

Please sign in to comment.