diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..da479972 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,14 @@ +# http://editorconfig.org + +root = true + +[*] +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true +indent_style = space +indent_size = 2 + +[*.{diff,md}] +trim_trailing_whitespace = false diff --git a/__snapshots__/test.js.snap b/__snapshots__/test.js.snap index e9864bc1..3bb02842 100644 --- a/__snapshots__/test.js.snap +++ b/__snapshots__/test.js.snap @@ -44,6 +44,26 @@ exports[`Test Fixtures emblem 1`] = ` exports[`Test Fixtures emblem 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... +[3/4] ⚙️ Checking for unused translations... +[4/4] ⚙️ Checking for missing translations... + + ⚠️ Found 1 unused translations! + You can use --fix to remove all unused translations. + + - in-repo-addon.unused (used in lib/in-repo-addon/translations/en.yaml) + + ⚠️ Found 2 missing translations! + + - translation-missing-in-addon (used in lib/in-repo-addon/addon/templates/addon.hbs) + - translation-missing-in-app (used in lib/in-repo-addon/app/templates/application.hbs) +" +`; + +exports[`Test Fixtures in-repo-translations 2`] = `Map {}`; + exports[`Test Fixtures missing-translations 1`] = ` "[1/4] 🔍 Finding JS and HBS files... [2/4] 🔍 Searching for translations keys in JS and HBS files... diff --git a/fixtures/in-repo-translations/app/controllers/application.js b/fixtures/in-repo-translations/app/controllers/application.js new file mode 100644 index 00000000..468eb331 --- /dev/null +++ b/fixtures/in-repo-translations/app/controllers/application.js @@ -0,0 +1,7 @@ +import Controller from '@ember/controller'; + +export default class ApplicationController extends Controller { + get foo() { + return this.intl.t('js-translation'); + } +} diff --git a/fixtures/in-repo-translations/app/templates/application.hbs b/fixtures/in-repo-translations/app/templates/application.hbs new file mode 100644 index 00000000..de75771b --- /dev/null +++ b/fixtures/in-repo-translations/app/templates/application.hbs @@ -0,0 +1,2 @@ +{{t "hbs-translation"}} +{{t "in-repo-addon.translation-outside-addon"}} diff --git a/fixtures/in-repo-translations/lib/in-repo-addon/addon/controllers/addon.js b/fixtures/in-repo-translations/lib/in-repo-addon/addon/controllers/addon.js new file mode 100644 index 00000000..bb53a8b6 --- /dev/null +++ b/fixtures/in-repo-translations/lib/in-repo-addon/addon/controllers/addon.js @@ -0,0 +1,7 @@ +import Controller from '@ember/controller'; + +export default class AddonController extends Controller { + get foo() { + return this.intl.t('in-repo-addon.addon.js-translation'); + } +} diff --git a/fixtures/in-repo-translations/lib/in-repo-addon/addon/templates/addon.hbs b/fixtures/in-repo-translations/lib/in-repo-addon/addon/templates/addon.hbs new file mode 100644 index 00000000..cbaf3b09 --- /dev/null +++ b/fixtures/in-repo-translations/lib/in-repo-addon/addon/templates/addon.hbs @@ -0,0 +1,3 @@ +{{t "in-repo-addon.addon.hbs-translation"}} +{{t "translation-outside-app-in-addon"}} +{{t "translation-missing-in-addon"}} diff --git a/fixtures/in-repo-translations/lib/in-repo-addon/app/controllers/application.js b/fixtures/in-repo-translations/lib/in-repo-addon/app/controllers/application.js new file mode 100644 index 00000000..4bdd1022 --- /dev/null +++ b/fixtures/in-repo-translations/lib/in-repo-addon/app/controllers/application.js @@ -0,0 +1,7 @@ +import Controller from '@ember/controller'; + +export default class ApplicationController extends Controller { + get foo() { + return this.intl.t('in-repo-addon.app.js-translation'); + } +} diff --git a/fixtures/in-repo-translations/lib/in-repo-addon/app/templates/application.hbs b/fixtures/in-repo-translations/lib/in-repo-addon/app/templates/application.hbs new file mode 100644 index 00000000..35a1c9a0 --- /dev/null +++ b/fixtures/in-repo-translations/lib/in-repo-addon/app/templates/application.hbs @@ -0,0 +1,3 @@ +{{t "in-repo-addon.app.hbs-translation"}} +{{t "translation-outside-app-in-app"}} +{{t "translation-missing-in-app"}} diff --git a/fixtures/in-repo-translations/lib/in-repo-addon/translations/en.yaml b/fixtures/in-repo-translations/lib/in-repo-addon/translations/en.yaml new file mode 100644 index 00000000..f95793e2 --- /dev/null +++ b/fixtures/in-repo-translations/lib/in-repo-addon/translations/en.yaml @@ -0,0 +1,9 @@ +in-repo-addon: + addon: + hbs-translation: HBS in in-repo addon addon + js-translation: JS in in-repo addon addon + app: + hbs-translation: HBS in in-repo addon app + js-translation: JS in in-repo addon app + translation-outside-addon: This translation is used outside the in-repo addon + unused: This translation is unused diff --git a/fixtures/in-repo-translations/package.json b/fixtures/in-repo-translations/package.json new file mode 100644 index 00000000..d4227c80 --- /dev/null +++ b/fixtures/in-repo-translations/package.json @@ -0,0 +1,8 @@ +{ + "name": "in-repo-translations", + "ember-addon": { + "paths": [ + "lib/in-repo-addon" + ] + } +} diff --git a/fixtures/in-repo-translations/translations/en.yaml b/fixtures/in-repo-translations/translations/en.yaml new file mode 100644 index 00000000..16810943 --- /dev/null +++ b/fixtures/in-repo-translations/translations/en.yaml @@ -0,0 +1,4 @@ +hbs-translation: HBS! +js-translation: JS! +translation-outside-app-in-addon: This translation is only used in the addon folder of the addon +translation-outside-app-in-app: This translation is only used in the app folder of the addon diff --git a/index.js b/index.js index 6c3bd52b..683a5177 100755 --- a/index.js +++ b/index.js @@ -28,7 +28,9 @@ async function run(rootDir, options = {}) { let config = readConfig(rootDir); log(`${step(1)} 🔍 Finding JS and HBS files...`); - let files = await findAppFiles(rootDir); + let appFiles = await findAppFiles(rootDir); + let inRepoFiles = await findInRepoFiles(rootDir); + let files = [...appFiles, ...inRepoFiles]; log(`${step(2)} 🔍 Searching for translations keys in JS and HBS files...`); let usedTranslationKeys = await analyzeFiles(rootDir, files); @@ -104,12 +106,41 @@ async function findAppFiles(cwd) { return globby(['app/**/*.js', 'app/**/*.hbs', 'app/**/*.emblem'], { cwd }); } +async function findInRepoFiles(cwd) { + let inRepoPaths = findInRepoPaths(cwd); + let inRepoFolders = joinPaths(inRepoPaths, ['addon', 'app']); + + return globby(joinPaths(inRepoFolders, ['**/*.js', '**/*.hbs', '**/*.emblem']), { cwd }); +} + async function findTranslationFiles(cwd) { - return globby(['translations/**/*.json', 'translations/**/*.yaml', 'translations/**/*.yml'], { + let inputFolders = ['', ...findInRepoPaths(cwd)]; + let translationPaths = joinPaths(inputFolders, ['translations']); + + return globby(joinPaths(translationPaths, ['**/*.json', '**/*.yaml', '**/*.yml']), { cwd, }); } +function findInRepoPaths(cwd) { + let pkgJSONPath = path.join(cwd, 'package.json'); + + if (!fs.existsSync(pkgJSONPath)) return []; + + let pkgJSON = JSON.parse(fs.readFileSync(path.join(cwd, 'package.json'))); + let inRepoPaths = pkgJSON && pkgJSON['ember-addon'] && pkgJSON['ember-addon']['paths']; + + return inRepoPaths || []; +} + +function joinPaths(inputPathOrPaths, outputPaths) { + if (Array.isArray(inputPathOrPaths)) { + return inputPathOrPaths.map(inputPath => joinPaths(inputPath, outputPaths)).flat(); + } else { + return outputPaths.map(directory => path.join(inputPathOrPaths, directory)); + } +} + async function analyzeFiles(cwd, files) { let allTranslationKeys = new Map(); diff --git a/test.js b/test.js index 95a6227b..5a830897 100644 --- a/test.js +++ b/test.js @@ -6,7 +6,12 @@ let fixtures = fs.readdirSync(`${__dirname}/fixtures/`); describe('Test Fixtures', () => { let output; let writtenFiles; - let fixturesWithErrors = ['emblem', 'missing-translations', 'unused-translations']; + let fixturesWithErrors = [ + 'emblem', + 'missing-translations', + 'unused-translations', + 'in-repo-translations', + ]; let fixturesWithFix = ['remove-unused-translations', 'remove-unused-translations-nested']; beforeEach(() => {