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

misc: refactor collect-strings.js to use glob and work on windows #9406

Merged
merged 17 commits into from
Jul 26, 2019
Merged
42 changes: 42 additions & 0 deletions lighthouse-core/lib/i18n/locales/en-XL.json
Original file line number Diff line number Diff line change
Expand Up @@ -1348,5 +1348,47 @@
},
"lighthouse-core/report/html/renderer/util.js | warningHeader": {
"message": "Ŵár̂ńîńĝś: "
},
"stack-packs/packs/wordpress.js | efficient_animated_content": {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These weren't being collected for en-XL before.

"message": "Ĉón̂śîd́êŕ ûṕl̂óâd́îńĝ ýôúr̂ ǴÎF́ t̂ó â śêŕv̂íĉé ŵh́îćĥ ẃîĺl̂ ḿâḱê ít̂ áv̂áîĺâb́l̂é t̂ó êḿb̂éd̂ áŝ án̂ H́T̂ḾL̂5 v́îd́êó."
},
"stack-packs/packs/wordpress.js | offscreen_images": {
"message": "Îńŝt́âĺl̂ á [l̂áẑý-l̂óâd́ Ŵór̂d́P̂ŕêśŝ ṕl̂úĝín̂](h́t̂t́p̂ś://ŵór̂d́p̂ŕêśŝ.ór̂ǵ/p̂ĺûǵîńŝ/śêár̂ćĥ/ĺâźŷ+ĺôád̂/) t́ĥát̂ ṕr̂óv̂íd̂éŝ t́ĥé âb́îĺît́ŷ t́ô d́êf́êŕ âńŷ óf̂f́ŝćr̂éêń îḿâǵêś, ôŕ ŝẃît́ĉh́ t̂ó â t́ĥém̂é t̂h́ât́ p̂ŕôv́îd́êś t̂h́ât́ f̂ún̂ćt̂íôńâĺît́ŷ. Ál̂śô ćôńŝíd̂ér̂ úŝín̂ǵ [t̂h́ê ÁM̂Ṕ p̂ĺûǵîń](ĥt́t̂ṕŝ://ẃôŕd̂ṕr̂éŝś.ôŕĝ/ṕl̂úĝín̂ś/âḿp̂/)."
},
"stack-packs/packs/wordpress.js | render_blocking_resources": {
"message": "T̂h́êŕê ár̂é â ńûḿb̂ér̂ óf̂ Ẃôŕd̂Ṕr̂éŝś p̂ĺûǵîńŝ t́ĥát̂ ćâń ĥél̂ṕ ŷóû [ín̂ĺîńê ćr̂ít̂íĉál̂ áŝśêt́ŝ](h́t̂t́p̂ś://ŵór̂d́p̂ŕêśŝ.ór̂ǵ/p̂ĺûǵîńŝ/śêár̂ćĥ/ćr̂ít̂íĉál̂+ćŝś/) ôŕ [d̂éf̂ér̂ ĺêśŝ ím̂ṕôŕt̂án̂t́ r̂éŝóûŕĉéŝ](h́t̂t́p̂ś://ŵór̂d́p̂ŕêśŝ.ór̂ǵ/p̂ĺûǵîńŝ/śêár̂ćĥ/d́êf́êŕ+ĉśŝ+j́âv́âśĉŕîṕt̂/). B́êẃâŕê t́ĥát̂ óp̂t́îḿîźât́îón̂ś p̂ŕôv́îd́êd́ b̂ý t̂h́êśê ṕl̂úĝín̂ś m̂áŷ b́r̂éâḱ f̂éât́ûŕêś ôf́ ŷóûŕ t̂h́êḿê ór̂ ṕl̂úĝín̂ś, ŝó ŷóû ẃîĺl̂ ĺîḱêĺŷ ńêéd̂ t́ô ḿâḱê ćôd́ê ćĥán̂ǵêś."
},
"stack-packs/packs/wordpress.js | time_to_first_byte": {
"message": "T̂h́êḿêś, p̂ĺûǵîńŝ, án̂d́ ŝér̂v́êŕ ŝṕêćîf́îćât́îón̂ś âĺl̂ ćôńt̂ŕîb́ût́ê t́ô śêŕv̂ér̂ ŕêśp̂ón̂śê t́îḿê. Ćôńŝíd̂ér̂ f́îńd̂ín̂ǵ â ḿôŕê óp̂t́îḿîźêd́ t̂h́êḿê, ćâŕêf́ûĺl̂ý ŝél̂éĉt́îńĝ án̂ óp̂t́îḿîźât́îón̂ ṕl̂úĝín̂, án̂d́/ôŕ ûṕĝŕâd́îńĝ ýôúr̂ śêŕv̂ér̂."
},
"stack-packs/packs/wordpress.js | total_byte_weight": {
"message": "Ĉón̂śîd́êŕ ŝh́ôẃîńĝ éx̂ćêŕp̂t́ŝ ín̂ ýôúr̂ ṕôśt̂ ĺîśt̂ś (ê.ǵ. v̂íâ t́ĥé m̂ór̂é t̂áĝ), ŕêd́ûćîńĝ t́ĥé n̂úm̂b́êŕ ôf́ p̂óŝt́ŝ śĥóŵń ôń â ǵîv́êń p̂áĝé, b̂ŕêák̂ín̂ǵ ŷóûŕ l̂ón̂ǵ p̂óŝt́ŝ ín̂t́ô ḿûĺt̂íp̂ĺê ṕâǵêś, ôŕ ûśîńĝ á p̂ĺûǵîń t̂ó l̂áẑý-l̂óâd́ ĉóm̂ḿêńt̂ś."
},
"stack-packs/packs/wordpress.js | unminified_css": {
"message": "Â ńûḿb̂ér̂ óf̂ [Ẃôŕd̂Ṕr̂éŝś p̂ĺûǵîńŝ](h́t̂t́p̂ś://ŵór̂d́p̂ŕêśŝ.ór̂ǵ/p̂ĺûǵîńŝ/śêár̂ćĥ/ḿîńîf́ŷ+ćŝś/) ĉán̂ śp̂éêd́ ûṕ ŷóûŕ ŝít̂é b̂ý ĉón̂ćât́êńât́îńĝ, ḿîńîf́ŷín̂ǵ, âńd̂ ćôḿp̂ŕêśŝín̂ǵ ŷóûŕ ŝt́ŷĺêś. Ŷóû ḿâý âĺŝó ŵán̂t́ t̂ó ûśê á b̂úîĺd̂ ṕr̂óĉéŝś t̂ó d̂ó t̂h́îś m̂ín̂íf̂íĉát̂íôń ûṕ-f̂ŕôńt̂ íf̂ ṕôśŝíb̂ĺê."
},
"stack-packs/packs/wordpress.js | unminified_javascript": {
"message": "Â ńûḿb̂ér̂ óf̂ [Ẃôŕd̂Ṕr̂éŝś p̂ĺûǵîńŝ](h́t̂t́p̂ś://ŵór̂d́p̂ŕêśŝ.ór̂ǵ/p̂ĺûǵîńŝ/śêár̂ćĥ/ḿîńîf́ŷ+j́âv́âśĉŕîṕt̂/) ćâń ŝṕêéd̂ úp̂ ýôúr̂ śît́ê b́ŷ ćôńĉát̂én̂át̂ín̂ǵ, m̂ín̂íf̂ýîńĝ, án̂d́ ĉóm̂ṕr̂éŝśîńĝ ýôúr̂ śĉŕîṕt̂ś. Ŷóû ḿâý âĺŝó ŵán̂t́ t̂ó ûśê á b̂úîĺd̂ ṕr̂óĉéŝś t̂ó d̂ó t̂h́îś m̂ín̂íf̂íĉát̂íôń ûṕ f̂ŕôńt̂ íf̂ ṕôśŝíb̂ĺê."
},
"stack-packs/packs/wordpress.js | unused_css_rules": {
"message": "Ĉón̂śîd́êŕ r̂éd̂úĉín̂ǵ, ôŕ ŝẃît́ĉh́îńĝ, t́ĥé n̂úm̂b́êŕ ôf́ [Ŵór̂d́P̂ŕêśŝ ṕl̂úĝín̂ś](ĥt́t̂ṕŝ://ẃôŕd̂ṕr̂éŝś.ôŕĝ/ṕl̂úĝín̂ś/) l̂óâd́îńĝ ún̂úŝéd̂ ĆŜŚ îń ŷóûŕ p̂áĝé. T̂ó îd́êńt̂íf̂ý p̂ĺûǵîńŝ t́ĥát̂ ár̂é âd́d̂ín̂ǵ êx́t̂ŕâńêóûś ĈŚŜ, t́r̂ý r̂ún̂ńîńĝ [ćôd́ê ćôv́êŕâǵê](h́t̂t́p̂ś://d̂év̂él̂óp̂ér̂ś.ĝóôǵl̂é.ĉóm̂/ẃêb́/ûṕd̂át̂éŝ/2017/04/d́êv́t̂óôĺŝ-ŕêĺêáŝé-n̂ót̂éŝ#ćôv́êŕâǵê) ín̂ Ćĥŕôḿê D́êv́T̂óôĺŝ. Ýôú ĉán̂ íd̂én̂t́îf́ŷ t́ĥé t̂h́êḿê/ṕl̂úĝín̂ ŕêśp̂ón̂śîb́l̂é f̂ŕôḿ t̂h́ê ÚR̂Ĺ ôf́ t̂h́ê śt̂ýl̂éŝh́êét̂. Ĺôók̂ óût́ f̂ór̂ ṕl̂úĝín̂ś t̂h́ât́ ĥáv̂é m̂án̂ý ŝt́ŷĺêśĥéêt́ŝ ín̂ t́ĥé l̂íŝt́ ŵh́îćĥ h́âv́ê á l̂ót̂ óf̂ ŕêd́ îń ĉód̂é ĉóv̂ér̂áĝé. Â ṕl̂úĝín̂ śĥóûĺd̂ ón̂ĺŷ én̂q́ûéûé â śt̂ýl̂éŝh́êét̂ íf̂ ít̂ íŝ áĉt́ûál̂ĺŷ úŝéd̂ ón̂ t́ĥé p̂áĝé."
},
"stack-packs/packs/wordpress.js | unused_javascript": {
"message": "Ĉón̂śîd́êŕ r̂éd̂úĉín̂ǵ, ôŕ ŝẃît́ĉh́îńĝ, t́ĥé n̂úm̂b́êŕ ôf́ [Ŵór̂d́P̂ŕêśŝ ṕl̂úĝín̂ś](ĥt́t̂ṕŝ://ẃôŕd̂ṕr̂éŝś.ôŕĝ/ṕl̂úĝín̂ś/) l̂óâd́îńĝ ún̂úŝéd̂ J́âv́âŚĉŕîṕt̂ ín̂ ýôúr̂ ṕâǵê. T́ô íd̂én̂t́îf́ŷ ṕl̂úĝín̂ś t̂h́ât́ âŕê ád̂d́îńĝ éx̂t́r̂án̂éôúŝ J́Ŝ, t́r̂ý r̂ún̂ńîńĝ [ćôd́ê ćôv́êŕâǵê](h́t̂t́p̂ś://d̂év̂él̂óp̂ér̂ś.ĝóôǵl̂é.ĉóm̂/ẃêb́/ûṕd̂át̂éŝ/2017/04/d́êv́t̂óôĺŝ-ŕêĺêáŝé-n̂ót̂éŝ#ćôv́êŕâǵê) ín̂ Ćĥŕôḿê D́êv́T̂óôĺŝ. Ýôú ĉán̂ íd̂én̂t́îf́ŷ t́ĥé t̂h́êḿê/ṕl̂úĝín̂ ŕêśp̂ón̂śîb́l̂é f̂ŕôḿ t̂h́ê ÚR̂Ĺ ôf́ t̂h́ê śĉŕîṕt̂. Ĺôók̂ óût́ f̂ór̂ ṕl̂úĝín̂ś t̂h́ât́ ĥáv̂é m̂án̂ý ŝćr̂íp̂t́ŝ ín̂ t́ĥé l̂íŝt́ ŵh́îćĥ h́âv́ê á l̂ót̂ óf̂ ŕêd́ îń ĉód̂é ĉóv̂ér̂áĝé.  ṕl̂úĝín̂ śĥóûĺd̂ ón̂ĺŷ én̂q́ûéûé â śĉŕîṕt̂ íf̂ ít̂ íŝ áĉt́ûál̂ĺŷ úŝéd̂ ón̂ t́ĥé p̂áĝé."
},
"stack-packs/packs/wordpress.js | uses_long_cache_ttl": {
"message": "R̂éâd́ âb́ôút̂ [B́r̂óŵśêŕ Ĉáĉh́îńĝ ín̂ Ẃôŕd̂Ṕr̂éŝś](ĥt́t̂ṕŝ://ćôd́êx́.ŵór̂d́p̂ŕêśŝ.ór̂ǵ/Ŵór̂d́P̂ŕêśŝ_Óp̂t́îḿîźât́îón̂#B́r̂óŵśêŕ_Ĉáĉh́îńĝ)."
},
"stack-packs/packs/wordpress.js | uses_optimized_images": {
"message": "Ĉón̂śîd́êŕ ûśîńĝ án̂ [ím̂áĝé ôṕt̂ím̂íẑát̂íôń Ŵór̂d́P̂ŕêśŝ ṕl̂úĝín̂](h́t̂t́p̂ś://ŵór̂d́p̂ŕêśŝ.ór̂ǵ/p̂ĺûǵîńŝ/śêár̂ćĥ/óp̂t́îḿîźê+ím̂áĝéŝ/) t́ĥát̂ ćôḿp̂ŕêśŝéŝ ýôúr̂ ím̂áĝéŝ ẃĥíl̂é r̂ét̂áîńîńĝ q́ûál̂ít̂ý."
},
"stack-packs/packs/wordpress.js | uses_responsive_images": {
"message": "Ûṕl̂óâd́ îḿâǵêś d̂ír̂éĉt́l̂ý t̂h́r̂óûǵĥ t́ĥé [m̂éd̂íâ ĺîb́r̂ár̂ý](ĥt́t̂ṕŝ://ćôd́êx́.ŵór̂d́p̂ŕêśŝ.ór̂ǵ/M̂éd̂íâ_Ĺîb́r̂ár̂ý_Ŝćr̂éêń) t̂ó êńŝúr̂é t̂h́ât́ t̂h́ê ŕêq́ûír̂éd̂ ím̂áĝé ŝíẑéŝ ár̂é âv́âíl̂áb̂ĺê, án̂d́ t̂h́êń îńŝér̂t́ t̂h́êḿ f̂ŕôḿ t̂h́ê ḿêd́îá l̂íb̂ŕâŕŷ ór̂ úŝé t̂h́ê ím̂áĝé ŵíd̂ǵêt́ t̂ó êńŝúr̂é t̂h́ê óp̂t́îḿâĺ îḿâǵê śîźêś âŕê úŝéd̂ (ín̂ćl̂úd̂ín̂ǵ t̂h́ôśê f́ôŕ t̂h́ê ŕêśp̂ón̂śîv́ê b́r̂éâḱp̂óîńt̂ś). Âv́ôíd̂ úŝín̂ǵ `F̂úl̂ĺ Ŝíẑé` îḿâǵêś ûńl̂éŝś t̂h́ê d́îḿêńŝíôńŝ ár̂é âd́êq́ûát̂é f̂ór̂ t́ĥéîŕ ûśâǵê. [Ĺêár̂ń M̂ór̂é](ĥt́t̂ṕŝ://ćôd́êx́.ŵór̂d́p̂ŕêśŝ.ór̂ǵ/Îńŝér̂t́îńĝ_Ím̂áĝéŝ_ín̂t́ô_Ṕôśt̂ś_âńd̂_Ṕâǵêś#Îḿâǵê_Śîźê)."
},
"stack-packs/packs/wordpress.js | uses_text_compression": {
"message": "Ŷóû ćâń êńâb́l̂é t̂éx̂t́ ĉóm̂ṕr̂éŝśîón̂ ín̂ ýôúr̂ ẃêb́ ŝér̂v́êŕ ĉón̂f́îǵûŕât́îón̂."
},
"stack-packs/packs/wordpress.js | uses_webp_images": {
"message": "Ĉón̂śîd́êŕ ûśîńĝ á [p̂ĺûǵîń](ĥt́t̂ṕŝ://ẃôŕd̂ṕr̂éŝś.ôŕĝ/ṕl̂úĝín̂ś/ŝéâŕĉh́/ĉón̂v́êŕt̂+ẃêb́p̂/) ór̂ śêŕv̂íĉé t̂h́ât́ ŵíl̂ĺ âút̂óm̂át̂íĉál̂ĺŷ ćôńv̂ér̂t́ ŷóûŕ ûṕl̂óâd́êd́ îḿâǵêś t̂ó t̂h́ê óp̂t́îḿâĺ f̂ór̂ḿât́ŝ."
}
}
114 changes: 60 additions & 54 deletions lighthouse-core/scripts/i18n/collect-strings.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
/* eslint-disable no-console, max-len */

