diff --git a/eslint.config.js b/eslint.config.js index 08d5c2f..8d16c0f 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -33,7 +33,7 @@ export default defineConfig([ "@typescript-eslint/no-explicit-any": "off", "@typescript-eslint/strict-boolean-expressions": "off", "@typescript-eslint/no-floating-promises": "error", - "@typescript-eslint/prefer-nullish-coalescing": "error", + "@typescript-eslint/prefer-nullish-coalescing": "warn", "@typescript-eslint/prefer-optional-chain": "error", "@typescript-eslint/no-unnecessary-type-assertion": "error", "@typescript-eslint/no-unnecessary-condition": "warn", diff --git a/src/unityEditor.ts b/src/unityEditor.ts index d36c4fe..05fc2ad 100644 --- a/src/unityEditor.ts +++ b/src/unityEditor.ts @@ -3,7 +3,7 @@ import fs from "fs-extra"; import path from "path"; import { ProjectInfo, TestMode, UnityBuildTarget, UnityEditorInfo } from "./types/unity.js"; import { CommandOptions, CommandResult, executeCommand } from "./utils/commandExecutor.js"; -import { redactSensitiveArgs } from "utils/security.js"; +import { redactSensitiveArgs } from "./utils/security.js"; /** * UnityEditor class provides a comprehensive interface for interacting with the Unity game engine editor diff --git a/src/unityHub.ts b/src/unityHub.ts index 8d7ced6..75234c4 100644 --- a/src/unityHub.ts +++ b/src/unityHub.ts @@ -234,12 +234,16 @@ class UnityHub { throw new Error("No module IDs provided."); } - const { stdout, stderr } = await this.execUnityHubCommand(args, { + const { stderr } = await this.execUnityHubCommand(args, { reject: false, + onStderr: (data: string) => { + console.warn(`Unity Hub stderr: ${data}`); + }, + onStdout: (data: string) => { + console.debug(`Unity Hub stdout: ${data}`); + }, }); - console.debug(`Add module command output: ${stdout}`); - if (stderr) { console.warn(`Add module command warning/error: ${stderr}`); } @@ -286,6 +290,12 @@ class UnityHub { const { stdout, stderr } = await this.execUnityHubCommand(args, { reject: false, + onStderr: (data: string) => { + console.warn(`Unity Hub stderr: ${data}`); + }, + onStdout: (data: string) => { + console.debug(`Unity Hub stdout: ${data}`); + }, }); if (stderr) { diff --git a/src/utils/commandExecutor.ts b/src/utils/commandExecutor.ts index 1950e50..173c6aa 100644 --- a/src/utils/commandExecutor.ts +++ b/src/utils/commandExecutor.ts @@ -3,6 +3,8 @@ import { Options, execa } from "execa"; export interface CommandOptions extends Options { reject?: boolean; timeout?: number; + onStdout?: (data: string) => void; + onStderr?: (data: string) => void; env?: Record; cwd?: string; } @@ -20,26 +22,44 @@ export async function executeCommand( options: CommandOptions = {} ): Promise { try { + const streamOutput = options.onStdout || options.onStderr; + const subprocess = execa(executable, args, { reject: options.reject ?? false, timeout: options.timeout, env: options.env, cwd: options.cwd, encoding: "utf8", + buffer: !streamOutput, }); - /* - // Pipe the output to the parent process - // This is commented out to avoid cluttering the output - // Uncomment if you want to see the output in real-time - if (subprocess.stdout) { - subprocess.stdout.pipe(process.stdout); - } + if (streamOutput) { + if (subprocess.stdout) { + subprocess.stdout.on("data", (data: Buffer) => { + const lines = data.toString().split(/\r?\n/); + for (const line of lines) { + if (line.trim()) { + if (options.onStdout) { + options.onStdout(line); + } + } + } + }); + } - if (subprocess.stderr) { - subprocess.stderr.pipe(process.stderr); + if (subprocess.stderr) { + subprocess.stderr.on("data", (data: Buffer) => { + const lines = data.toString().split(/\r?\n/); + for (const line of lines) { + if (line.trim()) { + if (options.onStderr) { + options.onStderr(line); + } + } + } + }); + } } - */ const { stdout, stderr, exitCode } = await subprocess;