parent
f34a4e394e
commit
dffa78e3dc
@ -0,0 +1,80 @@ |
|||||||
|
import path from "path"; |
||||||
|
import process from "process"; |
||||||
|
import { Stats } from "fs"; |
||||||
|
import fs from 'fs/promises' |
||||||
|
|
||||||
|
export async function findExecutable(command: string, cwd?: string, paths?: string[]): Promise<string> { |
||||||
|
// If we have an absolute path then we take it.
|
||||||
|
if (path.isAbsolute(command)) { |
||||||
|
return command; |
||||||
|
} |
||||||
|
if (cwd === undefined) { |
||||||
|
cwd = process.cwd(); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
const dir = path.dirname(command); |
||||||
|
if (dir !== '.') { |
||||||
|
// We have a directory and the directory is relative (see above). Make the path absolute
|
||||||
|
// to the current working directory.
|
||||||
|
return path.join(cwd, command); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (paths === undefined && typeof process.env['PATH'] === 'string') {
|
||||||
|
paths = (process && process.env['PATH'] && process.env['PATH'].split(path.delimiter)) || []; |
||||||
|
} |
||||||
|
// No PATH environment. Make path absolute to the cwd.
|
||||||
|
if (paths === undefined || paths.length === 0) { |
||||||
|
return path.join(cwd, command); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
async function fileExists(path: string): Promise<boolean> { |
||||||
|
|
||||||
|
try { |
||||||
|
if (await fs.stat(path)) { |
||||||
|
let statValue: Stats | undefined; |
||||||
|
try { |
||||||
|
statValue = await fs.stat(path); |
||||||
|
} catch (e: any) { |
||||||
|
if (e.message.startsWith('EACCES')) { |
||||||
|
// it might be symlink
|
||||||
|
statValue = await fs.lstat(path); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return statValue ? !statValue.isDirectory() : false; |
||||||
|
} |
||||||
|
} catch (e) { |
||||||
|
} |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
// We have a simple file name. We get the path variable from the env
|
||||||
|
// and try to find the executable on the path.
|
||||||
|
for (const pathEntry of paths) { |
||||||
|
|
||||||
|
// The path entry is absolute.
|
||||||
|
let fullPath: string; |
||||||
|
if (path.isAbsolute(pathEntry)) { |
||||||
|
fullPath = path.join(pathEntry, command); |
||||||
|
} else { |
||||||
|
fullPath = path.join(cwd, pathEntry, command); |
||||||
|
} |
||||||
|
if (await fileExists(fullPath)) { |
||||||
|
return fullPath; |
||||||
|
} |
||||||
|
let withExtension = fullPath + '.com'; |
||||||
|
if (await fileExists(withExtension)) { |
||||||
|
return withExtension; |
||||||
|
} |
||||||
|
withExtension = fullPath + '.exe'; |
||||||
|
if (await fileExists(withExtension)) { |
||||||
|
return withExtension; |
||||||
|
} |
||||||
|
} |
||||||
|
return path.join(cwd, command); |
||||||
|
} |
Loading…
Reference in new issue