diff --git a/src/utils/which.ts b/src/utils/which.ts index d7dcbd88b8..0254daaf7c 100644 --- a/src/utils/which.ts +++ b/src/utils/which.ts @@ -1,11 +1,10 @@ import { execa } from 'execa' -import { execSync_DEPRECATED } from './execSyncWrapper.js' +import { spawnSync } from 'node:child_process' async function whichNodeAsync(command: string): Promise { if (process.platform === 'win32') { // On Windows, use where.exe and return the first result - const result = await execa(`where.exe ${command}`, { - shell: true, + const result = await execa('where.exe', [command], { stderr: 'ignore', reject: false, }) @@ -19,8 +18,7 @@ async function whichNodeAsync(command: string): Promise { // On POSIX systems (macOS, Linux, WSL), use which // Cross-platform safe: Windows is handled above // eslint-disable-next-line custom-rules/no-cross-platform-process-issues - const result = await execa(`which ${command}`, { - shell: true, + const result = await execa('which', [command], { stderr: 'ignore', reject: false, }) @@ -33,11 +31,15 @@ async function whichNodeAsync(command: string): Promise { function whichNodeSync(command: string): string | null { if (process.platform === 'win32') { try { - const result = execSync_DEPRECATED(`where.exe ${command}`, { + const result = spawnSync('where.exe', [command], { + shell: false, encoding: 'utf-8', stdio: ['ignore', 'pipe', 'ignore'], }) - const output = result.toString().trim() + if (result.status !== 0 || !result.stdout) { + return null + } + const output = result.stdout.toString().trim() return output.split(/\r?\n/)[0] || null } catch { return null @@ -45,11 +47,15 @@ function whichNodeSync(command: string): string | null { } try { - const result = execSync_DEPRECATED(`which ${command}`, { + const result = spawnSync('which', [command], { + shell: false, encoding: 'utf-8', stdio: ['ignore', 'pipe', 'ignore'], }) - return result.toString().trim() || null + if (result.status !== 0 || !result.stdout) { + return null + } + return result.stdout.toString().trim() || null } catch { return null }