Skip to content

Commit

Permalink
Merge branch 'main' into fix/remove-gt-from-print-cmd-args
Browse files Browse the repository at this point in the history
  • Loading branch information
dsherret committed Feb 4, 2024
2 parents c943ea1 + 1d88634 commit c5e5284
Show file tree
Hide file tree
Showing 46 changed files with 6,349 additions and 3,745 deletions.
16 changes: 16 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,19 @@ jobs:

- name: test
run: deno test -A

- name: Get tag version
if: startsWith(github.ref, 'refs/tags/')
id: get_tag_version
run: echo TAG_VERSION=${GITHUB_REF/refs\/tags\//} >> $GITHUB_OUTPUT
- uses: actions/setup-node@v3
with:
node-version: '20.x'
registry-url: 'https://registry.npmjs.org'
- name: npm build
run: deno run -A ./scripts/build_npm.ts ${{steps.get_tag_version.outputs.TAG_VERSION}}
- name: npm publish
if: startsWith(github.ref, 'refs/tags/')
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
run: cd npm && npm publish
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/target
.vscode
deno.lock
npm
41 changes: 20 additions & 21 deletions Cargo.lock

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

115 changes: 110 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Cross platform shell tools for Deno inspired by [zx](https://github.com/google/z
- Makes more code work on Windows.
- Allows exporting the shell's environment to the current process.
- Uses [deno_task_shell](https://github.com/denoland/deno_task_shell)'s parser.
- Has common commands built-in for better Windows support.
1. Minimal globals or global configuration.
- Only a default instance of `$`, but it's not mandatory to use this.
1. No custom CLI.
Expand All @@ -21,13 +22,14 @@ Cross platform shell tools for Deno inspired by [zx](https://github.com/google/z
## Executing commands

```ts
#!/usr/bin/env -S deno run --allow-all
import $ from "https://deno.land/x/dax/mod.ts";

// run a command
await $`echo 5`; // outputs: 5

// more complex example outputting 1 to stdout and 2 to stderr
await $`echo 1 && deno eval 'console.error(2);'`;
// outputting 1 to stdout and running a sub process
await $`echo 1 && deno run main.ts`;

// parallel
await Promise.all([
Expand Down Expand Up @@ -56,8 +58,8 @@ console.log(result.prop); // 5
Get the result of stdout as bytes (makes stdout "quiet"):

```ts
const result = await $`echo 'test'`.bytes();
console.log(result); // Uint8Array(5) [ 116, 101, 115, 116, 10 ]
const bytes = await $`gzip < file.txt`.bytes();
console.log(bytes);
```

Get the result of stdout as a list of lines (makes stdout "quiet"):
Expand Down Expand Up @@ -90,6 +92,46 @@ const result = await $`deno eval 'console.log(1); console.error(2); console.log(
console.log(result.combined); // 1\n2\n3\n
```

### Piping

Piping stdout or stderr to a `Deno.WriterSync`:

```ts
await $`echo 1`.stdout(Deno.stderr);
await $`deno eval 'console.error(2);`.stderr(Deno.stdout);
```

Piping to a `WritableStream`:

```ts
await $`echo 1`.stdout(Deno.stderr.writable, { preventClose: true });
```

To a file path:

```ts
await $`echo 1`.stdout($.path("data.txt"));
```

To a file:

```ts
using file = $.path("data.txt").openSync({ write: true, create: true });
await $`echo 1`.stdout(file);
```

From one command to another:

```ts
const output = await $`echo foo && echo bar`
.pipe($`grep foo`)
.text();

// or using a pipe sequence
const output = await $`echo foo && echo bar | grep foo`
.text();
```

### Providing arguments to a command

Use an expression in a template literal to provide a single argument to a command:
Expand Down Expand Up @@ -137,13 +179,46 @@ const finalText = await $`echo ${result}`.text();
console.log(finalText); // 1
```

#### JavaScript objects to redirects

You can also provide JavaScript objects to shell output redirects:

```ts
const buffer = new Uint8Array(2);
await $`echo 1 && (echo 2 > ${buffer}) && echo 3`; // 1\n3\n
console.log(buffer); // Uint8Array(2) [ 50, 10 ] (2\n)
```

Supported objects: `Uint8Array`, `PathRef`, `WritableStream`, function that returns a `WritableStream`, any object that implements `[$.symbols.writable](): WritableStream`

Or input redirects:

```ts
// strings
const data = "my data in a string";
const bytes = await $`gzip < ${data}`;

// paths
const path = $.path("file.txt");
const bytes = await $`gzip < ${path}`;

// requests (this example does not make the request until after 5 seconds)
const request = $.request("https://plugins.dprint.dev/info.json")
.showProgress(); // show a progress bar while downloading
const bytes = await $`sleep 5 && gzip < ${request}`.bytes();
```

Supported objects: `string`, `Uint8Array`, `PathRef`, `RequestBuilder`, `ReadableStream`, function that returns a `ReadableStream`, any object that implements `[$.symbols.readable](): ReadableStream`

### Providing stdin

```ts
await $`command`.stdin("inherit"); // default
await $`command`.stdin("null");
await $`command`.stdin(new Uint8Array[1, 2, 3, 4]());
await $`command`.stdin(someReaderOrReadableStream);
await $`command`.stdin($.path("data.json"));
await $`command`.stdin($.request("https://plugins.dprint.dev/info.json"));
await $`command`.stdinText("some value");
```

Expand Down Expand Up @@ -646,6 +721,17 @@ console.log(response.code);
console.log(await response.json());
```

Requests can be piped to commands:

```ts
const request = $.request("https://plugins.dprint.dev/info.json");
await $`deno run main.ts`.stdin(request);

// or as a redirect... this sleeps 5 seconds, then makes
// request and redirects the output to the command
await $`sleep 5 && deno run main.ts < ${request}`;
```

See the [documentation on `RequestBuilder`](https://deno.land/x/dax/src/request.ts?s=RequestBuilder) for more details. It should be as flexible as `fetch`, but uses a builder API (ex. set headers via `.header(...)`).

### Showing progress
Expand Down Expand Up @@ -679,6 +765,25 @@ await $`echo 1 && echo 2`;
await $`echo 1 || echo 2`;
```

Pipe sequences:

```ts
await $`echo 1 | deno run main.ts`;
```

Redirects:

```ts
await $`echo 1 > output.txt`;
const gzippedBytes = await $`gzip < input.txt`.bytes();
```

Sub shells:

```ts
await $`(echo 1 && echo 2) > output.txt`;
```

Setting env var for command in the shell (generally you can just use `.env(...)` though):

```ts
Expand Down Expand Up @@ -789,7 +894,7 @@ You can also register your own custom commands using the `registerCommand` or `r
const commandBuilder = new CommandBuilder()
.registerCommand(
"true",
() => Promise.resolve({ kind: "continue", code: 0 }),
() => Promise.resolve({ code: 0 }),
);

const result = await commandBuilder
Expand Down
5 changes: 4 additions & 1 deletion deno.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
{
"lock": false,
"tasks": {
"test": "deno test -A",
"wasmbuild": "deno run -A https://deno.land/x/[email protected].4/main.ts --sync --out ./src/lib"
"wasmbuild": "deno run -A https://deno.land/x/[email protected].6/main.ts --sync --out ./src/lib"
},
"fmt": {
"proseWrap": "preserve",
Expand All @@ -11,11 +12,13 @@
"rules": {
"exclude": ["ban-types", "no-explicit-any", "no-this-alias"],
"include": [
"no-console",
"no-sync-fn-in-async-fn"
]
}
},
"exclude": [
"npm/",
"target/"
]
}
Loading

0 comments on commit c5e5284

Please sign in to comment.