| | |
| | | module.exports = minimatch |
| | | minimatch.Minimatch = Minimatch |
| | | |
| | | var path = { sep: '/' } |
| | | try { |
| | | path = require('path') |
| | | } catch (er) {} |
| | | var path = (function () { try { return require('path') } catch (e) {}}()) || { |
| | | sep: '/' |
| | | } |
| | | minimatch.sep = path.sep |
| | | |
| | | var GLOBSTAR = minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {} |
| | | var expand = require('brace-expansion') |
| | |
| | | } |
| | | |
| | | function ext (a, b) { |
| | | a = a || {} |
| | | b = b || {} |
| | | var t = {} |
| | | Object.keys(b).forEach(function (k) { |
| | | t[k] = b[k] |
| | | }) |
| | | Object.keys(a).forEach(function (k) { |
| | | t[k] = a[k] |
| | | }) |
| | | Object.keys(b).forEach(function (k) { |
| | | t[k] = b[k] |
| | | }) |
| | | return t |
| | | } |
| | | |
| | | minimatch.defaults = function (def) { |
| | | if (!def || !Object.keys(def).length) return minimatch |
| | | if (!def || typeof def !== 'object' || !Object.keys(def).length) { |
| | | return minimatch |
| | | } |
| | | |
| | | var orig = minimatch |
| | | |
| | | var m = function minimatch (p, pattern, options) { |
| | | return orig.minimatch(p, pattern, ext(def, options)) |
| | | return orig(p, pattern, ext(def, options)) |
| | | } |
| | | |
| | | m.Minimatch = function Minimatch (pattern, options) { |
| | | return new orig.Minimatch(pattern, ext(def, options)) |
| | | } |
| | | m.Minimatch.defaults = function defaults (options) { |
| | | return orig.defaults(ext(def, options)).Minimatch |
| | | } |
| | | |
| | | m.filter = function filter (pattern, options) { |
| | | return orig.filter(pattern, ext(def, options)) |
| | | } |
| | | |
| | | m.defaults = function defaults (options) { |
| | | return orig.defaults(ext(def, options)) |
| | | } |
| | | |
| | | m.makeRe = function makeRe (pattern, options) { |
| | | return orig.makeRe(pattern, ext(def, options)) |
| | | } |
| | | |
| | | m.braceExpand = function braceExpand (pattern, options) { |
| | | return orig.braceExpand(pattern, ext(def, options)) |
| | | } |
| | | |
| | | m.match = function (list, pattern, options) { |
| | | return orig.match(list, pattern, ext(def, options)) |
| | | } |
| | | |
| | | return m |
| | | } |
| | | |
| | | Minimatch.defaults = function (def) { |
| | | if (!def || !Object.keys(def).length) return Minimatch |
| | | return minimatch.defaults(def).Minimatch |
| | | } |
| | | |
| | | function minimatch (p, pattern, options) { |
| | | if (typeof pattern !== 'string') { |
| | | throw new TypeError('glob pattern string required') |
| | | } |
| | | assertValidPattern(pattern) |
| | | |
| | | if (!options) options = {} |
| | | |
| | |
| | | if (!options.nocomment && pattern.charAt(0) === '#') { |
| | | return false |
| | | } |
| | | |
| | | // "" only matches "" |
| | | if (pattern.trim() === '') return p === '' |
| | | |
| | | return new Minimatch(pattern, options).match(p) |
| | | } |
| | |
| | | return new Minimatch(pattern, options) |
| | | } |
| | | |
| | | if (typeof pattern !== 'string') { |
| | | throw new TypeError('glob pattern string required') |
| | | } |
| | | assertValidPattern(pattern) |
| | | |
| | | if (!options) options = {} |
| | | |
| | | pattern = pattern.trim() |
| | | |
| | | // windows support: need to use /, not \ |
| | | if (path.sep !== '/') { |
| | | if (!options.allowWindowsEscape && path.sep !== '/') { |
| | | pattern = pattern.split(path.sep).join('/') |
| | | } |
| | | |
| | |
| | | this.negate = false |
| | | this.comment = false |
| | | this.empty = false |
| | | this.partial = !!options.partial |
| | | |
| | | // make the set of regexps etc. |
| | | this.make() |
| | |
| | | |
| | | Minimatch.prototype.make = make |
| | | function make () { |
| | | // don't do it more than once. |
| | | if (this._made) return |
| | | |
| | | var pattern = this.pattern |
| | | var options = this.options |
| | | |
| | |
| | | // step 2: expand braces |
| | | var set = this.globSet = this.braceExpand() |
| | | |
| | | if (options.debug) this.debug = console.error |
| | | if (options.debug) this.debug = function debug() { console.error.apply(console, arguments) } |
| | | |
| | | this.debug(this.pattern, set) |
| | | |
| | |
| | | pattern = typeof pattern === 'undefined' |
| | | ? this.pattern : pattern |
| | | |
| | | if (typeof pattern === 'undefined') { |
| | | throw new TypeError('undefined pattern') |
| | | } |
| | | assertValidPattern(pattern) |
| | | |
| | | if (options.nobrace || |
| | | !pattern.match(/\{.*\}/)) { |
| | | // Thanks to Yeting Li <https://github.com/yetingli> for |
| | | // improving this regexp to avoid a ReDOS vulnerability. |
| | | if (options.nobrace || !/\{(?:(?!\{).)*\}/.test(pattern)) { |
| | | // shortcut. no need to expand. |
| | | return [pattern] |
| | | } |
| | | |
| | | return expand(pattern) |
| | | } |
| | | |
| | | var MAX_PATTERN_LENGTH = 1024 * 64 |
| | | var assertValidPattern = function (pattern) { |
| | | if (typeof pattern !== 'string') { |
| | | throw new TypeError('invalid pattern') |
| | | } |
| | | |
| | | if (pattern.length > MAX_PATTERN_LENGTH) { |
| | | throw new TypeError('pattern is too long') |
| | | } |
| | | } |
| | | |
| | | // parse a component of the expanded set. |
| | |
| | | Minimatch.prototype.parse = parse |
| | | var SUBPARSE = {} |
| | | function parse (pattern, isSub) { |
| | | if (pattern.length > 1024 * 64) { |
| | | throw new TypeError('pattern is too long') |
| | | } |
| | | assertValidPattern(pattern) |
| | | |
| | | var options = this.options |
| | | |
| | | // shortcuts |
| | | if (!options.noglobstar && pattern === '**') return GLOBSTAR |
| | | if (pattern === '**') { |
| | | if (!options.noglobstar) |
| | | return GLOBSTAR |
| | | else |
| | | pattern = '*' |
| | | } |
| | | if (pattern === '') return '' |
| | | |
| | | var re = '' |
| | |
| | | } |
| | | |
| | | switch (c) { |
| | | case '/': |
| | | /* istanbul ignore next */ |
| | | case '/': { |
| | | // completely not allowed, even escaped. |
| | | // Should already be path-split by now. |
| | | return false |
| | | } |
| | | |
| | | case '\\': |
| | | clearStateChar() |
| | |
| | | |
| | | // handle the case where we left a class open. |
| | | // "[z-a]" is valid, equivalent to "\[z-a\]" |
| | | if (inClass) { |
| | | // split where the last [ was, make sure we don't have |
| | | // an invalid re. if so, re-walk the contents of the |
| | | // would-be class to re-translate any characters that |
| | | // were passed through as-is |
| | | // TODO: It would probably be faster to determine this |
| | | // without a try/catch and a new RegExp, but it's tricky |
| | | // to do safely. For now, this is safe and works. |
| | | var cs = pattern.substring(classStart + 1, i) |
| | | try { |
| | | RegExp('[' + cs + ']') |
| | | } catch (er) { |
| | | // not a valid class! |
| | | var sp = this.parse(cs, SUBPARSE) |
| | | re = re.substr(0, reClassStart) + '\\[' + sp[0] + '\\]' |
| | | hasMagic = hasMagic || sp[1] |
| | | inClass = false |
| | | continue |
| | | } |
| | | // split where the last [ was, make sure we don't have |
| | | // an invalid re. if so, re-walk the contents of the |
| | | // would-be class to re-translate any characters that |
| | | // were passed through as-is |
| | | // TODO: It would probably be faster to determine this |
| | | // without a try/catch and a new RegExp, but it's tricky |
| | | // to do safely. For now, this is safe and works. |
| | | var cs = pattern.substring(classStart + 1, i) |
| | | try { |
| | | RegExp('[' + cs + ']') |
| | | } catch (er) { |
| | | // not a valid class! |
| | | var sp = this.parse(cs, SUBPARSE) |
| | | re = re.substr(0, reClassStart) + '\\[' + sp[0] + '\\]' |
| | | hasMagic = hasMagic || sp[1] |
| | | inClass = false |
| | | continue |
| | | } |
| | | |
| | | // finish up the class. |
| | |
| | | // something that could conceivably capture a dot |
| | | var addPatternStart = false |
| | | switch (re.charAt(0)) { |
| | | case '.': |
| | | case '[': |
| | | case '(': addPatternStart = true |
| | | case '[': case '.': case '(': addPatternStart = true |
| | | } |
| | | |
| | | // Hack to work around lack of negative lookbehind in JS |
| | |
| | | var flags = options.nocase ? 'i' : '' |
| | | try { |
| | | var regExp = new RegExp('^' + re + '$', flags) |
| | | } catch (er) { |
| | | } catch (er) /* istanbul ignore next - should be impossible */ { |
| | | // If it was an invalid regular expression, then it can't match |
| | | // anything. This trick looks for a character after the end of |
| | | // the string, which is of course impossible, except in multi-line |
| | |
| | | |
| | | try { |
| | | this.regexp = new RegExp(re, flags) |
| | | } catch (ex) { |
| | | } catch (ex) /* istanbul ignore next - should be impossible */ { |
| | | this.regexp = false |
| | | } |
| | | return this.regexp |
| | |
| | | return list |
| | | } |
| | | |
| | | Minimatch.prototype.match = match |
| | | function match (f, partial) { |
| | | Minimatch.prototype.match = function match (f, partial) { |
| | | if (typeof partial === 'undefined') partial = this.partial |
| | | this.debug('match', f, this.pattern) |
| | | // short-circuit in the case of busted things. |
| | | // comments, etc. |
| | |
| | | |
| | | // should be impossible. |
| | | // some invalid regexp stuff in the set. |
| | | /* istanbul ignore if */ |
| | | if (p === false) return false |
| | | |
| | | if (p === GLOBSTAR) { |
| | |
| | | // no match was found. |
| | | // However, in partial mode, we can't say this is necessarily over. |
| | | // If there's more *pattern* left, then |
| | | /* istanbul ignore if */ |
| | | if (partial) { |
| | | // ran out of file |
| | | this.debug('\n>>> no match, partial?', file, fr, pattern, pr) |
| | |
| | | // patterns with magic have been turned into regexps. |
| | | var hit |
| | | if (typeof p === 'string') { |
| | | if (options.nocase) { |
| | | hit = f.toLowerCase() === p.toLowerCase() |
| | | } else { |
| | | hit = f === p |
| | | } |
| | | hit = f === p |
| | | this.debug('string match', p, f, hit) |
| | | } else { |
| | | hit = f.match(p) |
| | |
| | | // this is ok if we're doing the match as part of |
| | | // a glob fs traversal. |
| | | return partial |
| | | } else if (pi === pl) { |
| | | } else /* istanbul ignore else */ if (pi === pl) { |
| | | // ran out of pattern, still have file left. |
| | | // this is only acceptable if we're on the very last |
| | | // empty segment of a file with a trailing slash. |
| | | // a/* should match a/b/ |
| | | var emptyFileEnd = (fi === fl - 1) && (file[fi] === '') |
| | | return emptyFileEnd |
| | | return (fi === fl - 1) && (file[fi] === '') |
| | | } |
| | | |
| | | // should be unreachable. |
| | | /* istanbul ignore next */ |
| | | throw new Error('wtf?') |
| | | } |
| | | |