Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/npm/cli.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRebecca Turner <me@re-becca.org>2016-01-28 03:42:20 +0300
committerRebecca Turner <me@re-becca.org>2016-01-29 01:58:48 +0300
commit9e5c84f1903748897e54f8ff099729ff744eab0f (patch)
treef42bed5ee7a8bdd3764f4d1df29a8287855756b5 /node_modules/which
parent375b9c42fe0c6de47ac2f92527354b2ea79b7968 (diff)
which@1.2.4
Update `isexe` and fix bug in pathExt, in which files without extensions would sometimes be preferred to files with extensions on Windows, even though those without extensions aren't executable. pathExt is a list of extensions that are considered executable (exe, cmd, bat, com on Windows). Credit: @isaacs
Diffstat (limited to 'node_modules/which')
-rw-r--r--node_modules/which/.npmignore3
-rw-r--r--node_modules/which/node_modules/isexe/.npmignore2
-rw-r--r--node_modules/which/node_modules/isexe/README.md51
-rw-r--r--node_modules/which/node_modules/isexe/access.js15
-rw-r--r--node_modules/which/node_modules/isexe/index.js59
-rw-r--r--node_modules/which/node_modules/isexe/mode.js37
-rw-r--r--node_modules/which/node_modules/isexe/package.json80
-rw-r--r--node_modules/which/node_modules/isexe/test/basic.js211
-rw-r--r--node_modules/which/node_modules/isexe/windows.js36
-rw-r--r--node_modules/which/package.json38
-rw-r--r--node_modules/which/test/basic.js33
-rw-r--r--node_modules/which/test/windows.js10
-rw-r--r--node_modules/which/which.js58
13 files changed, 572 insertions, 61 deletions
diff --git a/node_modules/which/.npmignore b/node_modules/which/.npmignore
new file mode 100644
index 000000000..0ac606ffc
--- /dev/null
+++ b/node_modules/which/.npmignore
@@ -0,0 +1,3 @@
+.nyc_output/
+coverage/
+node_modules/
diff --git a/node_modules/which/node_modules/isexe/.npmignore b/node_modules/which/node_modules/isexe/.npmignore
new file mode 100644
index 000000000..c1cb757ac
--- /dev/null
+++ b/node_modules/which/node_modules/isexe/.npmignore
@@ -0,0 +1,2 @@
+.nyc_output/
+coverage/
diff --git a/node_modules/which/node_modules/isexe/README.md b/node_modules/which/node_modules/isexe/README.md
new file mode 100644
index 000000000..30995ad7d
--- /dev/null
+++ b/node_modules/which/node_modules/isexe/README.md
@@ -0,0 +1,51 @@
+# isexe
+
+Minimal module to check if a file is executable.
+
+Uses `fs.access` if available, and tests against the `PATHEXT`
+environment variable on Windows.
+
+## USAGE
+
+```javascript
+var isexe = require('isexe')
+isexe('some-file-name', function (err, isExe) {
+ if (err) {
+ console.error('probably file does not exist or something', err)
+ } else if (isExe) {
+ console.error('this thing can be run')
+ } else {
+ console.error('cannot be run')
+ }
+})
+
+// same thing but synchronous, throws errors
+var isExe = isexe.sync('some-file-name')
+
+// treat errors as just "not executable"
+isexe('maybe-missing-file', { ignoreErrors: true }, callback)
+var isExe = isexe.sync('maybe-missing-file', { ignoreErrors: true })
+```
+
+## API
+
+### `isexe(path, [options], [callback])`
+
+Check if the path is executable. If no callback provided, and a
+global `Promise` object is available, then a Promise will be returned.
+
+Will raise whatever errors may be raised by `fs.access` or `fs.stat`,
+unless `options.ignoreErrors` is set to true.
+
+### `isexe.sync(path, [options])`
+
+Same as `isexe` but returns the value and throws any errors raised.
+
+### Options
+
+* `ignoreErrors` Treat all errors as "no, this is not executable", but
+ don't raise them.
+* `uid` Number to use as the user id when using the `mode` approach.
+* `gid` Number to use as the group id when using the `mode` approach.
+* `pathExt` List of path extensions to use instead of `PATHEXT`
+ environment variable on Windows.
diff --git a/node_modules/which/node_modules/isexe/access.js b/node_modules/which/node_modules/isexe/access.js
new file mode 100644
index 000000000..e67b28bd6
--- /dev/null
+++ b/node_modules/which/node_modules/isexe/access.js
@@ -0,0 +1,15 @@
+module.exports = isexe
+isexe.sync = sync
+
+var fs = require('fs')
+
+function isexe (path, _, cb) {
+ fs.access(path, fs.X_OK, function (er) {
+ cb(er, !er)
+ })
+}
+
+function sync (path, _) {
+ fs.accessSync(path, fs.X_OK)
+ return true
+}
diff --git a/node_modules/which/node_modules/isexe/index.js b/node_modules/which/node_modules/isexe/index.js
new file mode 100644
index 000000000..ff8ef113b
--- /dev/null
+++ b/node_modules/which/node_modules/isexe/index.js
@@ -0,0 +1,59 @@
+var fs = require('fs')
+var core
+if (process.platform === 'win32' || global.TESTING_WINDOWS) {
+ core = require('./windows.js')
+} else if (typeof fs.access === 'function') {
+ core = require('./access.js')
+} else {
+ core = require('./mode.js')
+}
+
+module.exports = isexe
+isexe.sync = sync
+
+function isexe (path, options, cb) {
+ if (typeof options === 'function') {
+ cb = options
+ options = {}
+ }
+
+ if (!cb) {
+ if (typeof Promise !== 'function') {
+ throw new TypeError('callback not provided')
+ }
+
+ return new Promise(function (resolve, reject) {
+ isexe(path, options || {}, function (er, is) {
+ if (er) {
+ reject(er)
+ } else {
+ resolve(is)
+ }
+ })
+ })
+ }
+
+ core(path, options || {}, function (er, is) {
+ // ignore EACCES because that just means we aren't allowed to run it
+ if (er) {
+ if (er.code === 'EACCES' || options && options.ignoreErrors) {
+ er = null
+ is = false
+ }
+ }
+ cb(er, is)
+ })
+}
+
+function sync (path, options) {
+ // my kingdom for a filtered catch
+ try {
+ return core.sync(path, options || {})
+ } catch (er) {
+ if (options && options.ignoreErrors || er.code === 'EACCES') {
+ return false
+ } else {
+ throw er
+ }
+ }
+}
diff --git a/node_modules/which/node_modules/isexe/mode.js b/node_modules/which/node_modules/isexe/mode.js
new file mode 100644
index 000000000..204428072
--- /dev/null
+++ b/node_modules/which/node_modules/isexe/mode.js
@@ -0,0 +1,37 @@
+module.exports = isexe
+isexe.sync = sync
+
+var fs = require('fs')
+
+function isexe (path, options, cb) {
+ fs.stat(path, function (er, st) {
+ cb(er, er ? false : checkMode(st, options))
+ })
+}
+
+function sync (path, options) {
+ return checkMode(fs.statSync(path), options)
+}
+
+function checkMode (stat, options) {
+ var mod = stat.mode
+ var uid = stat.uid
+ var gid = stat.gid
+
+ var myUid = options.uid !== undefined ?
+ options.uid : process.getuid && process.getuid()
+ var myGid = options.gid !== undefined ?
+ options.gid : process.getgid && process.getgid()
+
+ var u = parseInt('100', 8)
+ var g = parseInt('010', 8)
+ var o = parseInt('001', 8)
+ var ug = u | g
+
+ var ret = (mod & o) ||
+ (mod & g) && gid === myGid ||
+ (mod & u) && uid === myUid ||
+ (mod & ug) && myUid === 0
+
+ return ret
+}
diff --git a/node_modules/which/node_modules/isexe/package.json b/node_modules/which/node_modules/isexe/package.json
new file mode 100644
index 000000000..49aeeab2a
--- /dev/null
+++ b/node_modules/which/node_modules/isexe/package.json
@@ -0,0 +1,80 @@
+{
+ "_args": [
+ [
+ "isexe@^1.1.1",
+ "/Users/rebecca/code/npm/node_modules/which"
+ ]
+ ],
+ "_from": "isexe@>=1.1.1 <2.0.0",
+ "_id": "isexe@1.1.1",
+ "_inCache": true,
+ "_installable": true,
+ "_location": "/which/isexe",
+ "_nodeVersion": "4.0.0",
+ "_npmUser": {
+ "email": "i@izs.me",
+ "name": "isaacs"
+ },
+ "_npmVersion": "2.14.15",
+ "_phantomChildren": {},
+ "_requested": {
+ "name": "isexe",
+ "raw": "isexe@^1.1.1",
+ "rawSpec": "^1.1.1",
+ "scope": null,
+ "spec": ">=1.1.1 <2.0.0",
+ "type": "range"
+ },
+ "_requiredBy": [
+ "/which"
+ ],
+ "_resolved": "https://registry.npmjs.org/isexe/-/isexe-1.1.1.tgz",
+ "_shasum": "f0d4793ed2fb5c46bfdeab760bbb965f4485a66c",
+ "_shrinkwrap": null,
+ "_spec": "isexe@^1.1.1",
+ "_where": "/Users/rebecca/code/npm/node_modules/which",
+ "author": {
+ "email": "i@izs.me",
+ "name": "Isaac Z. Schlueter",
+ "url": "http://blog.izs.me/"
+ },
+ "bugs": {
+ "url": "https://github.com/isaacs/isexe/issues"
+ },
+ "dependencies": {},
+ "description": "Minimal module to check if a file is executable.",
+ "devDependencies": {
+ "mkdirp": "^0.5.1",
+ "rimraf": "^2.5.0",
+ "tap": "^5.1.2"
+ },
+ "directories": {
+ "test": "test"
+ },
+ "dist": {
+ "shasum": "f0d4793ed2fb5c46bfdeab760bbb965f4485a66c",
+ "tarball": "http://registry.npmjs.org/isexe/-/isexe-1.1.1.tgz"
+ },
+ "gitHead": "af83031caed58654ad9d20b98eb710d383618ad7",
+ "homepage": "https://github.com/isaacs/isexe#readme",
+ "keywords": [],
+ "license": "ISC",
+ "main": "index.js",
+ "maintainers": [
+ {
+ "name": "isaacs",
+ "email": "i@izs.me"
+ }
+ ],
+ "name": "isexe",
+ "optionalDependencies": {},
+ "readme": "ERROR: No README data found!",
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/isaacs/isexe.git"
+ },
+ "scripts": {
+ "test": "tap test/*.js --branches=100 --statements=100 --functions=100 --lines=100"
+ },
+ "version": "1.1.1"
+}
diff --git a/node_modules/which/node_modules/isexe/test/basic.js b/node_modules/which/node_modules/isexe/test/basic.js
new file mode 100644
index 000000000..969fc9a0a
--- /dev/null
+++ b/node_modules/which/node_modules/isexe/test/basic.js
@@ -0,0 +1,211 @@
+var t = require('tap')
+var fs = require('fs')
+var path = require('path')
+var fixture = path.resolve(__dirname, 'fixtures')
+var meow = fixture + '/meow.cat'
+var mine = fixture + '/mine.cat'
+var ours = fixture + '/ours.cat'
+var fail = fixture + '/fail.false'
+var noent = fixture + '/enoent.exe'
+var mkdirp = require('mkdirp')
+var rimraf = require('rimraf')
+
+var isWindows = process.platform === 'win32'
+var hasAccess = typeof fs.access === 'function'
+var winSkip = isWindows && 'windows'
+var accessSkip = !hasAccess && 'no fs.access function'
+var hasPromise = typeof Promise === 'function'
+var promiseSkip = !hasPromise && 'no global Promise'
+
+function reset () {
+ delete require.cache[require.resolve('../')]
+ return require('../')
+}
+
+t.test('setup fixtures', function (t) {
+ rimraf.sync(fixture)
+ mkdirp.sync(fixture)
+ fs.writeFileSync(meow, '#!/usr/bin/env cat\nmeow\n')
+ fs.chmodSync(meow, parseInt('0755', 8))
+ fs.writeFileSync(fail, '#!/usr/bin/env false\n')
+ fs.chmodSync(fail, parseInt('0644', 8))
+ fs.writeFileSync(mine, '#!/usr/bin/env cat\nmine\n')
+ fs.chmodSync(mine, parseInt('0744', 8))
+ fs.writeFileSync(ours, '#!/usr/bin/env cat\nours\n')
+ fs.chmodSync(ours, parseInt('0754', 8))
+ t.end()
+})
+
+t.test('promise', { skip: promiseSkip }, function (t) {
+ var isexe = reset()
+ t.test('meow async', function (t) {
+ isexe(meow).then(function (is) {
+ t.ok(is)
+ t.end()
+ })
+ })
+ t.test('fail async', function (t) {
+ isexe(fail).then(function (is) {
+ t.notOk(is)
+ t.end()
+ })
+ })
+ t.test('noent async', function (t) {
+ isexe(noent).catch(function (er) {
+ t.ok(er)
+ t.end()
+ })
+ })
+ t.test('noent ignore async', function (t) {
+ isexe(noent, { ignoreErrors: true }).then(function (is) {
+ t.notOk(is)
+ t.end()
+ })
+ })
+ t.end()
+})
+
+t.test('no promise', function (t) {
+ global.Promise = null
+ var isexe = reset()
+ t.throws('try to meow a promise', function () {
+ isexe(meow)
+ })
+ t.end()
+})
+
+t.test('access', { skip: accessSkip || winSkip }, function (t) {
+ runTest(t)
+})
+
+t.test('mode', { skip: winSkip }, function (t) {
+ delete fs.access
+ delete fs.accessSync
+ var isexe = reset()
+ t.ok(isexe.sync(ours, { uid: 0, gid: 0 }))
+ t.ok(isexe.sync(mine, { uid: 0, gid: 0 }))
+ runTest(t)
+})
+
+t.test('windows', function (t) {
+ global.TESTING_WINDOWS = true
+ var pathExt = '.EXE;.CAT;.CMD;.COM'
+ t.test('pathExt option', function (t) {
+ runTest(t, { pathExt: '.EXE;.CAT;.CMD;.COM' })
+ })
+ t.test('pathExt env', function (t) {
+ process.env.PATHEXT = pathExt
+ runTest(t)
+ })
+ t.test('no pathExt', function (t) {
+ // with a pathExt of '', any filename is fine.
+ // so the "fail" one would still pass.
+ runTest(t, { pathExt: '', skipFail: true })
+ })
+ t.test('pathext with empty entry', function (t) {
+ // with a pathExt of '', any filename is fine.
+ // so the "fail" one would still pass.
+ runTest(t, { pathExt: ';' + pathExt, skipFail: true })
+ })
+ t.end()
+})
+
+t.test('cleanup', function (t) {
+ rimraf.sync(fixture)
+ t.end()
+})
+
+function runTest (t, options) {
+ var isexe = reset()
+
+ var optionsIgnore = Object.create(options || {})
+ optionsIgnore.ignoreErrors = true
+
+ if (!options || !options.skipFail) {
+ t.notOk(isexe.sync(fail, options))
+ }
+ t.notOk(isexe.sync(noent, optionsIgnore))
+ if (!options) {
+ t.ok(isexe.sync(meow))
+ } else {
+ t.ok(isexe.sync(meow, options))
+ }
+
+ t.ok(isexe.sync(mine, options))
+ t.ok(isexe.sync(ours, options))
+ t.throws(function () {
+ isexe.sync(noent, options)
+ })
+
+ t.test('meow async', function (t) {
+ if (!options) {
+ isexe(meow, function (er, is) {
+ if (er) {
+ throw er
+ }
+ t.ok(is)
+ t.end()
+ })
+ } else {
+ isexe(meow, options, function (er, is) {
+ if (er) {
+ throw er
+ }
+ t.ok(is)
+ t.end()
+ })
+ }
+ })
+
+ t.test('mine async', function (t) {
+ isexe(mine, options, function (er, is) {
+ if (er) {
+ throw er
+ }
+ t.ok(is)
+ t.end()
+ })
+ })
+
+ t.test('ours async', function (t) {
+ isexe(ours, options, function (er, is) {
+ if (er) {
+ throw er
+ }
+ t.ok(is)
+ t.end()
+ })
+ })
+
+ if (!options || !options.skipFail) {
+ t.test('fail async', function (t) {
+ isexe(fail, options, function (er, is) {
+ if (er) {
+ throw er
+ }
+ t.notOk(is)
+ t.end()
+ })
+ })
+ }
+
+ t.test('noent async', function (t) {
+ isexe(noent, options, function (er, is) {
+ t.ok(er)
+ t.notOk(is)
+ t.end()
+ })
+ })
+
+ t.test('noent ignore async', function (t) {
+ isexe(noent, optionsIgnore, function (er, is) {
+ if (er) {
+ throw er
+ }
+ t.notOk(is)
+ t.end()
+ })
+ })
+
+ t.end()
+}
diff --git a/node_modules/which/node_modules/isexe/windows.js b/node_modules/which/node_modules/isexe/windows.js
new file mode 100644
index 000000000..aba8561f3
--- /dev/null
+++ b/node_modules/which/node_modules/isexe/windows.js
@@ -0,0 +1,36 @@
+module.exports = isexe
+isexe.sync = sync
+
+var fs = require('fs')
+
+function checkPathExt (path, options) {
+ var pathext = options.pathExt !== undefined ?
+ options.pathExt : process.env.PATHEXT
+
+ if (!pathext) {
+ return true
+ }
+
+ pathext = pathext.split(';')
+ if (pathext.indexOf('') !== -1) {
+ return true
+ }
+ for (var i = 0; i < pathext.length; i++) {
+ var p = pathext[i].toLowerCase()
+ if (p && path.substr(-p.length).toLowerCase() === p) {
+ return true
+ }
+ }
+ return false
+}
+
+function isexe (path, options, cb) {
+ fs.stat(path, function (er, st) {
+ cb(er, er ? false : checkPathExt(path, options))
+ })
+}
+
+function sync (path, options) {
+ fs.statSync(path)
+ return checkPathExt(path, options)
+}
diff --git a/node_modules/which/package.json b/node_modules/which/package.json
index 79d84875b..04f90fa68 100644
--- a/node_modules/which/package.json
+++ b/node_modules/which/package.json
@@ -1,12 +1,12 @@
{
"_args": [
[
- "which@1.2.1",
+ "which@~1.2.1",
"/Users/rebecca/code/npm"
]
],
- "_from": "which@1.2.1",
- "_id": "which@1.2.1",
+ "_from": "which@>=1.2.1 <1.3.0",
+ "_id": "which@1.2.4",
"_inCache": true,
"_installable": true,
"_location": "/which",
@@ -15,26 +15,27 @@
"email": "i@izs.me",
"name": "isaacs"
},
- "_npmVersion": "3.3.2",
+ "_npmVersion": "2.14.15",
"_phantomChildren": {},
"_requested": {
"name": "which",
- "raw": "which@1.2.1",
- "rawSpec": "1.2.1",
+ "raw": "which@~1.2.1",
+ "rawSpec": "~1.2.1",
"scope": null,
- "spec": "1.2.1",
- "type": "version"
+ "spec": ">=1.2.1 <1.3.0",
+ "type": "range"
},
"_requiredBy": [
"/",
"/node-gyp",
"/standard/standard-format/esformatter/npm-run/npm-path",
+ "/tap/foreground-child/cross-spawn-async",
"/tap/nyc/istanbul"
],
- "_resolved": "https://registry.npmjs.org/which/-/which-1.2.1.tgz",
- "_shasum": "a010c43aade1a798a3e6c1b1e453d45cb497a2bc",
+ "_resolved": "https://registry.npmjs.org/which/-/which-1.2.4.tgz",
+ "_shasum": "1557f96080604e5b11b3599eb9f45b50a9efd722",
"_shrinkwrap": null,
- "_spec": "which@1.2.1",
+ "_spec": "which@~1.2.1",
"_where": "/Users/rebecca/code/npm",
"author": {
"email": "i@izs.me",
@@ -48,20 +49,21 @@
"url": "https://github.com/isaacs/node-which/issues"
},
"dependencies": {
- "is-absolute": "^0.1.7"
+ "is-absolute": "^0.1.7",
+ "isexe": "^1.1.1"
},
"description": "Like which(1) unix command. Find the first instance of an executable in the PATH.",
"devDependencies": {
"mkdirp": "^0.5.0",
"rimraf": "^2.3.3",
- "tap": "^2.0.0"
+ "tap": "^5.1.1"
},
"directories": {},
"dist": {
- "shasum": "a010c43aade1a798a3e6c1b1e453d45cb497a2bc",
- "tarball": "http://registry.npmjs.org/which/-/which-1.2.1.tgz"
+ "shasum": "1557f96080604e5b11b3599eb9f45b50a9efd722",
+ "tarball": "http://registry.npmjs.org/which/-/which-1.2.4.tgz"
},
- "gitHead": "c3b472bd2e13a61a880eca44c76025920a4cb1d5",
+ "gitHead": "1375684d40af9de2ecc527d1ab9b87b537d7a1cc",
"homepage": "https://github.com/isaacs/node-which#readme",
"license": "ISC",
"main": "which.js",
@@ -79,7 +81,7 @@
"url": "git://github.com/isaacs/node-which.git"
},
"scripts": {
- "test": "tap test/*.js"
+ "test": "tap test/*.js --cov"
},
- "version": "1.2.1"
+ "version": "1.2.4"
}
diff --git a/node_modules/which/test/basic.js b/node_modules/which/test/basic.js
index 80e9e96b2..54c8d2384 100644
--- a/node_modules/which/test/basic.js
+++ b/node_modules/which/test/basic.js
@@ -51,17 +51,16 @@ t.test('make executable', function (t) {
})
t.test('find when executable', function (t) {
- t.plan(4)
var opt = { pathExt: '.sh' }
var expect = path.resolve(fixture, 'foo.sh').toLowerCase()
- var PATH = process.env.PATH
+ var PATH = process.env.PATH || process.env.Path
t.test('absolute', function (t) {
runTest(fixture + '/foo.sh', t)
})
t.test('with process.env.PATH', function (t) {
- process.env.PATH = fixture
+ process.env.PATH = process.env.Path = fixture
runTest('foo.sh', t)
})
@@ -73,6 +72,25 @@ t.test('find when executable', function (t) {
runTest('foo.sh', t)
})
+ t.test('with pathExt', {
+ skip: isWindows ? false : 'Only for Windows'
+ }, function (t) {
+ var pe = process.env.PATHEXT
+ process.env.PATHEXT = '.SH'
+
+ t.test('foo.sh', function (t) {
+ runTest('foo.sh', t)
+ })
+ t.test('foo', function (t) {
+ runTest('foo', t)
+ })
+ t.test('replace', function (t) {
+ process.env.PATHEXT = pe
+ t.end()
+ })
+ t.end()
+ })
+
t.test('with path opt', function (t) {
opt.path = fixture
runTest('foo.sh', t)
@@ -80,17 +98,20 @@ t.test('find when executable', function (t) {
function runTest(exec, t) {
t.plan(2)
+
+ var found = which.sync(exec, opt).toLowerCase()
+ t.equal(found, expect)
+
which(exec, opt, function (er, found) {
if (er)
throw er
t.equal(found.toLowerCase(), expect)
+ t.end()
process.env.PATH = PATH
})
-
- var found = which.sync(exec, opt).toLowerCase()
- t.equal(found, expect)
}
+ t.end()
})
t.test('clean', function (t) {
diff --git a/node_modules/which/test/windows.js b/node_modules/which/test/windows.js
new file mode 100644
index 000000000..1d5e4294a
--- /dev/null
+++ b/node_modules/which/test/windows.js
@@ -0,0 +1,10 @@
+// pretend to be Windows.
+if (process.platform === 'win32') {
+ var t = require('tap')
+ t.plan(0, 'already on windows')
+ process.exit(0)
+}
+
+process.env.Path = process.env.PATH.split(':').join(';')
+process.env.OSTYPE = 'cygwin'
+require('./basic.js')
diff --git a/node_modules/which/which.js b/node_modules/which/which.js
index e878351c1..5cf0124d7 100644
--- a/node_modules/which/which.js
+++ b/node_modules/which/which.js
@@ -7,46 +7,26 @@ var isWindows = process.platform === 'win32' ||
var path = require('path')
var COLON = isWindows ? ';' : ':'
-var isExe
+var isexe = require('isexe')
var fs = require('fs')
var isAbsolute = require('is-absolute')
-var G = parseInt('0010', 8)
-var U = parseInt('0100', 8)
-var UG = parseInt('0110', 8)
-
-if (isWindows) {
- // On windows, there is no good way to check that a file is executable
- isExe = function isExe () { return true }
-} else {
- isExe = function isExe (mod, uid, gid) {
- var ret = (mod & 1)
- || (mod & G) && process.getgid && gid === process.getgid()
- || (mod & U) && process.getuid && uid === process.getuid()
- || (mod & UG) && process.getuid && 0 === process.getuid()
-
- if (!ret && process.getgroups && (mod & G)) {
- var groups = process.getgroups()
- for (var g = 0; g < groups.length; g++) {
- if (groups[g] === gid)
- return true
- }
- }
-
- return ret
- }
-}
-
function getPathInfo(cmd, opt) {
var colon = opt.colon || COLON
- var pathEnv = opt.path || process.env.PATH || ''
+ var pathEnv = opt.path || process.env.Path || process.env.PATH || ''
var pathExt = ['']
pathEnv = pathEnv.split(colon)
+ var pathExtExe = ''
if (isWindows) {
pathEnv.unshift(process.cwd())
- pathExt = (opt.pathExt || process.env.PATHEXT || '.EXE').split(colon)
+ 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('')
}
@@ -56,7 +36,11 @@ function getPathInfo(cmd, opt) {
if (isAbsolute(cmd))
pathEnv = ['']
- return {env: pathEnv, ext: pathExt}
+ return {
+ env: pathEnv,
+ ext: pathExt,
+ extExe: pathExtExe
+ }
}
function which (cmd, opt, cb) {
@@ -68,6 +52,7 @@ function which (cmd, opt, cb) {
var info = getPathInfo(cmd, opt)
var pathEnv = info.env
var pathExt = info.ext
+ var pathExtExe = info.extExe
var found = []
;(function F (i, l) {
@@ -86,10 +71,8 @@ function which (cmd, opt, cb) {
;(function E (ii, ll) {
if (ii === ll) return F(i + 1, l)
var ext = pathExt[ii]
- fs.stat(p + ext, function (er, stat) {
- if (!er &&
- stat.isFile() &&
- isExe(stat.mode, stat.uid, stat.gid)) {
+ isexe(p + ext, { pathExt: pathExtExe }, function (er, is) {
+ if (!er && is) {
if (opt.all)
found.push(p + ext)
else
@@ -107,6 +90,7 @@ function whichSync (cmd, 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 ++) {
@@ -117,10 +101,10 @@ function whichSync (cmd, opt) {
var p = path.join(pathPart, cmd)
for (var j = 0, ll = pathExt.length; j < ll; j ++) {
var cur = p + pathExt[j]
- var stat
+ var is
try {
- stat = fs.statSync(cur)
- if (stat.isFile() && isExe(stat.mode, stat.uid, stat.gid)) {
+ is = isexe.sync(cur, { pathExt: pathExtExe })
+ if (is) {
if (opt.all)
found.push(cur)
else