Search code examples
javascriptcommand-line-interfaceyeomanyeoman-generator

How to skip Yeoman generator step when invoked from node script


I have a node js script that invokes a Yeoman generator that I wrote and I would like to skip the prompting step since I'm passing the data for the generator from the script. I searched the documentation but I didn't find anything relevant for this. Is it possible at all?

My script looks like this

const yeoman = require('yeoman-environment');
const env = yeoman.createEnv();

env.lookup(() => {

    env.run('mygenerator:subgenerator --moduleName Test3', {'skip-install': true, 'skip-prompting': true }, err => {
        console.log('done');
    });
});

And my generator has nothing special:

const BaseGenerator = require('./../base/index.js');

module.exports = class extends BaseGenerator {

    constructor(args, opts) {
        super(args, opts);

        this.props = opts;

        const destinationFolder = args.destinationFolder || '';
        const moduleName = args.moduleName || '';

        this.props = {
            moduleName,
            destinationFolder,
        };
    }

    prompting() {
        //...
    }

    writing() {
        //...
    }

};

I know that the generator gets the data I'm passing from the script. I potentially I could have a generator which deals with input and another one only for writing the files. But it'd be nice to have only one code and be able to skip some steps.

I saw in some stackoverflow answers that people pass the { 'skip-install': true } option to the generator. Then I tried to pass { 'skip-prompting': true }, but it doesn't do anything.

Thank you!

EDIT

The way that I solved this is the following:

All my sub generators extend a BaseGenerator that I wrote, which is the one that extends from Yeoman. In my BaseGenerator I added this method:

    shouldPrompt() {
        return typeof this.props.options === 'undefined' || 
            (typeof this.props.options.moduleName === 'undefined' &&
             typeof this.props.options.destinationFolder === 'undefined');
    }

I only use 2 parameters in my generators, moduleName and destinationFolder. So, that's all I want to check. Then, in the sub generators I added this:

    prompting() {

        if (this.shouldPrompt()) {

            this.log(chalk.red('Reducer generator'));

            const prompts = [ /*...*/ ];

            return this.prompt(prompts).then((props) => { this.props.options = props; });
        }

    }

Solution

  • You'll want to define options or arguments to accept these arguments from the terminal: http://yeoman.io/authoring/user-interactions.html

    Then, just use JavaScript to run or not the this.prompt() call (with if/else structure or any other conditional that works for your use case)

    Remember that Yeoman is still only JS code :)