I'm writing a yeoman generator.
I need to run some shell script after all files copied.
The generator is being called as a child generator so it should wait till script finished.
The script is some command file being run via spawn
:
that.spawnCommand('createdb.cmd');
As the script depends on files created by the generator it cannot run right inside generator's methods as all copy/template action are async and have not executed yet:
MyGenerator.prototype.serverApp = function serverApp() {
if (this.useLocalDb) {
this.copy('App_Data/createdb.cmd', 'App_Data/createdb.cmd');
// here I cannot run spawn with createdb.cmd as it doesn't exist
}
}
So the only place I found where I can run spawn is the 'end' event handler:
var MyGenerator = module.exports = function MyGenerator (args, options, config) {
this.on('end', function () {
if (that.useLocalDb) {
that.spawnCommand('createdb.cmd')
}
}
}
The script runs successfully but the generator finishes earlier than the child process. I need to tell Yeoman to wait for my child process. Something like this:
this.on('end', function (done) {
this.spawnCommand('createdb.cmd')
.on('close', function () {
done();
});
}.bind(this));
But 'end' handler doesn't have the argument with 'dine' callback.
How to do this?
UPDATE:
thanks to @SimonBoudrias I got it working.
The full working code is below.
BTW: end
method is described in the docs
var MyGenerator = module.exports = yeoman.generators.Base.extend({
constructor: function (args, options, config) {
yeoman.generators.Base.apply(this, arguments);
this.appName = this.options.appName;
},
prompting : function () {
// asking user
},
writing : function () {
// copying files
},
end: function () {
var that = this;
if (this.useLocalDb) {
var done = this.async();
process.chdir('App_Data');
this.spawnCommand('createdb.cmd').on('close', function () {
that._sayGoodbay();
done();
});
process.chdir('..');
} else {
this._sayGoodbay();
}
},
_sayGoodbay: funciton () {
// final words to user
}
});
Never trigger any action in the end
event. This event is to be used by implementors, not generator themselves.
In your case:
module.exports = generators.Base({
end: function () {
var done = this.async();
this.spawnCommand('createdb.cmd').on('close', done);
}
});