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(config): add support for audit/gatherer options #4394

Merged
merged 8 commits into from
Feb 14, 2018

Conversation

patrickhulce
Copy link
Collaborator

@patrickhulce patrickhulce commented Jan 30, 2018

big change coming in! closes #4206

introduces support for audit and gatherer options while maintaining backcompat with existing config options, internally all audits and gatherers are mapped to the new format

additionally, the very poorly named options input to gatherers I'm now calling context as it more roughly captures what's being passed in, also we avoid options.options :)

feedback very very welcome while it's still early please! :D

Usage - before

module.exports = {
  passes: [{
    gatherers: [
      'builtin-gatherer',
      class MyGatherer extends Gatherer { },
  }],
  audits: [
    'builtin-audit',
    class MyAudit extends Audit { },
  ]
}

Usage - after

module.exports = {
  passes: [{
    gatherers: [
      'builtin-gatherer', // legacy
      {path: 'seo/other-gatherer', options: {foo: 1}}, // new

      class MyGatherer extends Gatherer { }, // legacy
      {implementation: class MyGatherer {}}, // new
      {instance: new (class MyGatherer extends Gatherer { })()}, // new
  }],
  audits: [
    'builtin-audit',
    {path: 'byte-efficiency/other-audit', options: {foo: 1}},
    class MyAudit extends Audit { },
  ]
}

@@ -145,7 +146,7 @@ function validateCategories(categories, audits, groups) {
return;
}

const auditIds = audits.map(audit => audit.meta.name);
const auditIds = audits.map(audit => audit.implementation.meta.name);
Copy link
Collaborator

Choose a reason for hiding this comment

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

I find implementation such a weird name I wanted to call it instance but I see below that it's indeed the implementation but still find it weird 😛 but maybe that's because i'm no native speaker.

@wardpeet
Copy link
Collaborator

I really like this PR! not much to say about it. I haven't tested any of it but the approach looks good. I only think we need to document the option parameter a bit. We don't want it to be used as an escape hatch to smuggle custom settings in.

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.

Thanks for all the renames. It's great to have these things called more accurately.

A few questions below but first.. This is correct yah?

  • implementation: the class of a gatherer/audit
  • instance: an instance of that class/implementation
  • defn: whatever is resolved into the implementation.
    • Can you show me what one looks like? a gathererDefn and an auditDefn?

return gathererDefn;
}

if (typeof gathererDefn.beforePass === 'function') {
Copy link
Member

Choose a reason for hiding this comment

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

this is for backwards compat? if so can you add a comment with the case this covers?

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

return chain.then(_ => {
const artifactPromise = Promise.resolve().then(_ => gatherer.pass(options));
const gatherer = gathererDefn.instance;
Copy link
Member

Choose a reason for hiding this comment

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

feels like pass/beforePass shouldn't have to do this resolving on their own. can we provide instantiated gatherers instead of the config.gatherers or something?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

resolved in person, outcome: gather-runner will still need access to .instance and .options but will be oblivious to everything else

return new GathererClass();
const gathererPath = typeof gathererDefn === 'string' ? gathererDefn : gathererDefn.path;
const GathererClass = GatherRunner.getGathererClass(
gathererDefn.implementation || gathererPath, rootPath);
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 move all this into config.js? seems like it spiritually belongs over there.

There's also a lot of cases (6+?) being served by these lines:

// If this is already instantiated, don't do anything else.
if (gathererDefn.instance) {
return gathererDefn;
}
if (typeof gathererDefn.beforePass === 'function') {
return {instance: gathererDefn, options: {}};
}
const gathererPath = typeof gathererDefn === 'string' ? gathererDefn : gathererDefn.path;
const GathererClass = GatherRunner.getGathererClass(
gathererDefn.implementation || gathererPath, rootPath);

I'm hoping by moving it into config, we're going to end up with something simpler. Open to ideas.

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 just lots of test changes 😢 I'm on it though

return chain.then(_ => {
const artifactPromise = Promise.resolve().then(_ => gatherer.pass(options));
const gatherer = gathererDefn.instance;
context.options = gathererDefn.options || {};
Copy link
Member

Choose a reason for hiding this comment

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

at the very least let's comment that this is terrible. :)

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'll create a new context so it won't be terrible :)

@@ -491,14 +501,21 @@ class GatherRunner {

static instantiateGatherers(passes, rootPath) {
Copy link
Member

Choose a reason for hiding this comment

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

let's do instantiateGatherers back in config so by the time gatherrunner.run is called, everything has an instance.
this'll require updating some tests. sorry 'bout that.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

on it

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.

this is gtg, though I think we should land it after we cut the 2.9.1. sgty?

const gatherer = gathererDefn.instance;
// Abuse the passContext to pass through gatherer options
passContext.options = gathererDefn.options || {};
const artifactPromise = Promise.resolve().then(_ => gatherer.beforePass(passContext));
Copy link
Member

Choose a reason for hiding this comment

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

wdyt about a followup PR to rename options in all the gatherers to passContext?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

sg

@patrickhulce
Copy link
Collaborator Author

this is gtg, though I think we should land it after we cut the 2.9.1. sgty?

yeah good plan

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.

Add support for audit/gatherer options
4 participants