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

Simplify report generation: no pretty print, no formatter classes #1838

Merged
merged 5 commits into from
Mar 10, 2017

Conversation

brendankenny
Copy link
Member

This ended up being something of a monster since formatters have grown to touch so many parts of the codebase. This removes formatters completely, setting the stage for much simpler report refactors in the future.

The only remaining "formatting" is done with handlebar partials, and all that functionality now lives entirely with lighthouse-core/report/. The only thing any code outside that directory needs to know about formatting is the string specified by audits in their extendedInfo.formatter results (this hasn't changed at all from before, still on the Formatter.SUPPORTED_FORMATS object).

The individual commits stand on their own, but the last moves enough around that I'm not sure if going through them individually really helps with review. As mentioned in the commit messages, the PR:

  • removes pretty printing on the command line (fixes Is it time to deprecate the CLI report output? #1739)
  • simplifies the --output and --output-path options a bit since we got rid of pretty (see bin.ts/readme changes for details)
  • moves all handlebar helpers from getHelpers() in individual formatter files to the central handlebar-helpers.js. This is somewhat questionable organizationally, but they all live in a global namespace when they're registered anyways, and having them in one place will aid with future refactoring.
  • move partial html and css files from formatters/partials/ to report/partials/
  • eliminates the Formatter subclasses for each formatter since after Adopt handlebars precompiled templates #1752 the partial sources are retrieved from the precompiled partials anyway and with all the changes from above, they no longer have a use
  • keep formatter unit tests but instead have them compile and test the html produced by the partials directly

In addition, Formatter.SUPPORTED_FORMATS is now auto-generated from the available partial files and report-generator.js now throws on unknown formatters, so it should cut down on issues like #1820

Tested in CLI and extension, no visible changes

@brendankenny brendankenny changed the title Simplify report generation -- no pretty print, no formatter classes Simplify report generation: no pretty print, no formatter classes Mar 8, 2017
* Get stats about the longest initiator chain (as determined by time duration)
* @return {{duration: number, length: number, transferSize: number}}
*/
static _getLongestChain(tree) {
Copy link
Member Author

Choose a reason for hiding this comment

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

move from the formatter to the audit. I think it was only in the formatter because we didn't have extendedInfo when this was first written

value: chains
value: {
chains,
longestChain: CriticalRequestChains._getLongestChain(chains)
Copy link
Member Author

Choose a reason for hiding this comment

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

the change to the CriticalRequestChains extendedInfo is the only real externally-noticeable change. Added longestChain since it's used several times in the report, so no reason not to just precompute it

Copy link
Collaborator

@patrickhulce patrickhulce left a comment

Choose a reason for hiding this comment

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

death to the pretty print, long live the age of the new report! 💯 🥇

@@ -40,6 +40,58 @@ class CriticalRequestChains extends Audit {
};
}

static _traverse(tree, cb) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

did this used to live in the formatter?

Copy link
Collaborator

Choose a reason for hiding this comment

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

already answered, ignore

fs.readdirSync(__dirname + '/partials')
.filter(filename => filename.endsWith('.html'))
.forEach(filename => {
const baseName = filename.replace(/\.html$/, '');
Copy link
Collaborator

Choose a reason for hiding this comment

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

all of this is still lines up with eric's fix?

Copy link
Member Author

Choose a reason for hiding this comment

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

not entirely, it changes somewhat, but it is all working.

I moved us from three possible cases (caps for the SUPPORTED_FORMATS name, camel for the actual value of that variable, and kebab for the partial name, so we had to convert from camel to kebab to map from formatter to partial), to just caps and kebab (so the value of the formatter property is the same as the name of the partial)

Copy link
Member Author

Choose a reason for hiding this comment

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

so the value of the formatter property is the same as the name of the partial

(and that's now checked by a test)

Copy link
Contributor

Choose a reason for hiding this comment

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

Tested the PR and everything looks good.

const partialName = audit.extendedInfo.formatter;
const partial = reportPartials.report.partials[partialName];
if (!partial) {
throw new Error(`${auditName} requested unknown partial for formatting`);
Copy link
Collaborator

Choose a reason for hiding this comment

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

nice :)

* (e.g. `CRITICAL_REQUEST_CHAINS` to `critical-request-chains).
* @return {!Object<string, string>}
*/
static get SUPPORTED_FORMATS() {
Copy link
Member

Choose a reason for hiding this comment

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

does this need to be in caps?

Copy link
Member Author

Choose a reason for hiding this comment

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

does this need to be in caps?

no, I just left it how it was before so that audits don't have to change the formatter: Formatter.SUPPORTED_FORMATS.USER_TIMINGS (or whatever) line in extendedInfo.

Selecting the partial to use is a little awkward in general. It could also have been a string (like e.g requiredArtifacts is) since that's all that variable really is, but there is the advantage of if your editor does support code completion you get suggestions there. The SUPPORTED_FORMATS could have lived somewhere else, too (like on ReportGenerator).

Basically I didn't see an option that was legitimately better, so I just left it the same until we do come up with something :)

readme.md Outdated
@@ -34,7 +34,7 @@ Kick off a run by passing `lighthouse` the URL to audit:
lighthouse https://airhorner.com/
```

Lighthouse will prettyprint a report to CLI. You can control the output format by passing flags.
Lighthouse will write an HTML report to file. You can control the output format by passing flags.
Copy link
Contributor

Choose a reason for hiding this comment

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

"write the report to an HTML file"?

Copy link
Member Author

Choose a reason for hiding this comment

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

"write the report to an HTML file"?

I mean, the report is the html, it's not writing it to an HTML file...I don't know.

Copy link
Contributor

Choose a reason for hiding this comment

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

wording was a bit funny to me. "write your report to a file..."?

Copy link
Member Author

Choose a reason for hiding this comment

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

I think the point of the original statement is to point out what you get by default and call attention to the fact that there are flags to change that.

Agree it is a bit awkward. "Lighthouse will write an HTML report to file by default." to call attention to the fact that it's talking about the default behavior?

Also we could delete the line :)

Copy link
Contributor

Choose a reason for hiding this comment

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

"write an HTML report to file" sounds incomplete. "to a file", "to an HTML file"....

What about " By default, Lighthouse writes the report to an HTML file. You can control the output format by passing flags."

Copy link
Member Author

Choose a reason for hiding this comment

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

💥 done

readme.md Outdated
@@ -66,8 +66,13 @@ Configuration:

Output:
--output Reporter for the results, supports multiple values
[choices: "none", "pretty", "json", "html"] [default: "none"]
--output-path The file path to output the results
[choices: "json", "html"] [default: "none"]
Copy link
Contributor

Choose a reason for hiding this comment

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

[default: "html"] right?

Copy link
Member Author

Choose a reason for hiding this comment

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

[default: "html"] right?

whoops, yes. done.

* Figures out the total score for an aggregation
* @param {{total: number}} aggregation
* @return {number}
* Format number.
Copy link
Contributor

Choose a reason for hiding this comment

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

formatNumber formaters a number...

keanu2

Copy link
Member Author

Choose a reason for hiding this comment

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

formatNumber formaters a number

I got less creative as I went along and just stole it from the also excellent // format time

@@ -161,7 +195,7 @@ const handlebarHelpers = {
* @param {!Object} opts
* @return {string}
*/
createTreeRenderContext(tree, opts) {
createTreeRenderContext(tree = {}, opts) {
Copy link
Contributor

Choose a reason for hiding this comment

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

doc the default val?

Copy link
Member Author

Choose a reason for hiding this comment

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

this was to work around a wonky unit test in development, but no longer necessary \o/ removed.

fs.readdirSync(__dirname + '/partials')
.filter(filename => filename.endsWith('.html'))
.forEach(filename => {
const baseName = filename.replace(/\.html$/, '');
Copy link
Contributor

Choose a reason for hiding this comment

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

Tested the PR and everything looks good.

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

function toKebabCase(string) {
Copy link
Contributor

Choose a reason for hiding this comment

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

🚫 🍖

@brendankenny
Copy link
Member Author

merged! looking at the open PRs, I only see #1847 and #1840 needing to be updated after this, and that should just require const Formatter = require('../formatters/formatter'); -> const Formatter = require('../report/formatter');

@paulirish
Copy link
Member

@brendankenny thanks for checking! i've updated those PRs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Is it time to deprecate the CLI report output?
4 participants