Skip to content

Commit 231beaf

Browse files
authored
Rename signal option to cancelSignal (#880)
1 parent 7d0943f commit 231beaf

File tree

8 files changed

+43
-30
lines changed

8 files changed

+43
-30
lines changed

docs/scripts.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ Execa's scripting API mostly consists of only two methods: [`` $`command` ``](..
4646

4747
[No special binary](#main-binary) is recommended, no [global variable](#global-variables) is injected: scripts are regular Node.js files.
4848

49-
Execa is a thin wrapper around the core Node.js [`child_process` module](https://nodejs.org/api/child_process.html). Unlike zx, it lets you use [any of its native features](#background-processes): [`pid`](#pid), [IPC](https://nodejs.org/api/child_process.html#subprocesssendmessage-sendhandle-options-callback), [`unref()`](https://nodejs.org/api/child_process.html#subprocessunref), [`detached`](https://nodejs.org/api/child_process.html#child_processspawncommand-args-options), [`uid`](https://nodejs.org/api/child_process.html#child_processspawncommand-args-options), [`gid`](https://nodejs.org/api/child_process.html#child_processspawncommand-args-options), [`signal`](https://nodejs.org/api/child_process.html#child_processspawncommand-args-options), etc.
49+
Execa is a thin wrapper around the core Node.js [`child_process` module](https://nodejs.org/api/child_process.html). Unlike zx, it lets you use [any of its native features](#background-processes): [`pid`](#pid), [IPC](https://nodejs.org/api/child_process.html#subprocesssendmessage-sendhandle-options-callback), [`unref()`](https://nodejs.org/api/child_process.html#subprocessunref), [`detached`](https://nodejs.org/api/child_process.html#child_processspawncommand-args-options), [`uid`](https://nodejs.org/api/child_process.html#child_processspawncommand-args-options), [`gid`](https://nodejs.org/api/child_process.html#child_processspawncommand-args-options), [`cancelSignal`](https://nodejs.org/api/child_process.html#child_processspawncommand-args-options), etc.
5050

5151
### Modularity
5252

index.d.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -499,7 +499,7 @@ type CommonOptions<IsSync extends boolean = boolean> = {
499499

500500
/**
501501
Signal used to terminate the child process when:
502-
- using the `signal`, `timeout`, `maxBuffer` or `cleanup` option
502+
- using the `cancelSignal`, `timeout`, `maxBuffer` or `cleanup` option
503503
- calling [`subprocess.kill()`](https://nodejs.org/api/child_process.html#subprocesskillsignal) with no arguments
504504
505505
This can be either a name (like `"SIGTERM"`) or a number (like `9`).
@@ -514,7 +514,7 @@ type CommonOptions<IsSync extends boolean = boolean> = {
514514
The grace period is 5 seconds by default. This feature can be disabled with `false`.
515515
516516
This works when the child process is terminated by either:
517-
- the `signal`, `timeout`, `maxBuffer` or `cleanup` option
517+
- the `cancelSignal`, `timeout`, `maxBuffer` or `cleanup` option
518518
- calling [`subprocess.kill()`](https://nodejs.org/api/child_process.html#subprocesskillsignal) with no arguments
519519
520520
This does not work when the child process is terminated by either:
@@ -613,7 +613,7 @@ type CommonOptions<IsSync extends boolean = boolean> = {
613613
import {execa} from 'execa';
614614
615615
const abortController = new AbortController();
616-
const subprocess = execa('node', [], {signal: abortController.signal});
616+
const subprocess = execa('node', [], {cancelSignal: abortController.signal});
617617
618618
setTimeout(() => {
619619
abortController.abort();
@@ -627,7 +627,7 @@ type CommonOptions<IsSync extends boolean = boolean> = {
627627
}
628628
```
629629
*/
630-
readonly signal?: IfAsync<IsSync, AbortSignal>;
630+
readonly cancelSignal?: IfAsync<IsSync, AbortSignal>;
631631
};
632632

633633
export type Options = CommonOptions<false>;
@@ -664,7 +664,7 @@ type ExecaCommonReturnValue<IsSync extends boolean = boolean, OptionsType extend
664664
/**
665665
The numeric exit code of the process that was run.
666666
667-
This is `undefined` when the process could not be spawned or was terminated by a [signal](#signal-1).
667+
This is `undefined` when the process could not be spawned or was terminated by a [signal](#signal).
668668
*/
669669
exitCode?: number;
670670

@@ -728,7 +728,7 @@ type ExecaCommonReturnValue<IsSync extends boolean = boolean, OptionsType extend
728728
cwd: string;
729729

730730
/**
731-
Whether the process was canceled using the [`signal`](https://github.com/sindresorhus/execa#signal-1) option.
731+
Whether the process was canceled using the `cancelSignal` option.
732732
*/
733733
isCanceled: boolean;
734734

@@ -1028,7 +1028,7 @@ export function execa<OptionsType extends Options = {}>(
10281028
/**
10291029
Same as `execa()` but synchronous.
10301030
1031-
Cannot use the following options: `all`, `cleanup`, `buffer`, `detached`, `ipc`, `serialization`, `signal` and `lines`. Also, the `stdin`, `stdout`, `stderr`, `stdio` and `input` options cannot be an array, an iterable or a web stream. Node.js streams must have a file descriptor unless the `input` option is used.
1031+
Cannot use the following options: `all`, `cleanup`, `buffer`, `detached`, `ipc`, `serialization`, `cancelSignal` and `lines`. Also, the `stdin`, `stdout`, `stderr`, `stdio` and `input` options cannot be an array, an iterable or a web stream. Node.js streams must have a file descriptor unless the `input` option is used.
10321032
10331033
Returns or throws a `childProcessResult`. The `childProcess` is not returned: its methods and properties are not available. This includes [`.kill()`](https://nodejs.org/api/child_process.html#subprocesskillsignal), [`.pid`](https://nodejs.org/api/child_process.html#subprocesspid), `.pipe()` and the [`.stdin`/`.stdout`/`.stderr`](https://nodejs.org/api/child_process.html#subprocessstdout) streams.
10341034
@@ -1129,7 +1129,7 @@ export function execaCommand<OptionsType extends Options = {}>(
11291129
/**
11301130
Same as `execaCommand()` but synchronous.
11311131
1132-
Cannot use the following options: `all`, `cleanup`, `buffer`, `detached`, `ipc`, `serialization`, `signal` and `lines`. Also, the `stdin`, `stdout`, `stderr`, `stdio` and `input` options cannot be an array, an iterable or a web stream. Node.js streams must have a file descriptor unless the `input` option is used.
1132+
Cannot use the following options: `all`, `cleanup`, `buffer`, `detached`, `ipc`, `serialization`, `cancelSignal` and `lines`. Also, the `stdin`, `stdout`, `stderr`, `stdio` and `input` options cannot be an array, an iterable or a web stream. Node.js streams must have a file descriptor unless the `input` option is used.
11331133
11341134
Returns or throws a `childProcessResult`. The `childProcess` is not returned: its methods and properties are not available. This includes [`.kill()`](https://nodejs.org/api/child_process.html#subprocesskillsignal), [`.pid`](https://nodejs.org/api/child_process.html#subprocesspid), `.pipe()` and the [`.stdin`/`.stdout`/`.stderr`](https://nodejs.org/api/child_process.html#subprocessstdout) streams.
11351135
@@ -1187,7 +1187,7 @@ type Execa$<OptionsType extends CommonOptions = {}> = {
11871187
/**
11881188
Same as $\`command\` but synchronous.
11891189
1190-
Cannot use the following options: `all`, `cleanup`, `buffer`, `detached`, `ipc`, `serialization`, `signal` and `lines`. Also, the `stdin`, `stdout`, `stderr`, `stdio` and `input` options cannot be an array, an iterable or a web stream. Node.js streams must have a file descriptor unless the `input` option is used.
1190+
Cannot use the following options: `all`, `cleanup`, `buffer`, `detached`, `ipc`, `serialization`, `cancelSignal` and `lines`. Also, the `stdin`, `stdout`, `stderr`, `stdio` and `input` options cannot be an array, an iterable or a web stream. Node.js streams must have a file descriptor unless the `input` option is used.
11911191
11921192
Returns or throws a `childProcessResult`. The `childProcess` is not returned: its methods and properties are not available. This includes [`.kill()`](https://nodejs.org/api/child_process.html#subprocesskillsignal), [`.pid`](https://nodejs.org/api/child_process.html#subprocesspid), `.pipe()` and the [`.stdin`/`.stdout`/`.stderr`](https://nodejs.org/api/child_process.html#subprocessstdout) streams.
11931193
@@ -1241,7 +1241,7 @@ type Execa$<OptionsType extends CommonOptions = {}> = {
12411241
/**
12421242
Same as $\`command\` but synchronous.
12431243
1244-
Cannot use the following options: `all`, `cleanup`, `buffer`, `detached`, `ipc`, `serialization`, `signal` and `lines`. Also, the `stdin`, `stdout`, `stderr`, `stdio` and `input` options cannot be an array, an iterable or a web stream. Node.js streams must have a file descriptor unless the `input` option is used.
1244+
Cannot use the following options: `all`, `cleanup`, `buffer`, `detached`, `ipc`, `serialization`, `cancelSignal` and `lines`. Also, the `stdin`, `stdout`, `stderr`, `stdio` and `input` options cannot be an array, an iterable or a web stream. Node.js streams must have a file descriptor unless the `input` option is used.
12451245
12461246
Returns or throws a `childProcessResult`. The `childProcess` is not returned: its methods and properties are not available. This includes [`.kill()`](https://nodejs.org/api/child_process.html#subprocesskillsignal), [`.pid`](https://nodejs.org/api/child_process.html#subprocesspid), `.pipe()` and the [`.stdin`/`.stdout`/`.stderr`](https://nodejs.org/api/child_process.html#subprocessstdout) streams.
12471247

index.test-d.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1434,8 +1434,8 @@ execa('unicorns', {forceKillAfterDelay: undefined});
14341434
execaSync('unicorns', {forceKillAfterDelay: undefined});
14351435
expectError(execa('unicorns', {forceKillAfterDelay: 'true'}));
14361436
expectError(execaSync('unicorns', {forceKillAfterDelay: 'true'}));
1437-
execa('unicorns', {signal: new AbortController().signal});
1438-
expectError(execaSync('unicorns', {signal: new AbortController().signal}));
1437+
execa('unicorns', {cancelSignal: new AbortController().signal});
1438+
expectError(execaSync('unicorns', {cancelSignal: new AbortController().signal}));
14391439
execa('unicorns', {windowsVerbatimArguments: true});
14401440
execaSync('unicorns', {windowsVerbatimArguments: true});
14411441
execa('unicorns', {windowsHide: false});

lib/async.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,13 @@ const handleAsyncArguments = (rawFile, rawArgs, rawOptions) => {
3232
};
3333

3434
// Prevent passing the `timeout` option directly to `child_process.spawn()`
35-
const handleAsyncOptions = ({timeout, ...options}) => ({...options, timeoutDuration: timeout});
35+
const handleAsyncOptions = ({timeout, signal, cancelSignal, ...options}) => {
36+
if (signal !== undefined) {
37+
throw new TypeError('The "signal" option has been renamed to "cancelSignal" instead.');
38+
}
39+
40+
return {...options, timeoutDuration: timeout, signal: cancelSignal};
41+
};
3642

3743
const spawnProcessAsync = ({file, args, options, command, escapedCommand, stdioStreamsGroups}) => {
3844
let spawned;

lib/stream/exit.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import {once} from 'node:events';
22

33
// If `error` is emitted before `spawn`, `exit` will never be emitted.
4-
// However, `error` might be emitted after `spawn`, e.g. with the `signal` option.
4+
// However, `error` might be emitted after `spawn`, e.g. with the `cancelSignal` option.
55
// In that case, `exit` will still be emitted.
66
// Since the `exit` event contains the signal name, we want to make sure we are listening for it.
77
// This function also takes into account the following unlikely cases:

readme.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,7 @@ This is the preferred method when executing Node.js files.
315315

316316
Same as [`execa()`](#execacommandcommand-options), [`execaCommand()`](#execacommand-command-options), [$\`command\`](#command) but synchronous.
317317

318-
Cannot use the following options: [`all`](#all-2), [`cleanup`](#cleanup), [`buffer`](#buffer), [`detached`](#detached), [`ipc`](#ipc), [`serialization`](#serialization), [`signal`](#signal) and [`lines`](#lines). Also, the [`stdin`](#stdin), [`stdout`](#stdout-1), [`stderr`](#stderr-1), [`stdio`](#stdio-1) and [`input`](#input) options cannot be an array, an iterable or a web stream. Node.js streams [must have a file descriptor](#redirect-a-nodejs-stream-fromto-stdinstdoutstderr) unless the `input` option is used.
318+
Cannot use the following options: [`all`](#all-2), [`cleanup`](#cleanup), [`buffer`](#buffer), [`detached`](#detached), [`ipc`](#ipc), [`serialization`](#serialization), [`cancelSignal`](#cancelsignal) and [`lines`](#lines). Also, the [`stdin`](#stdin), [`stdout`](#stdout-1), [`stderr`](#stderr-1), [`stdio`](#stdio-1) and [`input`](#input) options cannot be an array, an iterable or a web stream. Node.js streams [must have a file descriptor](#redirect-a-nodejs-stream-fromto-stdinstdoutstderr) unless the `input` option is used.
319319

320320
Returns or throws a [`childProcessResult`](#childProcessResult). The [`childProcess`](#childprocess) is not returned: its methods and properties are not available. This includes [`.kill()`](https://nodejs.org/api/child_process.html#subprocesskillsignal), [`.pid`](https://nodejs.org/api/child_process.html#subprocesspid), [`.pipe()`](#pipefile-arguments-options) and the [`.stdin`/`.stdout`/`.stderr`](https://nodejs.org/api/child_process.html#subprocessstdout) streams.
321321

@@ -525,7 +525,7 @@ Whether the process timed out.
525525

526526
Type: `boolean`
527527

528-
Whether the process was canceled using the [`signal`](#signal-1) option.
528+
Whether the process was canceled using the [`cancelSignal`](#cancelsignal) option.
529529

530530
#### isTerminated
531531

@@ -541,7 +541,7 @@ Type: `number | undefined`
541541

542542
The numeric exit code of the process that was run.
543543

544-
This is `undefined` when the process could not be spawned or was terminated by a [signal](#signal-1).
544+
This is `undefined` when the process could not be spawned or was terminated by a [signal](#signal).
545545

546546
#### signal
547547

@@ -850,7 +850,7 @@ Default: `0`
850850

851851
If `timeout` is greater than `0`, the child process will be [terminated](#killsignal) if it runs for longer than that amount of milliseconds.
852852

853-
#### signal
853+
#### cancelSignal
854854

855855
Type: [`AbortSignal`](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal)
856856

@@ -868,7 +868,7 @@ If the child process is terminated but does not exit, forcefully exit it by send
868868
The grace period is 5 seconds by default. This feature can be disabled with `false`.
869869

870870
This works when the child process is terminated by either:
871-
- the [`signal`](#signal-1), [`timeout`](#timeout), [`maxBuffer`](#maxbuffer) or [`cleanup`](#cleanup) option
871+
- the [`cancelSignal`](#cancelsignal), [`timeout`](#timeout), [`maxBuffer`](#maxbuffer) or [`cleanup`](#cleanup) option
872872
- calling [`subprocess.kill()`](https://nodejs.org/api/child_process.html#subprocesskillsignal) with no arguments
873873

874874
This does not work when the child process is terminated by either:
@@ -884,7 +884,7 @@ Type: `string | number`\
884884
Default: `SIGTERM`
885885

886886
Signal used to terminate the child process when:
887-
- using the [`signal`](#signal-1), [`timeout`](#timeout), [`maxBuffer`](#maxbuffer) or [`cleanup`](#cleanup) option
887+
- using the [`cancelSignal`](#cancelsignal), [`timeout`](#timeout), [`maxBuffer`](#maxbuffer) or [`cleanup`](#cleanup) option
888888
- calling [`subprocess.kill()`](https://nodejs.org/api/child_process.html#subprocesskillsignal) with no arguments
889889

890890
This can be either a name (like `"SIGTERM"`) or a number (like `9`).
@@ -973,7 +973,7 @@ console.log(await pRetry(run, {retries: 5}));
973973
import {execa} from 'execa';
974974

975975
const abortController = new AbortController();
976-
const subprocess = execa('node', [], {signal: abortController.signal});
976+
const subprocess = execa('node', [], {cancelSignal: abortController.signal});
977977

978978
setTimeout(() => {
979979
abortController.abort();

test/exit/signal.js renamed to test/exit/cancel.js

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,23 +29,23 @@ test('result.isCanceled is false when abort isn\'t called in sync mode (failure)
2929

3030
test('error.isCanceled is true when abort is used', async t => {
3131
const abortController = new AbortController();
32-
const subprocess = execa('noop.js', {signal: abortController.signal});
32+
const subprocess = execa('noop.js', {cancelSignal: abortController.signal});
3333
abortController.abort();
3434
const {isCanceled} = await t.throwsAsync(subprocess);
3535
t.true(isCanceled);
3636
});
3737

3838
test('error.isCanceled is false when kill method is used', async t => {
3939
const abortController = new AbortController();
40-
const subprocess = execa('noop.js', {signal: abortController.signal});
40+
const subprocess = execa('noop.js', {cancelSignal: abortController.signal});
4141
subprocess.kill();
4242
const {isCanceled} = await t.throwsAsync(subprocess);
4343
t.false(isCanceled);
4444
});
4545

4646
test('calling abort is considered a signal termination', async t => {
4747
const abortController = new AbortController();
48-
const subprocess = execa('forever.js', {signal: abortController.signal});
48+
const subprocess = execa('forever.js', {cancelSignal: abortController.signal});
4949
await once(subprocess, 'spawn');
5050
abortController.abort();
5151
const {isTerminated, signal} = await t.throwsAsync(subprocess);
@@ -55,14 +55,14 @@ test('calling abort is considered a signal termination', async t => {
5555

5656
test('calling abort throws an error with message "Command was canceled"', async t => {
5757
const abortController = new AbortController();
58-
const subprocess = execa('noop.js', {signal: abortController.signal});
58+
const subprocess = execa('noop.js', {cancelSignal: abortController.signal});
5959
abortController.abort();
6060
await t.throwsAsync(subprocess, {message: /Command was canceled/});
6161
});
6262

6363
test('calling abort twice should show the same behaviour as calling it once', async t => {
6464
const abortController = new AbortController();
65-
const subprocess = execa('noop.js', {signal: abortController.signal});
65+
const subprocess = execa('noop.js', {cancelSignal: abortController.signal});
6666
abortController.abort();
6767
abortController.abort();
6868
const {isCanceled} = await t.throwsAsync(subprocess);
@@ -71,8 +71,15 @@ test('calling abort twice should show the same behaviour as calling it once', as
7171

7272
test('calling abort on a successfully completed process does not make result.isCanceled true', async t => {
7373
const abortController = new AbortController();
74-
const subprocess = execa('noop.js', {signal: abortController.signal});
74+
const subprocess = execa('noop.js', {cancelSignal: abortController.signal});
7575
const result = await subprocess;
7676
abortController.abort();
7777
t.false(result.isCanceled);
7878
});
79+
80+
test('Throws when using the former "signal" option name', t => {
81+
const abortController = new AbortController();
82+
t.throws(() => {
83+
execa('noop.js', {signal: abortController.signal});
84+
}, {message: /renamed to "cancelSignal"/});
85+
});

test/exit/kill.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ if (isWindows) {
9898

9999
test('`forceKillAfterDelay` works with the "signal" option', async t => {
100100
const abortController = new AbortController();
101-
const subprocess = spawnNoKillableSimple({signal: abortController.signal});
101+
const subprocess = spawnNoKillableSimple({cancelSignal: abortController.signal});
102102
await once(subprocess, 'spawn');
103103
abortController.abort();
104104
const {isTerminated, signal, isCanceled} = await t.throwsAsync(subprocess);
@@ -280,7 +280,7 @@ test('child process errors are handled after spawn', async t => {
280280

281281
test('child process double errors are handled after spawn', async t => {
282282
const abortController = new AbortController();
283-
const subprocess = execa('forever.js', {signal: abortController.signal});
283+
const subprocess = execa('forever.js', {cancelSignal: abortController.signal});
284284
await once(subprocess, 'spawn');
285285
const error = new Error('test');
286286
subprocess.emit('error', error);

0 commit comments

Comments
 (0)