Skip to content

Commit

Permalink
Add --group option
Browse files Browse the repository at this point in the history
This option makes it so that the output is displayed as if the commands were run sequentially.
  • Loading branch information
cdrini committed Apr 18, 2021
1 parent ccb6b8d commit 6aac78b
Show file tree
Hide file tree
Showing 9 changed files with 258 additions and 70 deletions.
9 changes: 7 additions & 2 deletions bin/concurrently.js
Expand Up @@ -55,6 +55,10 @@ const args = yargs
describe: 'Disables colors from logging',
type: 'boolean'
},
'group': {
describe: 'Order the output as if the commands were run sequentially.',
type: 'boolean'
},

// Kill others
'k': {
Expand Down Expand Up @@ -133,7 +137,7 @@ const args = yargs
'Can be either the index or the name of the process.'
}
})
.group(['m', 'n', 'name-separator', 'raw', 's', 'no-color'], 'General')
.group(['m', 'n', 'name-separator', 'raw', 's', 'no-color', 'group'], 'General')
.group(['p', 'c', 'l', 't'], 'Prefix styling')
.group(['i', 'default-input-target'], 'Input handling')
.group(['k', 'kill-others-on-fail'], 'Killing other processes')
Expand Down Expand Up @@ -167,7 +171,8 @@ concurrently(args._.map((command, index) => {
restartDelay: args.restartAfter,
restartTries: args.restartTries,
successCondition: args.success,
timestampFormat: args.timestampFormat
timestampFormat: args.timestampFormat,
group: args.group
}).then(
() => process.exit(0),
() => process.exit(1)
Expand Down
4 changes: 3 additions & 1 deletion index.js
Expand Up @@ -11,7 +11,6 @@ const Logger = require('./src/logger');

module.exports = (commands, options = {}) => {
const logger = new Logger({
outputStream: options.outputStream || process.stdout,
prefixFormat: options.prefix,
prefixLength: options.prefixLength,
raw: options.raw,
Expand All @@ -23,6 +22,9 @@ module.exports = (commands, options = {}) => {
raw: options.raw,
successCondition: options.successCondition,
cwd: options.cwd,
logger,
outputStream: options.outputStream || process.stdout,
group: options.group,
controllers: [
new LogError({ logger }),
new LogOutput({ logger }),
Expand Down
2 changes: 2 additions & 0 deletions src/command.js
Expand Up @@ -19,6 +19,7 @@ module.exports = class Command {
this.close = new Rx.Subject();
this.stdout = new Rx.Subject();
this.stderr = new Rx.Subject();
this.exited = false;
}

start() {
Expand All @@ -32,6 +33,7 @@ module.exports = class Command {
});
Rx.fromEvent(child, 'close').subscribe(([exitCode, signal]) => {
this.process = undefined;
this.exited = true;
this.close.next({
command: {
command: this.command,
Expand Down
10 changes: 10 additions & 0 deletions src/concurrently.js
Expand Up @@ -11,6 +11,7 @@ const CompletionListener = require('./completion-listener');

const getSpawnOpts = require('./get-spawn-opts');
const Command = require('./command');
const OutputWriter = require('./output-writer');

const defaults = {
spawn,
Expand Down Expand Up @@ -60,6 +61,15 @@ module.exports = (commands, options) => {
maybeRunMore(commandsLeft);
}

if (options.logger) {
const outputWriter = new OutputWriter({
outputStream: options.outputStream,
group: options.group,
commands,
});
options.logger.observable.subscribe(({command, text}) => outputWriter.write(command, text));
}

return new CompletionListener({ successCondition: options.successCondition }).listen(commands);
};

Expand Down
2 changes: 2 additions & 0 deletions src/defaults.js
Expand Up @@ -18,6 +18,8 @@ module.exports = {
// How many bytes we'll show on the command prefix
prefixLength: 10,
raw: false,
// Whether to display output ordered as if the commands were sequential
group: false,
// Number of attempts of restarting a process, if it exits with non-0 code
restartTries: 0,
// How many milliseconds concurrently should wait before restarting a process.
Expand Down
27 changes: 19 additions & 8 deletions src/logger.js
@@ -1,16 +1,19 @@
const chalk = require('chalk');
const _ = require('lodash');
const formatDate = require('date-fns/format');
const Rx = require('rxjs');

const defaults = require('./defaults');
/** @typedef {import('./command.js')} Command */

module.exports = class Logger {
constructor({ outputStream, prefixFormat, prefixLength, raw, timestampFormat }) {
constructor({ prefixFormat, prefixLength, raw, timestampFormat }) {
this.raw = raw;
this.outputStream = outputStream;
this.prefixFormat = prefixFormat;
this.prefixLength = prefixLength || defaults.prefixLength;
this.timestampFormat = timestampFormat || defaults.timestampFormat;
/** @type {Rx.Subject<{ command: Command, text: string }>} */
this.observable = new Rx.Subject();
}

shortenText(text) {
Expand Down Expand Up @@ -76,20 +79,20 @@ module.exports = class Logger {

logCommandText(text, command) {
const prefix = this.colorText(command, this.getPrefix(command));
return this.log(prefix + (prefix ? ' ' : ''), text);
return this.log(prefix + (prefix ? ' ' : ''), text, command);
}

logGlobalEvent(text) {
if (this.raw) {
return;
}

this.log(chalk.gray.dim('-->') + ' ', chalk.gray.dim(text) + '\n');
this.log(chalk.gray.dim('-->') + ' ', chalk.gray.dim(text) + '\n', null);
}

log(prefix, text) {
log(prefix, text, command) {
if (this.raw) {
return this.outputStream.write(text);
return this.emit(command, text);
}

// #70 - replace some ANSI code that would impact clearing lines
Expand All @@ -105,10 +108,18 @@ module.exports = class Logger {
});

if (!this.lastChar || this.lastChar === '\n') {
this.outputStream.write(prefix);
this.emit(command, prefix);
}

this.lastChar = text[text.length - 1];
this.outputStream.write(lines.join('\n'));
this.emit(command, lines.join('\n'));
}

/**
* @param {Command} command
* @param {string} text
*/
emit(command, text) {
this.observable.next({ command, text });
}
};

0 comments on commit 6aac78b

Please sign in to comment.