Comparing version 0.7.2 to 0.8.0
111
index.js
@@ -9,14 +9,6 @@ 'use strict'; | ||
var path = require('path'); | ||
var isGlob = require('is-glob'); | ||
var expandTilde = require('expand-tilde'); | ||
var mm = require('micromatch'); | ||
var utils = require('./utils'); | ||
/** | ||
* Expose `lookup` | ||
*/ | ||
module.exports = lookup; | ||
/** | ||
* @param {String|Array} `patterns` Glob pattern(s) or file path(s) to match against. | ||
* @param {String|Array} `pattern` Glob pattern or file path(s) to match against. | ||
* @param {Object} `options` Options to pass to [micromatch]. Note that if you want to start in a different directory than the current working directory, specify a `cwd` property here. | ||
@@ -27,58 +19,62 @@ * @return {String} Returns the first matching file. | ||
function lookup(patterns, opts) { | ||
if (typeof patterns !== 'string' && !Array.isArray(patterns)) { | ||
throw new TypeError('look-up expects a string or array as the first argument.'); | ||
module.exports = function (patterns, options) { | ||
if (typeof patterns === 'string') { | ||
return lookup(patterns, options); | ||
} | ||
// ensure the pattern is an array | ||
patterns = typeof patterns === 'string' | ||
? [patterns] | ||
: patterns; | ||
if (!Array.isArray(patterns)) { | ||
throw new TypeError('expected a string or array.'); | ||
} | ||
var cwd = (opts && opts.cwd) || '.'; | ||
cwd = path.resolve(expandTilde(cwd)); | ||
var len = patterns.length, i = -1; | ||
while (++i < len) { | ||
var res = lookup(patterns[i], options); | ||
if (res) return res; | ||
} | ||
var segs = cwd.split(/[\\\/]/); | ||
var slen = segs.length; | ||
return null; | ||
}; | ||
while (slen--) { | ||
var dir = segs.join('/'); | ||
var fp = findFile(dir, patterns, opts); | ||
if (fp) { return fp; } | ||
segs.pop(); | ||
function lookup(pattern, options) { | ||
var cwd = resolveCwd(options || {}); | ||
if (utils.isGlob(pattern)) { | ||
return matchFile(cwd, pattern, options); | ||
} else { | ||
return findFile(cwd, pattern); | ||
} | ||
return null; | ||
} | ||
function findFile(cwd, patterns, opts) { | ||
var len = patterns.length; | ||
function matchFile(cwd, pattern, opts) { | ||
var isMatch = utils.mm.matcher(pattern, opts); | ||
var files = fs.readdirSync(cwd); | ||
var len = files.length, i = -1; | ||
while (len--) { | ||
var pattern = expandTilde(patterns[len]); | ||
if (!isGlob(pattern)) { | ||
var fp = join(cwd, pattern); | ||
while (++i < len) { | ||
var name = files[i]; | ||
var fp = path.join(cwd, name); | ||
if (isMatch(name) || isMatch(fp)) { | ||
return fp; | ||
} | ||
} | ||
// we can avoid fs.readdir if this | ||
// resolves to an actual file | ||
if (fs.existsSync(fp)) { return fp; } | ||
var dir = path.dirname(cwd); | ||
if (dir === cwd) return null; | ||
} else { | ||
try { | ||
var files = fs.readdirSync(cwd); | ||
var re = mm.makeRe(pattern, opts); | ||
return matchFile(dir, pattern, opts); | ||
} | ||
for (var i = 0; i < files.length; i++) { | ||
var name = files[i]; | ||
var file = join(cwd, name); | ||
function findFile(cwd, filename) { | ||
var fp = cwd ? (cwd + '/' + filename) : filename; | ||
if (fs.existsSync(fp)) { | ||
return fp; | ||
} | ||
// try matching against the basename in the cwd, | ||
// or the absolute path | ||
if (re.test(name) || re.test(file)) { | ||
return file; | ||
} | ||
} | ||
} catch (err) { | ||
if (opts && opts.verbose) { throw err; } | ||
} | ||
var segs = cwd.split(path.sep); | ||
var len = segs.length - 1; | ||
while (len--) { | ||
cwd = segs.slice(0, len).join('/'); | ||
fp = cwd + '/' + filename; | ||
if (fs.existsSync(fp)) { | ||
return fp; | ||
} | ||
@@ -89,4 +85,9 @@ } | ||
function join(dir, fp) { | ||
return dir + '/' + fp; | ||
function resolveCwd(opts) { | ||
var cwd = opts.cwd || ''; | ||
if (/^\W/.test(cwd)) { | ||
cwd = utils.resolve(cwd); | ||
} | ||
return cwd; | ||
} | ||
{ | ||
"name": "look-up", | ||
"description": "Like findup-sync and supports the same features but 20x-40x faster on avg.", | ||
"version": "0.7.2", | ||
"description": "Faster drop-in replacement for find-up and findup-sync.", | ||
"version": "0.8.0", | ||
"homepage": "https://github.com/jonschlinkert/look-up", | ||
@@ -24,15 +24,25 @@ "author": "Jon Schlinkert (https://github.com/jonschlinkert)", | ||
"dependencies": { | ||
"expand-tilde": "^1.2.0", | ||
"is-glob": "^2.0.0", | ||
"micromatch": "^2.2.0" | ||
"is-glob": "^2.0.1", | ||
"lazy-cache": "^0.2.3", | ||
"micromatch": "jonschlinkert/micromatch#2.3.0", | ||
"normalize-path": "^2.0.0", | ||
"resolve-dir": "^0.1.0" | ||
}, | ||
"devDependencies": { | ||
"benchmarked": "^0.1.3", | ||
"chalk": "^0.5.1", | ||
"findup-sync": "^0.2.1", | ||
"mocha": "*", | ||
"normalize-path": "^0.3.0", | ||
"resolve": "^1.0.0", | ||
"should": "*", | ||
"user-home": "^1.1.1" | ||
"ansi-bold": "^0.1.1", | ||
"benchmarked": "^0.1.4", | ||
"find-up": "^1.0.0", | ||
"findup-sync": "^0.3.0", | ||
"glob": "^5.0.15", | ||
"gulp": "^3.9.0", | ||
"gulp-istanbul": "^0.10.1", | ||
"gulp-jshint": "^1.11.2", | ||
"gulp-mocha": "^2.1.3", | ||
"is-absolute": "^0.2.2", | ||
"jshint-stylish": "^2.0.1", | ||
"minimist": "^1.2.0", | ||
"mocha": "^2.3.3", | ||
"resolve": "^1.1.6", | ||
"should": "^7.1.0", | ||
"user-home": "^2.0.0" | ||
}, | ||
@@ -39,0 +49,0 @@ "keywords": [ |
# look-up [![NPM version](https://badge.fury.io/js/look-up.svg)](http://badge.fury.io/js/look-up) [![Build Status](https://travis-ci.org/jonschlinkert/look-up.svg)](https://travis-ci.org/jonschlinkert/look-up) | ||
> Like findup-sync and supports the same features but 20x-40x faster on avg. | ||
> Faster drop-in replacement for find-up and findup-sync. | ||
## Install | ||
Install with [npm](https://www.npmjs.com/) | ||
@@ -11,3 +13,3 @@ | ||
See the [benchmarks](#run-benchmarks) or [tests](./test.js). | ||
See the [benchmarks](#run-benchmarks) or [unit tests](./test.js). | ||
@@ -18,21 +20,18 @@ ## Usage | ||
var lookup = require('look-up'); | ||
lookup(pattern, {cwd: cwd, ...}); | ||
lookup('package.json'); | ||
//=> '/Users/jonschlinkert/dev/look-up/package.json' | ||
``` | ||
* `pattern` **{String|Array}**: glob pattern for the file to find | ||
* `options` **{Object}**: options to pass to [micromatch](https://github.com/jonschlinkert/micromatch) | ||
- `cwd` **{String}**: the directory to start looking (upwards) from | ||
look-up will recurse _up from the cwd_ until it finds the given file. | ||
**Examples:** | ||
```js | ||
lookup('**/c/package.json', { cwd: 'fixtures/a/b/c/d/e/f/g' }); | ||
//=> 'fixtures/a/b/c/package.json' | ||
lookup('package.json', { cwd: 'foo/bar' }); | ||
//=> '/Users/jonschlinkert/dev/look-up/package.json' | ||
``` | ||
Pass options to [micromatch](https://github.com/jonschlinkert/micromatch) | ||
Glob patterns are also supported (string or array): | ||
```js | ||
lookup('one.txt', { cwd: 'fixtures/a/b/c/d/e/f/g', matchBase: true }); | ||
//=> 'fixtures/a/b/c/d/one.txt' | ||
lookup(['*.json', '*.foo'], { cwd: 'foo/bar' }); | ||
//=> '/Users/jonschlinkert/dev/look-up/package.json' | ||
``` | ||
@@ -42,30 +41,34 @@ | ||
Install dev dependencies: | ||
Benchmarks were run on [mac and windows](https://github.com/jonschlinkert/look-up/issues/1). look-up is 5x-20x faster than [findup-sync](https://github.com/cowboy/node-findup-sync) and 3x faster than [find-up](https://github.com/sindresorhus/find-up) | ||
```bash | ||
npm i -d && npm run benchmark | ||
``` | ||
**Note** that [find-up](https://github.com/sindresorhus/find-up) does not support glob patterns, so these benchmarks only include arguments that are supported by all three libs. | ||
Benchmarks were run on [mac and windows](https://github.com/jonschlinkert/look-up/issues/1). look-up is 20-100x faster than [findup-sync](https://github.com/cowboy/node-findup-sync)on avg. | ||
As of October 04, 2015: | ||
```bash | ||
#1: deep-close.js | ||
findup.js x 645 ops/sec ±2.04% (84 runs sampled) | ||
lookup.js x 19,939 ops/sec ±0.98% (94 runs sampled) | ||
#1: deep-close | ||
findup-sync x 5,797 ops/sec ±1.66% (90 runs sampled) | ||
findup x 22,972 ops/sec ±0.82% (92 runs sampled) | ||
lookup x 64,389 ops/sec ±0.75% (92 runs sampled) | ||
#2: deep-far.js | ||
findup.js x 85.16 ops/sec ±2.07% (73 runs sampled) | ||
lookup.js x 5,546 ops/sec ±0.74% (95 runs sampled) | ||
#2: deep-far | ||
findup-sync x 2,165 ops/sec ±1.01% (92 runs sampled) | ||
findup x 8,250 ops/sec ±0.78% (96 runs sampled) | ||
lookup x 12,730 ops/sec ±0.93% (92 runs sampled) | ||
#3: nested.js | ||
findup.js x 200 ops/sec ±2.13% (77 runs sampled) | ||
lookup.js x 19,713 ops/sec ±0.86% (98 runs sampled) | ||
#3: nested | ||
findup-sync x 21,603 ops/sec ±0.76% (93 runs sampled) | ||
findup x 103,427 ops/sec ±0.93% (95 runs sampled) | ||
lookup x 381,425 ops/sec ±0.91% (91 runs sampled) | ||
#4: non-glob.js | ||
findup.js x 5,465 ops/sec ±2.20% (87 runs sampled) | ||
lookup.js x 20,068 ops/sec ±2.05% (86 runs sampled) | ||
#4: shallow | ||
findup-sync x 6,565 ops/sec ±0.66% (92 runs sampled) | ||
findup x 23,674 ops/sec ±0.89% (95 runs sampled) | ||
lookup x 57,029 ops/sec ±0.83% (93 runs sampled) | ||
``` | ||
#5: shallow.js | ||
findup.js x 135 ops/sec ±2.13% (75 runs sampled) | ||
lookup.js x 10,228 ops/sec ±0.96% (94 runs sampled) | ||
To run the [benchmarks](./benchmark), install dev dependencies: | ||
```bash | ||
npm i -d && npm run benchmark | ||
``` | ||
@@ -75,3 +78,3 @@ | ||
* [is-glob](https://www.npmjs.com/package/is-glob): Returns `true` if the given string looks like a glob pattern. | [homepage](https://github.com/jonschlinkert/is-glob) | ||
* [is-glob](https://www.npmjs.com/package/is-glob): Returns `true` if the given string looks like a glob pattern or an extglob pattern.… [more](https://www.npmjs.com/package/is-glob) | [homepage](https://github.com/jonschlinkert/is-glob) | ||
* [look-up-cli](https://www.npmjs.com/package/look-up-cli): Find a file matching a pattern by walking up parent directories | [homepage](https://github.com/lydell/look-up-cli) | ||
@@ -88,2 +91,13 @@ * [micromatch](https://www.npmjs.com/package/micromatch): Glob matching for javascript/node.js. A drop-in replacement and faster alternative to minimatch and multimatch. Just… [more](https://www.npmjs.com/package/micromatch) | [homepage](https://github.com/jonschlinkert/micromatch) | ||
## Coverage | ||
As of October 04, 2015: | ||
``` | ||
Statements : 100% (57/57) | ||
Branches : 100% (26/26) | ||
Functions : 100% (5/5) | ||
Lines : 100% (55/55) | ||
``` | ||
## Contributing | ||
@@ -107,2 +121,2 @@ | ||
_This file was generated by [verb-cli](https://github.com/assemble/verb-cli) on September 12, 2015._ | ||
_This file was generated by [verb-cli](https://github.com/assemble/verb-cli) on October 04, 2015._ |
GitHub dependency
Supply chain riskContains a dependency which resolves to a GitHub URL. Dependencies fetched from GitHub specifiers are not immutable can be used to inject untrusted code or reduce the likelihood of a reproducible install.
Found 1 instance in 1 package
Manifest confusion
Supply chain riskThis package has inconsistent metadata. This could be malicious or caused by an error when publishing the package.
Found 1 instance in 1 package
8248
73
116
5
16
1
1
+ Addedlazy-cache@^0.2.3
+ Addednormalize-path@^2.0.0
+ Addedresolve-dir@^0.1.0
+ Addedglobal-modules@0.2.3(transitive)
+ Addedglobal-prefix@0.1.5(transitive)
+ Addedhomedir-polyfill@1.0.3(transitive)
+ Addedini@1.3.8(transitive)
+ Addedis-windows@0.2.0(transitive)
+ Addedisexe@2.0.0(transitive)
+ Addedlazy-cache@0.2.7(transitive)
+ Addedparse-passwd@1.0.0(transitive)
+ Addedresolve-dir@0.1.1(transitive)
+ Addedwhich@1.3.1(transitive)
- Removedexpand-tilde@^1.2.0
- Removedarr-diff@2.0.0(transitive)
- Removedarr-flatten@1.1.0(transitive)
- Removedarray-unique@0.2.1(transitive)
- Removedbraces@1.8.5(transitive)
- Removedexpand-brackets@0.1.5(transitive)
- Removedexpand-range@1.8.2(transitive)
- Removedextglob@0.3.2(transitive)
- Removedfilename-regex@2.0.1(transitive)
- Removedfill-range@2.2.4(transitive)
- Removedfor-in@1.0.2(transitive)
- Removedfor-own@0.1.5(transitive)
- Removedglob-base@0.3.0(transitive)
- Removedglob-parent@2.0.0(transitive)
- Removedis-buffer@1.1.6(transitive)
- Removedis-dotfile@1.0.3(transitive)
- Removedis-equal-shallow@0.1.3(transitive)
- Removedis-extendable@0.1.1(transitive)
- Removedis-number@2.1.04.0.0(transitive)
- Removedis-posix-bracket@0.1.1(transitive)
- Removedis-primitive@2.0.0(transitive)
- Removedisarray@1.0.0(transitive)
- Removedisobject@2.1.0(transitive)
- Removedkind-of@3.2.26.0.3(transitive)
- Removedmath-random@1.0.4(transitive)
- Removedmicromatch@2.3.11(transitive)
- Removedobject.omit@2.0.1(transitive)
- Removedparse-glob@3.0.4(transitive)
- Removedpreserve@0.2.0(transitive)
- Removedrandomatic@3.1.1(transitive)
- Removedregex-cache@0.4.4(transitive)
- Removedrepeat-element@1.1.4(transitive)
- Removedrepeat-string@1.6.1(transitive)
Updatedis-glob@^2.0.1