From 85c5091f44548495143a70ca4e2ab014cfcb58f9 Mon Sep 17 00:00:00 2001 From: David Sherret Date: Sun, 17 Dec 2023 11:25:05 +0100 Subject: [PATCH] refactor: switch to local interfaces for `Deno.Reader`, `WriterSync`, `Closer` (#196) --- mod.test.ts | 4 ++-- mod.ts | 2 +- src/command.ts | 10 ++++++---- src/command_handler.ts | 5 +++-- src/commands/cat.ts | 2 +- src/common.ts | 3 ++- src/pipes.ts | 40 ++++++++++++++++++++++++++-------------- src/shell.ts | 6 +++--- 8 files changed, 44 insertions(+), 28 deletions(-) diff --git a/mod.test.ts b/mod.test.ts index 21ee04f..b06a227 100644 --- a/mod.test.ts +++ b/mod.test.ts @@ -730,7 +730,7 @@ Deno.test("abort", async () => { }); Deno.test("piping to stdin", async () => { - // Deno.Reader + // Reader { const bytes = new TextEncoder().encode("test\n"); const result = @@ -768,7 +768,7 @@ Deno.test("piping to stdin", async () => { } }); -Deno.test("spawning a command twice that has stdin set to a Deno.Reader should error", async () => { +Deno.test("spawning a command twice that has stdin set to a Reader should error", async () => { const bytes = new TextEncoder().encode("test\n"); const command = $`deno eval "const b = new Uint8Array(4); await Deno.stdin.read(b); await Deno.stdout.write(b);"` .stdin(new Buffer(bytes)); diff --git a/mod.ts b/mod.ts index 854622b..7ced3e7 100644 --- a/mod.ts +++ b/mod.ts @@ -35,7 +35,7 @@ export { FsFileWrapper, PathRef } from "./src/path.ts"; export type { ExpandGlobOptions, PathSymlinkOptions, SymlinkOptions, WalkEntry, WalkOptions } from "./src/path.ts"; export { CommandBuilder, CommandChild, CommandResult, KillSignal, KillSignalController } from "./src/command.ts"; export type { CommandContext, CommandHandler, CommandPipeReader, CommandPipeWriter } from "./src/command_handler.ts"; -export type { ShellPipeReader, ShellPipeWriterKind } from "./src/pipes.ts"; +export type { Closer, Reader, ShellPipeReader, ShellPipeWriterKind, WriterSync } from "./src/pipes.ts"; export type { ConfirmOptions, MultiSelectOption, diff --git a/src/command.ts b/src/command.ts index 9746f0f..8dd5aa6 100644 --- a/src/command.ts +++ b/src/command.ts @@ -21,9 +21,11 @@ import { InheritStaticTextBypassWriter, NullPipeWriter, PipedBuffer, + Reader, ShellPipeReader, ShellPipeWriter, ShellPipeWriterKind, + WriterSync, } from "./pipes.ts"; import { parseCommand, spawn } from "./shell.ts"; import { isShowingProgressBars } from "./console/progress/interval.ts"; @@ -33,7 +35,7 @@ type BufferStdio = "inherit" | "null" | "streamed" | Buffer; interface CommandBuilderState { command: string | undefined; - stdin: "inherit" | "null" | Box | "consumed">; + stdin: "inherit" | "null" | Box | "consumed">; combinedStdoutStderr: boolean; stdoutKind: ShellPipeWriterKind; stderrKind: ShellPipeWriterKind; @@ -692,7 +694,7 @@ export function parseAndSpawnCommand(state: CommandBuilderState) { } return [stdoutBuffer, stderrBuffer, undefined] as const; - function getOutputBuffer(innerWriter: Deno.WriterSync, kind: ShellPipeWriterKind) { + function getOutputBuffer(innerWriter: WriterSync, kind: ShellPipeWriterKind) { if (typeof kind === "object") { return kind; } @@ -718,7 +720,7 @@ export function parseAndSpawnCommand(state: CommandBuilderState) { } function finalizeCommandResultBuffer( - buffer: PipedBuffer | "inherit" | "null" | CapturingBufferWriter | InheritStaticTextBypassWriter | Deno.WriterSync, + buffer: PipedBuffer | "inherit" | "null" | CapturingBufferWriter | InheritStaticTextBypassWriter | WriterSync, ): BufferStdio { if (buffer instanceof CapturingBufferWriter) { return buffer.getBuffer(); @@ -736,7 +738,7 @@ export function parseAndSpawnCommand(state: CommandBuilderState) { } function finalizeCommandResultBufferForError( - buffer: PipedBuffer | "inherit" | "null" | CapturingBufferWriter | InheritStaticTextBypassWriter | Deno.WriterSync, + buffer: PipedBuffer | "inherit" | "null" | CapturingBufferWriter | InheritStaticTextBypassWriter | WriterSync, error: Error, ) { if (buffer instanceof InheritStaticTextBypassWriter) { diff --git a/src/command_handler.ts b/src/command_handler.ts index 2ad6bad..d99f7a8 100644 --- a/src/command_handler.ts +++ b/src/command_handler.ts @@ -1,11 +1,12 @@ import { ExecuteResult } from "./result.ts"; import type { KillSignal } from "./command.ts"; +import { Reader, WriterSync } from "./pipes.ts"; /** Used to read from stdin. */ -export type CommandPipeReader = "inherit" | "null" | Deno.Reader; +export type CommandPipeReader = "inherit" | "null" | Reader; /** Used to write to stdout or stderr. */ -export interface CommandPipeWriter extends Deno.WriterSync { +export interface CommandPipeWriter extends WriterSync { writeSync(p: Uint8Array): number; writeText(text: string): void; writeLine(text: string): void; diff --git a/src/commands/cat.ts b/src/commands/cat.ts index f516150..e386bf9 100644 --- a/src/commands/cat.ts +++ b/src/commands/cat.ts @@ -26,7 +26,7 @@ async function executeCat(context: CommandContext) { for (const path of flags.paths) { if (path === "-") { // read from stdin - if (typeof context.stdin === "object") { // stdin is a Deno.Reader + if (typeof context.stdin === "object") { // stdin is a Reader while (true) { const size = await context.stdin.read(buf); if (!size || size === 0) break; diff --git a/src/common.ts b/src/common.ts index 7ff6867..977890d 100644 --- a/src/common.ts +++ b/src/common.ts @@ -1,5 +1,6 @@ import { logger } from "./console/mod.ts"; import { BufReader, path } from "./deps.ts"; +import { Reader } from "./pipes.ts"; /** * Delay used for certain actions. @@ -216,7 +217,7 @@ export interface ShebangInfo { } const decoder = new TextDecoder(); -export async function getExecutableShebang(reader: Deno.Reader): Promise { +export async function getExecutableShebang(reader: Reader): Promise { const text = "#!/usr/bin/env "; const buffer = new Uint8Array(text.length); const bytesReadCount = await reader.read(buffer); diff --git a/src/pipes.ts b/src/pipes.ts index 1f4730b..8b011fb 100644 --- a/src/pipes.ts +++ b/src/pipes.ts @@ -3,7 +3,19 @@ import { Buffer, writeAllSync } from "./deps.ts"; const encoder = new TextEncoder(); -export type ShellPipeReader = "inherit" | "null" | Deno.Reader; +export interface Reader { + read(p: Uint8Array): Promise; +} + +export interface WriterSync { + writeSync(p: Uint8Array): number; +} + +export interface Closer { + close(): void; +} + +export type ShellPipeReader = "inherit" | "null" | Reader; /** * The behaviour to use for a shell pipe. * @value "inherit" - Sends the output directly to the current process' corresponding pipe (default). @@ -11,19 +23,19 @@ export type ShellPipeReader = "inherit" | "null" | Deno.Reader; * @value "piped" - Captures the pipe without outputting. * @value "inheritPiped" - Captures the pipe with outputting. */ -export type ShellPipeWriterKind = "inherit" | "null" | "piped" | "inheritPiped" | Deno.WriterSync; +export type ShellPipeWriterKind = "inherit" | "null" | "piped" | "inheritPiped" | WriterSync; -export class NullPipeWriter implements Deno.WriterSync { +export class NullPipeWriter implements WriterSync { writeSync(p: Uint8Array): number { return p.length; } } -export class ShellPipeWriter implements Deno.WriterSync { +export class ShellPipeWriter implements WriterSync { #kind: ShellPipeWriterKind; - #inner: Deno.WriterSync; + #inner: WriterSync; - constructor(kind: ShellPipeWriterKind, inner: Deno.WriterSync) { + constructor(kind: ShellPipeWriterKind, inner: WriterSync) { this.#kind = kind; this.#inner = inner; } @@ -45,11 +57,11 @@ export class ShellPipeWriter implements Deno.WriterSync { } } -export class CapturingBufferWriter implements Deno.WriterSync { +export class CapturingBufferWriter implements WriterSync { #buffer: Buffer; - #innerWriter: Deno.WriterSync; + #innerWriter: WriterSync; - constructor(innerWriter: Deno.WriterSync, buffer: Buffer) { + constructor(innerWriter: WriterSync, buffer: Buffer) { this.#innerWriter = innerWriter; this.#buffer = buffer; } @@ -67,11 +79,11 @@ export class CapturingBufferWriter implements Deno.WriterSync { const lineFeedCharCode = "\n".charCodeAt(0); -export class InheritStaticTextBypassWriter implements Deno.WriterSync { +export class InheritStaticTextBypassWriter implements WriterSync { #buffer: Buffer; - #innerWriter: Deno.WriterSync; + #innerWriter: WriterSync; - constructor(innerWriter: Deno.WriterSync) { + constructor(innerWriter: WriterSync) { this.#innerWriter = innerWriter; this.#buffer = new Buffer(); } @@ -99,11 +111,11 @@ export class InheritStaticTextBypassWriter implements Deno.WriterSync { } } -export interface PipedBufferListener extends Deno.WriterSync, Deno.Closer { +export interface PipedBufferListener extends WriterSync, Closer { setError(err: Error): void; } -export class PipedBuffer implements Deno.WriterSync { +export class PipedBuffer implements WriterSync { #inner: Buffer | PipedBufferListener; #hasSet = false; diff --git a/src/shell.ts b/src/shell.ts index 45977e3..988893e 100644 --- a/src/shell.ts +++ b/src/shell.ts @@ -3,7 +3,7 @@ import { CommandContext, CommandHandler } from "./command_handler.ts"; import { getExecutableShebangFromPath, ShebangInfo } from "./common.ts"; import { DenoWhichRealEnvironment, fs, path, which } from "./deps.ts"; import { wasmInstance } from "./lib/mod.ts"; -import { ShellPipeReader, ShellPipeWriter, ShellPipeWriterKind } from "./pipes.ts"; +import { Reader, ShellPipeReader, ShellPipeWriter, ShellPipeWriterKind, WriterSync } from "./pipes.ts"; import { EnvChange, ExecuteResult, getAbortedResult, resultFromCode } from "./result.ts"; export interface SequentialList { @@ -670,7 +670,7 @@ async function executeCommandArgs(commandArgs: string[], context: Context): Prom await pipeReaderToWriterSync(readable, writer, new AbortController().signal); } - async function pipeReaderToWriter(reader: Deno.Reader, writable: WritableStream, signal: AbortSignal) { + async function pipeReaderToWriter(reader: Reader, writable: WritableStream, signal: AbortSignal) { const abortedPromise = new Promise((resolve) => { signal.addEventListener("abort", listener); function listener() { @@ -695,7 +695,7 @@ async function executeCommandArgs(commandArgs: string[], context: Context): Prom async function pipeReaderToWriterSync( readable: ReadableStream, - writer: Deno.WriterSync, + writer: WriterSync, signal: AbortSignal, ) { const reader = readable.getReader();