同步运行包含shell进程的gulp任务

时间:2015-07-05 18:03:14

标签: gulp

我正在尝试使用gulp作为复杂系统的安装程序,包括创建文件夹,复制文件和运行compliation脚本。

目前我有以下任务:

 // 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();
});

当我运行gulp时,很明显,进程在后台启动,gulp任务立即完成。上面的第一个任务应该复制源文件,第二个任务编译它们。在实践中,第二个任务遇到错误,因为当第二个任务(几乎立即)启动时,第一个任务没有准备好复制。

如果我单独运行第二个任务,首先复制第一个任务的所有文件,它可以正常工作,但我输出如下:

 [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

因此离开任务需要6.68毫秒,而我希望只有在任务中指定的所有编译完成后才允许gulp离开。然后,我将运行另一个编译过程,该过程使用此步骤中的构建二进制文件作为依赖项。

如何以这种方式运行外部命令,只有在第一个任务完成外部进程的执行后才能启动下一个gulp任务?

1 个答案:

答案 0 :(得分:2)

您应该确保在开始prepare_comedi之前完成任务compile_comedi。为此,由于您在prepare任务上使用常规流,只需返回流:

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));
});

由于这些任务是相互依赖的并且需要某些顺序,因此您可能还需要考虑重构代码以实际创建两个方法并正常调用它们。看一下这个note

<强>更新

在下面的评论中解决您的问题,如果您希望在某个异步作业完成之前保留任务,那么您有三种选择:

  1. 返回一个流(上面的案例)
  2. 完成承诺并在完成后完成承诺(在此示例中使用Q):
  3. var Q = require('Q');
    
    gulp.task('asyncWithPromise', function() {
      var deferred = Q.defer();
    
      // anything asynchronous
      setTimeout(function() {
        Q.resolve('nice');
      }, 5000);
    
      return deferred.promise;
    });
    
    1. 接收callback功能并将其调用
    2. gulp.task('asyncWithPromise', function(done) {
        setTimeout(function() {
          done();
        }, 5000);
      });
      

      这些方法是in the docs