From 1d6ebdda153484c54ba057d1c8a6466415dfc54d Mon Sep 17 00:00:00 2001 From: David Sherret Date: Sat, 30 Mar 2024 18:18:35 -0400 Subject: [PATCH] fix: not finding a command should error in the shell (#257) --- mod.test.ts | 16 ++++++++++------ src/shell.ts | 10 +++++++--- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/mod.test.ts b/mod.test.ts index 2dc7f2f..5bf770b 100644 --- a/mod.test.ts +++ b/mod.test.ts @@ -192,6 +192,12 @@ Deno.test("should throw when exit code is non-zero", async () => { ); }); +Deno.test("should error in the shell when the command can't be found", async () => { + const output = await $`nonexistentcommanddaxtest`.noThrow().stderr("piped"); + assertEquals(output.code, 127); + assertEquals(output.stderr, "dax: nonexistentcommanddaxtest: command not found\n"); +}); + Deno.test("throws when providing an object that doesn't override toString", async () => { { const obj1 = {}; @@ -490,11 +496,9 @@ Deno.test("should not allow invalid command names", () => { Deno.test("should unregister commands", async () => { const builder = new CommandBuilder().unregisterCommand("export").noThrow(); - await assertRejects( - async () => await builder.command("export somewhere"), - Error, - "Command not found: export", - ); + const output = await builder.command("export somewhere").stderr("piped"); + assertEquals(output.code, 127); + assertEquals(output.stderr, "dax: export: command not found\n"); }); Deno.test("sleep command", async () => { @@ -1438,7 +1442,7 @@ Deno.test("shebang support", async (t) => { .text(); }, Error, - "Command not found: deno run", + "Exited with code: 127", ); }); diff --git a/src/shell.ts b/src/shell.ts index ef1d781..275350c 100644 --- a/src/shell.ts +++ b/src/shell.ts @@ -928,6 +928,10 @@ async function executeUnresolvedCommand( context: Context, ): Promise { const resolvedCommand = await resolveCommand(unresolvedCommand, context); + if (resolvedCommand === false) { + context.stderr.writeLine(`dax: ${unresolvedCommand.name}: command not found`); + return { code: 127 }; + } if (resolvedCommand.kind === "shebang") { return executeUnresolvedCommand(resolvedCommand.command, [...resolvedCommand.args, ...commandArgs], context); } @@ -1113,7 +1117,7 @@ function pipeCommandPipeReaderToWriterSync( } } -type ResolvedCommand = ResolvedPathCommand | ResolvedShebangCommand; +type ResolvedCommand = ResolvedPathCommand | ResolvedShebangCommand | false; interface ResolvedPathCommand { kind: "path"; @@ -1141,7 +1145,7 @@ async function resolveCommand(unresolvedCommand: UnresolvedCommand, context: Con // won't have a script with a shebang in it on Windows const result = await getExecutableShebangFromPath(commandPath); if (result === false) { - throw new Error(`Command not found: ${unresolvedCommand.name}`); + return false; } else if (result != null) { const args = await parseShebangArgs(result, context); const name = args.shift()!; @@ -1180,7 +1184,7 @@ async function resolveCommand(unresolvedCommand: UnresolvedCommand, context: Con }, }); if (commandPath == null) { - throw new Error(`Command not found: ${unresolvedCommand.name}`); + return false; } return { kind: "path",