concurrently
Advanced tools
Comparing version 0.1.1 to 1.0.0
{ | ||
"name": "concurrently", | ||
"version": "0.1.1", | ||
"version": "1.0.0", | ||
"description": "Run commands concurrently", | ||
@@ -5,0 +5,0 @@ "main": "src/main.js", |
@@ -5,3 +5,3 @@ # Concurrently | ||
**Version: 0.1.1** ([*previous stable*](https://github.com/kimmobrunfeldt/concurrently/tree/0.1.0)) | ||
**Version: 1.0.0** ([*previous stable*](https://github.com/kimmobrunfeldt/concurrently/tree/0.1.1)) | ||
@@ -8,0 +8,0 @@ Run multiple commands concurrently. |
@@ -19,2 +19,6 @@ #!/usr/bin/env node | ||
// Return success or failure of the 'first' child to terminate, the 'last' child, | ||
// or succeed only if 'all' children succeed | ||
success: 'all', | ||
// Prefix logging with pid | ||
@@ -65,2 +69,9 @@ // Possible values: 'pid', 'none', 'command', 'index' | ||
.option( | ||
'-s, --success <first|last|all>', | ||
'Return exit code of zero or one based on the success or failure ' + | ||
'of the "first" child to terminate, the "last" child, or succeed ' + | ||
' only if "all" child processes succeed. Default: ' + | ||
config.success + '\n' | ||
) | ||
.option( | ||
'-l, --prefix-length <length>', | ||
@@ -105,6 +116,49 @@ 'limit how many characters of the command is displayed in prefix.\n' + | ||
function stripCmdQuotes(cmd) { | ||
// Removes the quotes surrounding a command. | ||
if (cmd[0] === '"' || cmd[0] === '\'') { | ||
return cmd.substr(1, cmd.length - 2); | ||
} else { | ||
return cmd; | ||
} | ||
} | ||
function separateCmdArgs(cmd) { | ||
// We're splitting up the command into space-separated parts. | ||
// The first item is the command, all remaining items are the | ||
// arguments. To permit commands with spaces in the name | ||
// (or directory name), double slashes is a usable escape sequence. | ||
var escape = cmd.search('\\\s'), | ||
divide = cmd.search(/[^\\]\s/), | ||
path, args, parts; | ||
if (escape === -1) { | ||
// Not an escaped path. Most common case. | ||
parts = cmd.split(' '); | ||
} else if (escape > -1 && divide === -1) { | ||
// Escaped path without arguments. | ||
parts = [cmd.replace('\\ ', ' ')]; | ||
} else { | ||
// Escaped path with arguments. | ||
path = cmd.substr(0, divide + 1).replace('\\ ', ' '); | ||
args = cmd.substr(divide + 1).split(' ').filter(function(part) { | ||
return part.trim() != ''; | ||
}); | ||
parts = [path].concat(args); | ||
} | ||
// Parts contains the command as the first item and any arguments | ||
// as subsequent items. | ||
return parts; | ||
} | ||
function run(commands) { | ||
var childrenInfo = {}; | ||
var children = _.map(commands, function(cmd, index) { | ||
var parts = cmd.split(' '); | ||
// Remove quotes. | ||
cmd = stripCmdQuotes(cmd); | ||
// Split the command up in the command path and its arguments. | ||
var parts = separateCmdArgs(cmd); | ||
var child; | ||
@@ -178,3 +232,2 @@ try { | ||
var exitCodes = []; | ||
var closeStreams = _.pluck(streams, 'close'); | ||
@@ -197,9 +250,3 @@ var closeStream = Rx.Observable.merge.apply(this, closeStreams); | ||
if (aliveChildren.length === 0) { | ||
// Final exit code is 0 when all processes ran succesfully, | ||
// in other cases exit code 1 is used | ||
var someFailed = _.some(exitCodes, function(code) { | ||
return code !== 0 || code === null; | ||
}); | ||
var finalExitCode = someFailed ? 1 : 0; | ||
process.exit(finalExitCode); | ||
exit(exitCodes); | ||
} | ||
@@ -223,2 +270,19 @@ }); | ||
function exit(childExitCodes) { | ||
var success; | ||
switch (config.success) { | ||
case 'first': | ||
success = _.first(childExitCodes) === 0; | ||
break; | ||
case 'last': | ||
success = _.last(childExitCodes) === 0; | ||
break; | ||
default: | ||
success = _.every(childExitCodes, function(code) { | ||
return code === 0; | ||
}); | ||
} | ||
process.exit(success? 0 : 1); | ||
} | ||
function handleError(streams, childrenInfo) { | ||
@@ -225,0 +289,0 @@ // Output emitted errors from child process |
@@ -59,2 +59,21 @@ // Test basic usage of cli | ||
}); | ||
it('--success=first should return first exit code', function(done) { | ||
run('node ./src/main.js -k --success first "echo" "sleep 1000" ', {pipe: DEBUG_TESTS}) | ||
// When killed, sleep returns null exit code | ||
.then(function(exitCode) { | ||
assert.strictEqual(exitCode, 0); | ||
done(); | ||
}); | ||
}); | ||
it('--success=last should return last exit code', function(done) { | ||
// When killed, sleep returns null exit code | ||
run('node ./src/main.js -k --success last "echo" "sleep 1000" ', {pipe: DEBUG_TESTS}) | ||
.then(function(exitCode) { | ||
assert.notStrictEqual(exitCode, 0); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
@@ -65,1 +84,2 @@ | ||
} | ||
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
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
129662
647
0