If you follow the stack, this.installDependencies
eventually works its way down to https://github.com/yeoman/generator/blob/45258c0a48edfb917ecf915e842b091a26d17f3e/lib/actions/install.js#L36:
this.spawnCommand(installer, args, cb)
.on('error', cb)
.on('exit', this.emit.bind(this, installer + 'Install:end', paths))
.on('exit', function (err) {
if (err === 127) {
this.log.error('Could not find ' + installer + '. Please install with ' +
'`npm install -g ' + installer + '`.');
}
cb(err);
}.bind(this));
Chasing this down further, this.spawnCommand
comes from https://github.com/yeoman/generator/blob/master/lib/actions/spawn_command.js:
var spawn = require('child_process').spawn;
var win32 = process.platform === 'win32';
/**
* Normalize a command across OS and spawn it.
*
* @param {String} command
* @param {Array} args
*/
module.exports = function spawnCommand(command, args) {
var winCommand = win32 ? 'cmd' : command;
var winArgs = win32 ? ['/c'].concat(command, args) : args;
return spawn(winCommand, winArgs, { stdio: 'inherit' });
};
In other words, in your Generator's code, you can call this.spawnCommand
anytime, and pass it the arguments you wish the terminal to run. As in, this.spawnCommand('grunt', ['build'])
.
So then the next question is where do you put that? Thinking linearly, you can only trust that grunt build
will work after all of your dependencies have been installed.
From https://github.com/yeoman/generator/blob/45258c0a48edfb917ecf915e842b091a26d17f3e/lib/actions/install.js#L67-69,
this.installDependencies
accepts a callback, so your code might look like this:
this.on('end', function () {
this.installDependencies({
skipInstall: this.options['skip-install'],
callback: function () {
this.spawnCommand('grunt', ['build']);
}.bind(this) // bind the callback to the parent scope
});
});
Give it a shot! If all goes well, you should add some error handling on top of that new this.spawnCommand
call to be safe.
this
loses scope. I originally created a variable to cachethis
in the correct scope and used that to callspawnCommand
. However, I decided to usebind()
instead since it would be cleaner. I've edited the answer to reflect this. – Airlee