Skip to content

Commit

Permalink
Change behaviour.
Browse files Browse the repository at this point in the history
  • Loading branch information
dsherret committed Jan 29, 2024
1 parent e899265 commit 96c77f8
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 4 deletions.
22 changes: 20 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -179,19 +179,37 @@ 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`;
console.log(buffer); // Uint8Array(2) [ 50, 10 ]
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
Expand Down
14 changes: 14 additions & 0 deletions mod.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1269,6 +1269,12 @@ Deno.test("input redirects with provided object", async () => {
const output = await $`cat - < ${stream}`.text();
assertEquals(output, text);
}
// string
{
const text = "testing".repeat(1000);
const output = await $`cat - < ${text}`.text();
assertEquals(output, text);
}
// bytes
{
const text = "testing".repeat(1000);
Expand Down Expand Up @@ -1361,6 +1367,14 @@ Deno.test("output redirect with provided object", async () => {
await $`echo 1 > ${() => writableStream}`;
assertEquals(chunks, [new Uint8Array([49, 10])]);
}
{
assertThrows(
() => $`echo 1 > ${"test.txt"}`,
Error,
"Failed resolving expression in command. Cannot provide strings to output " +
"redirects. Did you mean to provide a path instead via the `$.path(...)` API?",
);
}
});

Deno.test("shebang support", async (t) => {
Expand Down
17 changes: 15 additions & 2 deletions src/command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1252,8 +1252,17 @@ function templateInner(
const expr = exprs[i];
const inputOrOutputRedirect = detectInputOrOutputRedirect(text);
if (inputOrOutputRedirect === "<") {
if (typeof expr === "string" || expr instanceof PathRef) {
if (expr instanceof PathRef) {
text += templateLiteralExprToString(expr, escape);
} else if (typeof expr === "string") {
handleReadableStream(() =>
new ReadableStream({
start(controller) {
controller.enqueue(new TextEncoder().encode(expr));
controller.close();
},
})
);
} else if (expr instanceof ReadableStream) {
handleReadableStream(() => expr);
} else if (expr?.[symbols.readable]) {
Expand Down Expand Up @@ -1303,7 +1312,7 @@ function templateInner(
throw new Error("Unsupported object provided to input redirect.");
}
} else if (inputOrOutputRedirect === ">") {
if (typeof expr === "string" || expr instanceof PathRef) {
if (expr instanceof PathRef) {
text += templateLiteralExprToString(expr, escape);
} else if (expr instanceof WritableStream) {
handleWritableStream(() => expr);
Expand Down Expand Up @@ -1349,6 +1358,10 @@ function templateInner(
);
}
});
} else if (typeof expr === "string") {
throw new Error(
"Cannot provide strings to output redirects. Did you mean to provide a path instead via the `$.path(...)` API?",
);
} else {
throw new Error("Unsupported object provided to output redirect.");
}
Expand Down

0 comments on commit 96c77f8

Please sign in to comment.