hooch 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/assets/javascripts/hooch.js +395 -1
- data/jasmine/jasmine-fixture.js +433 -0
- data/jasmine/node_modules/karma-chrome-launcher/CHANGELOG.md +108 -0
- data/jasmine/node_modules/karma-chrome-launcher/LICENSE +20 -0
- data/jasmine/node_modules/karma-chrome-launcher/README.md +49 -0
- data/jasmine/node_modules/karma-chrome-launcher/examples/simple/index.spec.js +5 -0
- data/jasmine/node_modules/karma-chrome-launcher/examples/simple/karma.conf.js +32 -0
- data/jasmine/node_modules/karma-chrome-launcher/gruntfile.js +63 -0
- data/jasmine/node_modules/karma-chrome-launcher/index.js +181 -0
- data/jasmine/node_modules/karma-chrome-launcher/node_modules/.bin/which +14 -0
- data/jasmine/node_modules/karma-chrome-launcher/node_modules/fs-access/index.js +41 -0
- data/jasmine/node_modules/karma-chrome-launcher/node_modules/fs-access/license +21 -0
- data/jasmine/node_modules/karma-chrome-launcher/node_modules/fs-access/node_modules/null-check/index.js +19 -0
- data/jasmine/node_modules/karma-chrome-launcher/node_modules/fs-access/node_modules/null-check/license +21 -0
- data/jasmine/node_modules/karma-chrome-launcher/node_modules/fs-access/node_modules/null-check/package.json +65 -0
- data/jasmine/node_modules/karma-chrome-launcher/node_modules/fs-access/node_modules/null-check/readme.md +34 -0
- data/jasmine/node_modules/karma-chrome-launcher/node_modules/fs-access/package.json +71 -0
- data/jasmine/node_modules/karma-chrome-launcher/node_modules/fs-access/readme.md +53 -0
- data/jasmine/node_modules/karma-chrome-launcher/node_modules/which/.travis.yml +8 -0
- data/jasmine/node_modules/karma-chrome-launcher/node_modules/which/LICENSE +15 -0
- data/jasmine/node_modules/karma-chrome-launcher/node_modules/which/README.md +34 -0
- data/jasmine/node_modules/karma-chrome-launcher/node_modules/which/bin/which +14 -0
- data/jasmine/node_modules/karma-chrome-launcher/node_modules/which/node_modules/is-absolute/LICENSE +21 -0
- data/jasmine/node_modules/karma-chrome-launcher/node_modules/which/node_modules/is-absolute/README.md +53 -0
- data/jasmine/node_modules/karma-chrome-launcher/node_modules/which/node_modules/is-absolute/index.js +27 -0
- data/jasmine/node_modules/karma-chrome-launcher/node_modules/which/node_modules/is-absolute/node_modules/is-relative/LICENSE-MIT +21 -0
- data/jasmine/node_modules/karma-chrome-launcher/node_modules/which/node_modules/is-absolute/node_modules/is-relative/README.md +38 -0
- data/jasmine/node_modules/karma-chrome-launcher/node_modules/which/node_modules/is-absolute/node_modules/is-relative/index.js +21 -0
- data/jasmine/node_modules/karma-chrome-launcher/node_modules/which/node_modules/is-absolute/node_modules/is-relative/package.json +75 -0
- data/jasmine/node_modules/karma-chrome-launcher/node_modules/which/node_modules/is-absolute/package.json +75 -0
- data/jasmine/node_modules/karma-chrome-launcher/node_modules/which/package.json +56 -0
- data/jasmine/node_modules/karma-chrome-launcher/node_modules/which/test/basic.js +99 -0
- data/jasmine/node_modules/karma-chrome-launcher/node_modules/which/which.js +111 -0
- data/jasmine/node_modules/karma-chrome-launcher/package.json +142 -0
- data/jasmine/node_modules/karma-chrome-launcher/test/jsflags.spec.js +53 -0
- data/jasmine/spec/hoochSpec.js +66 -0
- data/lib/hooch/version.rb +1 -1
- metadata +37 -3
@@ -0,0 +1,53 @@
|
|
1
|
+
# is-absolute [![NPM version](https://badge.fury.io/js/is-absolute.svg)](http://badge.fury.io/js/is-absolute) [![Build Status](https://travis-ci.org/jonschlinkert/is-absolute.svg)](https://travis-ci.org/jonschlinkert/is-absolute)
|
2
|
+
|
3
|
+
> Return true if a file path is absolute.
|
4
|
+
|
5
|
+
Based on the `isAbsolute` utility method in [express](https://github.com/visionmedia/express).
|
6
|
+
|
7
|
+
## Install with [npm](npmjs.org)
|
8
|
+
|
9
|
+
```bash
|
10
|
+
npm i is-absolute --save
|
11
|
+
```
|
12
|
+
|
13
|
+
## Usage
|
14
|
+
|
15
|
+
```js
|
16
|
+
var isAbsolute = require('is-absolute');
|
17
|
+
console.log(isAbsolute('a/b/c.js'));
|
18
|
+
//=> 'false';
|
19
|
+
```
|
20
|
+
|
21
|
+
## Running tests
|
22
|
+
Install dev dependencies.
|
23
|
+
|
24
|
+
```bash
|
25
|
+
npm i -d && npm test
|
26
|
+
```
|
27
|
+
|
28
|
+
|
29
|
+
## Contributing
|
30
|
+
Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](https://github.com/jonschlinkert/is-absolute/issues)
|
31
|
+
|
32
|
+
|
33
|
+
## Other projects
|
34
|
+
* [is-relative](https://github.com/jonschlinkert/is-relative): Returns `true` if the path appears to be relative.
|
35
|
+
* [is-dotfile](https://github.com/regexps/is-dotfile): Return true if a file path is (or has) a dotfile.
|
36
|
+
* [is-glob](https://github.com/jonschlinkert/is-glob): Returns `true` if the given string looks like a glob pattern.
|
37
|
+
* [cwd](https://github.com/jonschlinkert/cwd): Node.js util for easily getting the current working directory of a project based on package.json or the given path.
|
38
|
+
* [git-config-path](https://github.com/jonschlinkert/git-config-path): Resolve the path to the user's global .gitconfig.
|
39
|
+
|
40
|
+
## Author
|
41
|
+
|
42
|
+
**Jon Schlinkert**
|
43
|
+
|
44
|
+
+ [github/jonschlinkert](https://github.com/jonschlinkert)
|
45
|
+
+ [twitter/jonschlinkert](http://twitter.com/jonschlinkert)
|
46
|
+
|
47
|
+
## License
|
48
|
+
Copyright (c) 2014-2015 Jon Schlinkert
|
49
|
+
Released under the MIT license
|
50
|
+
|
51
|
+
***
|
52
|
+
|
53
|
+
_This file was generated by [verb-cli](https://github.com/assemble/verb-cli) on March 05, 2015._
|
data/jasmine/node_modules/karma-chrome-launcher/node_modules/which/node_modules/is-absolute/index.js
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
/*!
|
2
|
+
* is-absolute <https://github.com/jonschlinkert/is-absolute>
|
3
|
+
*
|
4
|
+
* Copyright (c) 2014-2015, Jon Schlinkert.
|
5
|
+
* Licensed under the MIT License.
|
6
|
+
*/
|
7
|
+
|
8
|
+
'use strict';
|
9
|
+
|
10
|
+
var isRelative = require('is-relative');
|
11
|
+
|
12
|
+
module.exports = function isAbsolute(filepath) {
|
13
|
+
if ('/' === filepath[0]) {
|
14
|
+
return true;
|
15
|
+
}
|
16
|
+
if (':' === filepath[1] && '\\' === filepath[2]) {
|
17
|
+
return true;
|
18
|
+
}
|
19
|
+
// Microsoft Azure absolute filepath
|
20
|
+
if ('\\\\' == filepath.substring(0, 2)) {
|
21
|
+
return true;
|
22
|
+
}
|
23
|
+
if (!isRelative(filepath)) {
|
24
|
+
return true;
|
25
|
+
}
|
26
|
+
};
|
27
|
+
|
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2014 Jon Schlinkert
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# is-relative [![NPM version](https://badge.fury.io/js/is-relative.svg)](http://badge.fury.io/js/is-relative)
|
2
|
+
|
3
|
+
> Returns `true` if the path appears to be relative.
|
4
|
+
|
5
|
+
## Install
|
6
|
+
### Install with [npm](npmjs.org)
|
7
|
+
|
8
|
+
```bash
|
9
|
+
npm i is-relative --save
|
10
|
+
```
|
11
|
+
|
12
|
+
## Usage
|
13
|
+
### [isRelative](index.js#L16)
|
14
|
+
|
15
|
+
* `filepath` **{String}**: Path to test.
|
16
|
+
* `returns`: {Boolean}
|
17
|
+
|
18
|
+
```js
|
19
|
+
var isRelative = require('is-relative');
|
20
|
+
isRelative('README.md');
|
21
|
+
//=> true
|
22
|
+
```
|
23
|
+
|
24
|
+
|
25
|
+
## Author
|
26
|
+
|
27
|
+
**Jon Schlinkert**
|
28
|
+
|
29
|
+
+ [github/jonschlinkert](https://github.com/jonschlinkert)
|
30
|
+
+ [twitter/jonschlinkert](http://twitter.com/jonschlinkert)
|
31
|
+
|
32
|
+
## License
|
33
|
+
Copyright (c) 2014 Jon Schlinkert
|
34
|
+
Released under the MIT license
|
35
|
+
|
36
|
+
***
|
37
|
+
|
38
|
+
_This file was generated by [verb](https://github.com/assemble/verb) on November 17, 2014._
|
@@ -0,0 +1,21 @@
|
|
1
|
+
'use strict';
|
2
|
+
|
3
|
+
/**
|
4
|
+
* ```js
|
5
|
+
* var isRelative = require('is-relative');
|
6
|
+
* isRelative('README.md');
|
7
|
+
* //=> true
|
8
|
+
* ```
|
9
|
+
*
|
10
|
+
* @name isRelative
|
11
|
+
* @param {String} `filepath` Path to test.
|
12
|
+
* @return {Boolean}
|
13
|
+
* @api public
|
14
|
+
*/
|
15
|
+
|
16
|
+
module.exports = function isRelative(filepath) {
|
17
|
+
if (typeof filepath !== 'string') {
|
18
|
+
throw new Error('isRelative expects a string.');
|
19
|
+
}
|
20
|
+
return !/^([a-z]+:)?[\\\/]/i.test(filepath);
|
21
|
+
};
|
@@ -0,0 +1,75 @@
|
|
1
|
+
{
|
2
|
+
"name": "is-relative",
|
3
|
+
"description": "Returns `true` if the path appears to be relative.",
|
4
|
+
"version": "0.1.3",
|
5
|
+
"homepage": "https://github.com/jonschlinkert/is-relative",
|
6
|
+
"author": {
|
7
|
+
"name": "Jon Schlinkert",
|
8
|
+
"url": "https://github.com/jonschlinkert"
|
9
|
+
},
|
10
|
+
"repository": {
|
11
|
+
"type": "git",
|
12
|
+
"url": "git://github.com/jonschlinkert/is-relative.git"
|
13
|
+
},
|
14
|
+
"bugs": {
|
15
|
+
"url": "https://github.com/jonschlinkert/is-relative/issues"
|
16
|
+
},
|
17
|
+
"licenses": [
|
18
|
+
{
|
19
|
+
"type": "MIT",
|
20
|
+
"url": "https://github.com/jonschlinkert/is-relative/blob/master/LICENSE-MIT"
|
21
|
+
}
|
22
|
+
],
|
23
|
+
"keywords": [
|
24
|
+
"absolute",
|
25
|
+
"check",
|
26
|
+
"file",
|
27
|
+
"filepath",
|
28
|
+
"is",
|
29
|
+
"normalize",
|
30
|
+
"path",
|
31
|
+
"path.relative",
|
32
|
+
"relative",
|
33
|
+
"resolve",
|
34
|
+
"slash",
|
35
|
+
"slashes",
|
36
|
+
"uri",
|
37
|
+
"url"
|
38
|
+
],
|
39
|
+
"main": "index.js",
|
40
|
+
"files": [
|
41
|
+
"index.js",
|
42
|
+
"LICENSE-MIT"
|
43
|
+
],
|
44
|
+
"engines": {
|
45
|
+
"node": ">=0.10.0"
|
46
|
+
},
|
47
|
+
"scripts": {
|
48
|
+
"test": "mocha -R spec"
|
49
|
+
},
|
50
|
+
"devDependencies": {
|
51
|
+
"mocha": "*",
|
52
|
+
"verb": ">= 0.2.6",
|
53
|
+
"verb-tag-jscomments": "^0.1.4"
|
54
|
+
},
|
55
|
+
"_id": "is-relative@0.1.3",
|
56
|
+
"_shasum": "905fee8ae86f45b3ec614bc3c15c869df0876e82",
|
57
|
+
"_from": "is-relative@>=0.1.0 <0.2.0",
|
58
|
+
"_npmVersion": "1.4.9",
|
59
|
+
"_npmUser": {
|
60
|
+
"name": "jonschlinkert",
|
61
|
+
"email": "github@sellside.com"
|
62
|
+
},
|
63
|
+
"maintainers": [
|
64
|
+
{
|
65
|
+
"name": "jonschlinkert",
|
66
|
+
"email": "github@sellside.com"
|
67
|
+
}
|
68
|
+
],
|
69
|
+
"dist": {
|
70
|
+
"shasum": "905fee8ae86f45b3ec614bc3c15c869df0876e82",
|
71
|
+
"tarball": "http://registry.npmjs.org/is-relative/-/is-relative-0.1.3.tgz"
|
72
|
+
},
|
73
|
+
"directories": {},
|
74
|
+
"_resolved": "https://registry.npmjs.org/is-relative/-/is-relative-0.1.3.tgz"
|
75
|
+
}
|
@@ -0,0 +1,75 @@
|
|
1
|
+
{
|
2
|
+
"name": "is-absolute",
|
3
|
+
"description": "Return true if a file path is absolute.",
|
4
|
+
"version": "0.1.7",
|
5
|
+
"homepage": "https://github.com/jonschlinkert/is-absolute",
|
6
|
+
"author": {
|
7
|
+
"name": "Jon Schlinkert",
|
8
|
+
"url": "https://github.com/jonschlinkert"
|
9
|
+
},
|
10
|
+
"repository": {
|
11
|
+
"type": "git",
|
12
|
+
"url": "git://github.com/jonschlinkert/is-absolute.git"
|
13
|
+
},
|
14
|
+
"bugs": {
|
15
|
+
"url": "https://github.com/jonschlinkert/is-absolute/issues"
|
16
|
+
},
|
17
|
+
"license": {
|
18
|
+
"type": "MIT",
|
19
|
+
"url": "https://github.com/jonschlinkert/is-absolute/blob/master/LICENSE"
|
20
|
+
},
|
21
|
+
"files": [
|
22
|
+
"index.js"
|
23
|
+
],
|
24
|
+
"main": "index.js",
|
25
|
+
"engines": {
|
26
|
+
"node": ">=0.10.0"
|
27
|
+
},
|
28
|
+
"scripts": {
|
29
|
+
"test": "mocha"
|
30
|
+
},
|
31
|
+
"dependencies": {
|
32
|
+
"is-relative": "^0.1.0"
|
33
|
+
},
|
34
|
+
"devDependencies": {
|
35
|
+
"mocha": "*"
|
36
|
+
},
|
37
|
+
"keywords": [
|
38
|
+
"absolute",
|
39
|
+
"check",
|
40
|
+
"file",
|
41
|
+
"filepath",
|
42
|
+
"is",
|
43
|
+
"normalize",
|
44
|
+
"path",
|
45
|
+
"path.relative",
|
46
|
+
"relative",
|
47
|
+
"resolve",
|
48
|
+
"slash",
|
49
|
+
"slashes",
|
50
|
+
"uri",
|
51
|
+
"url"
|
52
|
+
],
|
53
|
+
"gitHead": "90cca7b671620bf28b778a61fddc8a986a2e1095",
|
54
|
+
"_id": "is-absolute@0.1.7",
|
55
|
+
"_shasum": "847491119fccb5fb436217cc737f7faad50f603f",
|
56
|
+
"_from": "is-absolute@>=0.1.7 <0.2.0",
|
57
|
+
"_npmVersion": "2.5.1",
|
58
|
+
"_nodeVersion": "0.12.0",
|
59
|
+
"_npmUser": {
|
60
|
+
"name": "jonschlinkert",
|
61
|
+
"email": "github@sellside.com"
|
62
|
+
},
|
63
|
+
"maintainers": [
|
64
|
+
{
|
65
|
+
"name": "jonschlinkert",
|
66
|
+
"email": "github@sellside.com"
|
67
|
+
}
|
68
|
+
],
|
69
|
+
"dist": {
|
70
|
+
"shasum": "847491119fccb5fb436217cc737f7faad50f603f",
|
71
|
+
"tarball": "http://registry.npmjs.org/is-absolute/-/is-absolute-0.1.7.tgz"
|
72
|
+
},
|
73
|
+
"directories": {},
|
74
|
+
"_resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-0.1.7.tgz"
|
75
|
+
}
|
@@ -0,0 +1,56 @@
|
|
1
|
+
{
|
2
|
+
"author": {
|
3
|
+
"name": "Isaac Z. Schlueter",
|
4
|
+
"email": "i@izs.me",
|
5
|
+
"url": "http://blog.izs.me"
|
6
|
+
},
|
7
|
+
"name": "which",
|
8
|
+
"description": "Like which(1) unix command. Find the first instance of an executable in the PATH.",
|
9
|
+
"version": "1.1.2",
|
10
|
+
"repository": {
|
11
|
+
"type": "git",
|
12
|
+
"url": "git://github.com/isaacs/node-which.git"
|
13
|
+
},
|
14
|
+
"main": "which.js",
|
15
|
+
"bin": {
|
16
|
+
"which": "./bin/which"
|
17
|
+
},
|
18
|
+
"license": "ISC",
|
19
|
+
"dependencies": {
|
20
|
+
"is-absolute": "^0.1.7"
|
21
|
+
},
|
22
|
+
"devDependencies": {
|
23
|
+
"mkdirp": "^0.5.0",
|
24
|
+
"rimraf": "^2.3.3",
|
25
|
+
"tap": "^1.0.2"
|
26
|
+
},
|
27
|
+
"scripts": {
|
28
|
+
"test": "tap test/*.js"
|
29
|
+
},
|
30
|
+
"gitHead": "e576e42f0c377571884f844eec58b3ca4a331681",
|
31
|
+
"bugs": {
|
32
|
+
"url": "https://github.com/isaacs/node-which/issues"
|
33
|
+
},
|
34
|
+
"homepage": "https://github.com/isaacs/node-which#readme",
|
35
|
+
"_id": "which@1.1.2",
|
36
|
+
"_shasum": "486c48af6dfecc7a7dcf9c655acf108d2dcbdf3d",
|
37
|
+
"_from": "which@>=1.0.9 <2.0.0",
|
38
|
+
"_npmVersion": "3.3.1",
|
39
|
+
"_nodeVersion": "2.5.0",
|
40
|
+
"_npmUser": {
|
41
|
+
"name": "isaacs",
|
42
|
+
"email": "isaacs@npmjs.com"
|
43
|
+
},
|
44
|
+
"dist": {
|
45
|
+
"shasum": "486c48af6dfecc7a7dcf9c655acf108d2dcbdf3d",
|
46
|
+
"tarball": "http://registry.npmjs.org/which/-/which-1.1.2.tgz"
|
47
|
+
},
|
48
|
+
"maintainers": [
|
49
|
+
{
|
50
|
+
"name": "isaacs",
|
51
|
+
"email": "i@izs.me"
|
52
|
+
}
|
53
|
+
],
|
54
|
+
"directories": {},
|
55
|
+
"_resolved": "https://registry.npmjs.org/which/-/which-1.1.2.tgz"
|
56
|
+
}
|
@@ -0,0 +1,99 @@
|
|
1
|
+
var t = require('tap')
|
2
|
+
var fs = require('fs')
|
3
|
+
var rimraf = require('rimraf')
|
4
|
+
var mkdirp = require('mkdirp')
|
5
|
+
var fixture = __dirname + '/fixture'
|
6
|
+
var which = require('../which.js')
|
7
|
+
var path = require('path')
|
8
|
+
|
9
|
+
var isWindows = process.platform === 'win32' ||
|
10
|
+
process.env.OSTYPE === 'cygwin' ||
|
11
|
+
process.env.OSTYPE === 'msys'
|
12
|
+
|
13
|
+
var skip = { skip: isWindows ? 'not relevant on windows' : false }
|
14
|
+
|
15
|
+
t.test('setup', function (t) {
|
16
|
+
rimraf.sync(fixture)
|
17
|
+
mkdirp.sync(fixture)
|
18
|
+
fs.writeFileSync(fixture + '/foo.sh', 'echo foo\n')
|
19
|
+
t.end()
|
20
|
+
})
|
21
|
+
|
22
|
+
t.test('does not find non-executable', skip, function (t) {
|
23
|
+
t.plan(2)
|
24
|
+
|
25
|
+
t.test('absolute', function (t) {
|
26
|
+
t.plan(2)
|
27
|
+
which(fixture + '/foo.sh', function (er) {
|
28
|
+
t.isa(er, Error)
|
29
|
+
})
|
30
|
+
|
31
|
+
t.throws(function () {
|
32
|
+
which.sync(fixture + '/foo.sh')
|
33
|
+
})
|
34
|
+
})
|
35
|
+
|
36
|
+
t.test('with path', function (t) {
|
37
|
+
t.plan(2)
|
38
|
+
which('foo.sh', { path: fixture }, function (er) {
|
39
|
+
t.isa(er, Error)
|
40
|
+
})
|
41
|
+
|
42
|
+
t.throws(function () {
|
43
|
+
which.sync('foo.sh', { path: fixture })
|
44
|
+
})
|
45
|
+
})
|
46
|
+
})
|
47
|
+
|
48
|
+
t.test('make executable', function (t) {
|
49
|
+
fs.chmodSync(fixture + '/foo.sh', '0755')
|
50
|
+
t.end()
|
51
|
+
})
|
52
|
+
|
53
|
+
t.test('find when executable', function (t) {
|
54
|
+
t.plan(4)
|
55
|
+
var opt = { pathExt: '.sh' }
|
56
|
+
var expect = path.resolve(fixture, 'foo.sh').toLowerCase()
|
57
|
+
var PATH = process.env.PATH
|
58
|
+
|
59
|
+
t.test('absolute', function (t) {
|
60
|
+
runTest(fixture + '/foo.sh', t)
|
61
|
+
})
|
62
|
+
|
63
|
+
t.test('with process.env.PATH', function (t) {
|
64
|
+
process.env.PATH = fixture
|
65
|
+
runTest('foo.sh', t)
|
66
|
+
})
|
67
|
+
|
68
|
+
t.test('with process.env.Path', {
|
69
|
+
skip: isWindows ? false : 'Only for Windows'
|
70
|
+
}, function (t) {
|
71
|
+
process.env.PATH = ""
|
72
|
+
process.env.Path = fixture
|
73
|
+
runTest('foo.sh', t)
|
74
|
+
})
|
75
|
+
|
76
|
+
t.test('with path opt', function (t) {
|
77
|
+
opt.path = fixture
|
78
|
+
runTest('foo.sh', t)
|
79
|
+
})
|
80
|
+
|
81
|
+
function runTest(exec, t) {
|
82
|
+
t.plan(2)
|
83
|
+
which(exec, opt, function (er, found) {
|
84
|
+
if (er)
|
85
|
+
throw er
|
86
|
+
t.equal(found.toLowerCase(), expect)
|
87
|
+
process.env.PATH = PATH
|
88
|
+
})
|
89
|
+
|
90
|
+
var found = which.sync(exec, opt).toLowerCase()
|
91
|
+
t.equal(found, expect)
|
92
|
+
}
|
93
|
+
|
94
|
+
})
|
95
|
+
|
96
|
+
t.test('clean', function (t) {
|
97
|
+
rimraf.sync(fixture)
|
98
|
+
t.end()
|
99
|
+
})
|
@@ -0,0 +1,111 @@
|
|
1
|
+
module.exports = which
|
2
|
+
which.sync = whichSync
|
3
|
+
|
4
|
+
var isWindows = process.platform === 'win32' ||
|
5
|
+
process.env.OSTYPE === 'cygwin' ||
|
6
|
+
process.env.OSTYPE === 'msys'
|
7
|
+
|
8
|
+
var path = require('path')
|
9
|
+
var COLON = isWindows ? ';' : ':'
|
10
|
+
var isExe
|
11
|
+
var fs = require('fs')
|
12
|
+
var isAbsolute = require('is-absolute')
|
13
|
+
|
14
|
+
var G = parseInt('0010', 8)
|
15
|
+
var U = parseInt('0100', 8)
|
16
|
+
var UG = parseInt('0110', 8)
|
17
|
+
|
18
|
+
if (isWindows) {
|
19
|
+
// On windows, there is no good way to check that a file is executable
|
20
|
+
isExe = function isExe () { return true }
|
21
|
+
} else {
|
22
|
+
isExe = function isExe (mod, uid, gid) {
|
23
|
+
var ret = (mod & 1)
|
24
|
+
|| (mod & U) && process.getgid && gid === process.getgid()
|
25
|
+
|| (mod & G) && process.getuid && uid === process.getuid()
|
26
|
+
|| (mod & UG) && process.getuid && 0 === process.getuid()
|
27
|
+
|
28
|
+
if (!ret && process.getgroups && (mod & G)) {
|
29
|
+
var groups = process.getgroups()
|
30
|
+
for (var g = 0; g < groups.length; g++) {
|
31
|
+
if (groups[g] === gid)
|
32
|
+
return true
|
33
|
+
}
|
34
|
+
}
|
35
|
+
|
36
|
+
return ret
|
37
|
+
}
|
38
|
+
}
|
39
|
+
|
40
|
+
function getPathInfo(cmd, opt) {
|
41
|
+
var colon = opt.colon || COLON
|
42
|
+
var pathEnv = opt.path || process.env.PATH || ''
|
43
|
+
var pathExt = ['']
|
44
|
+
|
45
|
+
pathEnv = pathEnv.split(colon)
|
46
|
+
|
47
|
+
if (isWindows) {
|
48
|
+
pathEnv.unshift(process.cwd())
|
49
|
+
pathExt = (opt.pathExt || process.env.PATHEXT || '.EXE').split(colon)
|
50
|
+
if (cmd.indexOf('.') !== -1 && pathExt[0] !== '')
|
51
|
+
pathExt.unshift('')
|
52
|
+
}
|
53
|
+
|
54
|
+
// If it's absolute, then we don't bother searching the pathenv.
|
55
|
+
// just check the file itself, and that's it.
|
56
|
+
if (isAbsolute(cmd))
|
57
|
+
pathEnv = ['']
|
58
|
+
|
59
|
+
return {env: pathEnv, ext: pathExt}
|
60
|
+
}
|
61
|
+
|
62
|
+
function which (cmd, opt, cb) {
|
63
|
+
if (typeof opt === 'function') {
|
64
|
+
cb = opt
|
65
|
+
opt = {}
|
66
|
+
}
|
67
|
+
|
68
|
+
var info = getPathInfo(cmd, opt)
|
69
|
+
var pathEnv = info.env
|
70
|
+
var pathExt = info.ext
|
71
|
+
|
72
|
+
;(function F (i, l) {
|
73
|
+
if (i === l) return cb(new Error('not found: '+cmd))
|
74
|
+
var p = path.resolve(pathEnv[i], cmd)
|
75
|
+
;(function E (ii, ll) {
|
76
|
+
if (ii === ll) return F(i + 1, l)
|
77
|
+
var ext = pathExt[ii]
|
78
|
+
fs.stat(p + ext, function (er, stat) {
|
79
|
+
if (!er &&
|
80
|
+
stat.isFile() &&
|
81
|
+
isExe(stat.mode, stat.uid, stat.gid)) {
|
82
|
+
return cb(null, p + ext)
|
83
|
+
}
|
84
|
+
return E(ii + 1, ll)
|
85
|
+
})
|
86
|
+
})(0, pathExt.length)
|
87
|
+
})(0, pathEnv.length)
|
88
|
+
}
|
89
|
+
|
90
|
+
function whichSync (cmd, opt) {
|
91
|
+
opt = opt || {}
|
92
|
+
|
93
|
+
var info = getPathInfo(cmd, opt)
|
94
|
+
var pathEnv = info.env
|
95
|
+
var pathExt = info.ext
|
96
|
+
|
97
|
+
for (var i = 0, l = pathEnv.length; i < l; i ++) {
|
98
|
+
var p = path.join(pathEnv[i], cmd)
|
99
|
+
for (var j = 0, ll = pathExt.length; j < ll; j ++) {
|
100
|
+
var cur = p + pathExt[j]
|
101
|
+
var stat
|
102
|
+
try {
|
103
|
+
stat = fs.statSync(cur)
|
104
|
+
if (stat.isFile() && isExe(stat.mode, stat.uid, stat.gid))
|
105
|
+
return cur
|
106
|
+
} catch (ex) {}
|
107
|
+
}
|
108
|
+
}
|
109
|
+
|
110
|
+
throw new Error('not found: '+cmd)
|
111
|
+
}
|