From ca2e8130351a40d64e162117cc61179a7f756609 Mon Sep 17 00:00:00 2001 From: ehmicky Date: Tue, 4 Jun 2024 23:44:46 +0100 Subject: [PATCH] Improve documentation of Execa methods (#1115) --- docs/api.md | 101 +++++++++++++++++++++------------- docs/errors.md | 4 +- docs/execution.md | 4 +- docs/pipe.md | 2 +- docs/scripts.md | 2 +- docs/typescript.md | 8 +-- types/methods/command.d.ts | 12 +++- types/methods/main-async.d.ts | 2 +- types/methods/main-sync.d.ts | 8 ++- types/methods/node.d.ts | 4 +- types/methods/script.d.ts | 4 +- 11 files changed, 96 insertions(+), 55 deletions(-) diff --git a/docs/api.md b/docs/api.md index 6a82a51c15..6049ebfcae 100644 --- a/docs/api.md +++ b/docs/api.md @@ -6,7 +6,7 @@ # 📔 API reference -This lists all available [methods](#methods) and their [options](#options). This also describes the properties of the [subprocess](#subprocess), [result](#result) and [error](#execaerror) they return. +This lists all available [methods](#methods) and their [options](#options-1). This also describes the properties of the [subprocess](#subprocess), [result](#result) and [error](#execaerror) they return. ## Methods @@ -14,74 +14,99 @@ This lists all available [methods](#methods) and their [options](#options). This `file`: `string | URL`\ `arguments`: `string[]`\ -`options`: [`Options`](#options)\ +`options`: [`Options`](#options-1)\ _Returns_: [`ResultPromise`](#return-value) Executes a command using `file ...arguments`. More info on the [syntax](execution.md#array-syntax) and [escaping](escaping.md#array-syntax). -### execa\`command\` -### execa(options)\`command\` +### $(file, arguments?, options?) -`command`: `string`\ -`options`: [`Options`](#options)\ +`file`: `string | URL`\ +`arguments`: `string[]`\ +`options`: [`Options`](#options-1)\ _Returns_: [`ResultPromise`](#return-value) -Executes a command. `command` is a [template string](execution.md#template-string-syntax) that includes both the `file` and its `arguments`. +Same as [`execa()`](#execafile-arguments-options) but using [script-friendly default options](scripts.md#script-files). -More info on the [syntax](execution.md#template-string-syntax) and [escaping](escaping.md#template-string-syntax). +This is the preferred method when executing multiple commands in a script file. -### execa(options) +[More info.](scripts.md) -`options`: [`Options`](#options)\ -_Returns_: [`execa`](#execafile-arguments-options) +### execaNode(scriptPath, arguments?, options?) -Returns a new instance of Execa but with different default [`options`](#options). Consecutive calls are merged to previous ones. +`scriptPath`: `string | URL`\ +`arguments`: `string[]`\ +`options`: [`Options`](#options-1)\ +_Returns_: [`ResultPromise`](#return-value) -[More info.](execution.md#globalshared-options) +Same as [`execa()`](#execafile-arguments-options) but using the [`node: true`](#optionsnode) option. +Executes a Node.js file using `node scriptPath ...arguments`. + +This is the preferred method when executing Node.js files. + +[More info.](node.md) ### execaSync(file, arguments?, options?) -### execaSync\`command\` +### $.sync(file, arguments?, options?) +### $.s(file, arguments?, options?) +`file`: `string | URL`\ +`arguments`: `string[]`\ +`options`: [`SyncOptions`](#options-1)\ _Returns_: [`SyncResult`](#return-value) -Same as [`execa()`](#execafile-arguments-options) but synchronous. +Same as [`execa()`](#execafile-arguments-options) and [`$`](#file-arguments-options) but synchronous. -Returns or throws a subprocess [`result`](#result). The [`subprocess`](#subprocess) is not returned: its methods and properties are not available. +Returns a subprocess [`result`](#result) or throws an [`error`](#execasyncerror). The [`subprocess`](#subprocess) is not returned: its methods and properties are not available. + +Those methods are discouraged as they hold the CPU and lack multiple features. [More info.](execution.md#synchronous-execution) -### $(file, arguments?, options?) +### execa\`command\` +### $\`command\` +### execaNode\`command\` +### execaSync\`command\` +### $.sync\`command\` +### $.s\`command\` -`file`: `string | URL`\ -`arguments`: `string[]`\ -`options`: [`Options`](#options)\ -_Returns_: [`ResultPromise`](#return-value) +`command`: `string`\ +_Returns_: [`ResultPromise`](#return-value), [`SyncResult`](#return-value) -Same as [`execa()`](#execafile-arguments-options) but using [script-friendly default options](scripts.md#script-files). +Same as [`execa()`](#execafile-arguments-options), [`$()`](#file-arguments-options), [`execaNode()`](#execanodescriptpath-arguments-options) and [`execaSync()`](#execasyncfile-arguments-options) but using a [template string](execution.md#template-string-syntax). `command` includes both the `file` and its `arguments`. -Just like `execa()`, this can use the [template string syntax](execution.md#template-string-syntax) or [bind options](execution.md#globalshared-options). It can also be [run synchronously](#execasyncfile-arguments-options) using `$.sync()` or `$.s()`. +More info on the [syntax](execution.md#template-string-syntax) and [escaping](escaping.md#template-string-syntax). -This is the preferred method when executing multiple commands in a script file. +### execa(options)\`command\` +### $(options)\`command\` +### execaNode(options)\`command\` +### execaSync(options)\`command\` +### $.sync(options)\`command\` +### $.s(options)\`command\` -[More info.](scripts.md) +`command`: `string`\ +`options`: [`Options`](#options-1), [`SyncOptions`](#options-1)\ +_Returns_: [`ResultPromise`](#return-value), [`SyncResult`](#return-value) -### execaNode(scriptPath, arguments?, options?) +Same as [```execa`command` ```](#execacommand) but with [options](#options-1). -`scriptPath`: `string | URL`\ -`arguments`: `string[]`\ -`options`: [`Options`](#options)\ -_Returns_: [`ResultPromise`](#return-value) +[More info.](execution.md#template-string-syntax) -Same as [`execa()`](#execafile-arguments-options) but using the [`node: true`](#optionsnode) option. -Executes a Node.js file using `node scriptPath ...arguments`. +### execa(options) +### $(options) +### execaNode(options) +### execaSync(options) +### $.sync(options) +### $.s(options) -Just like `execa()`, this can use the [template string syntax](execution.md#template-string-syntax) or [bind options](execution.md#globalshared-options). +`options`: [`Options`](#options-1), [`SyncOptions`](#options-1)\ +_Returns_: [`ExecaMethod`](#execafile-arguments-options), [`ExecaScriptMethod`](#file-arguments-options), [`ExecaNodeMethod`](#execanodescriptpath-arguments-options), [`ExecaSyncMethod`](#execasyncfile-arguments-options), [`ExecaScriptSyncMethod`](#syncfile-arguments-options) -This is the preferred method when executing Node.js files. +Returns a new instance of those methods but with different default [`options`](#options-1). Consecutive calls are merged to previous ones. -[More info.](node.md) +[More info.](execution.md#globalshared-options) ### parseCommandString(command) @@ -221,12 +246,12 @@ Same as [`subprocess[Symbol.asyncIterator]`](#subprocesssymbolasynciterator) exc `file`: `string | URL`\ `arguments`: `string[]`\ -`options`: [`Options`](#options) and [`PipeOptions`](#pipeoptions)\ +`options`: [`Options`](#options-1) and [`PipeOptions`](#pipeoptions)\ _Returns_: [`Promise`](#result) [Pipe](https://nodejs.org/api/stream.html#readablepipedestination-options) the subprocess' [`stdout`](#subprocessstdout) to a second Execa subprocess' [`stdin`](#subprocessstdin). This resolves with that second subprocess' [result](#result). If either subprocess is rejected, this is rejected with that subprocess' [error](#execaerror) instead. -This follows the same syntax as [`execa(file, arguments?, options?)`](#execafile-arguments-options) except both [regular options](#options) and [pipe-specific options](#pipeoptions) can be specified. +This follows the same syntax as [`execa(file, arguments?, options?)`](#execafile-arguments-options) except both [regular options](#options-1) and [pipe-specific options](#pipeoptions) can be specified. [More info.](pipe.md#array-syntax) @@ -234,7 +259,7 @@ This follows the same syntax as [`execa(file, arguments?, options?)`](#execafile ### subprocess.pipe(options)\`command\` `command`: `string`\ -`options`: [`Options`](#options) and [`PipeOptions`](#pipeoptions)\ +`options`: [`Options`](#options-1) and [`PipeOptions`](#pipeoptions)\ _Returns_: [`Promise`](#result) Like [`subprocess.pipe(file, arguments?, options?)`](#subprocesspipefile-arguments-options) but using a [`command` template string](scripts.md#piping-stdout-to-another-command) instead. This follows the same syntax as `execa` [template strings](execution.md#template-string-syntax). diff --git a/docs/errors.md b/docs/errors.md index deba2ba6ea..d5eb5fe349 100644 --- a/docs/errors.md +++ b/docs/errors.md @@ -59,7 +59,7 @@ The subprocess can fail for other reasons. Some of them can be detected using a Otherwise, the subprocess failed because either: - An exception was thrown in a [stream](streams.md) or [transform](transform.md). - The command's executable file was not found. -- An invalid [option](api.md#options) was passed. +- An invalid [option](api.md#options-1) was passed. - There was not enough memory or too many subprocesses. ```js @@ -82,7 +82,7 @@ For better [debugging](debugging.md), [`error.message`](api.md#errormessage) inc [`error.shortMessage`](api.md#errorshortmessage) is the same but without `stdout`, `stderr` nor IPC messages. -[`error.originalMessage`](api.md#errororiginalmessage) is the same but also without the command. This exists only in specific instances, such as when calling [`subprocess.kill(error)`](termination.md#error-message-and-stack-trace), using the [`cancelSignal`](termination.md#canceling) option, passing an invalid command or [option](api.md#options), or throwing an exception in a [stream](streams.md) or [transform](transform.md). +[`error.originalMessage`](api.md#errororiginalmessage) is the same but also without the command. This exists only in specific instances, such as when calling [`subprocess.kill(error)`](termination.md#error-message-and-stack-trace), using the [`cancelSignal`](termination.md#canceling) option, passing an invalid command or [option](api.md#options-1), or throwing an exception in a [stream](streams.md) or [transform](transform.md). ```js try { diff --git a/docs/execution.md b/docs/execution.md index 76cdc66d2f..27a4d4b66c 100644 --- a/docs/execution.md +++ b/docs/execution.md @@ -100,7 +100,7 @@ await execa({env: {TASK_NAME: 'build'}})`echo $TASK_NAME`; ## Options -[Options](api.md#options) can be passed to influence the execution's behavior. +[Options](api.md#options-1) can be passed to influence the execution's behavior. ### Array syntax @@ -144,7 +144,7 @@ const {stdout} = await execa`npm run build`; ### Synchronous execution -[Every method](api.md#methods) can be called synchronously by appending `Sync` to the method's name. The [`result`](api.md#result) is returned without needing to `await`. The [`subprocess`](#subprocess) is not returned: its methods and properties are not available. +[`execaSync()`](api.md#execasyncfile-arguments-options) and [`$.sync()`](api.md#syncfile-arguments-options) return the [`result`](api.md#result) without needing to `await`. The [`subprocess`](#subprocess) is not returned: its methods and properties are not available. ```js import {execaSync} from 'execa'; diff --git a/docs/pipe.md b/docs/pipe.md index 41ceecfd96..2d80a6a9a5 100644 --- a/docs/pipe.md +++ b/docs/pipe.md @@ -35,7 +35,7 @@ const {stdout} = await execa`npm run build` ## Options -[Options](api.md#options) can be passed to either the source or the destination subprocess. Some [pipe-specific options](api.md#pipeoptions) can also be set by the destination subprocess. +[Options](api.md#options-1) can be passed to either the source or the destination subprocess. Some [pipe-specific options](api.md#pipeoptions) can also be set by the destination subprocess. ```js const {stdout} = await execa('npm', ['run', 'build'], subprocessOptions) diff --git a/docs/scripts.md b/docs/scripts.md index 04ae6702e6..a68c3d2f2c 100644 --- a/docs/scripts.md +++ b/docs/scripts.md @@ -35,7 +35,7 @@ await $`mkdir /tmp/${directoryName}`; ## Template string syntax -Just like [`execa`](api.md#execafile-arguments-options), [`$`](api.md#file-arguments-options) can use either the [template string syntax](execution.md#template-string-syntax) or the [array syntax](execution.md#array-syntax). +Just like [`execa`](api.md#execacommand), [`$`](api.md#command) can use either the [template string syntax](execution.md#template-string-syntax) or the [array syntax](execution.md#array-syntax). Conversely, the template string syntax can be used outside of script files: `$` is not required to use that syntax. For example, `execa` [can use it too](execution.md#template-string-syntax). diff --git a/docs/typescript.md b/docs/typescript.md index 22287f455d..49a231a08f 100644 --- a/docs/typescript.md +++ b/docs/typescript.md @@ -8,7 +8,7 @@ ## Available types -The following types can be imported: [`ResultPromise`](api.md#return-value), [`Subprocess`](api.md#subprocess), [`Result`](api.md#result), [`ExecaError`](api.md#execaerror), [`Options`](api.md#options), [`StdinOption`](api.md#optionsstdin), [`StdoutStderrOption`](api.md#optionsstdout), [`TemplateExpression`](api.md#execacommand) and [`Message`](api.md#subprocesssendmessagemessage-sendmessageoptions). +The following types can be imported: [`ResultPromise`](api.md#return-value), [`Subprocess`](api.md#subprocess), [`Result`](api.md#result), [`ExecaError`](api.md#execaerror), [`Options`](api.md#options-1), [`StdinOption`](api.md#optionsstdin), [`StdoutStderrOption`](api.md#optionsstdout), [`TemplateExpression`](api.md#execacommand) and [`Message`](api.md#subprocesssendmessagemessage-sendmessageoptions). ```ts import { @@ -35,7 +35,7 @@ const message: Message = 'hello world'; try { const subprocess: ResultPromise = execa(options)`npm run ${task}`; - await subprocess.sendMessage(message); + await subprocess.sendMessage?.(message); const result: Result = await subprocess; console.log(result.stdout); } catch (error) { @@ -47,7 +47,7 @@ try { ## Synchronous execution -Their [synchronous](#synchronous-execution) counterparts are [`SyncResult`](api.md#result), [`ExecaSyncError`](api.md#execasyncerror), [`SyncOptions`](api.md#options), [`StdinSyncOption`](api.md#optionsstdin), [`StdoutStderrSyncOption`](api.md#optionsstdout) and [`TemplateExpression`](api.md#execacommand). +Their [synchronous](#synchronous-execution) counterparts are [`SyncResult`](api.md#result), [`ExecaSyncError`](api.md#execasyncerror), [`SyncOptions`](api.md#options-1), [`StdinSyncOption`](api.md#optionsstdin), [`StdoutStderrSyncOption`](api.md#optionsstdout) and [`TemplateExpression`](api.md#execacommand). ```ts import { @@ -139,7 +139,7 @@ ReferenceError: exports is not defined in ES module scope ### Strict unions -Several options are typed as unions. For example, the [`serialization`](api.md#optionsserialization) option's type is `'advanced' | 'json'`, not `string`. Therefore the following example fails: +Several options are typed as unions of strings: [`stdin`](api.md#optionsstdin), [`stdout`](api.md#optionsstdout), [`stderr`](api.md#optionsstderr), [`encoding`](api.md#optionsencoding), [`serialization`](api.md#optionsserialization), [`verbose`](api.md#optionsverbose), [`killSignal`](api.md#optionskillsignal), [`from`](api.md#pipeoptionsfrom) and [`to`](api.md#pipeoptionsto). For example, the `serialization` option's type is `'advanced' | 'json'`, not `string`. Therefore the following example fails: ```ts import {execa} from 'execa'; diff --git a/types/methods/command.d.ts b/types/methods/command.d.ts index 55dd132cd6..58fd0441d2 100644 --- a/types/methods/command.d.ts +++ b/types/methods/command.d.ts @@ -6,9 +6,11 @@ import type {SimpleTemplateString} from './template.js'; /** Executes a command. `command` is a string that includes both the `file` and its `arguments`. -This is only intended for very specific cases, such as a REPL. This should be avoided otherwise. +When `command` is a template string, it includes both the `file` and its `arguments`. + +`execaCommand(options)` can be used to return a new instance of this method but with different default `options`. Consecutive calls are merged to previous ones. -Just like `execa()`, this can bind options. It can also be run synchronously using `execaCommandSync()`. +This is only intended for very specific cases, such as a REPL. This should be avoided otherwise. @param command - The program/script to execute and its arguments. @returns A `ResultPromise` that is both: @@ -50,7 +52,11 @@ type ExecaCommandArray = /** Same as `execaCommand()` but synchronous. -Returns or throws a subprocess `result`. The `subprocess` is not returned: its methods and properties are not available. +When `command` is a template string, it includes both the `file` and its `arguments`. + +`execaCommandSync(options)` can be used to return a new instance of this method but with different default `options`. Consecutive calls are merged to previous ones. + +Returns a subprocess `result` or throws an `error`. The `subprocess` is not returned: its methods and properties are not available. @param command - The program/script to execute and its arguments. @returns `SyncResult` diff --git a/types/methods/main-async.d.ts b/types/methods/main-async.d.ts index 148e848d35..096ffab55f 100644 --- a/types/methods/main-async.d.ts +++ b/types/methods/main-async.d.ts @@ -7,7 +7,7 @@ Executes a command using `file ...arguments`. When `command` is a template string, it includes both the `file` and its `arguments`. -`execa(options)` can be used to return a new instance of Execa but with different default `options`. Consecutive calls are merged to previous ones. +`execa(options)` can be used to return a new instance of this method but with different default `options`. Consecutive calls are merged to previous ones. @param file - The program/script to execute, as a string or file URL @param arguments - Arguments to pass to `file` on execution. diff --git a/types/methods/main-sync.d.ts b/types/methods/main-sync.d.ts index b40d0c8f29..d8a5bbf99b 100644 --- a/types/methods/main-sync.d.ts +++ b/types/methods/main-sync.d.ts @@ -5,7 +5,13 @@ import type {TemplateString} from './template.js'; /** Same as `execa()` but synchronous. -Returns or throws a subprocess `result`. The `subprocess` is not returned: its methods and properties are not available. +Returns a subprocess `result` or throws an `error`. The `subprocess` is not returned: its methods and properties are not available. + +When `command` is a template string, it includes both the `file` and its `arguments`. + +`execaSync(options)` can be used to return a new instance of this method but with different default `options`. Consecutive calls are merged to previous ones. + +This method is discouraged as it holds the CPU and lacks multiple features. @param file - The program/script to execute, as a string or file URL @param arguments - Arguments to pass to `file` on execution. diff --git a/types/methods/node.d.ts b/types/methods/node.d.ts index b92f654995..59f9e3d32b 100644 --- a/types/methods/node.d.ts +++ b/types/methods/node.d.ts @@ -6,7 +6,9 @@ import type {TemplateString} from './template.js'; Same as `execa()` but using the `node: true` option. Executes a Node.js file using `node scriptPath ...arguments`. -Just like `execa()`, this can use the template string syntax or bind options. +When `command` is a template string, it includes both the `file` and its `arguments`. + +`execaNode(options)` can be used to return a new instance of this method but with different default `options`. Consecutive calls are merged to previous ones. This is the preferred method when executing Node.js files. diff --git a/types/methods/script.d.ts b/types/methods/script.d.ts index c9ba4f1c89..29fcf0e977 100644 --- a/types/methods/script.d.ts +++ b/types/methods/script.d.ts @@ -11,7 +11,9 @@ import type {TemplateString} from './template.js'; /** Same as `execa()` but using script-friendly default options. -Just like `execa()`, this can use the template string syntax or bind options. It can also be run synchronously using `$.sync()` or `$.s()`. +When `command` is a template string, it includes both the `file` and its `arguments`. + +`$(options)` can be used to return a new instance of this method but with different default `options`. Consecutive calls are merged to previous ones. This is the preferred method when executing multiple commands in a script file.