You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
135 lines
3.1 KiB
135 lines
3.1 KiB
module.exports = which |
|
which.sync = whichSync |
|
|
|
var isWindows = process.platform === 'win32' || |
|
process.env.OSTYPE === 'cygwin' || |
|
process.env.OSTYPE === 'msys' |
|
|
|
var path = require('path') |
|
var COLON = isWindows ? ';' : ':' |
|
var isexe = require('isexe') |
|
|
|
function getNotFoundError (cmd) { |
|
var er = new Error('not found: ' + cmd) |
|
er.code = 'ENOENT' |
|
|
|
return er |
|
} |
|
|
|
function getPathInfo (cmd, opt) { |
|
var colon = opt.colon || COLON |
|
var pathEnv = opt.path || process.env.PATH || '' |
|
var pathExt = [''] |
|
|
|
pathEnv = pathEnv.split(colon) |
|
|
|
var pathExtExe = '' |
|
if (isWindows) { |
|
pathEnv.unshift(process.cwd()) |
|
pathExtExe = (opt.pathExt || process.env.PATHEXT || '.EXE;.CMD;.BAT;.COM') |
|
pathExt = pathExtExe.split(colon) |
|
|
|
|
|
// Always test the cmd itself first. isexe will check to make sure |
|
// it's found in the pathExt set. |
|
if (cmd.indexOf('.') !== -1 && pathExt[0] !== '') |
|
pathExt.unshift('') |
|
} |
|
|
|
// If it has a slash, then we don't bother searching the pathenv. |
|
// just check the file itself, and that's it. |
|
if (cmd.match(/\//) || isWindows && cmd.match(/\\/)) |
|
pathEnv = [''] |
|
|
|
return { |
|
env: pathEnv, |
|
ext: pathExt, |
|
extExe: pathExtExe |
|
} |
|
} |
|
|
|
function which (cmd, opt, cb) { |
|
if (typeof opt === 'function') { |
|
cb = opt |
|
opt = {} |
|
} |
|
|
|
var info = getPathInfo(cmd, opt) |
|
var pathEnv = info.env |
|
var pathExt = info.ext |
|
var pathExtExe = info.extExe |
|
var found = [] |
|
|
|
;(function F (i, l) { |
|
if (i === l) { |
|
if (opt.all && found.length) |
|
return cb(null, found) |
|
else |
|
return cb(getNotFoundError(cmd)) |
|
} |
|
|
|
var pathPart = pathEnv[i] |
|
if (pathPart.charAt(0) === '"' && pathPart.slice(-1) === '"') |
|
pathPart = pathPart.slice(1, -1) |
|
|
|
var p = path.join(pathPart, cmd) |
|
if (!pathPart && (/^\.[\\\/]/).test(cmd)) { |
|
p = cmd.slice(0, 2) + p |
|
} |
|
;(function E (ii, ll) { |
|
if (ii === ll) return F(i + 1, l) |
|
var ext = pathExt[ii] |
|
isexe(p + ext, { pathExt: pathExtExe }, function (er, is) { |
|
if (!er && is) { |
|
if (opt.all) |
|
found.push(p + ext) |
|
else |
|
return cb(null, p + ext) |
|
} |
|
return E(ii + 1, ll) |
|
}) |
|
})(0, pathExt.length) |
|
})(0, pathEnv.length) |
|
} |
|
|
|
function whichSync (cmd, opt) { |
|
opt = opt || {} |
|
|
|
var info = getPathInfo(cmd, opt) |
|
var pathEnv = info.env |
|
var pathExt = info.ext |
|
var pathExtExe = info.extExe |
|
var found = [] |
|
|
|
for (var i = 0, l = pathEnv.length; i < l; i ++) { |
|
var pathPart = pathEnv[i] |
|
if (pathPart.charAt(0) === '"' && pathPart.slice(-1) === '"') |
|
pathPart = pathPart.slice(1, -1) |
|
|
|
var p = path.join(pathPart, cmd) |
|
if (!pathPart && /^\.[\\\/]/.test(cmd)) { |
|
p = cmd.slice(0, 2) + p |
|
} |
|
for (var j = 0, ll = pathExt.length; j < ll; j ++) { |
|
var cur = p + pathExt[j] |
|
var is |
|
try { |
|
is = isexe.sync(cur, { pathExt: pathExtExe }) |
|
if (is) { |
|
if (opt.all) |
|
found.push(cur) |
|
else |
|
return cur |
|
} |
|
} catch (ex) {} |
|
} |
|
} |
|
|
|
if (opt.all && found.length) |
|
return found |
|
|
|
if (opt.nothrow) |
|
return null |
|
|
|
throw getNotFoundError(cmd) |
|
}
|
|
|