-
Notifications
You must be signed in to change notification settings - Fork 9.3k
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
fix: save artifacts and assets in output path #1601
Conversation
lighthouse-core/lib/asset-saver.js
Outdated
const traceData = data.traceData; | ||
fs.writeFileSync(`${filenamePrefix}-${index}.trace.json`, JSON.stringify(traceData, null, 2)); | ||
log.log('trace file saved to disk', filenamePrefix); | ||
const traceFilename = `${options.path}-${index}.trace.json`; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not super thrilled about calling this mixture of path and prefix path
but passing both options everywhere seemed like overkill. My arm could be twisted to revert though... :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
isn't it just passed to this one function? agreed that calling it path
is kind of confusing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's this and saveArtifacts and used back in bin.ts
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
initial comments. My brain may just be tired, but it does seem like some new variable names may add some clarity here...but it may also just be the nature of the save*()
beast we've created.
lighthouse-cli/bin.ts
Outdated
@@ -260,25 +260,31 @@ function runLighthouse(url: string, | |||
.then(chrome => chromeLauncher = chrome) | |||
.then(() => lighthouse(url, flags, config)) | |||
.then((results: Results) => { | |||
let promise = Promise.resolve(results); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe move all this printing stuff to its own function? Definitely getting hard to follow :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
will do
lighthouse-cli/bin.ts
Outdated
// delete artifacts from result so reports won't include artifacts. | ||
const artifacts = results.artifacts; | ||
results.artifacts = undefined; | ||
|
||
if (flags.saveArtifacts) { | ||
assetSaver.saveArtifacts(artifacts); | ||
promise = promise.then(_ => assetSaver.saveArtifacts(artifacts, resolvedPath)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
saveArtifacts
is sync, so does wrapping it matter?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suppose not, it just seemed like the odd duckling before
lighthouse-core/lib/asset-saver.js
Outdated
* @return {!Promise} | ||
*/ | ||
function saveAssets(artifacts, results) { | ||
return prepareAssets(artifacts, results).then(assets => { | ||
function saveAssets(artifacts, options = {}) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this doesn't appear to be treated as an optional parameter, so any need for the default?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah ended up not being optional anymore, I'll remove
lighthouse-core/lib/asset-saver.js
Outdated
const traceData = data.traceData; | ||
fs.writeFileSync(`${filenamePrefix}-${index}.trace.json`, JSON.stringify(traceData, null, 2)); | ||
log.log('trace file saved to disk', filenamePrefix); | ||
const traceFilename = `${options.path}-${index}.trace.json`; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
isn't it just passed to this one function? agreed that calling it path
is kind of confusing
lighthouse-cli/bin.ts
Outdated
} | ||
if (flags.saveAssets) { | ||
return assetSaver.saveAssets(artifacts, results).then(() => results); | ||
promise = promise.then(_ => assetSaver.saveAssets(artifacts, { | ||
title: path.basename(resolvedPath), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not really clear what title
is here, or why it's called that. file prefix?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it becomes the title of the screenshots HTML page, which was essentially this basename before but it needed all the results passed in to compute it
alright @brendankenny moved some things around and just got rid of title completely for now, hopefully it's clearer now |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
some more minor stuff. Definitely like the flow of this better. pwmetrics-events.js
threw a wrench in things, though :)
lighthouse-cli/bin.ts
Outdated
resolvedPath.slice(cwd.length + 1) : resolvedPath; | ||
|
||
// delete artifacts from result so reports won't include artifacts. | ||
const artifacts = results.artifacts; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe keep this in the caller and pass in artifacts
as a separate argument to saveResults
? Feels weird to remove them from the results in a function that's just saving things
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it feels weird have this part of the saving logic outside saveResults
haha, compromise? results = Object.assign({}, results, {artifacts: undefined});
lighthouse-core/lib/asset-saver.js
Outdated
@@ -90,24 +89,23 @@ img { | |||
/** | |||
* Save entire artifacts object to a single stringified file |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe add a line to the jsdoc that artifacts will be saved at pathWithBasename + '.artifacts.log'
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
lighthouse-core/lib/asset-saver.js
Outdated
@@ -131,19 +129,20 @@ function prepareAssets(artifacts, results) { | |||
/** | |||
* Writes trace(s) and associated screenshot(s) to disk. | |||
* @param {!Artifacts} artifacts | |||
* @param {!Results} results | |||
* @param {string} pathWithBasename |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same thing with jsdoc, pathWithBasename + '.trace.json'
and screenshots (though I guess the index thing makes that slightly harder to understand :)
lighthouse-cli/bin.ts
Outdated
flags: {output: any, outputPath: string, saveArtifacts: boolean, saveAssets: boolean}) { | ||
let promise = Promise.resolve(results); | ||
const cwd = process.cwd(); | ||
const configuredPath = !flags.outputPath || flags.outputPath === 'stdout' ? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it would be great to get some of the PR's first comment captured here or in a doc on the method (readme too?).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
lighthouse-cli/bin.ts
Outdated
flags.outputPath.replace(/\.\w{2,4}$/, ''); | ||
const resolvedPath = path.resolve(cwd, configuredPath); | ||
const pathWithBasename = resolvedPath.includes(cwd) ? | ||
resolvedPath.slice(cwd.length + 1) : resolvedPath; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe i'm missing something obvious, but what does slicing accomplish here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
my read is that resolvedPath always includes cwd because we just did path.resolve on it.
and so we'll always slice,
taking the absolute file path back to a relative one.
This is 1) the same as path.relative(cwd, resolvedPath)
AFAICT. but 2) i don't know why we nuke it, since its a more absolute location.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just nuked because with the default options the logging seemed a bit verbose to restate your cwd
, don't have particularly strong feelings about it though if we're fine with the absolute path being printed.
lighthouse-cli/bin.ts
Outdated
const cwd = process.cwd(); | ||
const configuredPath = !flags.outputPath || flags.outputPath === 'stdout' ? | ||
assetSaver.getFilenamePrefix(results) : | ||
flags.outputPath.replace(/\.\w{2,4}$/, ''); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
instead of this edit we could do...
const parsed = path.parse(flags.outputPath);
parsed.base = parsed.base.replace(parsed.ext, '');
path.format(parsed);
but i don't know if that's really worth it. :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like the explicitness of it but not a huge fan of the triple lines, haha :)
lighthouse-cli/bin.ts
Outdated
results.artifacts = undefined; | ||
|
||
if (flags.saveArtifacts) { | ||
assetSaver.saveArtifacts(artifacts, pathWithBasename); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
as mentioned offline, we can remove --save-artifacts flag and the functions if we want. AFAIK, they havent been used for ages and are only for debugging.
lighthouse-cli/bin.ts
Outdated
flags.outputPath.replace(/\.\w{2,4}$/, ''); | ||
const resolvedPath = path.resolve(cwd, configuredPath); | ||
const pathWithBasename = resolvedPath.includes(cwd) ? | ||
resolvedPath.slice(cwd.length + 1) : resolvedPath; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
my read is that resolvedPath always includes cwd because we just did path.resolve on it.
and so we'll always slice,
taking the absolute file path back to a relative one.
This is 1) the same as path.relative(cwd, resolvedPath)
AFAICT. but 2) i don't know why we nuke it, since its a more absolute location.
@@ -164,6 +164,23 @@ Options: | |||
installations are found [boolean] | |||
``` | |||
|
|||
### Output Path Examples | |||
|
|||
`--output-path=~/mydir/foo.out --save-assets` generates |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't believe this actually works, though, because we don't do ~
expansion
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
depends on your shell I suppose, should I change to an absolute path?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
depends on your shell I suppose
ah, yeah, I have to do --output-path ~/mydir/foo.out
for it to expand
lighthouse-cli/bin.ts
Outdated
const audits = results.audits; | ||
const artifacts = results.artifacts; | ||
// remove artifacts from result so reports won't include artifacts. | ||
results = Object.assign({}, results, {artifacts: undefined}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is fine (it makes some sense, we are dropping artifacts
since we don't want the them in the saved/printed results), but since this resolves on the changed results
I don't see the difference functionally?
So it still seems weird, but now it's that perfX relies on that side effect of saveResults
to not get 100MB reports :) Not sure of the optimal configuration here, though
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
only changes in the sense that the original results object is preserved, if we never intend artifacts on being consumed along with the rest of the results I'd advocate splitting them into distinct sets in the lighthouse return object. Since that'd probably break others at this point, I'll restructure a bit more instead.
lighthouse-cli/bin.ts
Outdated
flags.outputPath.replace(/\.\w{2,4}$/, ''); | ||
const resolvedPath = path.resolve(cwd, configuredPath); | ||
const pathWithBasename = resolvedPath.includes(cwd) ? | ||
path.relative(cwd, resolvedPath) : resolvedPath; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm personally +1 for dropping this line since it definitely adds mental overhead when reading. If it's annoying in the log we could fix it where it's logged instead
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
will do
lighthouse-cli/bin.ts
Outdated
promise = promise.then(_ => Printer.write(results, 'html', `${pathWithBasename}.report.html`)); | ||
} | ||
|
||
return promise.then(_ => Printer.write(results, flags.output, flags.outputPath)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you're inheriting this, but it seems kind of magical that we rely on Printer.write
to return results
. How do you feel about doing a resolve on results
here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed the need for it to return anything at all
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
More changes needed I came across during WPT integration investigation.
pretty
will use same name and location as output path.getFilenamePrefix
and be suffixed with.artifacts.log
Examples
--output-path=~/mydir/foo.out --save-assets
generates~/mydir/foo.out
~/mydir/foo.report.html
~/mydir/foo-0.trace.json
~/mydir/foo-0.screenshots.html
--output-path=./report.json --output json --save-artifacts
generates./report.json
./report.artifacts.log
--save-artifacts
generates./<HOST>_<DATE>.report.html
./<HOST>_<DATE>.artifacts.log