micromatch
Advanced tools
Comparing version 1.2.2 to 1.3.0
266
index.js
@@ -11,3 +11,5 @@ /*! | ||
var diff = require('arr-diff'); | ||
var fileRe = require('filename-regex'); | ||
var typeOf = require('kind-of'); | ||
var cache = require('regex-cache'); | ||
var isGlob = require('is-glob'); | ||
var expand = require('./lib/expand'); | ||
@@ -80,4 +82,5 @@ var utils = require('./lib/utils'); | ||
var negate = opts.negate || false; | ||
var orig = pattern; | ||
if (opts.nonegate !== true) { | ||
if (typeof pattern === 'string' && opts.nonegate !== true) { | ||
negate = pattern.charAt(0) === '!'; | ||
@@ -89,6 +92,3 @@ if (negate) { | ||
if (!(pattern instanceof RegExp)) { | ||
pattern = makeRe(pattern, opts); | ||
} | ||
var isMatch = matcher(pattern, opts); | ||
var len = files.length; | ||
@@ -102,11 +102,25 @@ var res = []; | ||
if (!isMatch(fp, pattern, opts)) { continue; } | ||
if (!isMatch(fp)) { continue; } | ||
res.push(fp); | ||
} | ||
if (opts.nonull && !res.length) { | ||
return pattern; | ||
if (res.length === 0) { | ||
if (opts.failglob === true) { | ||
throw new Error('micromatch found no matches for: "' + orig + '".'); | ||
} | ||
if (opts.nonull || opts.nullglob) { | ||
res.push(utils.unescapeGlob(orig)); | ||
} | ||
} | ||
if (negate) { return diff(files, res); } | ||
// if `negate` was diffined, diff negated files | ||
if (negate) { res = diff(files, res); } | ||
// if `ignore` was defined, diff ignored filed | ||
if (opts.ignore && opts.ignore.length) { | ||
pattern = opts.ignore; | ||
delete opts.ignore; | ||
return diff(res, micromatch(res, pattern, opts)); | ||
} | ||
return res; | ||
@@ -116,21 +130,74 @@ } | ||
/** | ||
* Returns true if the filepath matches the given | ||
* pattern. | ||
* Return a function for matching based on the | ||
* given `pattern` and `options`. | ||
* | ||
* @param {String} `pattern` | ||
* @param {Object} `options` | ||
* @return {Function} | ||
*/ | ||
function isMatch(fp, pattern, opts) { | ||
function matcher(pattern, opts) { | ||
// pattern is a function | ||
if (typeof pattern === 'function') { | ||
return pattern; | ||
} | ||
// pattern is a string | ||
if (!(pattern instanceof RegExp)) { | ||
pattern = makeRe(pattern, opts); | ||
if (!isGlob(pattern)) { | ||
return utils.matchPath(pattern, opts); | ||
} | ||
var re = makeRe(pattern, opts); | ||
if (opts && opts.matchBase) { | ||
return utils.hasFilename(re, opts); | ||
} | ||
return function (fp) { | ||
return re.test(fp); | ||
}; | ||
} | ||
// pattern is already a regex | ||
return function (fp) { | ||
return pattern.test(fp); | ||
}; | ||
} | ||
if (opts && opts.matchBase) { | ||
var matches = fileRe().exec(fp); | ||
if (pattern.test(matches[0])) { | ||
return true; | ||
} | ||
/** | ||
* Returns true if the filepath contains the given | ||
* pattern. Can also return a function for matching. | ||
* | ||
* ```js | ||
* isMatch('foo.md', '*.md', {}); | ||
* //=> true | ||
* | ||
* isMatch('*.md', {})('foo.md') | ||
* //=> true | ||
* ``` | ||
* | ||
* @param {String} `fp` | ||
* @param {String} `pattern` | ||
* @param {Object} `opts` | ||
* @return {Boolean} | ||
*/ | ||
function isMatch(fp, pattern, opts) { | ||
if (typeOf(pattern) === 'object') { | ||
return matcher(fp, pattern); | ||
} | ||
return pattern.test(fp); | ||
return matcher(pattern, opts)(fp); | ||
} | ||
/** | ||
* Returns true if the filepath matches the | ||
* given pattern. | ||
*/ | ||
function contains(fp, pattern, opts) { | ||
opts = opts || {}; | ||
opts.contains = (pattern !== ''); | ||
if (opts.contains && !isGlob(pattern)) { | ||
return fp.indexOf(pattern) !== -1; | ||
} | ||
return matcher(pattern, opts)(fp); | ||
} | ||
/** | ||
* Filter the keys in an object. | ||
@@ -147,10 +214,9 @@ * | ||
var keys = Object.keys(obj); | ||
var len = keys.length; | ||
var res = {}; | ||
while (len--) { | ||
var key = keys[len]; | ||
if (re.test(key)) { | ||
res[key] = obj[key]; | ||
for (var key in obj) { | ||
if (obj.hasOwnProperty(key)) { | ||
if (re.test(key)) { | ||
res[key] = obj[key]; | ||
} | ||
} | ||
@@ -192,3 +258,2 @@ } | ||
} | ||
return res; | ||
@@ -210,47 +275,33 @@ }; | ||
function makeRe(glob, options) { | ||
var opts = options || {}; | ||
function toRegex(glob, options) { | ||
// clone options to prevent mutating upstream variables | ||
var opts = Object.create(options || {}); | ||
var flags = opts.flags || ''; | ||
// reset cache, recompile regex if options change | ||
optsCache = typeof optsCache !== 'undefined' | ||
? optsCache | ||
: opts; | ||
if (!equal(optsCache, opts)) { | ||
cache = glob; | ||
globRe = null; | ||
if (opts.nocase && !/i/.test(flags)) { | ||
flags += 'i'; | ||
} | ||
// reset cache, recompile regex if glob changes | ||
cache = typeof cache !== 'undefined' | ||
? cache | ||
: glob; | ||
if (cache !== glob) { | ||
glob = utils.unixify(glob, opts); | ||
cache = glob; | ||
globRe = null; | ||
} | ||
// if `true`, then we can just return | ||
// the regex that was previously cached | ||
if (globRe instanceof RegExp) { | ||
return globRe; | ||
} | ||
if (opts.nocase) { flags += 'i'; } | ||
// pass in tokens to avoid parsing more than once | ||
// var parsed = !tokens ? expand(glob, opts) : tokens; | ||
var parsed = expand(glob, opts); | ||
opts.negated = opts.negated || parsed.negated || false; | ||
glob = wrapGlob(parsed.glob, opts.negated); | ||
opts.negated = opts.negated || parsed.negated; | ||
opts.negate = opts.negated; | ||
glob = wrapGlob(parsed.pattern, opts); | ||
// cache regex | ||
globRe = new RegExp(glob, flags); | ||
return globRe; | ||
try { | ||
return new RegExp(glob, flags); | ||
} catch (err) {} | ||
return /^$/; | ||
} | ||
/** | ||
* Wrap `toRegex` to memoize the generated regex | ||
* the string and options don't change | ||
*/ | ||
function makeRe(glob, opts) { | ||
return cache(toRegex, glob, opts); | ||
} | ||
/** | ||
* Create the regex to do the matching. If | ||
@@ -264,40 +315,25 @@ * the leading character in the `glob` is `!` | ||
function wrapGlob(glob, negate) { | ||
glob = ('(?:' + glob + ')$'); | ||
return '^' + (negate ? ('(?!^' + glob + ').*$') : glob); | ||
} | ||
/** | ||
* Return true if object A is equal (enough) | ||
* to object B. Used for options caching. All | ||
* we need to know is if the object has changed | ||
* in any way. | ||
* | ||
* @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) || a[prop] !== b[prop]) { | ||
return false; | ||
} | ||
function wrapGlob(glob, opts) { | ||
var prefix = (opts && !opts.contains) ? '^' : ''; | ||
var after = (opts && !opts.contains) ? '$' : ''; | ||
glob = ('(?:' + glob + ')' + after); | ||
if (opts && opts.negate) { | ||
return prefix + ('(?!^' + glob + ').*$'); | ||
} | ||
return true; | ||
return prefix + glob; | ||
} | ||
/** | ||
* Results cache | ||
* Public methods | ||
*/ | ||
var globRe; | ||
var cache; | ||
var optsCache; | ||
micromatch.braces = micromatch.braceExpand = require('braces'); | ||
micromatch.expand = expand; | ||
micromatch.filter = filter; | ||
micromatch.isMatch = isMatch; | ||
micromatch.contains = contains; | ||
micromatch.makeRe = makeRe; | ||
micromatch.match = match; | ||
micromatch.matchKeys = matchKeys; | ||
// no, this isn't permanent. I will organize | ||
// the following when the API is locked. | ||
/** | ||
@@ -308,43 +344,1 @@ * Expose `micromatch` | ||
module.exports = micromatch; | ||
/** | ||
* Expose `micromatch.match` | ||
*/ | ||
module.exports.match = match; | ||
/** | ||
* Expose `micromatch.isMatch` | ||
*/ | ||
module.exports.isMatch = isMatch; | ||
/** | ||
* Expose `micromatch.matchKeys` | ||
*/ | ||
module.exports.matchKeys = matchKeys; | ||
/** | ||
* Expose `micromatch.makeRe` | ||
*/ | ||
module.exports.makeRe = makeRe; | ||
/** | ||
* Expose `micromatch.braces` | ||
*/ | ||
module.exports.braces = require('braces'); | ||
/** | ||
* Expose `micromatch.filter` | ||
*/ | ||
module.exports.filter = filter; | ||
/** | ||
* Expose `micromatch.expand` | ||
*/ | ||
module.exports.expand = expand; |
@@ -10,7 +10,4 @@ /*! | ||
var isGlob = require('is-glob'); | ||
var braces = require('braces'); | ||
var parse = require('./parse'); | ||
var utils = require('./utils'); | ||
var chars = require('./chars'); | ||
var Glob = require('./glob'); | ||
@@ -33,53 +30,60 @@ /** | ||
function expand(glob, opts) { | ||
opts = opts || {}; | ||
function expand(pattern, options) { | ||
var opts = options || {}; | ||
var glob = new Glob(pattern, opts); | ||
function replace(re, str) { | ||
glob = glob.replace(re, esc(str)); | ||
glob.repl(re, esc(str)); | ||
pattern = glob.pattern; | ||
} | ||
if (specialCase(glob) && opts.safemode) { | ||
return new RegExp(utils.escapeRe(glob)); | ||
// return early if the glob pattern tests `true` | ||
if (specialCase(pattern) && opts.safemode) { | ||
return new RegExp(utils.escapeRe(pattern), 'g'); | ||
} | ||
if (opts.nonegate !== true) { | ||
var negate = glob.charCodeAt(0) === 33; /* '!' */ | ||
if (negate) { | ||
opts.negated = true; | ||
glob = glob.slice(1); | ||
} | ||
opts.negated = glob.negated; | ||
} | ||
// expand braces, e.g `{1..5}` | ||
if (glob.indexOf('{') !== -1 && opts.nobraces !== true) { | ||
glob = expandBraces(glob, opts); | ||
} | ||
glob.track('before brackets'); | ||
glob.brackets(); | ||
glob.track('before braces'); | ||
glob.braces(); | ||
glob.track('after braces'); | ||
glob.parse(); | ||
glob.repl('[]', '\\[\\]'); | ||
glob.repl('(?', '__QMARK_GROUP__'); | ||
// parse the glob pattern into tokens | ||
var tok = parse.glob(glob, opts); | ||
if (tok.isDotGlob) { | ||
var tok = glob.tokens; | ||
if (tok.dotfiles) { | ||
opts.dot = true; | ||
} | ||
if (!isGlob(glob)) { | ||
return {glob: utils.escapePath(glob), tokens: tok, options: opts}; | ||
if (!tok.isGlob) { | ||
return { | ||
pattern: utils.escapePath(glob.pattern), | ||
tokens: tok, | ||
options: opts | ||
}; | ||
} | ||
if (glob === '**' && opts.globstar !== false) { | ||
glob = doublestar(opts); | ||
if (glob.pattern === '**' && opts.globstar !== false) { | ||
glob.pattern = globstar(opts); | ||
} else { | ||
if (/^\*\.\w*$/.test(glob)) { | ||
glob = glob.replace(/\*/, star(opts.dot) + '\\'); | ||
return {glob: glob, tokens: tok, options: opts}; | ||
if (/^\*\.\w*$/.test(glob.pattern)) { | ||
glob.repl('*', star(opts.dot) + '\\'); | ||
glob.repl('__QMARK_GROUP__', '(?'); | ||
return glob; | ||
} | ||
// fix imbalanced brackets and parens | ||
if (/[[\]()]/.test(glob)) { | ||
glob = brackets(glob); | ||
glob = parens(glob); | ||
} | ||
glob.pattern = balance(glob.pattern, '[', ']'); | ||
// use heuristics to replace common escape patterns | ||
glob = escape(glob); | ||
glob.escape(glob.pattern); | ||
@@ -89,26 +93,34 @@ // if the glob is for one directory deep, we can | ||
if (tok.dirname === '') { | ||
return expandFilename(glob, tok, opts); | ||
return expandFilename(glob, opts); | ||
} | ||
// windows drives | ||
replace(/^(\w):([\\\/]+?)/gi, lookahead + '$1:$2'); | ||
// has '**/' | ||
replace(/\*\*\//g, '.*\\/?'); | ||
// has '**' | ||
replace(/\*\*/g, doublestar(opts)); | ||
// ends with '/*' | ||
// if the pattern has `**` | ||
if (tok.globstar) { | ||
glob.repl(/(^|[^\\])\*{2,}([^\\]|$)/g, '$1**$2'); | ||
// foo/** | ||
replace(/(\w+)\*\*(?!\/)/g, '(?=.)$1[^/]*?'); | ||
// **/ | ||
replace('**/', '(.*\\/|^)'); | ||
// ** | ||
replace('**', globstar(opts)); | ||
} | ||
// *.* | ||
replace('*.*', '([^/]*?.[^/]*?)'); | ||
// ends with /* | ||
replace(/\/\*$/g, '\\/' + stardot(opts)); | ||
// ends with '*', no slashes | ||
// ends with *, no slashes | ||
replace(/(?!\/)\*$/g, boxQ); | ||
// has '*' | ||
replace(/\*/g, stardot(opts)); | ||
replace('*', stardot(opts)); | ||
// has '?.' | ||
replace(/\?\./g, '?\\.'); | ||
// has '?:' | ||
replace(/\?:/g, '?:'); | ||
replace('?.', '?\\.'); | ||
replace('?:', '?:'); | ||
// first of '????' | ||
replace(/[^?]\?/g, '\\/'+ dotstarbase(opts.dot) + box); | ||
replace(/(?!\?)\?/g, '\\/'+ dotstarbase(opts.dot) + box); | ||
// rest of '????' | ||
replace(/\?/g, box); | ||
replace(/(?!\()\?/g, box); | ||
@@ -123,7 +135,10 @@ // escape '.abc' => '\\.abc' | ||
replace(/\\+\//g, '\\/'); | ||
glob = unesc(glob); | ||
} | ||
glob = unescape(glob); | ||
return {glob: glob, tokens: tok, options: opts}; | ||
glob.repl('__QMARK_GROUP__', '(?'); | ||
glob.unescape(glob.pattern); | ||
glob.repl('__UNESC_STAR__', '*'); | ||
glob.repl('%~', '?'); | ||
glob.repl('%%', '*'); | ||
return glob; | ||
} | ||
@@ -141,34 +156,41 @@ | ||
function expandFilename(glob, tok, opts) { | ||
switch (glob) { | ||
function expandFilename(glob, opts) { | ||
var tok = glob.tokens; | ||
switch (glob.pattern) { | ||
case '.': | ||
glob = '\\.'; | ||
glob.pattern = '\\.'; | ||
break; | ||
case '.*': | ||
glob = '\\..*'; | ||
glob.pattern = '\\..*'; | ||
break; | ||
case '*.*': | ||
glob = star(opts.dot) + '\\.[^/]*?'; | ||
glob.pattern = star(opts.dot) + '\\.[^/]*?'; | ||
break; | ||
case '*': | ||
glob = star(opts.dot); | ||
glob.pattern = star(opts.dot); | ||
break; | ||
default: | ||
if (tok.basename === '*') { | ||
glob = star(opts.dot) + '\\' + tok.extname; | ||
glob.pattern = star(opts.dot) + '\\' + tok.extname; | ||
} else { | ||
glob = glob.replace(/\?/g, '[^/]'); | ||
if (/^[^.]/.test(tok.filename)) { | ||
glob.repl(/(?!\()\?/g, '[^/]'); | ||
if (tok.filename.charAt(0) !== '.') { | ||
opts.dot = true; | ||
} | ||
glob = glob.replace(/\*/g, star(opts.dot)); | ||
glob.repl('*', star(opts.dot)); | ||
} | ||
} | ||
glob = unescape(glob); | ||
return {glob: glob, options: opts}; | ||
glob.repl('__QMARK_GROUP__', '(?'); | ||
glob.unescape(glob.pattern); | ||
glob.repl('__UNESC_STAR__', '*'); | ||
return glob; | ||
} | ||
/** | ||
* Special cases | ||
*/ | ||
function specialCase(glob) { | ||
if (/^\\$/.test(glob)) { | ||
if (glob === '\\') { | ||
return true; | ||
@@ -180,34 +202,15 @@ } | ||
/** | ||
* Naive approach to fixing brackets and parens | ||
* in character classes etc. | ||
* Escape imbalanced braces/bracket | ||
*/ | ||
function brackets(glob) { | ||
var lt = glob.match(/\[/g); | ||
var rt = glob.match(/\]/g); | ||
if (lt && rt && lt.length !== rt.length) { | ||
if (lt.length > rt.length) { | ||
return glob.replace(/\[/, '\\['); | ||
} | ||
return glob.replace(/\]/, '\\]'); | ||
} | ||
if (lt && !rt) { | ||
return glob.replace(/\[/, '\\['); | ||
} | ||
if (rt && !lt) { | ||
return glob.replace(/\]/, '\\]'); | ||
} | ||
return glob; | ||
} | ||
function balance(str, a, b) { | ||
var aarr = str.split(a); | ||
var alen = aarr.join('').length; | ||
var blen = str.split(b).join('').length; | ||
function parens(glob) { | ||
var lt = glob.match(/\(/g); | ||
var rt = glob.match(/\)/g); | ||
if (lt && rt && lt.length !== rt.length) { | ||
if (lt.length > rt.length) { | ||
return glob.replace(/\(/, '\\('); | ||
} | ||
return glob.replace(/\)/, '\\)'); | ||
if (alen !== blen) { | ||
str = aarr.join('\\' + a); | ||
return str.split(b).join('\\' + b); | ||
} | ||
return glob; | ||
return str; | ||
} | ||
@@ -220,24 +223,7 @@ | ||
function esc(str) { | ||
return str.replace(/\?/g, '%~') | ||
.replace(/\*/g, '%%'); | ||
str = str.split('?').join('%~'); | ||
str = str.split('*').join('%%'); | ||
return str; | ||
} | ||
function unesc(str) { | ||
return str.replace(/%%/g, '*') | ||
.replace(/%~/g, '?'); | ||
} | ||
function escape(str, ch) { | ||
var re = ch ? chars.escapeRegex[ch] : /\\([^\\])/g; | ||
return str.replace(re, function($0, $1) { | ||
return chars[ch ? 'ESC_TEMP' : 'ESC'][ch ? $0 : $1]; | ||
}); | ||
} | ||
function unescape(str) { | ||
return str.replace(/__([A-Z]+)_([A-Z]+)__/g, function($0, $1) { | ||
return chars[$1][$0]; | ||
}); | ||
} | ||
/** | ||
@@ -249,3 +235,2 @@ * Special patterns to be converted to regex. | ||
var box = '[^/]'; | ||
@@ -257,4 +242,3 @@ var boxQ = '[^/]*?'; | ||
var ex = {}; | ||
ex.dotfileGlob = '(?:^|\\\/)(?:\\.{1,2})(?:$|\\\/)'; | ||
ex.dotfileGlob = '(?:^|\\/)(?:\\.{1,2})(?:$|\\/)'; | ||
ex.stardot = '(?!' + ex.dotfileGlob + ')(?=.)[^/]*?'; | ||
@@ -278,5 +262,5 @@ ex.twoStarDot = '(?:(?!' + ex.dotfileGlob + ').)*?'; | ||
function doublestar(opts) { | ||
function globstar(opts) { | ||
if (opts.dot) { return ex.twoStarDot; } | ||
return '(?:(?!(?:^|\\\/)\\.).)*?'; | ||
return '(?:(?!(?:^|\\/)\\.).)*?'; | ||
} | ||
@@ -287,27 +271,1 @@ | ||
} | ||
/** | ||
* Expand braces in the given glob pattern. | ||
* | ||
* We only need to use the [braces] lib when | ||
* patterns are nested. | ||
* | ||
* @param {String} `glob` | ||
* @return {String} | ||
*/ | ||
function expandBraces(glob, options) { | ||
options = options || {}; | ||
options.makeRe = options.makeRe || true; | ||
var a = glob.match(/[\{\(\[]/g); | ||
var b = glob.match(/[\}\)\]]/g); | ||
if (a && b && (a.length !== b.length)) { | ||
options.makeRe = false; | ||
} | ||
var res = braces(glob, options); | ||
return res.join('|'); | ||
} |
'use strict'; | ||
var path = require('path'); | ||
var fileRe = require('filename-regex'); | ||
var win32 = process.platform === 'win32'; | ||
var win; | ||
var utils = module.exports; | ||
utils.filename = function filename(fp) { | ||
var seg = fp.match(fileRe()); | ||
return seg && seg[0]; | ||
}; | ||
utils.isPath = function isPath(pattern) { | ||
return function (fp) { | ||
return fp === pattern; | ||
}; | ||
}; | ||
utils.hasPath = function hasPath(pattern) { | ||
return function (fp) { | ||
return fp.indexOf(pattern) !== -1; | ||
}; | ||
}; | ||
utils.matchPath = function matchPath(pattern, opts) { | ||
var fn = (opts && opts.contains) | ||
? utils.hasPath(pattern) | ||
: utils.isPath(pattern); | ||
return fn; | ||
}; | ||
utils.hasFilename = function hasFilename(re) { | ||
return function (fp) { | ||
var name = utils.filename(fp); | ||
return name && re.test(name); | ||
}; | ||
}; | ||
/** | ||
@@ -14,3 +48,3 @@ * Coerce `val` to an array | ||
exports.arrayify = function arrayify(val) { | ||
utils.arrayify = function arrayify(val) { | ||
return !Array.isArray(val) | ||
@@ -25,4 +59,4 @@ ? [val] | ||
exports.unixify = function unixify(fp, opts) { | ||
if (opts && opts.normalize) { | ||
utils.unixify = function unixify(fp, opts) { | ||
if (opts && opts.unixify === true) { | ||
win = true; | ||
@@ -38,27 +72,16 @@ } else if (opts && opts.cache && typeof win === 'undefined') { | ||
exports.escapePath = function escapePath(fp) { | ||
/** | ||
* Escape/unescape utils | ||
*/ | ||
utils.escapePath = function escapePath(fp) { | ||
return fp.replace(/[\\.]/g, '\\$&'); | ||
}; | ||
exports.isDrive = function isDrive(fp) { | ||
return /^\w:/.test(fp); | ||
utils.unescapeGlob = function unescapeGlob(fp) { | ||
return fp.replace(/[\\"']/g, ''); | ||
}; | ||
exports.isCWD = function isCWD(fp) { | ||
return fp.charAt(0) === '.'; | ||
utils.escapeRe = function escapeRe(str) { | ||
return str.replace(/[-[\\$*+?.#^\s{}(|)\]]/g, '\\$&'); | ||
}; | ||
exports.isLongPath = function isLongPath(fp, len) { | ||
if (typeof len === 'number') { | ||
return len > 248; | ||
} | ||
return fp.length > 248; | ||
}; | ||
exports.isUNC = function isUNC(fp) { | ||
return /^\\\\/.test(fp); | ||
}; | ||
exports.escapeRe = function escapeRe(str) { | ||
return str.replace(/[$*+?.#\\^\s[-\]{}(|)]/g, '\\$&'); | ||
}; |
{ | ||
"name": "micromatch", | ||
"description": "Glob matching for javascript/node.js. A faster alternative to minimatch (10-20x faster on avg), with all the features you're used to using in your Grunt and gulp tasks.", | ||
"version": "1.2.2", | ||
"description": "Glob matching for javascript/node.js. A faster alternative to minimatch (10-45x faster on avg), with all the features you're used to using in your Grunt and gulp tasks.", | ||
"version": "1.3.0", | ||
"homepage": "https://github.com/jonschlinkert/micromatch", | ||
@@ -19,3 +19,3 @@ "author": { | ||
"type": "MIT", | ||
"url": "https://github.com/jonschlinkert/micromatch/blob/master/LICENSE-MIT" | ||
"url": "https://github.com/jonschlinkert/micromatch/blob/master/LICENSE" | ||
}, | ||
@@ -27,3 +27,3 @@ "main": "index.js", | ||
"scripts": { | ||
"test": "mocha -R spec", | ||
"test": "mocha", | ||
"benchmark": "node benchmark" | ||
@@ -38,5 +38,10 @@ }, | ||
"braces": "^1.6.0", | ||
"expand-brackets": "^0.1.0", | ||
"extglob": "^0.2.0", | ||
"filename-regex": "^2.0.0", | ||
"glob-path-regex": "^1.0.0", | ||
"is-glob": "^1.1.0" | ||
"is-glob": "^1.1.0", | ||
"kind-of": "^1.1.0", | ||
"parse-glob": "^1.2.0", | ||
"regex-cache": "^0.2.0" | ||
}, | ||
@@ -43,0 +48,0 @@ "devDependencies": { |
@@ -1,6 +0,6 @@ | ||
# micromatch [![NPM version](https://badge.fury.io/js/micromatch.svg)](http://badge.fury.io/js/micromatch) | ||
# micromatch [![NPM version](https://badge.fury.io/js/micromatch.svg)](http://badge.fury.io/js/micromatch) [![Build Status](https://travis-ci.org/jonschlinkert/micromatch.svg)](https://travis-ci.org/jonschlinkert/micromatch) | ||
> Glob matching for javascript/node.js. A faster alternative to minimatch (10-20x faster on avg), with all the features you're used to using in your Grunt and gulp tasks. | ||
> Glob matching for javascript/node.js. A faster alternative to minimatch (10-45x faster on avg), with all the features you're used to using in your Grunt and gulp tasks. | ||
- 10-20x faster than [minimatch] on average ([see benchmarks](#benchmarks)) | ||
- 10-45x faster than [minimatch] on average ([see benchmarks](#benchmarks)) | ||
- Focus on core Bash 4.3 specification features that are actually used (or can be used) in node.js | ||
@@ -20,2 +20,4 @@ - Supports passing glob patterns as a string or array | ||
+ Regex character classes (`foo/bar/baz-[1-5].js`) | ||
+ POSIX bracket expressions (`**/[:alpha:][:digit:]/`) | ||
+ extglobs (`**/+(x|y)`, `!(a|b)`, etc) | ||
@@ -118,2 +120,16 @@ You can combine these to create whatever matching patterns you need. | ||
### .contains | ||
Returns true if a file path contains a match for the given glob pattern. | ||
**Example** | ||
```js | ||
mm.contains('a/b/c', 'a/b'); | ||
//=> true | ||
mm.contains('a/b/c', 'a/*'); | ||
//=> true | ||
``` | ||
### .filter | ||
@@ -136,3 +152,3 @@ | ||
```js | ||
mm.makeRe('*.js'); | ||
mm.expand('*.js'); | ||
// results in: | ||
@@ -234,3 +250,3 @@ // { glob: '(?!\\.)(?=.)[^/]*?\\.js', | ||
As of January 30, 2015: | ||
As of February 11, 2015: | ||
@@ -318,3 +334,3 @@ ```bash | ||
_This file was generated by [verb](https://github.com/assemble/verb) on January 30, 2015._ | ||
_This file was generated by [verb](https://github.com/assemble/verb) on February 11, 2015._ | ||
@@ -326,10 +342,13 @@ [extended]: http://mywiki.wooledge.org/BashGuide/Patterns#Extended_Globs | ||
[arr-diff]: https://github.com/jonschlinkert/arr-diff | ||
[arr-filter]: https://github.com/jonschlinkert/arr-filter | ||
[arr-filter]: null | ||
[arr-map]: https://github.com/jonschlinkert/arr-map | ||
[array-slice]: https://github.com/jonschlinkert/array-slice | ||
[benchmarked]: null | ||
[braces]: https://github.com/jonschlinkert/braces | ||
[chalk]: null | ||
[expand-brackets]: https://github.com/jonschlinkert/expand-brackets | ||
[expand-range]: https://github.com/jonschlinkert/expand-range | ||
[extglob]: https://github.com/jonschlinkert/extglob | ||
[filename-regex]: https://github.com/regexps/filename-regex | ||
[fill-range]: https://github.com/jonschlinkert/fill-range | ||
[for-in]: https://github.com/jonschlinkert/for-in | ||
[for-own]: https://github.com/jonschlinkert/for-own | ||
[glob-path-regex]: https://github.com/regexps/glob-path-regex | ||
@@ -340,5 +359,7 @@ [is-glob]: https://github.com/jonschlinkert/is-glob | ||
[kind-of]: https://github.com/jonschlinkert/kind-of | ||
[make-iterator]: https://github.com/jonschlinkert/make-iterator | ||
[micromatch]: https://github.com/jonschlinkert/micromatch | ||
[parse-glob]: https://github.com/jonschlinkert/parse-glob | ||
[preserve]: https://github.com/jonschlinkert/preserve | ||
[randomatic]: https://github.com/jonschlinkert/randomatic | ||
[regex-cache]: https://github.com/jonschlinkert/regex-cache | ||
[repeat-element]: https://github.com/jonschlinkert/repeat-element | ||
@@ -345,0 +366,0 @@ [repeat-string]: https://github.com/jonschlinkert/repeat-string |
32834
8
861
362
10
+ Addedexpand-brackets@^0.1.0
+ Addedextglob@^0.2.0
+ Addedkind-of@^1.1.0
+ Addedparse-glob@^1.2.0
+ Addedregex-cache@^0.2.0
+ Addedansi@0.3.1(transitive)
+ Addedansi-regex@0.2.12.1.1(transitive)
+ Addedansi-styles@1.1.02.2.1(transitive)
+ Addedargparse@1.0.10(transitive)
+ Addedarr-union@3.1.0(transitive)
+ Addedasync-array-reduce@0.2.1(transitive)
+ Addedbalanced-match@1.0.2(transitive)
+ Addedbenchmark@1.0.0(transitive)
+ Addedbenchmarked@0.1.5(transitive)
+ Addedbrace-expansion@1.1.11(transitive)
+ Addedcamel-case@1.2.2(transitive)
+ Addedchalk@0.5.11.1.3(transitive)
+ Addedclone@1.0.4(transitive)
+ Addedclone-stats@0.0.1(transitive)
+ Addedconcat-map@0.0.1(transitive)
+ Addedescape-string-regexp@1.0.5(transitive)
+ Addedesprima@4.0.1(transitive)
+ Addedexpand-brackets@0.1.5(transitive)
+ Addedexpand-tilde@1.2.2(transitive)
+ Addedextend-shallow@1.1.42.0.1(transitive)
+ Addedextglob@0.2.0(transitive)
+ Addedfile-reader@1.1.1(transitive)
+ Addedfor-in@1.0.2(transitive)
+ Addedfor-own@0.1.5(transitive)
+ Addedfs-exists-sync@0.1.0(transitive)
+ Addedfs.realpath@1.0.0(transitive)
+ Addedglob@7.2.3(transitive)
+ Addedglobal-modules@0.2.3(transitive)
+ Addedglobal-prefix@0.1.5(transitive)
+ Addedhas-ansi@0.1.02.0.0(transitive)
+ Addedhas-glob@0.1.1(transitive)
+ Addedhas-values@0.1.4(transitive)
+ Addedhomedir-polyfill@1.0.3(transitive)
+ Addedinflight@1.0.6(transitive)
+ Addedinherits@2.0.4(transitive)
+ Addedini@1.3.8(transitive)
+ Addedis-extendable@0.1.1(transitive)
+ Addedis-extglob@1.0.0(transitive)
+ Addedis-glob@2.0.1(transitive)
+ Addedis-posix-bracket@0.1.1(transitive)
+ Addedis-valid-glob@0.3.0(transitive)
+ Addedis-windows@0.2.0(transitive)
+ Addedisexe@2.0.0(transitive)
+ Addedjs-yaml@3.14.1(transitive)
+ Addedkind-of@1.1.0(transitive)
+ Addedlazy-cache@1.0.42.0.2(transitive)
+ Addedlower-case@1.1.4(transitive)
+ Addedmap-files@0.8.2(transitive)
+ Addedmatched@0.4.4(transitive)
+ Addedminimatch@3.1.2(transitive)
+ Addedonce@1.4.0(transitive)
+ Addedos-homedir@1.0.2(transitive)
+ Addedparse-glob@1.2.0(transitive)
+ Addedparse-passwd@1.0.0(transitive)
+ Addedpath-is-absolute@1.0.1(transitive)
+ Addedread-yaml@1.1.0(transitive)
+ Addedregex-cache@0.2.1(transitive)
+ Addedreplace-ext@0.0.1(transitive)
+ Addedresolve-dir@0.1.1(transitive)
+ Addedsentence-case@1.1.3(transitive)
+ Addedset-getter@0.1.1(transitive)
+ Addedsprintf-js@1.0.3(transitive)
+ Addedstrip-ansi@0.3.03.0.1(transitive)
+ Addedsupports-color@0.2.02.0.0(transitive)
+ Addedto-object-path@0.3.0(transitive)
+ Addedupper-case@1.1.3(transitive)
+ Addedvinyl@1.2.0(transitive)
+ Addedwhich@1.3.1(transitive)
+ Addedwrappy@1.0.2(transitive)