136 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
		
		
			
		
	
	
			136 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
|  | 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) | ||
|  | } |