Reputation: 9441
I am trying to use gulp as an installer for complex system that involves creating folder, copying files around and runnin compliation scripts.
Presently I have the following gulp tasks:
// Some tasks skipped that set sessionFolder
gulp.task('default', function () {
// Main
runSequence('prepare_comedi', 'compile_comedi');
});
gulp.task('prepare_comedi', function () {
// Copies comedi files into build folder
gulp.src(['../comedi/**/*']).pipe(gulp.dest(sessionFolder));
});
gulp.task('compile_comedi', function () {
var logfile=this.currentTask.name+'.log';
gutil.log(gutil.colors.green(this.currentTask.name), ": building and installing COMEDI, logging to "+logfile);
var cmd= new run.Command('{ ./autogen.sh; ./configure; make; make install; depmod -a ; make dev;} > ../'+logfile+ ' 2>&1', {cwd:sessionFolder+'/comedi', verbosity:3});
cmd.exec();
});
When I run gulp, it becomes obvious that the processes start in background and gulp task finishes immediately. The first task above should copy source files, and second one compile them. In practice, second task hits the error, as the first task is not ready with copying when second task (almost immediately) starts.
If I run second task alone, previosuly having all files from first task copied, it works ok, but I have output like this:
[19:52:47] Starting 'compile_comedi'...
[19:52:47] compile_comedi : building and installing COMEDI, logging to compile_comedi.log
$ { ./autogen.sh; ./configure; make; make install; depmod -a ; make dev;} > ../compile_comedi.log 2>&1
[19:52:47] Finished 'compile_comedi' after 6.68 ms
So it takes 6.68 millisec to leave the task, while I want gulp to leave it only after all compilations specified in the task are finished. I then would run another compile process that uses built binaries from this step as a dependency.
How I can run external commands in such a way, that next gulp task starts only after first task complete execution of an external process?
Upvotes: 2
Views: 522
Reputation: 23394
You should make sure that the task prepare_comedi
is finalized prior to start compile_comedi
. In order to do so, since you're using regular streams on the prepare
task, simply return the stream:
gulp.task('prepare_comedi', function () {
// !!! returns the stream. Gulp will not consider the task as done
// until the stream ends.
return gulp.src(['../comedi/**/*']).pipe(gulp.dest(sessionFolder));
});
Since these tasks are interdependent and require certain order, you might also want to consider refactoring your code to actually create two methods and call them normally. Take a look at this note.
Update
Addressing your question in the comment below, if you want to hold a task until some asynchronous job has been completed, you have pretty much three choices:
var Q = require('Q');
gulp.task('asyncWithPromise', function() {
var deferred = Q.defer();
// anything asynchronous
setTimeout(function() {
Q.resolve('nice');
}, 5000);
return deferred.promise;
});
callback
function and calling itgulp.task('asyncWithPromise', function(done) {
setTimeout(function() {
done();
}, 5000);
});
These approaches are in the docs.
Upvotes: 2