Skip to content

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 { },
  ]
}

}

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 gatherers.reduce((chain, gathererDefn) => {
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 :)

}
}

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