Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use debug, use integer descriptors for spawned children. #35

Open
wants to merge 1 commit into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 43 additions & 29 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
#!/usr/bin/env node

'use strict';
var spawn = require('child_process').spawn;
var spawn = require('child_process').spawn,
debug = require('debug');

var sh, shFlag, children, args, wait, first, cmds, verbose, i ,len;
var verbose = debug('parallelshell:verbose'),
dbg = debug('parallelshell:dbg');

var sh, shFlag, children, args, wait, first, cmds, i ,len;
// parsing argv
cmds = [];
args = process.argv.slice(2);
if (args.length === 0) printUseageExit();
for (i = 0, len = args.length; i < len; i++) {
if (args[i][0] === '-') {
switch (args[i]) {
Expand All @@ -20,15 +25,12 @@ for (i = 0, len = args.length; i < len; i++) {
break;
case '-v':
case '--verbose':
verbose = true;
debug.enable('parallelshell:verbose');
verbose = debug('parallelshell:verbose');
break;
case '-h':
case '--help':
console.log('-h, --help output usage information');
console.log('-v, --verbose verbose logging');
console.log('-w, --wait will not close sibling processes on error');
console.log('-f, --first close all sibling processes after first exits (succes/error)');
process.exit();
printUseageExit();
break;
}
} else {
Expand All @@ -41,54 +43,64 @@ if (wait && first) {
process.exit(1);
}

function printUseageExit() {
console.log('Useage:');
console.log(' -h, --help output usage information');
console.log(' -v, --verbose verbose logging');
console.log(' -w, --wait will not close sibling processes on error');
console.log(' -f, --first close all sibling processes after first exits (succes/error)');
process.exit();
}

// called on close of a child process
function childClose (code) {
var i, len;
code = code ? (code.code || code) : code;
if (verbose) {
if (code > 0) {
console.error('parallelshell: `' + this.cmd + '` failed with exit code ' + code);
} else {
console.log('parallelshell: `' + this.cmd + '` ended successfully');
}
var actualCode = code ? (code.code || code) : code;
dbg('In childClose, with code: %d', actualCode);
if (actualCode > 0) {
verbose('`%s` failed with exit code: %d', actualCode);
} else {
verbose('`%s` ended successfully');
}
if (first || code > 0 && !wait) close(code);
if (first || actualCode > 0 && !wait) close(actualCode);
}

function status () {
if (verbose) {
var i, len;
console.log('parallelshell: Status');
var i, len;
if (verbose.enabled) {
verbose('Status');
for (i = 0, len = children.length; i < len; i++) {
if (children[i].exitCode === null) {
console.log('parallelshell: `' + children[i].cmd + '` is still running');
verbose('`%s` is still running', children[i].cmd);
} else if (children[i].exitCode > 0) {
console.log('parallelshell: `' + children[i].cmd + '` errored');
verbose('`%s` errored', children[i].cmd);
} else {
console.log('parallelshell: `' + children[i].cmd + '` finished');
verbose('`%s` finished', children[i].cmd);
}
}
}
}

// closes all children and the process
function close (code) {
dbg('In close with code: %d', code);
var i, len, closeHandler, closed = 0, opened = 0;

for (i = 0, len = children.length; i < len; i++) {
if (!children[i].exitCode) {
opened++;
children[i].removeAllListeners('close');
if (process.platform != "win32") {
children[i].kill("SIGINT");
spawn(sh, [shFlag, "kill -INT -"+children[i].pid]);
} else {
children[i].kill("SIGINT");
}
if (verbose) console.log('parallelshell: `' + children[i].cmd + '` will now be closed');
verbose('`' + children[i].cmd + '` will now be closed');
closeHandler = function (child) {
child.on('close', function() {
if (verbose) console.log('parallelshell: `' + child.cmd + '` closed successfully');
verbose('`' + child.cmd + '` closed successfully');
closed++;
dbg('opened: %d, closed: %d', opened, closed)
if (opened == closed) {
process.exit(code);
}
Expand All @@ -97,6 +109,7 @@ function close (code) {

}
}
dbg('opened: %d, closed: %d', opened, closed)
if (opened == closed) {process.exit(code);}

}
Expand All @@ -116,10 +129,11 @@ cmds.forEach(function (cmd) {
if (process.platform === 'win32') {
cmd = cmd.replace(/'/g,"\"");
}
var child = spawn(sh,[shFlag,cmd], {
dbg("Spawning the cmd `%s`", cmd)
var child = spawn(sh, [shFlag, cmd], {
cwd: process.cwd,
env: process.env,
stdio: ['pipe', process.stdout, process.stderr],
stdio: ['pipe', 1, 2],
windowsVerbatimArguments: process.platform === 'win32',
detached: process.platform != 'win32'
})
Expand All @@ -130,10 +144,10 @@ cmds.forEach(function (cmd) {

// close all children on ctrl+c
process.on('SIGINT', function() {
if (verbose) console.log('parallelshell: recieved SIGINT');
verbose('recieved SIGINT');
close();
});

process.on('exit', function(code) {
if (verbose) console.log('parallelshell: exit code:', code);
verbose('exit code: %d', code);
});
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,8 @@
"chai": "^2.3.0",
"coffee-script": "^1.9.2",
"mocha": "^2.2.4"
},
"dependencies": {
"debug": "^2.2.0"
}
}
7 changes: 4 additions & 3 deletions test/index.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,10 @@ waitingProcess = (time=10000) ->
failingProcess = "\"node -e 'throw new Error();'\""

usageInfo = """
-h, --help output usage information
-v, --verbose verbose logging
-w, --wait will not close sibling processes on error
Useage:
-h, --help output usage information
-v, --verbose verbose logging
-w, --wait will not close sibling processes on error
""".split("\n")

cmdWrapper = (cmd) ->
Expand Down