micromatch
Advanced tools
Comparing version 0.1.0 to 0.2.0
289
index.js
@@ -10,6 +10,287 @@ /*! | ||
var braces = require('braces') | ||
var unixify = require('unixify'); | ||
var union = require('arr-union'); | ||
var diff = require('arr-diff'); | ||
var braces = require('braces'); | ||
module.exports = function () { | ||
return braces.apply(braces, arguments); | ||
}; | ||
function makeRe(glob, options) { | ||
var opts = options || {}; | ||
var flags = ''; | ||
var i = 0; | ||
optsCache = optsCache || opts; | ||
if (!equal(optsCache, opts)) { | ||
regex = null; | ||
cache = glob; | ||
} | ||
cache = cache || glob; | ||
if (cache !== glob) { | ||
glob = unixify(glob); | ||
regex = null; | ||
cache = glob; | ||
} | ||
// if `true`, then we can just return | ||
// the regex that was previously cached | ||
if (regex instanceof RegExp) { | ||
return regex; | ||
} | ||
if (/\{/.test(glob)) { | ||
glob = expand(glob); | ||
} | ||
while (i < len) { | ||
var group = tokens[i++]; | ||
var re = group[1].re; | ||
var to = group[1].to; | ||
// apply special cases from options | ||
for (var key in opts) { | ||
if (group[1].hasOwnProperty(key)) { | ||
to += group[1][key]; | ||
} | ||
} | ||
glob = glob.replace(re, to); | ||
} | ||
if (opts.nocase) flags += 'i'; | ||
// cache the regex | ||
regex = globRegex(glob, flags); | ||
// return the result | ||
return regex; | ||
} | ||
/** | ||
* Pass an array of files and a glob pattern as a string. | ||
* This function is called by the main `micromatch` function | ||
* If you only need to pass a single pattern you might get | ||
* minor speed improvements using this function. | ||
* | ||
* @param {Array} `files` | ||
* @param {Array} `pattern` | ||
* @param {Object} `options` | ||
* @return {Array} | ||
*/ | ||
function match(files, pattern, options) { | ||
if (typeof files !== 'string' && !Array.isArray(files)) { | ||
throw new Error('micromatch.match() expects a string or array.'); | ||
} | ||
files = arrayify(files); | ||
var len = files.length; | ||
var res = []; | ||
var i = 0; | ||
while (i < len) { | ||
var fp = unixify(files[i++]); | ||
if (makeRe(pattern, options).test(fp)) { | ||
res.push(fp); | ||
} | ||
} | ||
return res; | ||
} | ||
/** | ||
* The main function. Pass an array of filepaths, | ||
* and a string or array of glob patterns | ||
* | ||
* @param {Array|String} `files` | ||
* @param {Array|String} `patterns` | ||
* @param {Object} `opts` | ||
* @return {Array} Array of matches | ||
*/ | ||
function micromatch(files, patterns, opts) { | ||
if (!files || !patterns) { | ||
return []; | ||
} | ||
files = arrayify(files); | ||
opts = opts || {}; | ||
if (typeof patterns === 'string') { | ||
return union([], match(files, patterns, opts)); | ||
} | ||
var len = patterns.length; | ||
var res = []; | ||
var i = 0; | ||
while (len--) { | ||
var glob = patterns[i++]; | ||
var concat = union; | ||
if (glob.charAt(0) === '!') { | ||
glob = glob.slice(1); | ||
concat = diff; | ||
} | ||
res = concat(res, match(files, glob, opts)); | ||
} | ||
return res; | ||
} | ||
/** | ||
* Create the regex to do the matching. If | ||
* the leading character in the `glob` is `!` | ||
* a negation regex is returned. | ||
* | ||
* @param {String} `glob` | ||
* @param {String} `flags` | ||
*/ | ||
function globRegex(glob, flags) { | ||
var res = '^' + glob + '$'; | ||
if (/^!/.test(glob)) { | ||
res = '^(?!((?!\\.)' + glob.slice(1) + ')$)'; | ||
} | ||
return new RegExp(res, flags); | ||
} | ||
/** | ||
* Regex for matching single-level braces | ||
*/ | ||
function bracesRegex() { | ||
return /\{([^{]+)\}/g; | ||
} | ||
/** | ||
* Expand braces in the given glob pattern. | ||
* | ||
* @param {String} `glob` | ||
* @return {String} | ||
*/ | ||
function expand (glob) { | ||
if (!isBasicBrace(glob)) { | ||
// avoid sending the glob to the `braces` lib if possible | ||
return glob.replace(bracesRegex(), function (_, inner) { | ||
return '(' + inner.split(',').join('|') + ')'; | ||
}); | ||
} else { | ||
// if it's nested, we'll use `braces` | ||
return braces(glob).join('|'); | ||
} | ||
} | ||
/** | ||
* Return `true` if the path contains nested | ||
* braces. If so, then the [braces] lib is used | ||
* for expansion. if not, we convert the braces | ||
* to a regex. | ||
* | ||
* @param {String} str | ||
* @return {Boolean} | ||
*/ | ||
function isBasicBrace(str) { | ||
if (/\.{2}/.test(str)) { | ||
return true; | ||
} | ||
var a = str.indexOf('{'); | ||
str = str.slice(a + 1); | ||
var i = 0; | ||
while (a !== -1) { | ||
var ch = str.charAt(i++); | ||
if (ch === '{') { | ||
return true; | ||
} | ||
if (ch === '}') { | ||
return false; | ||
} | ||
} | ||
return false; | ||
} | ||
/** | ||
* Return true if object A is equal (enough) | ||
* to object B. Used for options caching. | ||
* | ||
* @param {Object} a | ||
* @param {Object} b | ||
* @return {Boolean} | ||
*/ | ||
function equal(a, b) { | ||
if (!b) return false; | ||
for (var prop in b) { | ||
if (!a.hasOwnProperty(prop)) { | ||
return false; | ||
} | ||
if (a[prop] !== b[prop]) { | ||
return false; | ||
} | ||
} | ||
return true; | ||
} | ||
/** | ||
* Coerce `val` to an array | ||
* | ||
* @param {*} val | ||
* @return {Array} | ||
*/ | ||
function arrayify(val) { | ||
return !Array.isArray(val) | ||
? [val] | ||
: val; | ||
} | ||
/** | ||
* Results cache | ||
*/ | ||
var regex; | ||
var cache; | ||
var optsCache; | ||
/** | ||
* Special patterns | ||
*/ | ||
var matchBase = '[\\s\\S]+'; | ||
var dotfile = '[^\\/]*?'; | ||
/** | ||
* Glob tokens to match and replace with | ||
* regular expressions | ||
*/ | ||
var tokens = [ | ||
['\\\\', {re: /\\{2}/g, to: '\\/'}], | ||
['/', {re: /\//g, to: '\\/'}], | ||
['.', {re: /[.]/g, to: '\\.'}], | ||
['?', {re: /\?/g, to: '.'}], | ||
['**', {re: /[*]{2}/g, to: '[\\s\\S]+'}], | ||
['*', {re: /[*]/g, to: '[^\\/]*?', matchBase: matchBase, dot: dotfile}], | ||
]; | ||
var len = tokens.length; | ||
/** | ||
* Expose `micromatch` | ||
*/ | ||
module.exports = micromatch; | ||
/** | ||
* Expose `micromatch.match` | ||
*/ | ||
module.exports.match = match; | ||
/** | ||
* Expose `micromatch.makeRe` | ||
*/ | ||
module.exports.makeRe = makeRe; |
{ | ||
"name": "micromatch", | ||
"description": "Like minimatch, but smaller and faster.", | ||
"version": "0.1.0", | ||
"description": "Glob matching for javascript/node.js. Like minimatch, but 10-40x faster.", | ||
"version": "0.2.0", | ||
"homepage": "https://github.com/jonschlinkert/micromatch", | ||
@@ -17,8 +17,6 @@ "author": { | ||
}, | ||
"licenses": [ | ||
{ | ||
"type": "MIT", | ||
"url": "https://github.com/jonschlinkert/micromatch/blob/master/LICENSE-MIT" | ||
} | ||
], | ||
"license": { | ||
"type": "MIT", | ||
"url": "https://github.com/jonschlinkert/micromatch/blob/master/LICENSE-MIT" | ||
}, | ||
"main": "index.js", | ||
@@ -31,6 +29,34 @@ "engines": { | ||
}, | ||
"dependencies": { | ||
"arr-diff": "^0.2.2", | ||
"arr-union": "^1.0.0", | ||
"braces": "^0.1.5", | ||
"unixify": "^0.1.0" | ||
}, | ||
"devDependencies": { | ||
"benchmarked": "^0.1.3", | ||
"chalk": "^0.5.1", | ||
"minimatch": "^2.0.1", | ||
"mocha": "*", | ||
"should": "*" | ||
} | ||
"should": "*", | ||
"write": "^0.1.1" | ||
}, | ||
"keywords": [ | ||
"bash", | ||
"expand", | ||
"expansion", | ||
"expression", | ||
"file", | ||
"files", | ||
"glob", | ||
"globstar", | ||
"match", | ||
"matches", | ||
"minimatch", | ||
"multimatch", | ||
"path", | ||
"regex", | ||
"regular", | ||
"shell" | ||
] | ||
} |
# micromatch [![NPM version](https://badge.fury.io/js/micromatch.svg)](http://badge.fury.io/js/micromatch) | ||
> Like minimatch, but smaller and faster. | ||
> Glob matching for javascript/node.js. Like minimatch, but 10-40x faster. | ||
## Install | ||
### Install with [npm](npmjs.org) | ||
- 5-40x faster than minimatch ([benchmarks](#benchmarks)) | ||
- Extensice unit tests, well-organized code-base | ||
## Features | ||
**Supports** | ||
All the mainstream glob features you're used to using in your gulp and Grunt tasks: | ||
+ [Brace Expansion] - ex. `foo/bar-{1..5}.md`, `one/{two,three}/four.md` | ||
+ Globstar matching - ex. `**/*`, `a/b/*.js` | ||
**Does not support** | ||
+ [Extended glob matching][extended]. This might be supported in the future, either in core or as an extension, but it's hard to justify the cost in terms of speed and complexity for features no that are rarely used. | ||
## Install with [npm](npmjs.org) | ||
```bash | ||
@@ -12,8 +28,3 @@ npm i micromatch --save | ||
## Run tests | ||
```bash | ||
npm test | ||
``` | ||
## Usage | ||
@@ -23,7 +34,39 @@ | ||
var micromatch = require('micromatch'); | ||
mm(['a.js', 'b.md', 'c.txt'], '*.{js,txt}'); | ||
//=> ['a.js', 'c.txt'] | ||
``` | ||
## API | ||
Also supports negation patterns: | ||
```js | ||
mm(['a.js', 'b.md', 'c.txt'], '!*.{js,txt}'); | ||
//=> ['b.md'] | ||
mm(['a.md', 'b.js', 'c.txt', 'd.json'], ['*.*', '!*.{js,txt}']); | ||
//=> ['a.md', 'd.json'] | ||
``` | ||
## Benchmarks | ||
Run the benchmarks | ||
```bash | ||
node benchmark/ | ||
``` | ||
![image](https://cloud.githubusercontent.com/assets/383994/5535193/1c28a4a2-8a45-11e4-813a-0236586aa990.png) | ||
## Run tests | ||
Install dev dependencies | ||
```bash | ||
npm i -d && mocha | ||
``` | ||
## Contributing | ||
@@ -45,2 +88,5 @@ Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](https://github.com/jonschlinkert/micromatch/issues) | ||
_This file was generated by [verb](https://github.com/assemble/verb) on November 25, 2014._ | ||
_This file was generated by [verb](https://github.com/assemble/verb) on December 23, 2014._ | ||
[extended]: http://mywiki.wooledge.org/BashGuide/Patterns#Extended_Globs | ||
[Brace Expansion]: https://github.com/jonschlinkert/braces |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Trivial Package
Supply chain riskPackages less than 10 lines of code are easily copied into your own project and may not warrant the additional supply chain risk of an external dependency.
Found 1 instance in 1 package
9874
243
89
4
6
4
+ Addedarr-diff@^0.2.2
+ Addedarr-union@^1.0.0
+ Addedbraces@^0.1.5
+ Addedunixify@^0.1.0
+ Addedarr-diff@0.2.2(transitive)
+ Addedarr-union@1.0.0(transitive)
+ Addedarray-unique@0.1.1(transitive)
+ Addedbraces@0.1.5(transitive)
+ Addedexpand-range@0.1.1(transitive)
+ Addedis-number@0.1.1(transitive)
+ Addedrepeat-string@0.2.2(transitive)
+ Addedunixify@0.1.0(transitive)