Comparing version 1.1.0 to 1.5.1
253
index.js
/** | ||
* @license The MIT License (MIT) | ||
* @copyright Stanislav Kalashnik <darkpark.main@gmail.com> | ||
* @author Stanislav Kalashnik <darkpark.main@gmail.com> | ||
*/ | ||
@@ -13,93 +13,21 @@ | ||
/** | ||
* | ||
* | ||
* @constructor | ||
* @extends Emitter | ||
*/ | ||
function Runner () { | ||
console.assert(typeof this === 'object', 'must be constructed via new'); | ||
function wrap ( instance, taskId, taskBody ) { | ||
var time; | ||
// parent constructor call | ||
Emitter.call(this); | ||
this.tasks = {}; | ||
this.tree = {}; | ||
//this.running = {}; | ||
} | ||
// inheritance | ||
Runner.prototype = Object.create(Emitter.prototype); | ||
Runner.prototype.constructor = Runner; | ||
/** | ||
* Remove all attributes from the model. | ||
* | ||
* @param {string} id task name | ||
* @param {function} body task method | ||
* | ||
* @return {function} task | ||
* | ||
* @fires Runner#clear | ||
*/ | ||
Runner.prototype.task = function ( id, body ) { | ||
if ( id && typeof id === 'string' && body && typeof body === 'function' ) { | ||
this.tasks[id] = body; | ||
body.id = id; | ||
//console.log(body); | ||
} | ||
return body; | ||
}; | ||
//function done ( instance, fn ) { | ||
// // mark finished | ||
// fn.running = false; | ||
// | ||
// // there are some listeners | ||
// if ( instance.events['finish'] ) { | ||
// // notify listeners | ||
// instance.emit('finish', {id: fn.id}); | ||
// //console.log('finish', fn.id); | ||
// } | ||
//} | ||
// | ||
//function wrap ( instance, fn ) { | ||
// // is there a callback for task? | ||
// if ( fn.length === 0 ) { | ||
// // start task sync | ||
// fn(); | ||
// // finish | ||
// done(); | ||
// } else { | ||
// // start task async | ||
// fn(done); | ||
// } | ||
//} | ||
Runner.prototype.wrap = function ( task ) { | ||
var self = this, | ||
time; | ||
return function ( cb ) { | ||
var done = function () { | ||
// mark finished | ||
task.running = false; | ||
time = Date.now() - time; | ||
/*console.log('finish', task.id, time);/**/ | ||
// there are some listeners | ||
if ( self.events['finish'] ) { | ||
if ( instance.events['finish'] ) { | ||
// notify listeners | ||
self.emit('finish', {id: task.id, time: time}); | ||
instance.emit('finish', {id: taskId, time: Date.now() - time}); | ||
} | ||
// callback from user or | ||
if ( cb && typeof cb === 'function' ) { | ||
if ( cb ) { | ||
console.assert(typeof cb === 'function', 'user callback should be a function'); | ||
cb.apply(null, arguments); | ||
} | ||
// mark finished | ||
taskBody.running = false; | ||
}, | ||
@@ -109,25 +37,23 @@ result; | ||
// exist and not already executing | ||
if ( task && !task.running ) { | ||
if ( taskBody && !taskBody.running ) { | ||
// mark to prevent multiple starts | ||
task.running = true; | ||
taskBody.running = true; | ||
time = Date.now(); | ||
/*console.log('start', task.id);/**/ | ||
// there are some listeners | ||
if ( self.events['start'] ) { | ||
if ( instance.events['start'] ) { | ||
// notify listeners | ||
self.emit('start', {id: task.id}); | ||
instance.emit('start', {id: taskId}); | ||
} | ||
// is there a callback for task? | ||
if ( task.length === 0 ) { | ||
if ( taskBody.length === 0 ) { | ||
// start task sync | ||
result = task(); | ||
result = taskBody(); | ||
// finish | ||
done(); | ||
done(result === false); | ||
} else { | ||
//console.log(task.id); | ||
// start task async | ||
result = task(done); | ||
result = taskBody(done); | ||
} | ||
@@ -138,10 +64,53 @@ } | ||
}; | ||
} | ||
/** | ||
* @constructor | ||
* @extends Emitter | ||
*/ | ||
function Runner () { | ||
console.assert(typeof this === 'object', 'must be constructed via new'); | ||
// parent constructor call | ||
Emitter.call(this); | ||
this.tasks = {}; | ||
} | ||
// inheritance | ||
Runner.prototype = Object.create(Emitter.prototype); | ||
Runner.prototype.constructor = Runner; | ||
/** | ||
* Create a task with the given identifier. | ||
* | ||
* @param {string} id task unique name | ||
* @param {function} body task method | ||
* | ||
* @return {function} task | ||
* | ||
* //@fires Runner#clear | ||
*/ | ||
Runner.prototype.task = function ( id, body ) { | ||
console.assert(arguments.length === 2, 'wrong arguments number'); | ||
console.assert(typeof id === 'string', 'task id should be a string'); | ||
console.assert(id.length > 0, 'empty id'); | ||
console.assert(typeof body === 'function', 'task body should be a function'); | ||
this.tasks[id] = body; | ||
return body; | ||
}; | ||
// accepts list of task ids | ||
Runner.prototype.parallel = function () { | ||
var self = this, | ||
tasks = Array.prototype.slice.call(arguments), | ||
func; | ||
task; | ||
// no tasks were given | ||
if ( tasks.length === 0 ) { | ||
@@ -151,34 +120,24 @@ return null; | ||
func = function ( done ) { | ||
var readyTasks = []; | ||
// wrap not running tasks only | ||
tasks.forEach(function ( task ) { | ||
task = self.tasks[task] || task; | ||
if ( task && !task.running ) { | ||
readyTasks.push( | ||
function ( done ) { | ||
return self.run(task, done); | ||
} | ||
); | ||
} | ||
}); | ||
parallel(readyTasks, done); | ||
task = function ( done ) { | ||
parallel(tasks.map(function ( taskId ) { | ||
return function ( callback ) { | ||
return self.run(taskId, callback); | ||
}; | ||
}), done); | ||
}; | ||
func.group = true; | ||
func.type = 'parallel'; | ||
func.children = tasks; | ||
// apply custom task name | ||
Object.defineProperty(task, 'name', {value: '<parallel>'}); | ||
return func; | ||
return task; | ||
}; | ||
// accepts list of task ids | ||
Runner.prototype.serial = function () { | ||
var self = this, | ||
tasks = Array.prototype.slice.call(arguments), | ||
func; | ||
task; | ||
// no tasks were given | ||
if ( tasks.length === 0 ) { | ||
@@ -188,26 +147,14 @@ return null; | ||
func = function ( done ) { | ||
var readyTasks = []; | ||
// wrap not running tasks only | ||
tasks.forEach(function ( task ) { | ||
task = self.tasks[task] || task; | ||
if ( task && !task.running ) { | ||
readyTasks.push( | ||
function ( done ) { | ||
return self.run(task, done); | ||
} | ||
); | ||
} | ||
}); | ||
serial(readyTasks, done); | ||
task = function ( done ) { | ||
serial(tasks.map(function ( taskId ) { | ||
return function ( callback ) { | ||
return self.run(taskId, callback); | ||
}; | ||
}), done); | ||
}; | ||
func.group = true; | ||
func.type = 'serial'; | ||
func.children = tasks; | ||
// apply custom task name | ||
Object.defineProperty(task, 'name', {value: '<serial>'}); | ||
return func; | ||
return task; | ||
}; | ||
@@ -222,14 +169,32 @@ | ||
* | ||
* @return {*} task execution result | ||
* @return {boolean} is task really started | ||
*/ | ||
Runner.prototype.run = function ( task, done ) { | ||
var result; | ||
var started = false, | ||
taskId, taskBody; | ||
task = this.tasks[task] || task; | ||
console.assert(arguments.length >= 1, 'wrong arguments number'); | ||
console.assert(typeof task === 'string' || typeof task === 'function', 'task should be a string or a function'); | ||
console.assert(!!task, 'task is empty'); | ||
console.assert(!done || typeof done === 'function', 'done should be a function'); | ||
if ( typeof task === 'function' && !task.running ) { | ||
result = this.wrap(task)(done); | ||
if ( typeof task === 'string' ) { | ||
taskId = task; | ||
taskBody = this.tasks[task]; | ||
} else if ( typeof task === 'function' ) { | ||
taskId = task.name || '<noname>'; | ||
taskBody = task; | ||
} | ||
return result; | ||
if ( taskBody ) { | ||
if ( !taskBody.running ) { | ||
wrap(this, taskId, taskBody)(done); | ||
started = true; | ||
} | ||
} else { | ||
this.emit('error', {id: taskId, code: 404}); | ||
} | ||
return started; | ||
}; | ||
@@ -239,3 +204,3 @@ | ||
Runner.prototype.start = function ( done ) { | ||
this.run(this.tasks.default, done); | ||
this.run('default', done); | ||
}; | ||
@@ -242,0 +207,0 @@ |
{ | ||
"name": "cjs-runner", | ||
"version": "1.1.0", | ||
"version": "1.5.1", | ||
"description": "Simple task runner.", | ||
@@ -14,16 +14,16 @@ "author": { | ||
"scripts": { | ||
"lint": "eslint .", | ||
"lint": "eslint --ignore-pattern '/docs/' .", | ||
"mocha": "node ./tests/main.js", | ||
"test": "npm run mocha && npm run lint", | ||
"jsdoc": "jsdoc --destination doc *.js readme.md" | ||
"jsdoc": "jsdoc --destination docs *.js readme.md" | ||
}, | ||
"dependencies": { | ||
"cjs-async": "1.*.*", | ||
"cjs-emitter": "1.*.*" | ||
"cjs-async": "^1.6.0", | ||
"cjs-emitter": "^1.5.3" | ||
}, | ||
"devDependencies": { | ||
"cjs-eslint-config": "1.*.*", | ||
"eslint": "3.*.*", | ||
"mocha": "3.*.*", | ||
"should": "11.*.*" | ||
"cjs-eslint": "^1.1.1", | ||
"jsdoc": "^3.5.5", | ||
"mocha": "^5.2.0", | ||
"should": "^13.2.3" | ||
}, | ||
@@ -30,0 +30,0 @@ "keywords": [ |
119
readme.md
@@ -9,3 +9,3 @@ Task runner | ||
[![Gitter](https://img.shields.io/badge/gitter-join%20chat-blue.svg?style=flat-square)](https://gitter.im/DarkPark/cjssdk) | ||
[![RunKit](https://img.shields.io/badge/RunKit-try-yellow.svg?style=flat-square)](https://runkit.com/npm/cjs-runner) | ||
[![RunKit](https://img.shields.io/badge/RunKit-try-yellow.svg?style=flat-square)](https://npm.runkit.com/cjs-runner) | ||
@@ -32,6 +32,6 @@ | ||
Create a simple task: | ||
Create a simple sync task: | ||
```js | ||
runner.task('make', function () { | ||
runner.task('lint', function () { | ||
// some actions | ||
@@ -41,18 +41,117 @@ }); | ||
Create a simple async task: | ||
```js | ||
t1 = runner.task('static', runner.serial('jade:build', 'sass:build')); | ||
runner.task('build', function ( done ) { | ||
someAsyncCall(function () { | ||
// handle call result | ||
done(); | ||
}); | ||
}); | ||
``` | ||
t1 = runner.task({ | ||
name: 'static', | ||
dependency: ['jade:build', 'sass:build'] | ||
Create a task with serial subtasks: | ||
```js | ||
runner.task('serve', runner.serial('lint', 'build')); | ||
``` | ||
Create a task with parallel subtasks: | ||
```js | ||
runner.task('build', runner.parallel('jade:build', 'sass:build')); | ||
``` | ||
It's possible to use either anonymous or named functions as well: | ||
```js | ||
runner.task('build', runner.parallel('jade:build', 'sass:build', function lessBuild ( done ) { | ||
// function name "lessBuild" is used as task name | ||
// otherwise <noname> is printed | ||
done(); | ||
})); | ||
``` | ||
Batch tasks creation: | ||
```js | ||
Object.assign(runner.tasks, | ||
{ | ||
taskName1: taskFunction1, | ||
taskName2: taskFunction2 | ||
}, | ||
{ | ||
taskName3: taskFunction3, | ||
taskName4: taskFunction4 | ||
} | ||
); | ||
``` | ||
Execute a task by name: | ||
```js | ||
runner.run('lint'); | ||
``` | ||
Execute a task and handle the result: | ||
```js | ||
runner.run('lint', function ( error ) { | ||
if ( error ) { | ||
console.log('the task has failed!'); | ||
} | ||
}); | ||
``` | ||
runner.start(['build']); | ||
Execute a task as a named or anonymous function: | ||
```js | ||
runner.run(function ( done ) { | ||
done(); | ||
}); | ||
``` | ||
Execute task series: | ||
```js | ||
runner.run(runner.parallel('lint', 'build')); | ||
``` | ||
Execute task chain: | ||
```js | ||
// no result check | ||
runner.start(); | ||
// hook on task completion | ||
runner.start(function () { | ||
console.log('finished'); | ||
}); | ||
// hook on task completion | ||
runner.start(function ( error ) { | ||
if ( error ) { | ||
console.log('failed!'); | ||
} | ||
}); | ||
``` | ||
Hook on task start/stop events: | ||
```js | ||
runner.addListener('start', function ( event ) { | ||
// {id: 'lint'} | ||
console.log(event); | ||
}); | ||
runner.addListener('finish', function ( event ) { | ||
// {id: 'lint', time: 1} | ||
console.log(event); | ||
}); | ||
``` | ||
## Contribution ## | ||
If you have any problem or suggestion please open an issue [here](https://github.com/cjssdk/runner/issues). | ||
Pull requests are welcomed with respect to the [JavaScript Code Style](https://github.com/DarkPark/jscs). | ||
If you have any problems or suggestions please open an [issue](https://github.com/cjssdk/runner/issues) | ||
according to the contribution [rules](.github/contributing.md). | ||
@@ -59,0 +158,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
10177
159
4
157
2
Updatedcjs-async@^1.6.0
Updatedcjs-emitter@^1.5.3