onkami
onkami

Reputation: 9441

running gulp tasks that include shell processes synchronously

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

Answers (1)

Caio Cunha
Caio Cunha

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:

  1. return a stream (case above)
  2. returning a promise and fulfilling it when you're done (using Q in this example):
var Q = require('Q');

gulp.task('asyncWithPromise', function() {
  var deferred = Q.defer();

  // anything asynchronous
  setTimeout(function() {
    Q.resolve('nice');
  }, 5000);

  return deferred.promise;
});
  1. Receiving a callback function and calling it
gulp.task('asyncWithPromise', function(done) {
  setTimeout(function() {
    done();
  }, 5000);
});

These approaches are in the docs.

Upvotes: 2

Related Questions