Skip to content

Commit 8ed92d4

Browse files
committed
Allow shell option to be a file URL
1 parent 640ae39 commit 8ed92d4

File tree

6 files changed

+18
-10
lines changed

6 files changed

+18
-10
lines changed

index.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@ export type CommonOptions<EncodingType extends EncodingOption = DefaultEncodingO
256256
257257
@default false
258258
*/
259-
readonly shell?: boolean | string;
259+
readonly shell?: boolean | string | URL;
260260

261261
/**
262262
Specify the character encoding used to decode the `stdout` and `stderr` output. If set to `'buffer'`, then `stdout` and `stderr` will be a `Uint8Array` instead of a string.

index.js

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,16 +30,16 @@ const getEnv = ({env: envOption, extendEnv, preferLocal, localDir, execPath}) =>
3030
return env;
3131
};
3232

33+
const normalizeFileUrl = file => file instanceof URL ? fileURLToPath(file) : file;
34+
3335
const getFilePath = file => {
34-
if (file instanceof URL) {
35-
return fileURLToPath(file);
36-
}
36+
const fileString = normalizeFileUrl(file);
3737

38-
if (typeof file !== 'string') {
38+
if (typeof fileString !== 'string') {
3939
throw new TypeError('First argument must be a string or a file URL.');
4040
}
4141

42-
return file;
42+
return fileString;
4343
};
4444

4545
const handleArguments = (file, args, options = {}) => {
@@ -63,6 +63,7 @@ const handleArguments = (file, args, options = {}) => {
6363
windowsHide: true,
6464
verbose: verboseDefault,
6565
...options,
66+
shell: normalizeFileUrl(options.shell),
6667
};
6768

6869
options.env = getEnv(options);

index.test-d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,7 @@ execa('unicorns', {uid: 0});
264264
execa('unicorns', {gid: 0});
265265
execa('unicorns', {shell: true});
266266
execa('unicorns', {shell: '/bin/sh'});
267+
execa('unicorns', {shell: fileUrl});
267268
execa('unicorns', {timeout: 1000});
268269
execa('unicorns', {maxBuffer: 1000});
269270
execa('unicorns', {killSignal: 'SIGTERM'});

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@
6565
"path-key": "^4.0.0",
6666
"tempfile": "^5.0.0",
6767
"tsd": "^0.29.0",
68+
"which": "^4.0.0",
6869
"xo": "^0.56.0"
6970
},
7071
"c8": {

readme.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -718,7 +718,7 @@ Sets the group identity of the process.
718718

719719
#### shell
720720

721-
Type: `boolean | string`\
721+
Type: `boolean | string | URL`\
722722
Default: `false`
723723

724724
If `true`, runs `file` inside of a shell. Uses `/bin/sh` on UNIX and `cmd.exe` on Windows. A different shell can be specified as a string. The shell should understand the `-c` switch on UNIX or `/d /s /c` on Windows.

test/test.js

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {fileURLToPath, pathToFileURL} from 'node:url';
44
import test from 'ava';
55
import isRunning from 'is-running';
66
import getNode from 'get-node';
7+
import which from 'which';
78
import {execa, execaSync, execaNode, $} from '../index.js';
89
import {setFixtureDir, PATH_KEY, FIXTURES_DIR_URL} from './helpers/fixtures-dir.js';
910

@@ -245,11 +246,15 @@ test('can use `options.shell: true`', async t => {
245246
t.is(stdout, 'foo');
246247
});
247248

248-
test('can use `options.shell: string`', async t => {
249-
const shell = process.platform === 'win32' ? 'cmd.exe' : '/bin/bash';
249+
const testShellPath = async (t, mapPath) => {
250+
const shellPath = process.platform === 'win32' ? 'cmd.exe' : 'bash';
251+
const shell = mapPath(await which(shellPath));
250252
const {stdout} = await execa('node test/fixtures/noop.js foo', {shell});
251253
t.is(stdout, 'foo');
252-
});
254+
};
255+
256+
test('can use `options.shell: string`', testShellPath, identity);
257+
test('can use `options.shell: file URL`', testShellPath, pathToFileURL);
253258

254259
test('use extend environment with `extendEnv: true` and `shell: true`', async t => {
255260
process.env.TEST = 'test';

0 commit comments

Comments
 (0)