datahaven/test/utils/shell.ts
Facundo Farall 4c7a64fc39
fix: 🚨 Add error in TS for missing awaits (#81)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **Documentation**
- Added detailed IDE configuration recommendations for Rust, Solidity,
and TypeScript in the README to enhance developer experience.

- **Chores**
- Updated Biome configuration files and package dependencies to the
latest schema and version.
- Refined code formatting, linting, and import organization settings for
consistency across the project.

- **Refactor**
- Reordered import statements in multiple files for improved
readability.
- Simplified function signatures and ensured proper async handling in
utility scripts.

- **Bug Fixes**
- Ensured proper completion of asynchronous operations in shell utility
functions.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Gonza Montiel <gonzamontiel@users.noreply.github.com>
2025-05-19 22:28:43 +00:00

76 lines
1.9 KiB
TypeScript

import { existsSync } from "node:fs";
import { spawn } from "bun";
import { logger } from "./logger";
export type LogLevel = "info" | "debug" | "error" | "warn";
export const runShellCommandWithLogger = async (
command: string,
options?: {
cwd?: string;
env?: object;
logLevel?: LogLevel;
waitFor?: (...args: unknown[]) => Promise<void>;
}
) => {
const { cwd = ".", env = {}, logLevel = "info" as LogLevel } = options || {};
try {
if (!existsSync(cwd)) {
logger.error("❌ CWD does not exist:", cwd);
throw new Error("❌ CWD does not exist");
}
const proc = spawn(["sh", "-c", command], {
cwd,
stdout: "pipe",
stderr: "pipe",
env: {
...process.env,
...env
}
});
const stdoutReader = proc.stdout.getReader();
const stderrReader = proc.stderr.getReader();
const readStream = async (
reader: typeof stdoutReader | typeof stderrReader,
streamName: string,
logLevel: LogLevel
) => {
try {
while (true) {
const { done, value } = await reader.read();
if (done) break;
const text = new TextDecoder().decode(value);
const trimmedText = text.trim();
if (trimmedText) {
logger[logLevel](
trimmedText.includes("\n") ? `>_ \n${trimmedText}` : `>_ ${trimmedText}`
);
}
}
} catch (err) {
logger.error(`Error reading from ${streamName} stream:`, err);
} finally {
reader.releaseLock();
}
};
await Promise.all([
readStream(stdoutReader, "stdout", logLevel),
readStream(stderrReader, "stderr", "error")
]);
if (options?.waitFor) {
await options.waitFor();
}
await proc.exited;
} catch (err) {
logger.error("❌ Error running shell command:", command, "in", cwd);
logger.error(err);
throw err;
}
};