From 81a3940df6c8305bf787a11ea91df9ab51886e1c Mon Sep 17 00:00:00 2001 From: Anton Golub Date: Fri, 31 Jan 2025 00:01:13 +0300 Subject: [PATCH] docs: describe `$.defaults` and shell setup helpers, mention asyncIterator, align headers formatting (#1091) --- docs/api.md | 100 ++++++++++++++++++++++++++++------------ docs/cli.md | 35 +++++++------- docs/configuration.md | 51 +++++++++++++++----- docs/process-promise.md | 22 +++++++-- 4 files changed, 147 insertions(+), 61 deletions(-) diff --git a/docs/api.md b/docs/api.md index cfc3c88c92..a1559fb24f 100644 --- a/docs/api.md +++ b/docs/api.md @@ -1,6 +1,6 @@ # API Reference -## $.sync +## `$.sync` Zx provides both synchronous and asynchronous command executions, returns [`ProcessOutput`](./process-output) or [`ProcessPromise`](./process-promise) respectively. ```js @@ -8,7 +8,7 @@ const list = await $`ls -la` const dir = $.sync`pwd` ``` -## $({...}) +## `$({...})` `$` object holds the default zx [configuration](./configuration), which is used for all execution. To specify a custom preset use `$` as factory: @@ -36,7 +36,7 @@ const $3 = $({ sync: true })({ nothrow: true }) assert.equal($3`exit 3`.exitCode, 3) ``` -### $({input}) +### `$({input})` The input option passes the specified `stdin` to the command. @@ -48,7 +48,7 @@ const p4 = $({ input: p3 })`cat` const p5 = $({ input: await p3 })`cat` ``` -### $({signal}) +### `$({signal})` The signal option makes the process abortable. @@ -59,7 +59,7 @@ const p = $({ signal })`sleep 9999` setTimeout(() => signal.abort('reason'), 1000) ``` -### $({timeout}) +### `$({timeout})` The timeout option makes the process autokillable after the specified delay. @@ -97,8 +97,9 @@ interface Options { halt: boolean } ``` +See also [Configuration](./configuration). -## cd() +## `cd()` Changes the current working directory. @@ -116,7 +117,7 @@ cd(await $`mktemp -d`) > ⚠️ `cd` invokes `process.chdir()` internally, so it does affect the global context. To keep `process.cwd()` in sync with separate `$` calls enable [syncProcessCwd()](#syncprocesscwd) hook. -## fetch() +## `fetch()` A wrapper around the [node-fetch-native](https://www.npmjs.com/package/node-fetch-native) package. @@ -125,7 +126,7 @@ package. const resp = await fetch('https://medv.io') ``` -## question() +## `question()` A wrapper around the [readline](https://nodejs.org/api/readline.html) package. @@ -133,7 +134,7 @@ A wrapper around the [readline](https://nodejs.org/api/readline.html) package. const bear = await question('What kind of bear is best? ') ``` -## sleep() +## `sleep()` A wrapper around the `setTimeout` function. @@ -141,7 +142,7 @@ A wrapper around the `setTimeout` function. await sleep(1000) ``` -## echo() +## `echo()` A `console.log()` alternative which can take [ProcessOutput](#processoutput). @@ -153,7 +154,7 @@ echo`Current branch is ${branch}.` echo('Current branch is', branch) ``` -## stdin() +## `stdin()` Returns the stdin as a string. @@ -161,7 +162,7 @@ Returns the stdin as a string. const content = JSON.parse(await stdin()) ``` -## within() +## `within()` Creates a new async context. @@ -195,7 +196,7 @@ const version = await within(async () => { echo(version) // => v16.20.0 ``` -## syncProcessCwd() +## `syncProcessCwd()` Keeps the `process.cwd()` in sync with the internal `$` current working directory if it is changed via [cd()](#cd). @@ -208,7 +209,7 @@ syncProcessCwd(false) // pass false to disable the hook > This feature is disabled by default because of performance overhead. -## retry() +## `retry()` Retries a callback for a few times. Will return after the first successful attempt, or will throw after specifies attempts count. @@ -223,7 +224,7 @@ const p = await retry(20, '1s', () => $`curl https://medv.io`) const p = await retry(30, expBackoff(), () => $`curl https://medv.io`) ``` -## spinner() +## `spinner()` Starts a simple CLI spinner. @@ -236,7 +237,7 @@ await spinner('working...', () => $`sleep 99`) And it's disabled for `CI` by default. -## glob() +## `glob()` The [globby](https://github.com/sindresorhus/globby) package. @@ -244,7 +245,7 @@ The [globby](https://github.com/sindresorhus/globby) package. const packages = await glob(['package.json', 'packages/*/package.json']) ``` -## which() +## `which()` The [which](https://github.com/npm/node-which) package. @@ -258,7 +259,7 @@ If nothrow option is used, returns null if not found. const pathOrNull = await which('node', { nothrow: true }) ``` -## ps() +## `ps` The [@webpod/ps](https://github.com/webpod/ps) package to provide a cross-platform way to list processes. @@ -269,7 +270,7 @@ const children = await ps.tree({ pid: 123 }) const fulltree = await ps.tree({ pid: 123, recursive: true }) ``` -## kill() +## `kill()` A process killer. @@ -278,7 +279,7 @@ await kill(123) await kill(123, 'SIGKILL') ``` -## tmpdir() +## `tmpdir()` Creates a temporary directory. @@ -287,7 +288,7 @@ t1 = tmpdir() // /os/based/tmp/zx-1ra1iofojgg/ t2 = tmpdir('foo') // /os/based/tmp/zx-1ra1iofojgg/foo/ ``` -## tmpfile() +## `tmpfile()` Temp file factory. @@ -298,7 +299,7 @@ f3 = tmpfile('f3.txt', 'string or buffer') f4 = tmpfile('f4.sh', 'echo "foo"', 0o744) // executable ``` -## minimist +## `minimist` The [minimist](https://www.npmjs.com/package/minimist) package. @@ -306,7 +307,7 @@ The [minimist](https://www.npmjs.com/package/minimist) package. const argv = minimist(process.argv.slice(2), {}) ``` -## argv +## `argv` A minimist-parsed version of the `process.argv` as `argv`. @@ -330,7 +331,7 @@ const myCustomArgv = minimist(process.argv.slice(2), { }) ``` -## chalk +## `chalk` The [chalk](https://www.npmjs.com/package/chalk) package. @@ -338,7 +339,7 @@ The [chalk](https://www.npmjs.com/package/chalk) package. console.log(chalk.blue('Hello world!')) ``` -## fs +## `fs` The [fs-extra](https://www.npmjs.com/package/fs-extra) package. @@ -346,7 +347,7 @@ The [fs-extra](https://www.npmjs.com/package/fs-extra) package. const {version} = await fs.readJson('./package.json') ``` -## os +## `os` The [os](https://nodejs.org/api/os.html) package. @@ -354,7 +355,7 @@ The [os](https://nodejs.org/api/os.html) package. await $`cd ${os.homedir()} && mkdir example` ``` -## path +## `path` The [path](https://nodejs.org/api/path.html) package. @@ -362,7 +363,7 @@ The [path](https://nodejs.org/api/path.html) package. await $`mkdir ${path.join(basedir, 'output')}` ``` -## yaml +## `yaml` The [yaml](https://www.npmjs.com/package/yaml) package. @@ -370,7 +371,8 @@ The [yaml](https://www.npmjs.com/package/yaml) package. console.log(YAML.parse('foo: bar').foo) ``` -## dotenv +## `dotenv` + The [envapi](https://www.npmjs.com/package/envapi) package. An API to interact with environment vars in [dotenv](https://www.npmjs.com/package/dotenv) format. @@ -388,3 +390,43 @@ await $({ env })`echo $FOO`.stdout // BAR dotenv.config('.env') process.env.FOO // BAR ``` + +## `quote()` + +Default bash quoting function. + +```js +quote("$FOO") // "$'$FOO'" +``` + +## `quotePowerShell()` + +PowerShell specific quoting. + +```js +quotePowerShell("$FOO") // "'$FOO'" +``` + +## `useBash()` + +Enables bash preset: sets `$.shell` to `bash` and `$.quote` to `quote`. + +```js +useBash() +``` + +## `usePowerShell()` + +Switches to PowerShell. Applies the `quotePowerShell` for quoting. + +```js +usePowerShell() +``` + +## `usePwsh()` + +Sets pwsh (PowerShell v7+) as `$.shell` default. + +```js +usePwsh() +``` diff --git a/docs/cli.md b/docs/cli.md index ca558299ad..729693fa03 100644 --- a/docs/cli.md +++ b/docs/cli.md @@ -11,7 +11,8 @@ zx script.mjs If script does not have a file extension (like `.git/hooks/pre-commit`), zx assumes that it is an [ESM](https://nodejs.org/api/modules.html#modules_module_createrequire_filename) -module. +module unless the `--ext` option is specified. + ```bash zx docs/markdown.md @@ -36,7 +37,7 @@ await $`pwd` EOF ``` -## --eval +## `--eval` Evaluate the following argument as a script. @@ -44,10 +45,10 @@ Evaluate the following argument as a script. cat package.json | zx --eval 'const v = JSON.parse(await stdin()).version; echo(v)' ``` -## --repl +## `--repl` Starts zx in [REPL](https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop) mode. -## --install +## `--install` ```js // script.mjs: @@ -70,7 +71,7 @@ the import. import sh from 'tinysh' // @^1 ``` -## --registry +## `--registry` By default, `zx` uses `https://registry.npmjs.org` as a registry. Customize if needed. @@ -78,15 +79,15 @@ By default, `zx` uses `https://registry.npmjs.org` as a registry. Customize if n zx --registry=https://registry.yarnpkg.com script.mjs ``` -## --quiet +## `--quiet` Suppress any outputs. -## --verbose +## `--verbose` Enable verbose mode. -## --shell +## `--shell` Specify a custom shell binary. @@ -94,7 +95,7 @@ Specify a custom shell binary. zx --shell=/bin/bash script.mjs ``` -## --prefer-local, -l +## `--prefer-local, -l` Prefer locally installed packages bins. @@ -102,7 +103,7 @@ Prefer locally installed packages bins. zx --shell=/bin/bash script.mjs ``` -## --prefix & --postfix +## `--prefix & --postfix` Attach a command to the beginning or the end of every command. @@ -110,7 +111,7 @@ Attach a command to the beginning or the end of every command. zx --prefix='echo foo;' --postfix='; echo bar' script.mjs ``` -## --cwd +## `--cwd` Set the current working directory. @@ -118,7 +119,7 @@ Set the current working directory. zx --cwd=/foo/bar script.mjs ``` -## --env +## `--env` Specify an env file. ```bash @@ -128,15 +129,15 @@ zx --env=/path/to/some.env script.mjs When `cwd` option is specified, it will be used as base path: `--cwd='/foo/bar' --env='../.env'` → `/foo/.env` -## --ext +## `--ext` Override the default (temp) script extension. Default is `.mjs`. -## --version, -v +## `--version, -v` Print the current `zx` version. -## --help, -h +## `--help, -h` Print help notes. @@ -156,13 +157,13 @@ steps: ZX_SHELL: '/bin/bash' ``` -## __filename & __dirname +## `__filename & __dirname` In [ESM](https://nodejs.org/api/esm.html) modules, Node.js does not provide `__filename` and `__dirname` globals. As such globals are really handy in scripts, zx provides these for use in `.mjs` files (when using the `zx` executable). -## require() +## `require()` In [ESM](https://nodejs.org/api/modules.html#modules_module_createrequire_filename) modules, the `require()` function is not defined. diff --git a/docs/configuration.md b/docs/configuration.md index 70338bad01..ec6e81760a 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -1,6 +1,6 @@ # Configuration -## $.shell +## `$.shell` Specifies what shell is used. Default is `which bash`. @@ -10,13 +10,13 @@ $.shell = '/usr/bin/bash' Or use a CLI argument: `--shell=/bin/bash` -## $.spawn +## `$.spawn` Specifies a `spawn` api. Defaults to `require('child_process').spawn`. To override a sync API implementation, set `$.spawnSync` correspondingly. -## $.prefix +## `$.prefix` Specifies the command that will be prefixed to all commands run. @@ -24,7 +24,7 @@ Default is `set -euo pipefail;`. Or use a CLI argument: `--prefix='set -e;'` -## $.postfix +## `$.postfix` Like a `$.prefix`, but for the end of the command. @@ -32,7 +32,7 @@ Like a `$.prefix`, but for the end of the command. $.postfix = '; exit $LastExitCode' // for PowerShell compatibility ``` -## $.preferLocal +## `$.preferLocal` Specifies whether to prefer `node_modules/.bin` located binaries over globally system installed ones. @@ -49,12 +49,12 @@ $.preferLocal = '/some/to/bin' $.preferLocal = ['/path/to/bin', '/another/path/bin'] ``` -## $.quote +## `$.quote` Specifies a function for escaping special characters during command substitution. -## $.verbose +## `$.verbose` Specifies verbosity. Default is `false`. @@ -63,26 +63,26 @@ outputs. Or use the CLI argument: `--verbose` to set `true`. -## $.quiet +## `$.quiet` Suppresses all output. Default is `false`. Via CLI argument: `--quiet` sets `$.quiet = true`. -## $.env +## `$.env` Specifies an environment variables map. Defaults to `process.env`. -## $.cwd +## `$.cwd` Specifies a current working directory of all processes created with the `$`. The [cd()](#cd) func changes only `process.cwd()` and if no `$.cwd` specified, all `$` processes use `process.cwd()` by default (same as `spawn` behavior). -## $.log +## `$.log` Specifies a [logging function](src/core.ts). @@ -101,7 +101,7 @@ $.log = (entry: LogEntry) => { } ``` -## $.timeout +## `$.timeout` Specifies a timeout for the command execution. @@ -111,3 +111,30 @@ $.timeoutSignal= 'SIGKILL' await $`sleep 999` ``` + +## `$.defaults` + +Holds the default configuration values. They will be used if the corresponding +`$` options are not specified. + +```ts +$.defaults = { + cwd: process.cwd(), + env: process.env, + verbose: false, + quiet: false, + sync: false, + shell: true, + prefix: 'set -euo pipefail;', // for bash + postfix: '; exit $LastExitCode', // for powershell + nothrow: false, + stdio: 'pipe', // equivalent to ['pipe', 'pipe', 'pipe'] + detached: false, + preferLocal: false, + spawn: childProcess.spawn, + spawnSync: childProcess.spawnSync, + log: $.log, + killSignal: 'SIGTERM', + timeoutSignal: 'SIGTERM' +} +``` diff --git a/docs/process-promise.md b/docs/process-promise.md index 8e3d95db37..4f31cecceb 100644 --- a/docs/process-promise.md +++ b/docs/process-promise.md @@ -76,6 +76,17 @@ await p.lines() // ['foo', 'bar'] await $`echo '{"foo": "bar"}'`.json() // {foo: 'bar'} ``` +## `[Symbol.asyncIterator]` + +Returns an async iterator of the stdout process. + +```js +const p = $`echo "Line1\nLine2\nLine3"` +for await (const line of p) { + console.log() +} +``` + ## `pipe()` Redirects the output of the process. @@ -245,13 +256,18 @@ p.abort('reason') ``` ## `stdio()` +Specifies a standard input-output for the process. -Specifies a stdio for the process. +```js +const h$ = $({halt: true}) +const p1 = h$`read`.stdio('inherit', 'pipe', null).run() +const p2 = h$`read`.stdio('pipe').run() // sets ['pipe', 'pipe', 'pipe'] +``` -Default is `.stdio('inherit', 'pipe', 'pipe')`. +Keep in mind, `stdio` should be set before the process is started, so the preset syntax might be preferable: ```js -const p = $`read`.stdio('pipe') +await $({stdio: ['pipe', 'pipe', 'pipe']})`read` ``` ## `nothrow()`