gulp-shell
Advanced tools
Comparing version 0.5.2 to 0.6.0
@@ -8,9 +8,9 @@ var gulp = require('gulp') | ||
gulp.task('test', shell.task('mocha -c')) | ||
gulp.task('test', shell.task('mocha')) | ||
gulp.task('coverage', ['test'], shell.task('istanbul cover _mocha -- -c')) | ||
gulp.task('coverage', ['test'], shell.task('istanbul cover _mocha')) | ||
gulp.task('coveralls', ['coverage'], shell.task('cat coverage/lcov.info | coveralls')) | ||
gulp.task('lint', shell.task('eslint ' + paths.js.join(' '))) | ||
gulp.task('lint', shell.task('standard ' + paths.js.join(' '))) | ||
@@ -17,0 +17,0 @@ gulp.task('default', ['coverage', 'lint']) |
72
index.js
var _ = require('lodash') | ||
var async = require('async') | ||
var exec = require('child_process').exec | ||
var gutil = require('gulp-util') | ||
var path = require('path') | ||
var spawn = require('child_process').spawn | ||
var through = require('through2') | ||
@@ -10,3 +10,3 @@ | ||
function normalizeCommands(commands) { | ||
function normalizeCommands (commands) { | ||
if (typeof commands === 'string') { | ||
@@ -23,11 +23,10 @@ commands = [commands] | ||
function normalizeOptions(options) { | ||
function normalizeOptions (options) { | ||
options = _.extend({ | ||
cwd: process.cwd(), | ||
shell: true, | ||
quiet: false, | ||
verbose: false, | ||
ignoreErrors: false, | ||
errorMessage: 'Command `<%= command %>` failed with exit code <%= error.code %>', | ||
quiet: false, | ||
interactive: false, | ||
cwd: process.cwd(), | ||
maxBuffer: 16 * 1024 * 1024 | ||
errorMessage: 'Command `<%= command %>` failed with exit code <%= error.code %>' | ||
}, options) | ||
@@ -43,3 +42,3 @@ | ||
function runCommands(commands, options, file, done) { | ||
function runCommands (commands, options, file, done) { | ||
async.eachSeries(commands, function (command, done) { | ||
@@ -53,48 +52,32 @@ var context = _.extend({file: file}, options.templateData) | ||
var child = exec(command, { | ||
var child = spawn(command, { | ||
env: options.env, | ||
cwd: gutil.template(options.cwd, context), | ||
maxBuffer: options.maxBuffer, | ||
timeout: options.timeout | ||
}, function (error, stdout, stderr) { | ||
if (options.interactive) { | ||
process.stdin.unpipe(child.stdin) | ||
process.stdin.resume() | ||
process.stdin.pause() | ||
shell: options.shell, | ||
stdio: options.quiet ? 'ignore' : 'inherit' | ||
}) | ||
child.on('exit', function (code) { | ||
if (code === 0 || options.ignoreErrors) { | ||
return done() | ||
} | ||
if (error && !options.ignoreErrors) { | ||
error.stdout = stdout | ||
error.stderr = stderr | ||
var context = _.extend({ | ||
command: command, | ||
file: file, | ||
error: {code: code} | ||
}, options.templateData) | ||
var errorContext = _.extend({ | ||
command: command, | ||
file: file, | ||
error: error | ||
}, options.templateData) | ||
var message = gutil.template(options.errorMessage, context) | ||
error.message = gutil.template(options.errorMessage, errorContext) | ||
} | ||
done(options.ignoreErrors ? null : error) | ||
done(new gutil.PluginError(PLUGIN_NAME, message)) | ||
}) | ||
if (options.interactive) { | ||
process.stdin.resume() | ||
process.stdin.setEncoding('utf8') | ||
process.stdin.pipe(child.stdin) | ||
} | ||
if (!options.quiet) { | ||
child.stdout.pipe(process.stdout) | ||
child.stderr.pipe(process.stderr) | ||
} | ||
}, done) | ||
} | ||
function shell(commands, options) { | ||
function shell (commands, options) { | ||
commands = normalizeCommands(commands) | ||
options = normalizeOptions(options) | ||
var stream = through.obj(function (file, unused, done) { | ||
var stream = through.obj(function (file, _encoding, done) { | ||
var self = this | ||
@@ -104,6 +87,3 @@ | ||
if (error) { | ||
self.emit('error', new gutil.PluginError({ | ||
plugin: PLUGIN_NAME, | ||
message: error.message | ||
})) | ||
self.emit('error', error) | ||
} else { | ||
@@ -110,0 +90,0 @@ self.push(file) |
{ | ||
"name": "gulp-shell", | ||
"version": "0.5.2", | ||
"version": "0.6.0", | ||
"description": "A handy command line interface for gulp", | ||
@@ -27,16 +27,16 @@ "main": "index.js", | ||
"devDependencies": { | ||
"chai": "~3.4.0", | ||
"coveralls": "~2.11.4", | ||
"eslint": "~1.10.3", | ||
"gulp": "~3.9.0", | ||
"istanbul": "~0.4.0", | ||
"mocha": "~2.3.3", | ||
"mocha-lcov-reporter": "~1.0.0" | ||
"chai": "^3.5.0", | ||
"coveralls": "^2.11.16", | ||
"gulp": "^3.9.1", | ||
"istanbul": "^0.4.5", | ||
"mocha": "^3.2.0", | ||
"mocha-lcov-reporter": "^1.3.0", | ||
"standard": "^8.6.0" | ||
}, | ||
"dependencies": { | ||
"async": "^1.5.0", | ||
"gulp-util": "^3.0.7", | ||
"lodash": "^4.0.0", | ||
"through2": "^2.0.0" | ||
"async": "^2.1.5", | ||
"gulp-util": "^3.0.8", | ||
"lodash": "^4.17.4", | ||
"through2": "^2.0.3" | ||
} | ||
} |
# gulp-shell | ||
[![NPM version][npm-image]][npm-url] | ||
[![Standard - JavaScript Style Guide][standard-image]][standard-url] | ||
[![Build Status][travis-image]][travis-url] | ||
@@ -11,2 +12,4 @@ [![Coveralls Status][coveralls-image]][coveralls-url] | ||
[npm-image]: https://img.shields.io/npm/v/gulp-shell.svg | ||
[standard-image]: https://img.shields.io/badge/code_style-standard-brightgreen.svg | ||
[standard-url]: http://standardjs.com/ | ||
[travis-url]: https://travis-ci.org/sun-zheng-an/gulp-shell | ||
@@ -74,32 +77,28 @@ [travis-image]: https://img.shields.io/travis/sun-zheng-an/gulp-shell/master.svg | ||
[template]: http://lodash.com/docs#template | ||
[file]: https://github.com/wearefractal/vinyl | ||
#### options.cwd | ||
#### options.verbose | ||
type: `String` | ||
type: `Boolean` | ||
default: [`process.cwd()`](http://nodejs.org/api/process.html#process_process_cwd) | ||
default: `false` | ||
Sets the current working directory for the command. This can be a [template][] which can be interpolated by some [file][] info (e.g. `file.path`). | ||
Set to `true` to print the command(s) to stdout as they are executed | ||
#### options.env | ||
#### options.errorMessage | ||
type: `Object` | ||
type: `String` | ||
By default, all the commands will be executed in an environment with all the variables in [`process.env`](http://nodejs.org/api/process.html#process_process_env) and `PATH` prepended by `./node_modules/.bin` (allowing you to run executables in your Node's dependencies). | ||
default: ``Command `<%= command %>` failed with exit code <%= error.code %>`` | ||
You can override any environment variables with this option. | ||
You can add a custom error message for when the command fails. | ||
This can be a [template][] which can be interpolated with the current `command`, some [file][] info (e.g. `file.path`) and some [error][] info (e.g. `error.code`). | ||
For example, setting it to `{PATH: process.env.PATH}` will reset the `PATH` if the default one brings your some troubles. | ||
[error]: http://nodejs.org/api/child_process.html#child_process_child_process_exec_command_options_callback | ||
#### options.shell | ||
#### options.ignoreErrors | ||
type: `String` | ||
type: `Boolean` | ||
default: `/bin/sh` on UNIX, and `cmd.exe` on Windows | ||
default: `false` | ||
Change it to `bash` if you like. | ||
By default, it will emit an `error` event when the command finishes unsuccessfully. | ||
#### options.quiet | ||
@@ -113,3 +112,3 @@ | ||
#### options.interactive | ||
#### options.verbose | ||
@@ -120,44 +119,28 @@ type: `Boolean` | ||
Turn it on only if you need to run some interactive commands. | ||
Set to `true` to print the command(s) to stdout as they are executed | ||
#### options.cwd | ||
#### options.ignoreErrors | ||
type: `String` | ||
type: `Boolean` | ||
default: [`process.cwd()`](http://nodejs.org/api/process.html#process_process_cwd) | ||
default: `false` | ||
Sets the current working directory for the command. This can be a [template][] which can be interpolated by some [file][] info (e.g. `file.path`). | ||
By default, it will emit an `error` event when the command finishes unsuccessfully. | ||
[template]: http://lodash.com/docs#template | ||
#### options.errorMessage | ||
#### options.templateData | ||
type: `String` | ||
type: `Object` | ||
default: ``Command `<%= command %>` failed with exit code <%= error.code %>`` | ||
The data that can be accessed in template. | ||
You can add a custom error message for when the command fails. | ||
This can be a [template][] which can be interpolated with the current `command`, some [file][] info (e.g. `file.path`) and some error info (e.g. `error.code`). | ||
#### options.maxBuffer | ||
#### options.templateData | ||
type: `Number` | ||
default: 16MB(16 * 1024 * 1024) | ||
You won't need to set this option unless you encounter a "stdout maxBuffer exceeded" error. | ||
#### options.timeout | ||
type: `Number` | ||
default: undefined (no timeout) | ||
The maximum amount of time in milliseconds the process is allowed to run. | ||
#### options.env | ||
type: `Object` | ||
By default, all the commands will be executed in an environment with all the variables in [`process.env`](http://nodejs.org/api/process.html#process_process_env) and `PATH` prepended by `./node_modules/.bin` (allowing you to run executables in your Node's dependencies). | ||
The data that can be accessed in [template][]. | ||
You can override any environment variables with this option. | ||
For example, setting it to `{PATH: process.env.PATH}` will reset the `PATH` if the default one brings your some troubles. | ||
[template]: http://lodash.com/docs#template | ||
[file]: https://github.com/wearefractal/vinyl |
@@ -1,2 +0,2 @@ | ||
/*eslint-env mocha */ | ||
/* eslint-env mocha */ | ||
@@ -9,9 +9,6 @@ var gutil = require('gulp-util') | ||
var originalStdoutWrite = process.stdout.write | ||
function expectToOutput(expected, done) { | ||
process.stdout.write = function (actual) { | ||
process.stdout.write = originalStdoutWrite | ||
expect(actual.toLowerCase()).to.include(expected.toLowerCase()) | ||
done() | ||
} | ||
function expectToBeOk (stream, done) { | ||
stream | ||
.on('error', done) | ||
.on('data', function () { done() }) | ||
} | ||
@@ -46,5 +43,7 @@ | ||
it('executes command after interpolation', function (done) { | ||
var stream = shell(['echo <%= file.path %>']) | ||
var stream = shell([ | ||
'test <%= file.path %> = ' + fakeFile.path | ||
]) | ||
expectToOutput(fakeFile.path, done) | ||
expectToBeOk(stream, done) | ||
@@ -55,5 +54,7 @@ stream.write(fakeFile) | ||
it('prepends `./node_modules/.bin` to `PATH`', function (done) { | ||
var stream = shell(['echo $PATH']) | ||
var stream = shell([ | ||
'echo $PATH | grep -q "' + join(process.cwd(), 'node_modules/.bin') + '"' | ||
], {shell: 'bash'}) | ||
expectToOutput(join(process.cwd(), 'node_modules/.bin'), done) | ||
expectToBeOk(stream, done) | ||
@@ -68,5 +69,4 @@ stream.write(fakeFile) | ||
expect(task).to.be.a('function') | ||
expectToOutput('hello world', done) | ||
task() | ||
task(done) | ||
}) | ||
@@ -76,9 +76,9 @@ }) | ||
describe('options', function () { | ||
describe('ignoreErrors', function () { | ||
it('emits error by default', function (done) { | ||
var stream = shell(['false']) | ||
describe('cwd', function () { | ||
it('sets the current working directory when `cwd` is a string', function (done) { | ||
var stream = shell([ | ||
'test $PWD = ' + join(__dirname, '../..') | ||
], {cwd: '..'}) | ||
stream.on('error', function () { | ||
done() | ||
}) | ||
expectToBeOk(stream, done) | ||
@@ -88,13 +88,21 @@ stream.write(fakeFile) | ||
it("won't emit error when `ignoreErrors` == true", function (done) { | ||
var stream = shell(['false'], {ignoreErrors: true}) | ||
it('uses the process current working directory when `cwd` is not passed', function (done) { | ||
var stream = shell([ | ||
'test $PWD = ' + join(__dirname, '..') | ||
]) | ||
stream.on('error', function () { | ||
throw new Error() | ||
}) | ||
expectToBeOk(stream, done) | ||
stream.on('data', function () { | ||
done() | ||
}) | ||
stream.write(fakeFile) | ||
}) | ||
}) | ||
describe('shell', function () { | ||
it('changes the shell', function (done) { | ||
var stream = shell([ | ||
'[[ $0 = bash ]]' | ||
], {shell: 'bash'}) | ||
expectToBeOk(stream, done) | ||
stream.write(fakeFile) | ||
@@ -108,6 +116,13 @@ }) | ||
expectToOutput('this should not match anything!', done) | ||
expectToBeOk(stream, done) | ||
stream.on('data', function () { | ||
process.stdout.write = originalStdoutWrite | ||
stream.write(fakeFile) | ||
}) | ||
}) | ||
describe('ignoreErrors', function () { | ||
it('emits error by default', function (done) { | ||
var stream = shell(['false']) | ||
stream.on('error', function () { | ||
done() | ||
@@ -118,11 +133,14 @@ }) | ||
}) | ||
}) | ||
describe('interactive', function () { | ||
it('reads input when `interactive` == true', function (done) { | ||
var stream = shell(['read s; echo $s'], {interactive: true}) | ||
it("won't emit error when `ignoreErrors` == true", function (done) { | ||
var stream = shell(['false'], {ignoreErrors: true}) | ||
process.stdin.push('something\n') | ||
expectToOutput('something', done) | ||
stream.on('error', function () { | ||
throw new Error() | ||
}) | ||
stream.on('data', function () { | ||
done() | ||
}) | ||
stream.write(fakeFile) | ||
@@ -158,21 +176,3 @@ }) | ||
}) | ||
describe('cwd', function () { | ||
it('sets the current working directory when `cwd` is a string', function (done) { | ||
var stream = shell(['pwd'], {cwd: '..'}) | ||
expectToOutput(join(__dirname, '../..'), done) | ||
stream.write(fakeFile) | ||
}) | ||
it('uses the process current working directory when `cwd` is not passed', function (done) { | ||
var stream = shell(['pwd']) | ||
expectToOutput(join(__dirname, '..'), done) | ||
stream.write(fakeFile) | ||
}) | ||
}) | ||
}) | ||
}) |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
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
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
13320
220
143
+ Addedasync@2.6.4(transitive)
- Removedasync@1.5.2(transitive)
Updatedasync@^2.1.5
Updatedgulp-util@^3.0.8
Updatedlodash@^4.17.4
Updatedthrough2@^2.0.3