From d91c238854456dd8356f8a2205e0d57ca9129aeb Mon Sep 17 00:00:00 2001 From: Alfi Maulana Date: Thu, 21 Nov 2024 22:04:45 +0700 Subject: [PATCH] feat: add `exec` function Signed-off-by: Alfi Maulana --- src/exec.test.ts | 13 +++++++++++++ src/exec.ts | 26 ++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 src/exec.test.ts create mode 100644 src/exec.ts diff --git a/src/exec.test.ts b/src/exec.test.ts new file mode 100644 index 0000000..0aca427 --- /dev/null +++ b/src/exec.test.ts @@ -0,0 +1,13 @@ +import { exec } from "./exec.js"; + +describe("execute commands", () => { + it("should successfully execute a command", async () => { + await exec("node", ["--version"]); + }); + + it("should fail to execute a command", async () => { + await expect(exec("node", ["--invalid"])).rejects.toThrow( + "Command exited with status code 9", + ); + }); +}); diff --git a/src/exec.ts b/src/exec.ts new file mode 100644 index 0000000..4d5f222 --- /dev/null +++ b/src/exec.ts @@ -0,0 +1,26 @@ +import { spawn } from "node:child_process"; + +/** + * Executes a command with the given arguments. + * + * The command is executed with `stdin` ignored and both `stdout` and `stderr` inherited by the parent process. + * + * @param command The command to execute. + * @param args The arguments to pass to the command. + * @returns A promise that resolves when the command exits successfully or rejects if it exits with a non-zero status code or encounters an error. + */ +export async function exec(command: string, args: string[]): Promise { + return new Promise((resolve, reject) => { + const proc = spawn(command, args, { + stdio: ["ignore", "inherit", "inherit"], + }); + proc.on("error", reject); + proc.on("close", (code) => { + if (code === 0) { + resolve(); + } else { + reject(new Error(`Command exited with status code ${code}`)); + } + }); + }); +}