Skip to content

Commit

Permalink
Bring spawn-command into concurrently (#479)
Browse files Browse the repository at this point in the history
  • Loading branch information
gustavohenke committed Jun 5, 2024
1 parent c700980 commit 04b7d4a
Show file tree
Hide file tree
Showing 8 changed files with 77 additions and 54 deletions.
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ tired of opening terminals and made **concurrently**.
- Cross platform (including Windows)
- Output is easy to follow with prefixes
- With `--kill-others` switch, all commands are killed if one dies
- Spawns commands with [spawn-command](https://github.com/mmalecki/spawn-command)

## Installation

Expand Down
6 changes: 0 additions & 6 deletions declarations/spawn-command.d.ts

This file was deleted.

1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@
"lodash": "^4.17.21",
"rxjs": "^7.8.1",
"shell-quote": "^1.8.1",
"spawn-command": "0.0.2-1",
"supports-color": "^8.1.1",
"tree-kill": "^1.2.2",
"yargs": "^17.7.2"
Expand Down
9 changes: 1 addition & 8 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 2 additions & 3 deletions src/concurrently.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import assert from 'assert';
import _ from 'lodash';
import { cpus } from 'os';
import spawn from 'spawn-command';
import { Writable } from 'stream';
import treeKill from 'tree-kill';

Expand All @@ -13,10 +12,10 @@ import { ExpandNpmWildcard } from './command-parser/expand-npm-wildcard';
import { StripQuotes } from './command-parser/strip-quotes';
import { CompletionListener, SuccessCondition } from './completion-listener';
import { FlowController } from './flow-control/flow-controller';
import { getSpawnOpts } from './get-spawn-opts';
import { Logger } from './logger';
import { OutputWriter } from './output-writer';
import { PrefixColorSelector } from './prefix-color-selector';
import { getSpawnOpts, spawn } from './spawn';

const defaults: ConcurrentlyOptions = {
spawn,
Expand Down Expand Up @@ -119,7 +118,7 @@ export type ConcurrentlyOptions = {

/**
* A function that will spawn commands.
* Defaults to the `spawn-command` module.
* Defaults to a function that spawns using either `cmd.exe` or `/bin/sh`.
*/
spawn: SpawnCommand;

Expand Down
34 changes: 0 additions & 34 deletions src/get-spawn-opts.spec.ts

This file was deleted.

52 changes: 52 additions & 0 deletions src/spawn.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { getSpawnOpts, spawn } from './spawn';

const baseProcess = {
platform: 'win32' as const,
cwd: () => '',
env: {},
};

describe('spawn()', () => {
it('spawns the given command', async () => {
const fakeSpawn = jest.fn();
spawn('echo banana', {}, fakeSpawn, baseProcess);
expect(fakeSpawn).toHaveBeenCalled();
expect(fakeSpawn.mock.calls[0][1].join(' ')).toContain('echo banana');
});

it('returns spawned process', async () => {
const childProcess = {};
const fakeSpawn = jest.fn().mockReturnValue(childProcess);
const child = spawn('echo banana', {}, fakeSpawn, baseProcess);
expect(child).toBe(childProcess);
});
});

describe('getSpawnOpts()', () => {
it('sets detached mode to false for Windows platform', () => {
expect(getSpawnOpts({ process: baseProcess }).detached).toBe(false);
});

it('sets stdio to inherit when raw', () => {
expect(getSpawnOpts({ raw: true }).stdio).toBe('inherit');
});

it('merges FORCE_COLOR into env vars if color supported', () => {
const process = { ...baseProcess, env: { foo: 'bar' } };
expect(getSpawnOpts({ process, colorSupport: false }).env).toEqual(process.env);
expect(getSpawnOpts({ process, colorSupport: { level: 1 } }).env).toEqual({
FORCE_COLOR: '1',
foo: 'bar',
});
});

it('sets default cwd to process.cwd()', () => {
const process = { ...baseProcess, cwd: () => 'process-cwd' };
expect(getSpawnOpts({ process }).cwd).toBe('process-cwd');
});

it('overrides default cwd', () => {
const cwd = 'foobar';
expect(getSpawnOpts({ cwd }).cwd).toBe(cwd);
});
});
23 changes: 22 additions & 1 deletion src/get-spawn-opts.ts → src/spawn.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,27 @@
import { SpawnOptions } from 'child_process';
import { ChildProcess, spawn as baseSpawn, SpawnOptions } from 'child_process';
import supportsColor from 'supports-color';

/**
* Spawns a command using `cmd.exe` on Windows, or `/bin/sh` elsewhere.
*/
// Implementation based off of https://github.com/mmalecki/spawn-command/blob/v0.0.2-1/lib/spawn-command.js
export function spawn(
command: string,
options: SpawnOptions,
// For testing
spawn: (command: string, args: string[], options: SpawnOptions) => ChildProcess = baseSpawn,
process: Pick<NodeJS.Process, 'platform'> = global.process,
): ChildProcess {
let file = '/bin/sh';
let args = ['-c', command];
if (process.platform === 'win32') {
file = 'cmd.exe';
args = ['/s', '/c', `"${command}"`];
options.windowsVerbatimArguments = true;
}
return spawn(file, args, options);
}

export const getSpawnOpts = ({
colorSupport = supportsColor.stdout,
cwd,
Expand Down

0 comments on commit 04b7d4a

Please sign in to comment.