From d8c7ae2f6ba898959e60aec21d7c7a96e4eaf17b Mon Sep 17 00:00:00 2001 From: Gustavo Henke Date: Sun, 2 Jan 2022 19:46:56 +1100 Subject: [PATCH] Expose commands via API before they finish running Closes #209 --- bin/concurrently.ts | 2 +- src/concurrently.ts | 34 +++++++++++++++++++++++++++------- 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/bin/concurrently.ts b/bin/concurrently.ts index 5f28434a..f06a6a6b 100755 --- a/bin/concurrently.ts +++ b/bin/concurrently.ts @@ -185,7 +185,7 @@ concurrently(args._.map((command, index) => ({ successCondition: args.success, timestampFormat: args['timestamp-format'], timings: args.timings -}).then( +}).result.then( () => process.exit(0), () => process.exit(1) ); diff --git a/src/concurrently.ts b/src/concurrently.ts index f741c38d..88419dbe 100644 --- a/src/concurrently.ts +++ b/src/concurrently.ts @@ -3,7 +3,7 @@ import _ from 'lodash'; import spawn from 'spawn-command'; import { Writable } from 'stream'; import treeKill from 'tree-kill'; -import { Command, CommandInfo, KillProcess, SpawnCommand } from './command'; +import { CloseEvent, Command, CommandInfo, KillProcess, SpawnCommand } from './command'; import { CommandParser } from './command-parser/command-parser'; import { ExpandNpmShortcut } from './command-parser/expand-npm-shortcut'; import { ExpandNpmWildcard } from './command-parser/expand-npm-wildcard'; @@ -29,6 +29,21 @@ const defaults: ConcurrentlyOptions = { */ export type ConcurrentlyCommandInput = string | Partial; +export type ConcurrentlyResult = { + /** + * All commands created and ran by concurrently. + */ + commands: Command[], + + /** + * A promise that resolves when concurrently ran successfully according to the specified + * success condition, or reject otherwise. + * + * Both the resolved and rejected value is the list of all command's close events. + */ + result: Promise, +}; + export type ConcurrentlyOptions = { logger?: Logger, @@ -85,12 +100,14 @@ export type ConcurrentlyOptions = { /** * Core concurrently functionality -- spawns the given commands concurrently and - * returns a promise that will await for them to finish. + * returns the commands themselves + the result according to the specified success condition. * * @see CompletionListener - * @returns A promise that resolves when the commands ran successfully, or rejects otherwise. */ -export function concurrently(baseCommands: ConcurrentlyCommandInput[], baseOptions?: Partial) { +export function concurrently( + baseCommands: ConcurrentlyCommandInput[], + baseOptions?: Partial, +): ConcurrentlyResult { assert.ok(Array.isArray(baseCommands), '[concurrently] commands should be an array'); assert.notStrictEqual(baseCommands.length, 0, '[concurrently] no commands provided'); @@ -148,13 +165,16 @@ export function concurrently(baseCommands: ConcurrentlyCommandInput[], baseOptio maybeRunMore(commandsLeft); } - return new CompletionListener({ - successCondition: options.successCondition, - }) + const result = new CompletionListener({ successCondition: options.successCondition }) .listen(commands) .finally(() => { handleResult.onFinishCallbacks.forEach((onFinish) => onFinish()); }); + + return { + result, + commands, + }; }; function mapToCommandInfo(command: ConcurrentlyCommandInput): CommandInfo {