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

core: unify config and CLI settings #4849

Merged
merged 12 commits into from
Mar 27, 2018
Merged

Conversation

patrickhulce
Copy link
Collaborator

@patrickhulce patrickhulce commented Mar 22, 2018

closes #4478

with this you can

  • filter audits/categories from CLI i.e. lighthouse --only-categories seo https://google.com 🎉 cc @rviscomi FYI
  • use all CLI flags in your config.settings object i.e. {settings: {disableDeviceEmulation: true}}

precursor to landing the throttling changes we discussed we need to eliminate this config.settings/flags discrepancy which is a big enough change on its own to split out to this separate PR (and a huge win on its own! 🎉 😃)

essentially this PR eliminates all references to .flags beyond the initial index.js that calls new Config to merge the flags into settings

also cleans up some naming discrepancy that config was used to refer to passConfig which became super confusing when we actually needed access to config.settings

  • options -> passContext when applicable
  • config -> passConfig when applicable
  • flags -> settings

@@ -5,10 +5,14 @@
*/
'use strict';

const Driver = require('../gather/driver');
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I'm not a fan of requiring core files in default config, but we'll need a strategy for this when it comes to throttling soon. split constants out to a separate file? have them canonically live in config?

Copy link
Collaborator

@wardpeet wardpeet Mar 22, 2018

Choose a reason for hiding this comment

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

if those settings like max_wait_for_fully_loaded will live in settings they can probably be removed from the original file so why not put them in here to start with? we could export them from this file so other files that might need it as a fallback can still get those values

Copy link
Collaborator Author

@patrickhulce patrickhulce Mar 22, 2018

Choose a reason for hiding this comment

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

well that's the question up for discussion :)

it makes some sense to continue having them colocated with the logic they affect as well as to simplify unit testing where a full default config is not given (think the lantern simulation settings for example)

I take it you vote to keep them in the config?

Copy link
Member

Choose a reason for hiding this comment

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

+1 for putting these constants in the config. Requiring the driver from cli-flags was the absolute worst. Basing them in config seems most natural.

Copy link
Collaborator

Choose a reason for hiding this comment

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

@patrickhulce yeah +1 for config

