-
Notifications
You must be signed in to change notification settings - Fork 4
/
ResolveCommand.js
50 lines (43 loc) · 2.11 KB
/
ResolveCommand.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import { spawnSync } from 'child_process'
import { resolve } from 'path'
import { run } from './Run'
const configureWin32 = (extList = (process.env.PATHEXT || '.EXE;.BAT;.CMD').toUpperCase().split(';')) => [ // process.env.PATHEXT // '.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC'
'where.exe', // search cwd // https://ss64.com/nt/where.html
(stdoutString) => stdoutString.split('\r\n').find((path) => extList.includes(path.slice(path.lastIndexOf('.')).toUpperCase())) || ''
]
const configureLinux = () => [
'which', // do not search cwd // https://ss64.com/bash/which.html
(stdoutString) => stdoutString.trim()
]
const CONFIGURE_MAP = {
linux: configureLinux,
win32: configureWin32,
darwin: configureLinux,
android: configureLinux
}
let cacheConfigure
const configureCached = () => {
if (cacheConfigure === undefined) {
const configure = CONFIGURE_MAP[ process.platform ]
if (!configure) throw new Error(`unsupported platform: ${process.platform}`)
cacheConfigure = configure()
}
return cacheConfigure
}
const resolveCommandName = (commandName, cwd) => { // if not found, result in empty string: ""
const [ checkCommand, processFunc ] = configureCached()
return processFunc(String(spawnSync(checkCommand, [ commandName ], { cwd }).stdout || ''))
}
const resolveCommandNameAsync = async (commandName, cwd) => { // if not found, result in empty string: ""
const [ checkCommand, processFunc ] = configureCached()
const { promise, stdoutPromise } = run({ command: checkCommand, argList: [ commandName ], option: { cwd }, quiet: true })
return processFunc(String(await promise.then(() => stdoutPromise, () => '')))
}
// try resolve command, fast resolve if command itself contain path sep
const resolveCommand = (command, cwd) => REGEXP_PATH_SEP.test(command) ? resolve(cwd || '', command) : resolveCommandName(command, cwd)
const resolveCommandAsync = async (command, cwd) => REGEXP_PATH_SEP.test(command) ? resolve(cwd || '', command) : resolveCommandNameAsync(command, cwd)
const REGEXP_PATH_SEP = /[\\/]/
export {
resolveCommandName, resolveCommandNameAsync,
resolveCommand, resolveCommandAsync
}