diff options
author | Florian Dold <florian.dold@gmail.com> | 2016-10-10 03:43:44 +0200 |
---|---|---|
committer | Florian Dold <florian.dold@gmail.com> | 2016-10-10 03:43:44 +0200 |
commit | abd94a7f5a50f43c797a11b53549ae48fff667c3 (patch) | |
tree | ab8ed457f65cdd72e13e0571d2975729428f1551 /node_modules/micromatch/lib | |
parent | a0247c6a3fd6a09a41a7e35a3441324c4dcb58be (diff) |
add node_modules to address #4364
Diffstat (limited to 'node_modules/micromatch/lib')
-rw-r--r-- | node_modules/micromatch/lib/chars.js | 67 | ||||
-rw-r--r-- | node_modules/micromatch/lib/expand.js | 304 | ||||
-rw-r--r-- | node_modules/micromatch/lib/glob.js | 193 | ||||
-rw-r--r-- | node_modules/micromatch/lib/utils.js | 149 |
4 files changed, 713 insertions, 0 deletions
diff --git a/node_modules/micromatch/lib/chars.js b/node_modules/micromatch/lib/chars.js new file mode 100644 index 000000000..a1ffe3714 --- /dev/null +++ b/node_modules/micromatch/lib/chars.js @@ -0,0 +1,67 @@ +'use strict'; + +var chars = {}, unesc, temp; + +function reverse(object, prepender) { + return Object.keys(object).reduce(function(reversed, key) { + var newKey = prepender ? prepender + key : key; // Optionally prepend a string to key. + reversed[object[key]] = newKey; // Swap key and value. + return reversed; // Return the result. + }, {}); +} + +/** + * Regex for common characters + */ + +chars.escapeRegex = { + '?': /\?/g, + '@': /\@/g, + '!': /\!/g, + '+': /\+/g, + '*': /\*/g, + '(': /\(/g, + ')': /\)/g, + '[': /\[/g, + ']': /\]/g +}; + +/** + * Escape characters + */ + +chars.ESC = { + '?': '__UNESC_QMRK__', + '@': '__UNESC_AMPE__', + '!': '__UNESC_EXCL__', + '+': '__UNESC_PLUS__', + '*': '__UNESC_STAR__', + ',': '__UNESC_COMMA__', + '(': '__UNESC_LTPAREN__', + ')': '__UNESC_RTPAREN__', + '[': '__UNESC_LTBRACK__', + ']': '__UNESC_RTBRACK__' +}; + +/** + * Unescape characters + */ + +chars.UNESC = unesc || (unesc = reverse(chars.ESC, '\\')); + +chars.ESC_TEMP = { + '?': '__TEMP_QMRK__', + '@': '__TEMP_AMPE__', + '!': '__TEMP_EXCL__', + '*': '__TEMP_STAR__', + '+': '__TEMP_PLUS__', + ',': '__TEMP_COMMA__', + '(': '__TEMP_LTPAREN__', + ')': '__TEMP_RTPAREN__', + '[': '__TEMP_LTBRACK__', + ']': '__TEMP_RTBRACK__' +}; + +chars.TEMP = temp || (temp = reverse(chars.ESC_TEMP)); + +module.exports = chars; diff --git a/node_modules/micromatch/lib/expand.js b/node_modules/micromatch/lib/expand.js new file mode 100644 index 000000000..e99b081eb --- /dev/null +++ b/node_modules/micromatch/lib/expand.js @@ -0,0 +1,304 @@ +/*! + * micromatch <https://github.com/jonschlinkert/micromatch> + * + * Copyright (c) 2014-2015, Jon Schlinkert. + * Licensed under the MIT License. + */ + +'use strict'; + +var utils = require('./utils'); +var Glob = require('./glob'); + +/** + * Expose `expand` + */ + +module.exports = expand; + +/** + * Expand a glob pattern to resolve braces and + * similar patterns before converting to regex. + * + * @param {String|Array} `pattern` + * @param {Array} `files` + * @param {Options} `opts` + * @return {Array} + */ + +function expand(pattern, options) { + if (typeof pattern !== 'string') { + throw new TypeError('micromatch.expand(): argument should be a string.'); + } + + var glob = new Glob(pattern, options || {}); + var opts = glob.options; + + if (!utils.isGlob(pattern)) { + glob.pattern = glob.pattern.replace(/([\/.])/g, '\\$1'); + return glob; + } + + glob.pattern = glob.pattern.replace(/(\+)(?!\()/g, '\\$1'); + glob.pattern = glob.pattern.split('$').join('\\$'); + + if (typeof opts.braces !== 'boolean' && typeof opts.nobraces !== 'boolean') { + opts.braces = true; + } + + if (glob.pattern === '.*') { + return { + pattern: '\\.' + star, + tokens: tok, + options: opts + }; + } + + if (glob.pattern === '*') { + return { + pattern: oneStar(opts.dot), + tokens: tok, + options: opts + }; + } + + // parse the glob pattern into tokens + glob.parse(); + var tok = glob.tokens; + tok.is.negated = opts.negated; + + // dotfile handling + if ((opts.dotfiles === true || tok.is.dotfile) && opts.dot !== false) { + opts.dotfiles = true; + opts.dot = true; + } + + if ((opts.dotdirs === true || tok.is.dotdir) && opts.dot !== false) { + opts.dotdirs = true; + opts.dot = true; + } + + // check for braces with a dotfile pattern + if (/[{,]\./.test(glob.pattern)) { + opts.makeRe = false; + opts.dot = true; + } + + if (opts.nonegate !== true) { + opts.negated = glob.negated; + } + + // if the leading character is a dot or a slash, escape it + if (glob.pattern.charAt(0) === '.' && glob.pattern.charAt(1) !== '/') { + glob.pattern = '\\' + glob.pattern; + } + + /** + * Extended globs + */ + + // expand braces, e.g `{1..5}` + glob.track('before braces'); + if (tok.is.braces) { + glob.braces(); + } + glob.track('after braces'); + + // expand extglobs, e.g `foo/!(a|b)` + glob.track('before extglob'); + if (tok.is.extglob) { + glob.extglob(); + } + glob.track('after extglob'); + + // expand brackets, e.g `[[:alpha:]]` + glob.track('before brackets'); + if (tok.is.brackets) { + glob.brackets(); + } + glob.track('after brackets'); + + // special patterns + glob._replace('[!', '[^'); + glob._replace('(?', '(%~'); + glob._replace(/\[\]/, '\\[\\]'); + glob._replace('/[', '/' + (opts.dot ? dotfiles : nodot) + '[', true); + glob._replace('/?', '/' + (opts.dot ? dotfiles : nodot) + '[^/]', true); + glob._replace('/.', '/(?=.)\\.', true); + + // windows drives + glob._replace(/^(\w):([\\\/]+?)/gi, '(?=.)$1:$2', true); + + // negate slashes in exclusion ranges + if (glob.pattern.indexOf('[^') !== -1) { + glob.pattern = negateSlash(glob.pattern); + } + + if (opts.globstar !== false && glob.pattern === '**') { + glob.pattern = globstar(opts.dot); + + } else { + glob.pattern = balance(glob.pattern, '[', ']'); + glob.escape(glob.pattern); + + // if the pattern has `**` + if (tok.is.globstar) { + glob.pattern = collapse(glob.pattern, '/**'); + glob.pattern = collapse(glob.pattern, '**/'); + glob._replace('/**/', '(?:/' + globstar(opts.dot) + '/|/)', true); + glob._replace(/\*{2,}/g, '**'); + + // 'foo/*' + glob._replace(/(\w+)\*(?!\/)/g, '$1[^/]*?', true); + glob._replace(/\*\*\/\*(\w)/g, globstar(opts.dot) + '\\/' + (opts.dot ? dotfiles : nodot) + '[^/]*?$1', true); + + if (opts.dot !== true) { + glob._replace(/\*\*\/(.)/g, '(?:**\\/|)$1'); + } + + // 'foo/**' or '{**,*}', but not 'foo**' + if (tok.path.dirname !== '' || /,\*\*|\*\*,/.test(glob.orig)) { + glob._replace('**', globstar(opts.dot), true); + } + } + + // ends with /* + glob._replace(/\/\*$/, '\\/' + oneStar(opts.dot), true); + // ends with *, no slashes + glob._replace(/(?!\/)\*$/, star, true); + // has 'n*.' (partial wildcard w/ file extension) + glob._replace(/([^\/]+)\*/, '$1' + oneStar(true), true); + // has '*' + glob._replace('*', oneStar(opts.dot), true); + glob._replace('?.', '?\\.', true); + glob._replace('?:', '?:', true); + + glob._replace(/\?+/g, function(match) { + var len = match.length; + if (len === 1) { + return qmark; + } + return qmark + '{' + len + '}'; + }); + + // escape '.abc' => '\\.abc' + glob._replace(/\.([*\w]+)/g, '\\.$1'); + // fix '[^\\\\/]' + glob._replace(/\[\^[\\\/]+\]/g, qmark); + // '///' => '\/' + glob._replace(/\/+/g, '\\/'); + // '\\\\\\' => '\\' + glob._replace(/\\{2,}/g, '\\'); + } + + // unescape previously escaped patterns + glob.unescape(glob.pattern); + glob._replace('__UNESC_STAR__', '*'); + + // escape dots that follow qmarks + glob._replace('?.', '?\\.'); + + // remove unnecessary slashes in character classes + glob._replace('[^\\/]', qmark); + + if (glob.pattern.length > 1) { + if (/^[\[?*]/.test(glob.pattern)) { + // only prepend the string if we don't want to match dotfiles + glob.pattern = (opts.dot ? dotfiles : nodot) + glob.pattern; + } + } + + return glob; +} + +/** + * Collapse repeated character sequences. + * + * ```js + * collapse('a/../../../b', '../'); + * //=> 'a/../b' + * ``` + * + * @param {String} `str` + * @param {String} `ch` Character sequence to collapse + * @return {String} + */ + +function collapse(str, ch) { + var res = str.split(ch); + var isFirst = res[0] === ''; + var isLast = res[res.length - 1] === ''; + res = res.filter(Boolean); + if (isFirst) res.unshift(''); + if (isLast) res.push(''); + return res.join(ch); +} + +/** + * Negate slashes in exclusion ranges, per glob spec: + * + * ```js + * negateSlash('[^foo]'); + * //=> '[^\\/foo]' + * ``` + * + * @param {String} `str` glob pattern + * @return {String} + */ + +function negateSlash(str) { + return str.replace(/\[\^([^\]]*?)\]/g, function(match, inner) { + if (inner.indexOf('/') === -1) { + inner = '\\/' + inner; + } + return '[^' + inner + ']'; + }); +} + +/** + * Escape imbalanced braces/bracket. This is a very + * basic, naive implementation that only does enough + * to serve the purpose. + */ + +function balance(str, a, b) { + var aarr = str.split(a); + var alen = aarr.join('').length; + var blen = str.split(b).join('').length; + + if (alen !== blen) { + str = aarr.join('\\' + a); + return str.split(b).join('\\' + b); + } + return str; +} + +/** + * Special patterns to be converted to regex. + * Heuristics are used to simplify patterns + * and speed up processing. + */ + +/* eslint no-multi-spaces: 0 */ +var qmark = '[^/]'; +var star = qmark + '*?'; +var nodot = '(?!\\.)(?=.)'; +var dotfileGlob = '(?:\\/|^)\\.{1,2}($|\\/)'; +var dotfiles = '(?!' + dotfileGlob + ')(?=.)'; +var twoStarDot = '(?:(?!' + dotfileGlob + ').)*?'; + +/** + * Create a regex for `*`. + * + * If `dot` is true, or the pattern does not begin with + * a leading star, then return the simpler regex. + */ + +function oneStar(dotfile) { + return dotfile ? '(?!' + dotfileGlob + ')(?=.)' + star : (nodot + star); +} + +function globstar(dotfile) { + if (dotfile) { return twoStarDot; } + return '(?:(?!(?:\\/|^)\\.).)*?'; +} diff --git a/node_modules/micromatch/lib/glob.js b/node_modules/micromatch/lib/glob.js new file mode 100644 index 000000000..c61332673 --- /dev/null +++ b/node_modules/micromatch/lib/glob.js @@ -0,0 +1,193 @@ +'use strict'; + +var chars = require('./chars'); +var utils = require('./utils'); + +/** + * Expose `Glob` + */ + +var Glob = module.exports = function Glob(pattern, options) { + if (!(this instanceof Glob)) { + return new Glob(pattern, options); + } + this.options = options || {}; + this.pattern = pattern; + this.history = []; + this.tokens = {}; + this.init(pattern); +}; + +/** + * Initialize defaults + */ + +Glob.prototype.init = function(pattern) { + this.orig = pattern; + this.negated = this.isNegated(); + this.options.track = this.options.track || false; + this.options.makeRe = true; +}; + +/** + * Push a change into `glob.history`. Useful + * for debugging. + */ + +Glob.prototype.track = function(msg) { + if (this.options.track) { + this.history.push({msg: msg, pattern: this.pattern}); + } +}; + +/** + * Return true if `glob.pattern` was negated + * with `!`, also remove the `!` from the pattern. + * + * @return {Boolean} + */ + +Glob.prototype.isNegated = function() { + if (this.pattern.charCodeAt(0) === 33 /* '!' */) { + this.pattern = this.pattern.slice(1); + return true; + } + return false; +}; + +/** + * Expand braces in the given glob pattern. + * + * We only need to use the [braces] lib when + * patterns are nested. + */ + +Glob.prototype.braces = function() { + if (this.options.nobraces !== true && this.options.nobrace !== true) { + // naive/fast check for imbalanced characters + var a = this.pattern.match(/[\{\(\[]/g); + var b = this.pattern.match(/[\}\)\]]/g); + + // if imbalanced, don't optimize the pattern + if (a && b && (a.length !== b.length)) { + this.options.makeRe = false; + } + + // expand brace patterns and join the resulting array + var expanded = utils.braces(this.pattern, this.options); + this.pattern = expanded.join('|'); + } +}; + +/** + * Expand bracket expressions in `glob.pattern` + */ + +Glob.prototype.brackets = function() { + if (this.options.nobrackets !== true) { + this.pattern = utils.brackets(this.pattern); + } +}; + +/** + * Expand bracket expressions in `glob.pattern` + */ + +Glob.prototype.extglob = function() { + if (this.options.noextglob === true) return; + + if (utils.isExtglob(this.pattern)) { + this.pattern = utils.extglob(this.pattern, {escape: true}); + } +}; + +/** + * Parse the given pattern + */ + +Glob.prototype.parse = function(pattern) { + this.tokens = utils.parseGlob(pattern || this.pattern, true); + return this.tokens; +}; + +/** + * Replace `a` with `b`. Also tracks the change before and + * after each replacement. This is disabled by default, but + * can be enabled by setting `options.track` to true. + * + * Also, when the pattern is a string, `.split()` is used, + * because it's much faster than replace. + * + * @param {RegExp|String} `a` + * @param {String} `b` + * @param {Boolean} `escape` When `true`, escapes `*` and `?` in the replacement. + * @return {String} + */ + +Glob.prototype._replace = function(a, b, escape) { + this.track('before (find): "' + a + '" (replace with): "' + b + '"'); + if (escape) b = esc(b); + if (a && b && typeof a === 'string') { + this.pattern = this.pattern.split(a).join(b); + } else { + this.pattern = this.pattern.replace(a, b); + } + this.track('after'); +}; + +/** + * Escape special characters in the given string. + * + * @param {String} `str` Glob pattern + * @return {String} + */ + +Glob.prototype.escape = function(str) { + this.track('before escape: '); + var re = /["\\](['"]?[^"'\\]['"]?)/g; + + this.pattern = str.replace(re, function($0, $1) { + var o = chars.ESC; + var ch = o && o[$1]; + if (ch) { + return ch; + } + if (/[a-z]/i.test($0)) { + return $0.split('\\').join(''); + } + return $0; + }); + + this.track('after escape: '); +}; + +/** + * Unescape special characters in the given string. + * + * @param {String} `str` + * @return {String} + */ + +Glob.prototype.unescape = function(str) { + var re = /__([A-Z]+)_([A-Z]+)__/g; + this.pattern = str.replace(re, function($0, $1) { + return chars[$1][$0]; + }); + this.pattern = unesc(this.pattern); +}; + +/** + * Escape/unescape utils + */ + +function esc(str) { + str = str.split('?').join('%~'); + str = str.split('*').join('%%'); + return str; +} + +function unesc(str) { + str = str.split('%~').join('?'); + str = str.split('%%').join('*'); + return str; +} diff --git a/node_modules/micromatch/lib/utils.js b/node_modules/micromatch/lib/utils.js new file mode 100644 index 000000000..7c24a5106 --- /dev/null +++ b/node_modules/micromatch/lib/utils.js @@ -0,0 +1,149 @@ +'use strict'; + +var win32 = process && process.platform === 'win32'; +var path = require('path'); +var fileRe = require('filename-regex'); +var utils = module.exports; + +/** + * Module dependencies + */ + +utils.diff = require('arr-diff'); +utils.unique = require('array-unique'); +utils.braces = require('braces'); +utils.brackets = require('expand-brackets'); +utils.extglob = require('extglob'); +utils.isExtglob = require('is-extglob'); +utils.isGlob = require('is-glob'); +utils.typeOf = require('kind-of'); +utils.normalize = require('normalize-path'); +utils.omit = require('object.omit'); +utils.parseGlob = require('parse-glob'); +utils.cache = require('regex-cache'); + +/** + * Get the filename of a filepath + * + * @param {String} `string` + * @return {String} + */ + +utils.filename = function filename(fp) { + var seg = fp.match(fileRe()); + return seg && seg[0]; +}; + +/** + * Returns a function that returns true if the given + * pattern is the same as a given `filepath` + * + * @param {String} `pattern` + * @return {Function} + */ + +utils.isPath = function isPath(pattern, opts) { + opts = opts || {}; + return function(fp) { + var unixified = utils.unixify(fp, opts); + if(opts.nocase){ + return pattern.toLowerCase() === unixified.toLowerCase(); + } + return pattern === unixified; + }; +}; + +/** + * Returns a function that returns true if the given + * pattern contains a `filepath` + * + * @param {String} `pattern` + * @return {Function} + */ + +utils.hasPath = function hasPath(pattern, opts) { + return function(fp) { + return utils.unixify(pattern, opts).indexOf(fp) !== -1; + }; +}; + +/** + * Returns a function that returns true if the given + * pattern matches or contains a `filepath` + * + * @param {String} `pattern` + * @return {Function} + */ + +utils.matchPath = function matchPath(pattern, opts) { + var fn = (opts && opts.contains) + ? utils.hasPath(pattern, opts) + : utils.isPath(pattern, opts); + return fn; +}; + +/** + * Returns a function that returns true if the given + * regex matches the `filename` of a file path. + * + * @param {RegExp} `re` + * @return {Boolean} + */ + +utils.hasFilename = function hasFilename(re) { + return function(fp) { + var name = utils.filename(fp); + return name && re.test(name); + }; +}; + +/** + * Coerce `val` to an array + * + * @param {*} val + * @return {Array} + */ + +utils.arrayify = function arrayify(val) { + return !Array.isArray(val) + ? [val] + : val; +}; + +/** + * Normalize all slashes in a file path or glob pattern to + * forward slashes. + */ + +utils.unixify = function unixify(fp, opts) { + if (opts && opts.unixify === false) return fp; + if (opts && opts.unixify === true || win32 || path.sep === '\\') { + return utils.normalize(fp, false); + } + if (opts && opts.unescape === true) { + return fp ? fp.toString().replace(/\\(\w)/g, '$1') : ''; + } + return fp; +}; + +/** + * Escape/unescape utils + */ + +utils.escapePath = function escapePath(fp) { + return fp.replace(/[\\.]/g, '\\$&'); +}; + +utils.unescapeGlob = function unescapeGlob(fp) { + return fp.replace(/[\\"']/g, ''); +}; + +utils.escapeRe = function escapeRe(str) { + return str.replace(/[-[\\$*+?.#^\s{}(|)\]]/g, '\\$&'); +}; + +/** + * Expose `utils` + */ + +module.exports = utils; |