@@ -563,8 +565,13 @@ class Config {
* @return {!Set<string>}
*/
static getAuditIdsInCategories(categories) {
const audits = _flatten(Object.keys(categories).map(id => categories[id].audits));
return new Set(audits.map(audit => audit.id));
/** @type {Array<string>} */
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I wanted to try to do some type checking in config, did 2 changes and then scared off by the sea of red. save that for later :)

Copy link
Collaborator

Choose a reason for hiding this comment

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

when you say @brendankenny 3 times, your type checking will be resolved automatically

Copy link
Member

Choose a reason for hiding this comment

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

yeah, it's the worst file :) We might have to do it a few methods at a time, turning on type checking for changes and then turning it back on when committing so the build stays green :)

Copy link
Member

@paulirish paulirish left a comment

Choose a reason for hiding this comment

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

looks pretty awesome!

I like how flags and settings come together in beautiful harmony and the rest of the pipeline gets to consider it as one.

@@ -5,10 +5,14 @@
*/
'use strict';

const Driver = require('../gather/driver');
Copy link
Member

Choose a reason for hiding this comment

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

+1 for putting these constants in the config. Requiring the driver from cli-flags was the absolute worst. Basing them in config seems most natural.

@@ -21,7 +21,7 @@ const Sentry = require('./lib/sentry');
class Runner {
static run(connection, opts) {
// Clean opts input.
opts.flags = opts.flags || {};
Copy link
Member

Choose a reason for hiding this comment

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

you can also remove flags from return Runner.run(connection, {url, flags, config}) in index.js

settings: ConfigSettings;
}

export interface ConfigSettings {
Copy link
Member

Choose a reason for hiding this comment

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

technically doesn't this extend Flags ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

yeah we'll need to decide what to do here, flags is currently what comes back fresh off yargs, which is slightly different than the flags that get passed into core which is what ConfigSettings extends, I'll extract the shared stuff and have both extend that 👍

@@ -28,12 +28,10 @@ const DEFAULT_PAUSE_AFTER_LOAD = 0;
const DEFAULT_NETWORK_QUIET_THRESHOLD = 5000;
// Controls how long to wait between longtasks before determining the CPU is idle, off by default
const DEFAULT_CPU_QUIET_THRESHOLD = 0;
// Controls maximum amount of time to wait before continuing
const DEFAULT_MAX_WAIT_FOR_LOAD = require('../config/constants').MAX_WAIT_FOR_LOAD;
Copy link
Member

Choose a reason for hiding this comment

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

we might not be able to do this now (lots of test modifications?), but it would be pretty cool to pull all the references to these constants out of driver altogether, and just have the various pauseAfterLoadMs, etc (basically all of ConfigSettings) required on the config by the time it gets into driver

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

yeah sg for followup 👍

Copy link
Member

Choose a reason for hiding this comment

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

to clarify, this wouldn't be only about a neat architecture or whatever. It would also let you --print-config or whatever so you could get a full print out of exactly what the LH run will be like (and what things you could provide instead) without having to look up defaults or whatever


declare global {
module LH {
namespace LH {
Copy link
Member

Choose a reason for hiding this comment

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

was this change necessary? I don't actually remember the reasoning (and it's possible the reasons no longer apply as this file changed), but I do remember it was a deliberate decision at the time :)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

no it keeps getting automatically changed or a bad rebase or something :)

* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
*/
'use strict';
Copy link
Member

Choose a reason for hiding this comment

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

might be dumb, but: maybe defaults.js or something? It might be good to have it be specifically a place where we keep defaults for these kinds of controls and avoid the temptation of just having it be a grab bag of constants we need across files

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

point taken but can we please pick another name? default.js and defaults.js would just be nuts 😆 maybe we rename default.js -> default-config.js?

Copy link
Member

Choose a reason for hiding this comment

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

haha, forgot about default.js.

default.js -> default-config.js actually makes a lot of sense, but not sure if you want to do that in this PR. Maybe we don't reference it that many places so it's not too bad?

Copy link
Collaborator Author

@patrickhulce patrickhulce Mar 23, 2018

Choose a reason for hiding this comment

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

yeah agreed, let's do this in followup, how about I just leave the Driver require for now (revert constants.js) and address all these in separate go for review?

Copy link
Member

Choose a reason for hiding this comment

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

SGTM

@patrickhulce
Copy link
Collaborator Author

patrickhulce commented Mar 23, 2018

so this look good to you folks then? 😃 @paulirish @brendankenny

Copy link
Member

@paulirish paulirish left a comment

Choose a reason for hiding this comment

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

lgtm from me

let pauseAfterLoadMs = passConfig && passConfig.pauseAfterLoadMs;
let networkQuietThresholdMs = passConfig && passConfig.networkQuietThresholdMs;
let cpuQuietThresholdMs = passConfig && passConfig.cpuQuietThresholdMs;
let maxWaitMs = passContext.settings && passContext.settings.maxWaitForLoad;
Copy link
Member

Choose a reason for hiding this comment

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

wanna clean this up?

could do..

const passConfig = passContext.passConfig || {};  // dunno if the `|| {} ` is required
const {pauseAfterLoadMs, networkQuietThresholdMs, cpuQuietThresholdMs, maxWaitMs} = passConfig;

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

done

disableCpuThrottling?: boolean;
disableNetworkThrottling?: boolean;

extraHeaders?: string;
Copy link
Member

Choose a reason for hiding this comment

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

this one doesnt belong in sharedflagsettings?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

correct, in LHFlags it's a string but in ConfigSettings its an object of headers

@patrickhulce
Copy link
Collaborator Author

@brendankenny does this have your ✝️🙏?

Copy link
Member

@brendankenny brendankenny left a comment

Choose a reason for hiding this comment

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

two last comments/suggestions, but LGTM!

* @return {!Promise}
*/
static loadPage(driver, options) {
return driver.gotoURL(options.url, {
static loadPage(driver, passContext) {
Copy link
Member

Choose a reason for hiding this comment

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

it's a little weird that the passContext received here isn't (quite) the same object/shape as the options object passed on to gotoURL (now also called passContext on the receiver side). Can we unify?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I guess if I were being real about it, I'd leave gotoURL as options that is {waitForLoad: boolean, passContext: Object} rather than abuse passContext, but the layer of nesting was annoying. I'm guessing you're in favor of doing that instead? :)

Copy link
Member

Choose a reason for hiding this comment

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

ha, it is more awkward but probably better. It'll get better when we pull out a passContext type :)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

done 👍

*/
constructor(configJSON, configPath) {
constructor(configJSON, configPath, flags) {
Copy link
Member

Choose a reason for hiding this comment

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

should we drop the optional configPath since it's on flags now?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

good call done 👍

@patrickhulce patrickhulce merged commit ecb3a8c into master Mar 27, 2018
@patrickhulce patrickhulce deleted the unify_config_cli_settings branch March 27, 2018 22:15
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.

Make it easier to run a specific audit category from CLI
5 participants