diff --git a/src/command_handler.ts b/src/command_handler.ts index a43e9a8..092affc 100644 --- a/src/command_handler.ts +++ b/src/command_handler.ts @@ -2,10 +2,10 @@ import { ExecuteResult } from "./result.ts"; export type CommandPipeReader = "inherit" | "null" | Deno.Reader; -export interface CommandPipeWriter extends Deno.Writer { - write(p: Uint8Array): Promise; - writeText(text: string): Promise; - writeLine(text: string): Promise; +export interface CommandPipeWriter extends Deno.WriterSync { + writeSync(p: Uint8Array): number; + writeText(text: string): void; + writeLine(text: string): void; } export interface CommandContext { diff --git a/src/deps.ts b/src/deps.ts index 3b892a0..85644b4 100644 --- a/src/deps.ts +++ b/src/deps.ts @@ -2,5 +2,5 @@ export * as colors from "https://deno.land/std@0.153.0/fmt/colors.ts"; export * as fs from "https://deno.land/std@0.153.0/fs/mod.ts"; export { Buffer } from "https://deno.land/std@0.153.0/io/buffer.ts"; export * as path from "https://deno.land/std@0.153.0/path/mod.ts"; -export { readAll, writeAll } from "https://deno.land/std@0.153.0/streams/conversion.ts"; +export { readAll, writeAllSync } from "https://deno.land/std@0.153.0/streams/conversion.ts"; export { RealEnvironment as DenoWhichRealEnvironment, which, whichSync } from "https://deno.land/x/which@0.2.1/mod.ts"; diff --git a/src/pipes.ts b/src/pipes.ts index e8b4891..9b92a59 100644 --- a/src/pipes.ts +++ b/src/pipes.ts @@ -1,4 +1,4 @@ -import { Buffer, writeAll } from "./deps.ts"; +import { Buffer, writeAllSync } from "./deps.ts"; const encoder = new TextEncoder(); @@ -12,17 +12,17 @@ export type ShellPipeReader = "inherit" | "null" | Deno.Reader; */ export type ShellPipeWriterKind = "inherit" | "null" | "piped" | "inheritPiped"; -export class NullPipeWriter implements Deno.Writer { - write(p: Uint8Array): Promise { - return Promise.resolve(p.length); +export class NullPipeWriter implements Deno.WriterSync { + writeSync(p: Uint8Array): number { + return p.length; } } -export class ShellPipeWriter implements Deno.Writer { +export class ShellPipeWriter implements Deno.WriterSync { #kind: ShellPipeWriterKind; - #inner: Deno.Writer; + #inner: Deno.WriterSync; - constructor(kind: ShellPipeWriterKind, inner: Deno.Writer) { + constructor(kind: ShellPipeWriterKind, inner: Deno.WriterSync) { this.#kind = kind; this.#inner = inner; } @@ -31,24 +31,24 @@ export class ShellPipeWriter implements Deno.Writer { return this.#kind; } - write(p: Uint8Array): Promise { - return this.#inner.write(p); + writeSync(p: Uint8Array) { + return this.#inner.writeSync(p); } - async writeText(text: string) { - return writeAll(this, encoder.encode(text)); + writeText(text: string) { + return writeAllSync(this, encoder.encode(text)); } - async writeLine(text: string) { + writeLine(text: string) { return this.writeText(text + "\n"); } } -export class CapturingBufferWriter implements Deno.Writer { +export class CapturingBufferWriter implements Deno.WriterSync { #buffer: Buffer; - #innerWriter: Deno.Writer; + #innerWriter: Deno.WriterSync; - constructor(innerWriter: Deno.Writer, buffer: Buffer) { + constructor(innerWriter: Deno.WriterSync, buffer: Buffer) { this.#innerWriter = innerWriter; this.#buffer = buffer; } @@ -57,9 +57,8 @@ export class CapturingBufferWriter implements Deno.Writer { return this.#buffer; } - async write(p: Uint8Array): Promise { - const nWritten = await this.#innerWriter.write(p); - // sync is ok because Buffer is sync + writeSync(p: Uint8Array) { + const nWritten = this.#innerWriter.writeSync(p); this.#buffer.writeSync(p.slice(0, nWritten)); return nWritten; } diff --git a/src/shell.ts b/src/shell.ts index a3efb1c..ed10b64 100644 --- a/src/shell.ts +++ b/src/shell.ts @@ -604,7 +604,7 @@ async function executeCommandArgs(commandArgs: string[], context: Context) { } // don't abort... ensure all of stdout/stderr is read in case the process // exits before this finishes - await pipeReaderToWriter(reader, writer, new AbortController().signal); + await pipeReaderToWriterSync(reader, writer, new AbortController().signal); } async function pipeReaderToWriter(reader: Deno.Reader, writer: Deno.Writer, signal: AbortSignal) { @@ -625,6 +625,24 @@ async function executeCommandArgs(commandArgs: string[], context: Context) { } } + async function pipeReaderToWriterSync(reader: Deno.Reader, writer: Deno.WriterSync, signal: AbortSignal) { + while (!signal.aborted) { + const buffer = new Uint8Array(1024); + const length = await reader.read(buffer); + if (length === 0 || length == null) { + break; + } + writeAll(buffer.subarray(0, length)); + } + + function writeAll(arr: Uint8Array) { + let nwritten = 0; + while (nwritten < arr.length && !signal.aborted) { + nwritten += writer.writeSync(arr.subarray(nwritten)); + } + } + } + function getStdioStringValue(value: ShellPipeReader | ShellPipeWriterKind) { if (value === "inheritPiped") { return "piped";