(binary: string)
| 30 | * need version/feature info should do that separately. |
| 31 | */ |
| 32 | export function findOnPath(binary: string): string | null { |
| 33 | const PATH = process.env.PATH; |
| 34 | if (typeof PATH !== "string" || PATH.length === 0) return null; |
| 35 | |
| 36 | const isWindows = process.platform === "win32"; |
| 37 | const dirs = PATH.split(delimiter); |
| 38 | |
| 39 | // Windows: try common executable extensions per directory. |
| 40 | // POSIX: just the bare name. |
| 41 | const candidates = isWindows |
| 42 | ? [`${binary}.exe`, `${binary}.cmd`, `${binary}.bat`, `${binary}.com`] |
| 43 | : [binary]; |
| 44 | |
| 45 | for (const dir of dirs) { |
| 46 | if (!dir) continue; // empty PATH segments (rare but valid) |
| 47 | for (const candidate of candidates) { |
| 48 | const fullPath = join(dir, candidate); |
| 49 | if (isExecutable(fullPath, isWindows)) return fullPath; |
| 50 | } |
| 51 | } |
| 52 | return null; |
| 53 | } |
| 54 | |
| 55 | function isExecutable(path: string, isWindows: boolean): boolean { |
| 56 | try { |
no test coverage detected