Blame view

node_modules/which/which.js 3.11 KB
aaac7fed   liuqimichale   add
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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
  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)
  }