Skip to content

Commit

Permalink
Patch to allow customization of the gulp module within run-sequence. C…
Browse files Browse the repository at this point in the history
  • Loading branch information
OverZealous committed Sep 18, 2014
1 parent 7b4396b commit 689dbcc
Show file tree
Hide file tree
Showing 5 changed files with 268 additions and 209 deletions.
173 changes: 94 additions & 79 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,79 +1,94 @@
# run-sequence

[![NPM version][npm-image]][npm-url] [![Build Status][travis-image]][travis-url]

Runs a sequence of gulp tasks in the specified order. This function is designed to solve the situation where you have defined run-order, but choose not to or cannot use dependencies.

> ### Please Note
>
> This is intended to be a temporary solution until [orchestrator](https://github.com/robrich/orchestrator/) is updated to support [non-dependent ordered tasks](https://github.com/robrich/orchestrator/issues/21).
>
> Be aware that this solution is a hack, and may stop working with a future update to orchestrator.
Each argument to `run-sequence` is run in order. This works by listening to the `task_stop` and `task_err` events, and keeping track of which tasks have been completed. You can still run some of the tasks in parallel, by providing an array of task names for one or more of the arguments.

If the final argument is a function, it will be used as a callback after all the functions are either finished or an error has occurred.

## Usage

First, install `run-sequence` as a development dependency:

```shell
npm install --save-dev run-sequence
```

Then add use it in your gulpfile, like so:

```js
var gulp = require('gulp');
var runSequence = require('run-sequence');
var clean = require('gulp-clean');

// This will run in this order:
// * build-clean
// * build-scripts and build-styles in parallel
// * build-html
// * Finally call the callback function
gulp.task('build', function(callback) {
runSequence('build-clean',
['build-scripts', 'build-styles'],
'build-html',
callback);
});

// configure build-clean, build-scripts, build-styles, build-html as you
// wish, but make sure they either return a stream or handle the callback
// Example:

gulp.task('build-clean', function() {
return gulp.src(BUILD_DIRECTORY).pipe(clean());
// ^^^^^^
// This is the key here, to make sure tasks run asynchronously!
});

gulp.task('build-scripts', function() {
return gulp.src(SCRIPTS_SRC).pipe(...)...
// ^^^^^^
// This is the key here, to make sure tasks run asynchronously!
});
```

## Help Support This Project

If you'd like to support this and other OverZealous Creations (Phil DeJarnett) projects, [donate via Gittip][gittip-url]!

[![Support via Gittip][gittip-image]][gittip-url]

## LICENSE

[MIT License](http://en.wikipedia.org/wiki/MIT_License)


[npm-url]: https://npmjs.org/package/run-sequence
[npm-image]: https://badge.fury.io/js/run-sequence.png

[travis-url]: http://travis-ci.org/OverZealous/run-sequence
[travis-image]: https://secure.travis-ci.org/OverZealous/run-sequence.png?branch=master

[gittip-url]: https://www.gittip.com/OverZealous/
[gittip-image]: https://raw2.github.com/OverZealous/gittip-badge/0.1.2/dist/gittip.png
# run-sequence

[![NPM version][npm-image]][npm-url] [![Build Status][travis-image]][travis-url]

Runs a sequence of gulp tasks in the specified order. This function is designed to solve the situation where you have defined run-order, but choose not to or cannot use dependencies.

> ### Please Note
>
> This is intended to be a temporary solution until [orchestrator](https://github.com/robrich/orchestrator/) is updated to support [non-dependent ordered tasks](https://github.com/robrich/orchestrator/issues/21).
>
> Be aware that this solution is a hack, and may stop working with a future update to orchestrator.
Each argument to `run-sequence` is run in order. This works by listening to the `task_stop` and `task_err` events, and keeping track of which tasks have been completed. You can still run some of the tasks in parallel, by providing an array of task names for one or more of the arguments.

If the final argument is a function, it will be used as a callback after all the functions are either finished or an error has occurred.

## Usage

First, install `run-sequence` as a development dependency:

```shell
npm install --save-dev run-sequence
```

Then add use it in your gulpfile, like so:

```js
var gulp = require('gulp');
var runSequence = require('run-sequence');
var clean = require('gulp-clean');

// This will run in this order:
// * build-clean
// * build-scripts and build-styles in parallel
// * build-html
// * Finally call the callback function
gulp.task('build', function(callback) {
runSequence('build-clean',
['build-scripts', 'build-styles'],
'build-html',
callback);
});

// configure build-clean, build-scripts, build-styles, build-html as you
// wish, but make sure they either return a stream or handle the callback
// Example:

gulp.task('build-clean', function() {
return gulp.src(BUILD_DIRECTORY).pipe(clean());
// ^^^^^^
// This is the key here, to make sure tasks run asynchronously!
});

gulp.task('build-scripts', function() {
return gulp.src(SCRIPTS_SRC).pipe(...)...
// ^^^^^^
// This is the key here, to make sure tasks run asynchronously!
});
```

### Using within gulp submodules

If you have a complex gulp setup with your tasks split up across different files, you may get the error that `run-sequence` is unable to find your tasks. In this case, you can configure `run-sequence` to look at the gulp within the submodule, like so:

```js
// submodule tasks/mygulptask.js

var gulp = require('gulp'), // might be a different instance than the toplevel one
// this uses the gulp you provide
runSequence = require('run-sequence').use(gulp);

// ...and then use normally
runSequence('subtask1', 'subtask2');
```

## Help Support This Project

If you'd like to support this and other OverZealous Creations (Phil DeJarnett) projects, [donate via Gittip][gittip-url]!

[![Support via Gittip][gittip-image]][gittip-url]

## LICENSE

[MIT License](http://en.wikipedia.org/wiki/MIT_License)


[npm-url]: https://npmjs.org/package/run-sequence
[npm-image]: https://badge.fury.io/js/run-sequence.png

[travis-url]: http://travis-ci.org/OverZealous/run-sequence
[travis-image]: https://secure.travis-ci.org/OverZealous/run-sequence.png?branch=master

[gittip-url]: https://www.gittip.com/OverZealous/
[gittip-image]: https://raw2.github.com/OverZealous/gittip-badge/0.1.2/dist/gittip.png
160 changes: 81 additions & 79 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,79 +1,81 @@
/*jshint node:true */

"use strict";

var gulp = require('gulp'),
colors = require('chalk');

function verifyTaskSets(taskSets, skipArrays) {
if(taskSets.length === 0) {
throw new Error('No tasks were provided to run-sequence');
}
taskSets.forEach(function(t) {
var isTask = typeof t === "string",
isArray = !skipArrays && Array.isArray(t);
if(!isTask && !isArray) {
throw new Error("Task "+t+" is not a valid task string.");
}
if(isTask && !gulp.hasTask(t)) {
throw new Error("Task "+t+" is not configured as a task on gulp.");
}
if(isArray) {
if(t.length === 0) {
throw new Error("An empty array was provided as a task set");
}
verifyTaskSets(t, true);
}
});
}

function runSequence() {
var taskSets = Array.prototype.slice.call(arguments),
callBack = typeof taskSets[taskSets.length-1] === 'function' ? taskSets.pop() : false,
currentTaskSet,

finish = function(err) {
gulp.removeListener('task_stop', onTaskEnd);
gulp.removeListener('task_err', onError);
if(callBack) {
callBack(err);
} else if(err) {
console.log(colors.red('Error running task sequence:'), err);
}
},

onError = function(err) {
finish(err);
},
onTaskEnd = function(event) {
var idx = currentTaskSet.indexOf(event.task);
if(idx > -1) {
currentTaskSet.splice(idx,1);
}
if(currentTaskSet.length === 0) {
runNextSet();
}
},

runNextSet = function() {
if(taskSets.length) {
var command = taskSets.shift();
if(!Array.isArray(command)) {
command = [command];
}
currentTaskSet = command;
gulp.start.apply(gulp, command);
} else {
finish();
}
};

verifyTaskSets(taskSets);

gulp.on('task_stop', onTaskEnd);
gulp.on('task_err', onError);

runNextSet();
}

module.exports = runSequence;
/*jshint node:true */

"use strict";

var colors = require('chalk');

function verifyTaskSets(gulp, taskSets, skipArrays) {
if(taskSets.length === 0) {
throw new Error('No tasks were provided to run-sequence');
}
taskSets.forEach(function(t) {
var isTask = typeof t === "string",
isArray = !skipArrays && Array.isArray(t);
if(!isTask && !isArray) {
throw new Error("Task "+t+" is not a valid task string.");
}
if(isTask && !gulp.hasTask(t)) {
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).");
}
if(isArray) {
if(t.length === 0) {
throw new Error("An empty array was provided as a task set");
}
verifyTaskSets(gulp, t, true);
}
});
}

function runSequence(gulp) {
var taskSets = Array.prototype.slice.call(arguments, 1),
callBack = typeof taskSets[taskSets.length-1] === 'function' ? taskSets.pop() : false,
currentTaskSet,

finish = function(err) {
gulp.removeListener('task_stop', onTaskEnd);
gulp.removeListener('task_err', onError);
if(callBack) {
callBack(err);
} else if(err) {
console.log(colors.red('Error running task sequence:'), err);
}
},

onError = function(err) {
finish(err);
},
onTaskEnd = function(event) {
var idx = currentTaskSet.indexOf(event.task);
if(idx > -1) {
currentTaskSet.splice(idx,1);
}
if(currentTaskSet.length === 0) {
runNextSet();
}
},

runNextSet = function() {
if(taskSets.length) {
var command = taskSets.shift();
if(!Array.isArray(command)) {
command = [command];
}
currentTaskSet = command;
gulp.start.apply(gulp, command);
} else {
finish();
}
};

verifyTaskSets(gulp, taskSets);

gulp.on('task_stop', onTaskEnd);
gulp.on('task_err', onError);

runNextSet();
}

module.exports = runSequence.bind(null, require('gulp'));
module.exports.use = function(gulp) {
return runSequence.bind(null, gulp);
};
Loading

0 comments on commit 689dbcc

Please sign in to comment.