Socket
Socket
Sign inDemoInstall

concurrently

Package Overview
Dependencies
Maintainers
2
Versions
60
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

concurrently - npm Package Compare versions

Comparing version 3.5.1 to 3.6.0

.eslintrc.json

14

package.json
{
"name": "concurrently",
"version": "3.5.1",
"version": "3.6.0",
"description": "Run commands concurrently",

@@ -14,3 +14,8 @@ "main": "src/main.js",

"scripts": {
"test": "mocha"
"lint": "eslint .",
"test": "mocha",
"echo": "echo",
"echo-test": "echo test",
"echo-sound-beep": "echo beep",
"echo-sound-boop": "echo boop"
},

@@ -36,6 +41,7 @@ "repository": {

"dependencies": {
"chalk": "0.5.1",
"chalk": "^2.4.1",
"commander": "2.6.0",
"date-fns": "^1.23.0",
"lodash": "^4.5.1",
"read-pkg": "^3.0.0",
"rx": "2.3.24",

@@ -48,2 +54,3 @@ "spawn-command": "^0.0.2-1",

"chai": "^1.10.0",
"eslint": "^4.19.1",
"mocha": "^2.1.0",

@@ -55,4 +62,5 @@ "mustache": "^1.0.0",

"shelljs": "^0.3.0",
"sinon": "^4.1.3",
"string": "^3.0.0"
}
}

@@ -49,2 +49,42 @@ # Concurrently

NPM run commands can be shortened:
```bash
concurrently "npm:watch-js" "npm:watch-css" "npm:watch-node"
# Equivalent to:
concurrently -n watch-js,watch-css,watch-node "npm run watch-js" "npm run watch-css" "npm run watch-node"
```
NPM shortened commands also support wildcards. Given the following scripts in
package.json:
```javascript
{
//...
"scripts": {
// ...
"watch-js": "...",
"watch-css": "...",
"watch-node": "...",
// ...
},
// ...
}
```
```bash
concurrently "npm:watch-*"
# Equivalent to:
concurrently -n js,css,node "npm run watch-js" "npm run watch-css" "npm run watch-node"
# Any name provided for the wildcard command will be used as a prefix to the wildcard
# part of the script name:
concurrently -n w: npm:watch-*
# Equivalent to:
concurrently -n w:js,w:css,w:node "npm run watch-js" "npm run watch-css" "npm run watch-node"
```
Good frontend one-liner example [here](https://github.com/kimmobrunfeldt/dont-copy-paste-this-frontend-template/blob/5cd2bde719654941bdfc0a42c6f1b8e69ae79980/package.json#L9).

@@ -96,2 +136,11 @@

--default-input-target <identifier> identifier for child process to which input on stdin should be sent if not specified at start of input. Can be either the index or the name of the process. Default: 0
Input:
Input can be sent to any of the child processes using either the name or index
of the command followed by a colon. If no child identifier is specified then the
input will be sent to the child specified by the `--default-input-target`
option, which defaults to index 0.
Examples:

@@ -122,3 +171,55 @@

$ concurrently --names "HTTP,WATCH" -c "bgBlue.bold,bgMagenta.bold" "http-server" "npm run watch"
- Shortened NPM run commands
$ concurrently npm:watch-node npm:watch-js npm:watch-css
- Send input to default
$ concurrently "nodemon" "npm run watch-js"
rs # Sends rs command to nodemon process
- Specify a default-input-target
$ concurrently --default-input-target 1 "npm run watch-js" nodemon
rs
- Send input to specific child identified by index
$ concurrently "npm run watch-js" nodemon
1:rs
- Send input to specific child identified by name
$ concurrently -n js,srv "npm run watch-js" nodemon
srv:rs
- Send input to default
$ concurrently "nodemon" "npm run watch-js"
rs # Sends rs command to nodemon process
- Specify a default-input-target
$ concurrently --default-input-target 1 "npm run watch-js" nodemon
rs
- Send input to specific child identified by index
$ concurrently "npm run watch-js" nodemon
1:rs
- Send input to specific child identified by name
$ concurrently -n js,srv "npm run watch-js" nodemon
srv:rs
- Shortened NPM run commands
$ concurrently npm:watch-node npm:watch-js npm:watch-css
- Shortened NPM run command with wildcard
$ concurrently npm:watch-*
For more details, visit https://github.com/kimmobrunfeldt/concurrently

@@ -125,0 +226,0 @@ ```

#!/usr/bin/env node
'use strict';
var Rx = require('rx');
var path = require('path');
var formatDate = require('date-fns/format');
var program = require('commander');
var _ = require('lodash');
var treeKill = require('tree-kill');
var chalk = require('chalk');
var spawn = require('spawn-command');
var supportsColor = require('supports-color');
var IS_WINDOWS = /^win/.test(process.platform);
const Rx = require('rx');
const path = require('path');
const formatDate = require('date-fns/format');
const program = require('commander');
const _ = require('lodash');
const treeKill = require('tree-kill');
const chalk = require('chalk');
const spawn = require('spawn-command');
const supportsColor = require('supports-color');
const IS_WINDOWS = /^win/.test(process.platform);
var config = {
const findChild = require('./findChild.js');
const parseCmds = require('./parseCmds');
let config = {
// Kill other processes if one dies

@@ -58,8 +62,11 @@ killOthers: false,

// By default, restart once
restartTries: 1
restartTries: 1,
// Default identifier for child to which input on stdin should be sent.
defaultInputTarget: '0'
};
function main() {
var firstBase = path.basename(process.argv[0]);
var secondBase = path.basename(process.argv[1]);
const firstBase = path.basename(process.argv[0]);
const secondBase = path.basename(process.argv[1]);
if (firstBase === 'concurrent' || secondBase === 'concurrent') {

@@ -71,5 +78,5 @@ console.error('Warning: "concurrent" command is deprecated, use "concurrently" instead.\n');

config = mergeDefaultsWithArgs(config);
applyDynamicDefaults(config)
run(program.args);
const cmds = parseCmds(program.args, config);
run(cmds);
}

@@ -157,6 +164,21 @@

config.restartTries + '\n'
)
.option(
'--default-input-target <identifier>',
'identifier for child process to which input on ' +
'stdin should be sent if not specified at start ' +
'of input. Can be either the index or the name ' +
'of the process. Default: ' + config.defaultInputTarget + '\n'
);
program.on('--help', function() {
var help = [
const help = [
' Input:',
'',
' Input can be sent to any of the child processes using either the name or',
' index of the command followed by a colon. If no child identifier is',
' specified then the input will be sent to the child specified by the',
' `--default-input-target` option, which defaults to index 0.',
'',
' Examples:',

@@ -187,2 +209,30 @@ '',

' $ concurrently --names "HTTP,WATCH" -c "bgBlue.bold,bgMagenta.bold" "http-server" "npm run watch"',
'',
' - Send input to default',
'',
' $ concurrently "nodemon" "npm run watch-js"',
' rs # Sends rs command to nodemon process',
'',
' - Specify a default-input-target',
'',
' $ concurrently --default-input-target 1 "npm run watch-js" nodemon',
' rs',
'',
' - Send input to specific child identified by index',
'',
' $ concurrently "npm run watch-js" nodemon',
' 1:rs',
'',
' - Send input to specific child identified by name',
'',
' $ concurrently -n js,srv "npm run watch-js" nodemon',
' srv:rs',
'',
' - Shortened NPM run commands',
'',
' $ concurrently npm:watch-node npm:watch-js npm:watch-css',
'',
' - Shortened NPM run command with wildcard',
'',
' $ concurrently npm:watch-*',
''

@@ -192,3 +242,3 @@ ];

var url = 'https://github.com/kimmobrunfeldt/concurrently';
const url = 'https://github.com/kimmobrunfeldt/concurrently';
console.log(' For more details, visit ' + url);

@@ -206,27 +256,8 @@ console.log('');

function applyDynamicDefaults(config) {
if (!config.prefix) {
config.prefix = config.names ? 'name' : 'index';
}
}
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 run(commands) {
var childrenInfo = {};
var lastPrefixColor = _.get(chalk, chalk.gray.dim);
var prefixColors = config.prefixColors.split(',');
var names = config.names.split(config.nameSeparator);
var children = _.map(commands, function(cmd, index) {
// Remove quotes.
cmd = stripCmdQuotes(cmd);
const childrenInfo = {};
let lastPrefixColor = _.get(chalk, chalk.gray.dim);
const children = _.map(commands, function(cmdInfo, index) {
var spawnOpts = config.raw ? {stdio: 'inherit'} : {};
const spawnOpts = config.raw ? {stdio: 'inherit'} : {};
if (IS_WINDOWS) {

@@ -236,17 +267,16 @@ spawnOpts.detached = false;

if (supportsColor) {
spawnOpts.env = Object.assign({FORCE_COLOR: supportsColor.level}, process.env)
spawnOpts.env = Object.assign({FORCE_COLOR: supportsColor.level}, process.env);
}
var child = spawnChild(cmd, spawnOpts);
const child = spawnChild(cmdInfo.cmd, spawnOpts);
if (index < prefixColors.length) {
var prefixColorPath = prefixColors[index];
if (cmdInfo.color) {
const prefixColorPath = cmdInfo.color;
lastPrefixColor = _.get(chalk, prefixColorPath, chalk.gray.dim);
}
var name = index < names.length ? names[index] : '';
childrenInfo[child.pid] = {
command: cmd,
command: cmdInfo.cmd,
index: index,
name: name,
name: cmdInfo.name,
options: spawnOpts,

@@ -259,3 +289,3 @@ restartTries: config.restartTries,

var streams = toStreams(children);
const streams = toStreams(children);

@@ -265,12 +295,30 @@ handleChildEvents(streams, children, childrenInfo);

['SIGINT', 'SIGTERM'].forEach(function(signal) {
process.on(signal, function() {
children.forEach(function(child) {
treeKill(child.pid, signal);
process.on(signal, function() {
children.forEach(function(child) {
treeKill(child.pid, signal);
});
});
});
});
process.stdin.on('data', (chunk) => {
let line = chunk.toString();
let targetId = config.defaultInputTarget;
if (line.indexOf(':') >= 0) {
const parts = line.split(':');
targetId = parts[0];
line = parts[1];
}
const target = findChild(targetId, children, childrenInfo);
if (target) {
target.stdin.write(line);
} else {
logError('', chalk.gray.dim, `Unable to find command [${targetId}]\n`);
}
});
}
function spawnChild(cmd, options) {
var child;
let child;
try {

@@ -289,3 +337,3 @@ child = spawn(cmd, options);

return _.map(children, function(child) {
var childStreams = {
const childStreams = {
error: Rx.Node.fromEvent(child, 'error'),

@@ -319,8 +367,8 @@ close: Rx.Node.fromEvent(child, 'close')

function handleOutput(streams, childrenInfo, source) {
var sourceStreams = _.map(streams, source);
var combinedSourceStream = Rx.Observable.merge.apply(this, sourceStreams);
const sourceStreams = _.map(streams, source);
const combinedSourceStream = Rx.Observable.merge.apply(this, sourceStreams);
combinedSourceStream.subscribe(function(event) {
var prefix = getPrefix(childrenInfo, event.child);
var prefixColor = childrenInfo[event.child.pid].prefixColor;
const prefix = getPrefix(childrenInfo, event.child);
const prefixColor = childrenInfo[event.child.pid].prefixColor;
log(prefix, prefixColor, event.data.toString());

@@ -331,18 +379,18 @@ });

function handleClose(streams, children, childrenInfo) {
var aliveChildren = _.clone(children);
var exitCodes = [];
var closeStreams = _.map(streams, 'close');
var closeStream = Rx.Observable.merge.apply(this, closeStreams);
var othersKilled = false
let aliveChildren = _.clone(children);
const exitCodes = [];
const closeStreams = _.map(streams, 'close');
const closeStream = Rx.Observable.merge.apply(this, closeStreams);
let othersKilled = false;
// TODO: Is it possible that amount of close events !== count of spawned?
closeStream.subscribe(function(event) {
var exitCode = event.data;
var nonSuccess = exitCode !== 0;
const exitCode = event.data;
const nonSuccess = exitCode !== 0;
exitCodes.push(exitCode);
var prefix = getPrefix(childrenInfo, event.child);
var childInfo = childrenInfo[event.child.pid];
var prefixColor = childInfo.prefixColor;
var command = childInfo.command;
const prefix = getPrefix(childrenInfo, event.child);
const childInfo = childrenInfo[event.child.pid];
const prefixColor = childInfo.prefixColor;
const command = childInfo.command;
logEvent(prefix, prefixColor, command + ' exited with code ' + exitCode);

@@ -363,9 +411,9 @@

if (!othersKilled) {
if (config.killOthers) {
killOtherProcesses(aliveChildren);
othersKilled = true;
} else if (config.killOthersOnFail && nonSuccess) {
killOtherProcesses(aliveChildren);
othersKilled = true;
}
if (config.killOthers) {
killOtherProcesses(aliveChildren);
othersKilled = true;
} else if (config.killOthersOnFail && nonSuccess) {
killOtherProcesses(aliveChildren);
othersKilled = true;
}
}

@@ -377,7 +425,7 @@ });

setTimeout(function() {
var childInfo = childrenInfo[event.child.pid];
var prefix = getPrefix(childrenInfo, event.child);
var prefixColor = childInfo.prefixColor;
const childInfo = childrenInfo[event.child.pid];
const prefix = getPrefix(childrenInfo, event.child);
const prefixColor = childInfo.prefixColor;
logEvent(prefix, prefixColor, childInfo.command + ' restarted');
var newChild = spawnChild(childInfo.command, childInfo.options);
const newChild = spawnChild(childInfo.command, childInfo.options);

@@ -387,4 +435,4 @@ childrenInfo[newChild.pid] = childrenInfo[event.child.pid];

var children = [newChild];
var streams = toStreams(children);
const children = [newChild];
const streams = toStreams(children);
handleChildEvents(streams, children, childrenInfo);

@@ -404,14 +452,14 @@ }, config.restartAfter);

function exit(childExitCodes) {
var success;
let 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;
});
case 'first':
success = _.first(childExitCodes) === 0;
break;
case 'last':
success = _.last(childExitCodes) === 0;
break;
default:
success = _.every(childExitCodes, function(code) {
return code === 0;
});
}

@@ -423,7 +471,7 @@ process.exit(success ? 0 : 1);

// Output emitted errors from child process
var errorStreams = _.map(streams, 'error');
var processErrorStream = Rx.Observable.merge.apply(this, errorStreams);
const errorStreams = _.map(streams, 'error');
const processErrorStream = Rx.Observable.merge.apply(this, errorStreams);
processErrorStream.subscribe(function(event) {
var command = childrenInfo[event.child.pid].command;
const command = childrenInfo[event.child.pid].command;
logError('', chalk.gray.dim, 'Error occured when executing command: ' + command);

@@ -443,9 +491,10 @@ logError('', chalk.gray.dim, event.data.stack);

function getPrefix(childrenInfo, child) {
var prefixes = getPrefixes(childrenInfo, child);
if (_.includes(_.keys(prefixes), config.prefix)) {
return '[' + prefixes[config.prefix] + '] ';
const prefixes = getPrefixes(childrenInfo, child);
const prefixType = config.prefix || prefixes.name ? 'name' : 'index';
if (_.includes(_.keys(prefixes), prefixType)) {
return '[' + prefixes[prefixType] + '] ';
}
return _.reduce(prefixes, function(memo, val, key) {
var re = new RegExp('{' + key + '}', 'g');
const re = new RegExp('{' + key + '}', 'g');
return memo.replace(re, val);

@@ -456,3 +505,3 @@ }, config.prefix) + ' ';

function getPrefixes(childrenInfo, child) {
var prefixes = {};
const prefixes = {};

@@ -465,3 +514,3 @@ prefixes.none = '';

var command = childrenInfo[child.pid].command;
const command = childrenInfo[child.pid].command;
prefixes.command = shortenText(command, config.prefixLength);

@@ -477,7 +526,7 @@ return prefixes;

var endLength = Math.floor(length / 2);
var startLength = length - endLength;
const endLength = Math.floor(length / 2);
const startLength = length - endLength;
var first = text.substring(0, startLength);
var last = text.substring(text.length - endLength, text.length);
const first = text.substring(0, startLength);
const last = text.substring(text.length - endLength, text.length);
return first + cut + last;

@@ -491,3 +540,5 @@ }

function logEvent(prefix, prefixColor, text) {
if (config.raw) return;
if (config.raw) {
return;
}

@@ -503,7 +554,7 @@ logWithPrefix(prefix, prefixColor, text + '\n', chalk.gray.dim);

var lastChar;
let lastChar;
function logWithPrefix(prefix, prefixColor, text, color) {
if (config.raw) {
if (config.raw) {
process.stdout.write(text);

@@ -515,7 +566,7 @@ return;

var lines = text.split('\n');
const lines = text.split('\n');
// Do not bgColor trailing space
var coloredPrefix = colorText(prefix.replace(/ $/, ''), prefixColor) + ' ';
var paddedLines = _.map(lines, function(line, index) {
var coloredLine = color ? colorText(line, color) : line;
const coloredPrefix = colorText(prefix.replace(/ $/, ''), prefixColor) + ' ';
const paddedLines = _.map(lines, function(line, index) {
let coloredLine = color ? colorText(line, color) : line;
if (index !== 0 && index !== (lines.length - 1)) {

@@ -527,3 +578,3 @@ coloredLine = coloredPrefix + coloredLine;

if (!lastChar || lastChar == '\n' ){
if (!lastChar || lastChar === '\n' ) {
process.stdout.write(coloredPrefix);

@@ -530,0 +581,0 @@ }

['SIGINT', 'SIGTERM'].forEach(function(signal) {
process.on(signal, function() {
console.log(signal);
process.exit(1);
});
process.on(signal, function() {
console.log(signal);
process.exit(1);
});
});
function doNothing() {
setTimeout(doNothing, 1000);
setTimeout(doNothing, 1000);
}

@@ -11,0 +11,0 @@

@@ -0,14 +1,15 @@

'use strict';
// Test basic usage of cli
var path = require('path');
var assert = require('assert');
var run = require('./utils').run;
var IS_WINDOWS = /^win/.test(process.platform);
const path = require('path');
const assert = require('assert');
const run = require('./utils').run;
const IS_WINDOWS = /^win/.test(process.platform);
// Note: Set the DEBUG_TESTS environment variable to `true` to see output of test commands.
var TEST_DIR = 'dir/';
const TEST_DIR = 'dir/';
// Abs path to test directory
var testDir = path.resolve(__dirname);
const testDir = path.resolve(__dirname);
process.chdir(path.join(testDir, '..'));

@@ -63,5 +64,5 @@

it('--kill-others-on-fail should NOT kill other commands if none of them exits with non-zero status code', (done) => {
var readline = require('readline');
var exits = 0;
var sigtermInOutput = false;
const readline = require('readline');
let exits = 0;
let sigtermInOutput = false;

@@ -80,3 +81,3 @@ run('node ./src/main.js --kill-others-on-fail "echo killTest1" "echo killTest2" "echo killTest3"', {

}).then(function() {
if(sigtermInOutput) {
if (sigtermInOutput) {
done(new Error('There was a "SIGTERM" in console output'));

@@ -122,3 +123,3 @@ } else if (exits !== 3) {

it('--prefix should default to "index"', () => {
var collectedLines = []
const collectedLines = [];

@@ -128,3 +129,3 @@ return run('node ./src/main.js "echo one" "echo two"', {

if (/(one|two)$/.exec(line)) {
collectedLines.push(line)
collectedLines.push(line);
}

@@ -136,7 +137,7 @@ }

collectedLines.sort()
collectedLines.sort();
assert.deepEqual(collectedLines, [
'[0] one',
'[1] two'
])
]);
});

@@ -146,3 +147,3 @@ });

it('--names should set a different default prefix', () => {
var collectedLines = []
const collectedLines = [];

@@ -152,3 +153,3 @@ return run('node ./src/main.js -n aa,bb "echo one" "echo two"', {

if (/(one|two)$/.exec(line)) {
collectedLines.push(line)
collectedLines.push(line);
}

@@ -160,7 +161,7 @@ }

collectedLines.sort()
collectedLines.sort();
assert.deepEqual(collectedLines, [
'[aa] one',
'[bb] two'
])
]);
});

@@ -170,5 +171,5 @@ });

it('--allow-restart should restart a proccess with non-zero exit code', (done) => {
var readline = require('readline');
var exitedWithOne = false;
var restarted = false;
const readline = require('readline');
let exitedWithOne = false;
let restarted = false;

@@ -178,5 +179,5 @@ run('node ./src/main.js --allow-restart "sleep 0.1 && exit 1" "sleep 1"', {

onOutputLine: (line) => {
var re = /exited with code (.+)/.exec(line);
const re = /exited with code (.+)/.exec(line);
if (re && re[1] === '1') {
exitedWithOne = true
exitedWithOne = true;
}

@@ -198,4 +199,4 @@

it('--restart-after=n should restart a proccess after n miliseconds', (done) => {
var readline = require('readline');
var start, end;
const readline = require('readline');
let start, end;

@@ -223,4 +224,4 @@ run('node ./src/main.js --allow-restart --restart-after 300 "exit 1" "sleep 1"', {

it('--restart-tries=n should restart a proccess at most n times', (done) => {
var readline = require('readline');
var restartedTimes = 0;
const readline = require('readline');
let restartedTimes = 0;

@@ -235,3 +236,3 @@ run('node ./src/main.js --allow-restart --restart-tries 2 "exit 1" "sleep 1"', {

}).then(function() {
if (restartedTimes == 2) {
if (restartedTimes === 2) {
done();

@@ -245,42 +246,161 @@ } else {

['SIGINT', 'SIGTERM'].forEach((signal) => {
if (IS_WINDOWS) {
console.log('IS_WINDOWS=true');
console.log('Skipping SIGINT/SIGTERM propagation tests ..');
return;
}
if (IS_WINDOWS) {
console.log('IS_WINDOWS=true');
console.log('Skipping SIGINT/SIGTERM propagation tests ..');
return;
}
it('killing it with ' + signal + ' should propagate the signal to the children', function(done) {
var readline = require('readline');
var waitingStart = 2;
var waitingSignal = 2;
it('killing it with ' + signal + ' should propagate the signal to the children', function(done) {
const readline = require('readline');
let waitingStart = 2;
let waitingSignal = 2;
function waitForSignal(cb) {
if (waitingSignal) {
setTimeout(waitForSignal, 100);
} else {
cb();
}
}
function waitForSignal(cb) {
if (waitingSignal) {
setTimeout(waitForSignal, 100);
} else {
cb();
}
}
run('node ./src/main.js "node ./test/support/signal.js" "node ./test/support/signal.js"', {
onOutputLine: function(line, child) {
// waiting for startup
if (/STARTED/.test(line)) {
waitingStart--;
run('node ./src/main.js "node ./test/support/signal.js" "node ./test/support/signal.js"', {
onOutputLine: function(line, child) {
// waiting for startup
if (/STARTED/.test(line)) {
waitingStart--;
}
if (!waitingStart) {
// both processes are started
child.kill(signal);
}
// waiting for signal
if (new RegExp(signal).test(line)) {
waitingSignal--;
}
}
}).then(function() {
waitForSignal(done);
});
});
});
it('sends input to default stdin target process', (done) => {
let echoed = false;
run('node ./src/main.js "node ./test/support/read-echo.js"', {
onOutputLine: (line, child) => {
if (/READING/.test(line)) {
child.stdin.write('stop\n');
}
if (/\[\d+\] stop/.test(line)) {
echoed = true;
}
}
if (!waitingStart) {
// both processes are started
child.kill(signal);
})
.then(() => {
assert(echoed);
})
.then(done, done);
});
it('sends input to specified default stdin target process', (done) => {
let echoed = false;
run('node ./src/main.js --default-input-target 1 "echo test" "node ./test/support/read-echo.js"', {
onOutputLine: (line, child) => {
if (/READING/.test(line)) {
child.stdin.write('stop\n');
}
if (/\[1\] stop/.test(line)) {
echoed = true;
}
}
})
.then(() => {
assert(echoed);
})
.then(done, done);
});
// waiting for signal
if (new RegExp(signal).test(line)) {
waitingSignal--;
it('sends input to child specified by index', (done) => {
let echoed = false;
run('node ./src/main.js "echo test" "node ./test/support/read-echo.js"', {
onOutputLine: (line, child) => {
if (/READING/.test(line)) {
child.stdin.write('1:stop\n');
}
if (/\[1\] stop/.test(line)) {
echoed = true;
}
}
}
}).then(function() {
waitForSignal(done);
});
});
})
.then(() => {
assert(echoed);
})
.then(done, done);
});
it('emits error when specified read stream is not found', (done) => {
let errorEmitted = false;
run('node ./src/main.js "echo test" "node ./test/support/read-echo.js"', {
onOutputLine: (line, child) => {
if (/READING/.test(line)) {
child.stdin.write('2:stop\n');
}
if ('Unable to find command [2]' === line.trim()) {
errorEmitted = true;
// Stop read process to continue the test
child.stdin.write('1:stop\n');
}
}
})
.then(() => {
assert(errorEmitted);
})
.then(done, done);
});
it('should expand npm: command shortcuts', (done) => {
let echo1 = false;
let echo2 = false;
run('node ./src/main.js "npm:echo-test" "npm:echo -- testarg"', {
onOutputLine: function(line, child) {
if (line === '[echo-test] test') {
echo1 = true;
} else if (line === '[echo] testarg') {
echo2 = true;
}
}
})
.then((exitCode) => {
assert.strictEqual(exitCode, 0);
assert.ok(echo1);
assert.ok(echo2);
})
.then(done, done);
});
it('expands npm run shortcut wildcards', (done) => {
let echoBeep = false;
let echoBoop = false;
run('node ./src/main.js "npm:echo-sound-*"', {
onOutputLine: (line, child) => {
if (line === '[beep] beep') {
echoBeep = true;
} else if (line === '[boop] boop') {
echoBoop = true;
}
}
})
.then((exitCode) => {
assert.strictEqual(exitCode, 0);
assert.ok(echoBeep);
assert.ok(echoBoop);
})
.then(done, done);
});
});

@@ -287,0 +407,0 @@

@@ -1,8 +0,9 @@

var childProcess = require('child_process');
var _ = require('lodash');
var readline = require('readline')
var shellQuote = require('shell-quote');
'use strict';
const childProcess = require('child_process');
const _ = require('lodash');
const readline = require('readline');
const shellQuote = require('shell-quote');
// If true, output of commands are shown
var DEBUG_TESTS = process.env.DEBUG_TESTS === 'true';
const DEBUG_TESTS = process.env.DEBUG_TESTS === 'true';

@@ -14,6 +15,7 @@ function run(cmd, opts) {

onOutputLine: undefined,
onErrorLine: undefined
}, opts);
var child;
var parts = shellQuote.parse(cmd);
let child;
const parts = shellQuote.parse(cmd);
try {

@@ -31,2 +33,8 @@ child = childProcess.spawn(_.head(parts), _.tail(parts), {

if (opts.onErrorLine) {
readLines(child, opts.onErrorLine, 'stderr');
}
readLines(child, (l) => { console.log(l); }, 'stderr');
return new Promise(function(resolve, reject) {

@@ -43,5 +51,7 @@ child.on('error', function(err) {

function readLines(child, callback) {
var rl = readline.createInterface({
input: child.stdout,
function readLines(child, callback, src) {
src = src || 'stdout';
const rl = readline.createInterface({
input: child[src],
output: null

@@ -55,3 +65,3 @@ });

callback(line, child)
callback(line, child);
});

@@ -58,0 +68,0 @@ }

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc