index.js 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. /*jshint node:true */
  2. "use strict";
  3. var colors = require('chalk');
  4. var gutil = require('gulp-util');
  5. function verifyTaskSets(gulp, taskSets, skipArrays) {
  6. if(taskSets.length === 0) {
  7. throw new Error('No tasks were provided to run-sequence');
  8. }
  9. var foundTasks = {};
  10. taskSets.forEach(function(t) {
  11. var isTask = typeof t === "string",
  12. isArray = !skipArrays && Array.isArray(t);
  13. if(!isTask && !isArray) {
  14. throw new Error("Task "+t+" is not a valid task string.");
  15. }
  16. if(isTask && !gulp.hasTask(t)) {
  17. throw new Error("Task "+t+" is not configured as a task on gulp. If this is a submodule, you may need to use require('run-sequence').use(gulp).");
  18. }
  19. if(skipArrays && isTask) {
  20. if(foundTasks[t]) {
  21. throw new Error("Task "+t+" is listed more than once. This is probably a typo.");
  22. }
  23. foundTasks[t] = true;
  24. }
  25. if(isArray) {
  26. if(t.length === 0) {
  27. throw new Error("An empty array was provided as a task set");
  28. }
  29. verifyTaskSets(gulp, t, true, foundTasks);
  30. }
  31. });
  32. }
  33. function runSequence(gulp) {
  34. // load gulp directly when no external was passed
  35. if(gulp === undefined) {
  36. gulp = require('gulp');
  37. }
  38. // Slice and dice the input to prevent modification of parallel arrays.
  39. var taskSets = Array.prototype.slice.call(arguments, 1).map(function(task) {
  40. return Array.isArray(task) ? task.slice() : task;
  41. }),
  42. callBack = typeof taskSets[taskSets.length-1] === 'function' ? taskSets.pop() : false,
  43. currentTaskSet,
  44. finish = function(e) {
  45. gulp.removeListener('task_stop', onTaskEnd);
  46. gulp.removeListener('task_err', onError);
  47. var error;
  48. if (e && e.err) {
  49. error = new gutil.PluginError('run-sequence(' + e.task + ')', e.err, {showStack: true});
  50. }
  51. if(callBack) {
  52. callBack(error);
  53. } else if(error) {
  54. gutil.log(colors.red(error.toString()));
  55. }
  56. },
  57. onError = function(err) {
  58. finish(err);
  59. },
  60. onTaskEnd = function(event) {
  61. var idx = currentTaskSet.indexOf(event.task);
  62. if(idx > -1) {
  63. currentTaskSet.splice(idx,1);
  64. }
  65. if(currentTaskSet.length === 0) {
  66. runNextSet();
  67. }
  68. },
  69. runNextSet = function() {
  70. if(taskSets.length) {
  71. var command = taskSets.shift();
  72. if(!Array.isArray(command)) {
  73. command = [command];
  74. }
  75. currentTaskSet = command;
  76. gulp.start.apply(gulp, command);
  77. } else {
  78. finish();
  79. }
  80. };
  81. verifyTaskSets(gulp, taskSets);
  82. gulp.on('task_stop', onTaskEnd);
  83. gulp.on('task_err', onError);
  84. runNextSet();
  85. }
  86. module.exports = runSequence.bind(null, undefined);
  87. module.exports.use = function(gulp) {
  88. return runSequence.bind(null, gulp);
  89. };