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

[Composability] Compose with generators #484

Closed
SBoudrias opened this issue Jan 30, 2014 · 6 comments
Closed

[Composability] Compose with generators #484

SBoudrias opened this issue Jan 30, 2014 · 6 comments

Comments

@SBoudrias
Copy link
Member

Currently the only way for a generator author to compose with an external generator is to use hooks (hookFor, runHooks).

Hooks are great, but may be doing too much:

  • Hooks only* work with globally installed generators
  • Hooks allow the end user to override the generator call

This mean, as an author, you have no garantee that you're running a specific generator, and that the generator is the version you expect.

I think authors need a reliable way to compose with another generator in a fully predictable way. As so, author must be able to run a specific generator (not user overridable) with a specific version (local package).

As so, we need to create a new API to allow this use case. I'd like to propose Base#composeWith( Generator, [ arguments, options ]).

this.composeWith( require('generator-sass') );
this.composeWith( require('generator-sass'), { 'add-boostrap': true }); // or whatever is standard in the code base, I'll have to double check
this.composeWith( require('generator-sass'), {}, { always: true }); // See below

I believe in composed state initiated by the end-user, we should skip author initiated composition by default, unless a special arguments is provided. This would differentiate between strong composition link (like core feature absolutly needed) and weak composition links (relying on cool feature that could be override by the end user).


* Sure you could manually stub it

@sindresorhus
Copy link
Member

This is how I always imagined it would work. Huge 👍!

@SBoudrias
Copy link
Member Author

A lot of components inside Yeoman base themselve on path resolution logic. Is it an option that we pass module path rather than a Constructor? E.g.:

this.composeWith( require.resolve('generator-sass') );

I feel this is ugly, but... I'm not sure I see a workaround that can be used in the current structure.

@sindresorhus
Copy link
Member

Nope, I'd rather we fix the current structure.

@SBoudrias
Copy link
Member Author

I've been searching for an elegant solution, but I didn't find any. The system is currently very tightly tied to the file-system, I don't think we can change it without uncovering large and deep changes to how generators are gather and resolved.

So, I propose to use a solution similar to hookFor; that is using namespaces and available generators (peerDependencies). So you'd call:

// Basic
this.composeWith('bootstrap', { arg: 'one' });

// Allowing using a local path for "advance" use
this.composeWith('sass', { arg: 'one' }, { local: require.resolve('generator-sass') });

This may not seem ideal, but it'll work in a clear enough way. We can think of ways to fix our hard dependencies on the file system for futures versions - probably for 1.0 or later as it'll probably bring breaking changes. Right now I think we can work correctly with this and bring composability sooner than later without being blocked by large internal changes.

@mazerte
Copy link

mazerte commented Feb 11, 2014

👍

@addyosmani
Copy link
Member

I personally favor the global generator approach similar to how we're handling this in hookFor. It's a lot less verbose than some of the alternatives and I'm okay with us breaking backwards compat in the name of composability (as long as we feel there are no other options for keeping that in place whilst avoiding long lookup paths).

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

No branches or pull requests

4 participants