const fs = require('fs');
const glob = require('glob');
const path = require('path');
const esprima = require('esprima');

Expand All @@ -22,12 +23,12 @@ const UISTRINGS_REGEX = /UIStrings = (.|\s)*?\};\n/im;
*/

const ignoredPathComponents = [
'/.git',
'/scripts',
'/node_modules',
'/test/',
'-test.js',
'-renderer.js',
'**/.git/**',
'**/scripts/**',
'**/node_modules/**',
'**/test/**',
'**/*-test.js',
'**/*-renderer.js',
];

// @ts-ignore - @types/esprima lacks all of these
Expand All @@ -44,52 +45,51 @@ function computeDescription(ast, property, startRange) {

/**
* @param {string} dir
* @param {Record<string, ICUMessageDefn>} strings
* @return {Record<string, ICUMessageDefn>}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you revert the changes to the param/return type (here and for createPsuedoLocaleStrings) so it's only an internal change? the changes are fine, but it's going to make updating #9114 that much more work after this lands

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's just chill this until after placeholders land

*/
function collectAllStringsInDir(dir, strings = {}) {
for (const name of fs.readdirSync(dir)) {
const fullPath = path.join(dir, name);
const relativePath = path.relative(LH_ROOT, fullPath);
if (ignoredPathComponents.some(p => fullPath.includes(p))) continue;

if (fs.statSync(fullPath).isDirectory()) {
collectAllStringsInDir(fullPath, strings);
} else {
if (name.endsWith('.js')) {
if (!process.env.CI) console.log('Collecting from', relativePath);
const content = fs.readFileSync(fullPath, 'utf8');
const exportVars = require(fullPath);
const regexMatches = !!UISTRINGS_REGEX.test(content);
const exportsUIStrings = !!exportVars.UIStrings;
if (!regexMatches && !exportsUIStrings) continue;

if (regexMatches && !exportsUIStrings) {
throw new Error('UIStrings defined but not exported');
}

if (exportsUIStrings && !regexMatches) {
throw new Error('UIStrings exported but no definition found');
}

// @ts-ignore regex just matched
const justUIStrings = 'const ' + content.match(UISTRINGS_REGEX)[0];
// just parse the UIStrings substring to avoid ES version issues, save time, etc
// @ts-ignore - esprima's type definition is supremely lacking
const ast = esprima.parse(justUIStrings, {comment: true, range: true});

for (const stmt of ast.body) {
if (stmt.type !== 'VariableDeclaration') continue;
if (stmt.declarations[0].id.name !== 'UIStrings') continue;

let lastPropertyEndIndex = 0;
for (const property of stmt.declarations[0].init.properties) {
const key = property.key.name;
const message = exportVars.UIStrings[key];
const description = computeDescription(ast, property, lastPropertyEndIndex);
strings[`${relativePath} | ${key}`] = {message, description};
lastPropertyEndIndex = property.range[1];
}
}
function collectAllStringsInDir(dir) {
/** @type {Record<string, ICUMessageDefn>} */
const strings = {};

const files = glob.sync(path.relative(LH_ROOT, dir) + '/**/*.js', {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

comment about glob only accepting /? I'm surprised that path.relative works on windows for this since it's going to have slashes going the wrong way....

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Evidently, glob doesn't only accept /. and I guess it does allow for mixed - path separators. I wonder if any comment at all would be more confusing than no comment :P

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we 100% positive it's working as expected...

https://github.com/isaacs/node-glob#windows is so convincing that only / works! 😆

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is node-glob === glob?

Copy link
Collaborator Author

@connorjclark connorjclark Jul 19, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

anyway, I have empirical evidence that it works .... on my one Windows machine ;) Running collect strings resulted in no unstaged changes. Got all the expected output.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is node-glob === glob

Yep :)

Just makes me nervous...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

apparently this is a whole thing: isaacs/minimatch#109, isaacs/node-glob#212 🤷‍♂

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

aight, passing these to path.join normalizes to the OS's file sep.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Which despite what the docs of node-glob state, it does seem to then convert to /

https://github.com/isaacs/node-glob/blob/e3fe170d9156e7c444a57b44a9e45e46c66f2dbf/glob.js#L701-L702

AFAICT :)

cwd: LH_ROOT,
ignore: ignoredPathComponents,
});
for (const relativePathToRoot of files) {
const absolutePath = path.join(LH_ROOT, relativePathToRoot);
if (!process.env.CI) console.log('Collecting from', relativePathToRoot);

const content = fs.readFileSync(absolutePath, 'utf8');
const exportVars = require(absolutePath);
const regexMatches = !!UISTRINGS_REGEX.test(content);
const exportsUIStrings = !!exportVars.UIStrings;
if (!regexMatches && !exportsUIStrings) continue;

if (regexMatches && !exportsUIStrings) {
throw new Error('UIStrings defined but not exported');
}

if (exportsUIStrings && !regexMatches) {
throw new Error('UIStrings exported but no definition found');
}

// @ts-ignore regex just matched
const justUIStrings = 'const ' + content.match(UISTRINGS_REGEX)[0];
// just parse the UIStrings substring to avoid ES version issues, save time, etc
// @ts-ignore - esprima's type definition is supremely lacking
const ast = esprima.parse(justUIStrings, {comment: true, range: true});

for (const stmt of ast.body) {
if (stmt.type !== 'VariableDeclaration') continue;
if (stmt.declarations[0].id.name !== 'UIStrings') continue;

let lastPropertyEndIndex = 0;
for (const property of stmt.declarations[0].init.properties) {
const key = property.key.name;
const message = exportVars.UIStrings[key];
const description = computeDescription(ast, property, lastPropertyEndIndex);
strings[`${relativePathToRoot} | ${key}`] = {message, description};
lastPropertyEndIndex = property.range[1];
}
}
}
Expand All @@ -99,6 +99,7 @@ function collectAllStringsInDir(dir, strings = {}) {

/**
* @param {Record<string, ICUMessageDefn>} strings
* @return {Record<string, ICUMessageDefn>}
*/
function createPsuedoLocaleStrings(strings) {
/** @type {Record<string, ICUMessageDefn>} */
Expand Down Expand Up @@ -152,13 +153,18 @@ function writeStringsToLocaleFormat(locale, strings) {
fs.writeFileSync(fullPath, JSON.stringify(output, null, 2) + '\n');
}

const strings = collectAllStringsInDir(path.join(LH_ROOT, 'lighthouse-core'));
const psuedoLocalizedStrings = createPsuedoLocaleStrings(strings);
const coreStrings = collectAllStringsInDir(path.join(LH_ROOT, 'lighthouse-core'));
console.log('Collected from LH core!');

collectAllStringsInDir(path.join(LH_ROOT, 'stack-packs/packs'), strings);
const stackPackStrings = collectAllStringsInDir(path.join(LH_ROOT, 'stack-packs/packs'));
console.log('Collected from Stack Packs!');

const strings = {
...coreStrings,
...stackPackStrings,
};

const psuedoLocalizedStrings = createPsuedoLocaleStrings(strings);
writeStringsToLocaleFormat('en-US', strings);
writeStringsToLocaleFormat('locales/en-XL', psuedoLocalizedStrings);
console.log('Written to disk!');