From 2774187857c4d23e61c01cbfa36c7f1338470f2b Mon Sep 17 00:00:00 2001 From: Tom Esterez Date: Mon, 27 Jan 2020 02:48:17 -0500 Subject: [PATCH] Return exit codes (#213) --- README.md | 2 +- src/completion-listener.js | 48 ++++++++++++++++++--------------- src/completion-listener.spec.js | 22 +++++++-------- 3 files changed, 38 insertions(+), 34 deletions(-) diff --git a/README.md b/README.md index 4ed1f5bb..bbf2203a 100644 --- a/README.md +++ b/README.md @@ -247,7 +247,7 @@ concurrently can be used programmatically by using the API documented below: to use when prefixing with `time`. Default: `yyyy-MM-dd HH:mm:ss.ZZZ` > Returns: a `Promise` that resolves if the run was successful (according to `successCondition` option), -> or rejects otherwise. +> or rejects, containing an array with the exit codes of each command that has been run. Example: diff --git a/src/completion-listener.js b/src/completion-listener.js index d5439463..b4e735ac 100644 --- a/src/completion-listener.js +++ b/src/completion-listener.js @@ -7,29 +7,33 @@ module.exports = class CompletionListener { this.scheduler = scheduler; } - listen(commands) { - const closeStreams = commands.map(command => command.close); - const allClosed = Rx.zip(...closeStreams); - return Rx.merge(...closeStreams).pipe( - bufferCount(closeStreams.length), - map(exitCodes => { - switch (this.successCondition) { - /* eslint-disable indent */ - case 'first': - return exitCodes[0] === 0; + isSuccess(exitCodes) { + switch (this.successCondition) { + /* eslint-disable indent */ + case 'first': + return exitCodes[0] === 0; + + case 'last': + return exitCodes[exitCodes.length - 1] === 0; - case 'last': - return exitCodes[exitCodes.length - 1] === 0; + default: + return exitCodes.every(exitCode => exitCode === 0); + /* eslint-enable indent */ + } + } - default: - return exitCodes.every(exitCode => exitCode === 0); - /* eslint-enable indent */ - } - }), - switchMap(success => success - ? Rx.of(null, this.scheduler) - : Rx.throwError(new Error(), this.scheduler)), - take(1) - ).toPromise(); + listen(commands) { + const closeStreams = commands.map(command => command.close); + return Rx.merge(...closeStreams) + .pipe( + bufferCount(closeStreams.length), + switchMap(exitCodes => + this.isSuccess(exitCodes) + ? Rx.of(exitCodes, this.scheduler) + : Rx.throwError(exitCodes, this.scheduler) + ), + take(1) + ) + .toPromise(); } }; diff --git a/src/completion-listener.spec.js b/src/completion-listener.spec.js index 9b371ef2..9c6bef32 100644 --- a/src/completion-listener.spec.js +++ b/src/completion-listener.spec.js @@ -9,10 +9,11 @@ beforeEach(() => { scheduler = new TestScheduler(); }); -const createController = successCondition => new CompletionListener({ - successCondition, - scheduler -}); +const createController = successCondition => + new CompletionListener({ + successCondition, + scheduler + }); describe('with default success condition set', () => { it('succeeds if all processes exited with code 0', () => { @@ -23,7 +24,7 @@ describe('with default success condition set', () => { scheduler.flush(); - return expect(result).resolves.toBeNull(); + return expect(result).resolves.toEqual([0, 0]); }); it('fails if one of the processes exited with non-0 code', () => { @@ -34,11 +35,10 @@ describe('with default success condition set', () => { scheduler.flush(); - expect(result).rejects.toThrowError(); + expect(result).rejects.toEqual([0, 1]); }); }); - describe('with success condition set to first', () => { it('succeeds if first process to exit has code 0', () => { const result = createController('first').listen(commands); @@ -48,7 +48,7 @@ describe('with success condition set to first', () => { scheduler.flush(); - return expect(result).resolves.toBeNull(); + return expect(result).resolves.toEqual([0, 1]); }); it('fails if first process to exit has non-0 code', () => { @@ -59,7 +59,7 @@ describe('with success condition set to first', () => { scheduler.flush(); - return expect(result).rejects.toThrowError(); + return expect(result).rejects.toEqual([1, 0]); }); }); @@ -72,7 +72,7 @@ describe('with success condition set to last', () => { scheduler.flush(); - return expect(result).resolves.toBeNull(); + return expect(result).resolves.toEqual([1, 0]); }); it('fails if last process to exit has non-0 code', () => { @@ -83,6 +83,6 @@ describe('with success condition set to last', () => { scheduler.flush(); - return expect(result).rejects.toThrowError(); + return expect(result).rejects.toEqual([0, 1]); }); });