Skip to content

Commit

Permalink
Add ssh command for executing scripts on remote hosts
Browse files Browse the repository at this point in the history
  • Loading branch information
antonmedv committed Feb 27, 2023
1 parent 16f3939 commit dd36707
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 24 deletions.
69 changes: 45 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,22 +35,27 @@ npm i -g zx

## Goods

[$](#command-) · [cd()](#cd) · [fetch()](#fetch) · [question()](#question) · [sleep()](#sleep) · [echo()](#echo) · [stdin()](#stdin) · [within()](#within) ·
[$](#command-) · [cd()](#cd) · [fetch()](#fetch) · [question()](#question) · [sleep()](#sleep) · [echo()](#echo) · [stdin()](#stdin) · [within()](#within) · [retry()](#retry) · [spinner()](#spinner) ·
[chalk](#chalk-package) · [fs](#fs-package) · [os](#os-package) · [path](#path-package) · [glob](#globby-package) · [yaml](#yaml-package) · [minimist](#minimist-package) · [which](#which-package) ·
[__filename](#__filename--__dirname) · [__dirname](#__filename--__dirname) · [require()](#require)

For running commands on remote hosts,
see [webpod](https://github.com/webpod/webpod).

## Documentation

Write your scripts in a file with an `.mjs` extension in order to
use `await` at the top level. If you prefer the `.js` extension,
wrap your scripts in something like `void async function () {...}()`.

Add the following shebang to the beginning of your `zx` scripts:

```bash
#!/usr/bin/env zx
```

Now you will be able to run your script like so:

```bash
chmod +x ./script.mjs
./script.mjs
Expand Down Expand Up @@ -117,9 +122,13 @@ class ProcessPromise extends Promise<ProcessOutput> {
stdout: Readable
stderr: Readable
exitCode: Promise<number>

pipe(dest): ProcessPromise

kill(): Promise<void>

nothrow(): this

quiet(): this
}
```
Expand All @@ -134,11 +143,13 @@ class ProcessOutput {
readonly stderr: string
readonly signal: string
readonly exitCode: number

toString(): string // Combined stdout & stderr.
}
```

The output of the process is captured as-is. Usually, programs print a new line `\n` at the end.
The output of the process is captured as-is. Usually, programs print a new
line `\n` at the end.
If `ProcessOutput` is used as an argument to some other `$` process,
**zx** will use stdout and trim the new line.

Expand All @@ -160,7 +171,8 @@ await $`pwd` // => /tmp

### `fetch()`

A wrapper around the [node-fetch](https://www.npmjs.com/package/node-fetch) package.
A wrapper around the [node-fetch](https://www.npmjs.com/package/node-fetch)
package.

```js
let resp = await fetch('https://medv.io')
Expand Down Expand Up @@ -312,7 +324,9 @@ The [minimist](https://www.npmjs.com/package/minimist) package available
as global const `argv`.

```js
if( argv.someFlag ){ echo('yes') }
if (argv.someFlag) {
echo('yes')
}
```

### `which` package
Expand Down Expand Up @@ -398,7 +412,8 @@ $.log = (entry: LogEntry) => {
### `__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,
`__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()`
Expand All @@ -423,10 +438,12 @@ await $`echo $FOO`

### Passing array of values

When passing an array of values as an argument to `$`, items of the array will be escaped
When passing an array of values as an argument to `$`, items of the array will
be escaped
individually and concatenated via space.

Example:

```js
let files = [...]
await $`tar cz ${files}`
Expand All @@ -438,14 +455,16 @@ It is possible to make use of `$` and other functions via explicit imports:

```js
#!/usr/bin/env node
import {$} from 'zx'
import { $ } from 'zx'

await $`date`
```

### Scripts without extensions

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)
assumes that it is
an [ESM](https://nodejs.org/api/modules.html#modules_module_createrequire_filename)
module.

### Markdown scripts
Expand All @@ -459,7 +478,7 @@ zx docs/markdown.md
### TypeScript scripts

```ts
import {$} from 'zx'
import { $ } from 'zx'
// Or
import 'zx/globals'

Expand All @@ -469,7 +488,8 @@ void async function () {
```

Set [`"type": "module"`](https://nodejs.org/api/packages.html#packages_type)
in **package.json** and [`"module": "ESNext"`](https://www.typescriptlang.org/tsconfig/#module)
in **package.json**
and [`"module": "ESNext"`](https://www.typescriptlang.org/tsconfig/#module)
in **tsconfig.json**.

### Executing remote scripts
Expand All @@ -486,7 +506,7 @@ zx https://medv.io/game-of-life.js
The `zx` supports executing scripts from stdin.

```js
zx <<'EOF'
zx << 'EOF'
await $`pwd`
EOF
```
Expand All @@ -504,17 +524,18 @@ cat package.json | zx --eval 'let v = JSON.parse(await stdin()).version; echo(v)
```js
// script.mjs:
import sh from 'tinysh'

sh.say('Hello, world!')
```

Add `--install` flag to the `zx` command to install missing dependencies
Add `--install` flag to the `zx` command to install missing dependencies
automatically.

```bash
zx --install script.mjs
```

You can also specify needed version by adding comment with `@` after
You can also specify needed version by adding comment with `@` after
the import.

```js
Expand All @@ -524,7 +545,7 @@ import sh from 'tinysh' // @^1
### Attaching a profile

By default `child_process` does not include aliases and bash functions.
But you are still able to do it by hand. Just attach necessary directives
But you are still able to do it by hand. Just attach necessary directives
to the `$.prefix`.

```js
Expand All @@ -541,21 +562,21 @@ jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v3

- name: Build
env:
FORCE_COLOR: 3
run: |
npx zx <<'EOF'
await $`...`
EOF
- name: Build
env:
FORCE_COLOR: 3
run: |
npx zx <<'EOF'
await $`...`
EOF
```
### Canary / Beta / RC builds
Impatient early adopters can try the experimental zx versions.
But keep in mind: these builds are ⚠️️ __beta__ in every sense.
Impatient early adopters can try the experimental zx versions.
But keep in mind: these builds are ⚠️️__beta__ in every sense.
```bash
npm i zx@dev
Expand Down
14 changes: 14 additions & 0 deletions package-lock.json

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

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
"minimist": "^1.2.8",
"node-fetch": "3.2.10",
"ps-tree": "^1.2.0",
"webpod": "^0.0.2",
"which": "^3.0.0",
"yaml": "^2.2.1"
},
Expand Down
1 change: 1 addition & 0 deletions src/goods.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export { default as which } from 'which'
export { default as YAML } from 'yaml'
export { default as path } from 'node:path'
export { default as os } from 'node:os'
export { ssh } from 'webpod'

export let argv = minimist(process.argv.slice(2))
export function updateArgv(args: string[]) {
Expand Down

0 comments on commit dd36707

Please sign in to comment.