Update bundled node-glob.

This commit is contained in:
Nathan Rajlich 2012-02-27 13:01:58 -08:00
parent a29d3f7d5f
commit a35dd339c6
28 changed files with 2538 additions and 329 deletions

173
node_modules/glob/README.md generated vendored
View file

@ -47,27 +47,56 @@ See:
* `man 5 gitignore`
* [minimatch documentation](https://github.com/isaacs/minimatch)
## Glob Class
## glob(pattern, [options], cb)
Create a glob object by instanting the `glob.Glob` class.
* `pattern` {String} Pattern to be matched
* `options` {Object}
* `cb` {Function}
* `err` {Error | null}
* `matches` {Array<String>} filenames found matching the pattern
Perform an asynchronous glob search.
## glob.sync(pattern, [options]
* `pattern` {String} Pattern to be matched
* `options` {Object}
* return: {Array<String>} filenames found matching the pattern
Perform a synchronous glob search.
## Class: glob.Glob
Create a Glob object by instanting the `glob.Glob` class.
```javascript
var Glob = require("glob").Glob
var mg = new Glob(pattern, options)
var mg = new Glob(pattern, options, cb)
```
It's an EventEmitter.
It's an EventEmitter, and starts walking the filesystem to find matches
immediately.
### new glob.Glob(pattern, [options], [cb])
* `pattern` {String} pattern to search for
* `options` {Object}
* `cb` {Function} Called when an error occurs, or matches are found
* `err` {Error | null}
* `matches` {Array<String>} filenames found matching the pattern
Note that if the `sync` flag is set in the options, then matches will
be immediately available on the `g.found` member.
### Properties
* `minimatch` The minimatch object that the glob uses.
* `options` The options object passed in.
* `matches` A [FastList](https://github.com/isaacs/fast-list) object
containing the matches as they are found.
* `error` The error encountered. When an error is encountered, the
glob object is in an undefined state, and should be discarded.
* `aborted` Boolean which is set to true when calling `abort()`. There
is no way at this time to continue a glob search after aborting.
is no way at this time to continue a glob search after aborting, but
you can re-use the statCache to avoid having to duplicate syscalls.
### Events
@ -75,10 +104,9 @@ It's an EventEmitter.
matches found. If the `nonull` option is set, and no match was found,
then the `matches` list contains the original pattern. The matches
are sorted, unless the `nosort` flag is set.
* `match` Every time a match is found, this is emitted with the pattern.
* `partial` Emitted when a directory matches the start of a pattern, and
is then searched for additional matches.
* `error` Emitted when an unexpected error is encountered.
* `match` Every time a match is found, this is emitted with the matched.
* `error` Emitted when an unexpected error is encountered, or whenever
any fs error occurs if `options.strict` is set.
* `abort` When `abort()` is called, this event is raised.
### Methods
@ -88,27 +116,118 @@ It's an EventEmitter.
### Options
All the options that can be passed to Minimatch can also be passed to
Glob to change pattern matching behavior. Additionally, these ones
are added which are glob-specific, or have glob-specific ramifcations.
Glob to change pattern matching behavior. Also, some have been added,
or have glob-specific ramifications.
All options are false by default.
All options are false by default, unless otherwise noted.
* `cwd` The current working directory in which to search. Since, unlike
Minimatch, Glob requires a working directory to start in, this
defaults to `process.cwd()`.
* `root` Since Glob requires a root setting, this defaults to
`path.resolve(options.cwd, "/")`.
* `mark` Add a `/` character to directory matches.
* `follow` Use `stat` instead of `lstat`. This is only relevant if
`stat` or `mark` are true.
All options are added to the glob object, as well.
* `cwd` The current working directory in which to search. Defaults
to `process.cwd()`.
* `root` The place where patterns starting with `/` will be mounted
onto. Defaults to `path.resolve(options.cwd, "/")` (`/` on Unix
systems, and `C:\` or some such on Windows.)
* `nomount` By default, a pattern starting with a forward-slash will be
"mounted" onto the root setting, so that a valid filesystem path is
returned. Set this flag to disable that behavior.
* `mark` Add a `/` character to directory matches. Note that this
requires additional stat calls.
* `nosort` Don't sort the results.
* `stat` Set to true to stat/lstat *all* results. This reduces performance
somewhat, but guarantees that the results are files that actually
exist.
* `silent` When an error other than `ENOENT` or `ENOTDIR` is encountered
* `stat` Set to true to stat *all* results. This reduces performance
somewhat, and is completely unnecessary, unless `readdir` is presumed
to be an untrustworthy indicator of file existence. It will cause
ELOOP to be triggered one level sooner in the case of cyclical
symbolic links.
* `silent` When an unusual error is encountered
when attempting to read a directory, a warning will be printed to
stderr. Set the `silent` option to true to suppress these warnings.
* `strict` When an error other than `ENOENT` or `ENOTDIR` is encountered
* `strict` When an unusual error is encountered
when attempting to read a directory, the process will just continue on
in search of other matches. Set the `strict` option to raise an error
in these cases.
* `statCache` A cache of results of filesystem information, to prevent
unnecessary stat calls. While it should not normally be necessary to
set this, you may pass the statCache from one glob() call to the
options object of another, if you know that the filesystem will not
change between calls. (See "Race Conditions" below.)
* `sync` Perform a synchronous glob search.
* `nounique` In some cases, brace-expanded patterns can result in the
same file showing up multiple times in the result set. By default,
this implementation prevents duplicates in the result set.
Set this flag to disable that behavior.
* `nonull` Set to never return an empty set, instead returning a set
containing the pattern itself. This is the default in glob(3).
* `nocase` Perform a case-insensitive match. Note that case-insensitive
filesystems will sometimes result in glob returning results that are
case-insensitively matched anyway, since readdir and stat will not
raise an error.
* `debug` Set to enable debug logging in minimatch and glob.
* `globDebug` Set to enable debug logging in glob, but not minimatch.
## Comparisons to other fnmatch/glob implementations
While strict compliance with the existing standards is a worthwhile
goal, some discrepancies exist between node-glob and other
implementations, and are intentional.
If the pattern starts with a `!` character, then it is negated. Set the
`nonegate` flag to suppress this behavior, and treat leading `!`
characters normally. This is perhaps relevant if you wish to start the
pattern with a negative extglob pattern like `!(a|B)`. Multiple `!`
characters at the start of a pattern will negate the pattern multiple
times.
If a pattern starts with `#`, then it is treated as a comment, and
will not match anything. Use `\#` to match a literal `#` at the
start of a line, or set the `nocomment` flag to suppress this behavior.
The double-star character `**` is supported by default, unless the
`noglobstar` flag is set. This is supported in the manner of bsdglob
and bash 4.1, where `**` only has special significance if it is the only
thing in a path part. That is, `a/**/b` will match `a/x/y/b`, but
`a/**b` will not. **Note that this is different from the way that `**` is
handled by ruby's `Dir` class.**
If an escaped pattern has no matches, and the `nonull` flag is set,
then glob returns the pattern as-provided, rather than
interpreting the character escapes. For example,
`glob.match([], "\\*a\\?")` will return `"\\*a\\?"` rather than
`"*a?"`. This is akin to setting the `nullglob` option in bash, except
that it does not resolve escaped pattern characters.
If brace expansion is not disabled, then it is performed before any
other interpretation of the glob pattern. Thus, a pattern like
`+(a|{b),c)}`, which would not be valid in bash or zsh, is expanded
**first** into the set of `+(a|b)` and `+(a|c)`, and those patterns are
checked for validity. Since those two are valid, matching proceeds.
## Windows
**Please only use forward-slashes in glob expressions.**
Though windows uses either `/` or `\` as its path separator, only `/`
characters are used by this glob implementation. You must use
forward-slashes **only** in glob expressions. Back-slashes will always
be interpreted as escape characters, not path separators.
Results from absolute patterns such as `/foo/*` are mounted onto the
root setting using `path.join`. On windows, this will by default result
in `/foo/*` matching `C:\foo\bar.txt`.
## Race Conditions
Glob searching, by its very nature, is susceptible to race conditions,
since it relies on directory walking and such.
As a result, it is possible that a file that exists when glob looks for
it may have been deleted or modified by the time it returns the result.
As part of its internal implementation, this program caches all stat
and readdir calls that it makes, in order to cut down on system
overhead. However, this also makes it even more susceptible to races,
especially if the statCache object is reused between glob calls.
Users are thus advised not to use a glob result as a
guarantee of filesystem state in the face of rapid changes.
For the vast majority of operations, this is never a problem.

694
node_modules/glob/glob.js generated vendored
View file

@ -1,3 +1,39 @@
// Approach:
//
// 1. Get the minimatch set
// 2. For each pattern in the set, PROCESS(pattern)
// 3. Store matches per-set, then uniq them
//
// PROCESS(pattern)
// Get the first [n] items from pattern that are all strings
// Join these together. This is PREFIX.
// If there is no more remaining, then stat(PREFIX) and
// add to matches if it succeeds. END.
// readdir(PREFIX) as ENTRIES
// If fails, END
// If pattern[n] is GLOBSTAR
// // handle the case where the globstar match is empty
// // by pruning it out, and testing the resulting pattern
// PROCESS(pattern[0..n] + pattern[n+1 .. $])
// // handle other cases.
// for ENTRY in ENTRIES (not dotfiles)
// // attach globstar + tail onto the entry
// PROCESS(pattern[0..n] + ENTRY + pattern[n .. $])
//
// else // not globstar
// for ENTRY in ENTRIES (not dotfiles, unless pattern[n] is dot)
// Test ENTRY against pattern[n+1]
// If fails, continue
// If passes, PROCESS(pattern[0..n] + item + pattern[n+1 .. $])
//
// Caveat:
// Cache all stats and readdirs results to minimize syscall. Since all
// we ever care about is existence and directory-ness, we can just keep
// `true` for files, and [children,...] for directories, or `false` for
// things that don't exist.
module.exports = glob
var fs = require("graceful-fs")
@ -5,27 +41,9 @@ var fs = require("graceful-fs")
, Minimatch = minimatch.Minimatch
, inherits = require("inherits")
, EE = require("events").EventEmitter
, FastList = require("fast-list")
, path = require("path")
, isDir = {}
// Globbing is a *little* bit different than just matching, in some
// key ways.
//
// First, and importantly, it matters a great deal whether a pattern
// is "absolute" or "relative". Absolute patterns are patterns that
// start with / on unix, or a full device/unc path on windows.
//
// Second, globs interact with the actual filesystem, so being able
// to stop searching as soon as a match is no longer possible is of
// the utmost importance. It would not do to traverse a large file
// tree, and then eliminate all but one of the options, if it could
// be possible to skip the traversal early.
// Get a Minimatch object from the pattern and options. Then, starting
// from the options.root or the cwd, read the dir, and do a partial
// match on all the files if it's a dir, or a regular match if it's not.
, assert = require("assert")
function glob (pattern, options, cb) {
if (typeof options === "function") cb = options, options = {}
@ -36,13 +54,8 @@ function glob (pattern, options, cb) {
return
}
var m = new Glob(pattern, options, cb)
if (options.sync) {
return m.found
} else {
return m
}
var g = new Glob(pattern, options, cb)
return g.sync ? g.found : g
}
glob.fnmatch = deprecated
@ -73,330 +86,457 @@ function Glob (pattern, options, cb) {
if (typeof cb === "function") {
this.on("error", cb)
this.on("end", function (matches) { cb(null, matches) })
this.on("end", function (matches) {
// console.error("cb with matches", matches)
cb(null, matches)
})
}
options = options || {}
if (!options.hasOwnProperty("maxDepth")) options.maxDepth = 1000
if (!options.hasOwnProperty("maxLength")) options.maxLength = 4096
this.maxDepth = options.maxDepth || 1000
this.maxLength = options.maxLength || Infinity
this.statCache = options.statCache || {}
var cwd = this.cwd = options.cwd =
options.cwd || process.cwd()
this.changedCwd = false
var cwd = process.cwd()
if (!options.hasOwnProperty("cwd")) this.cwd = cwd
else {
this.cwd = options.cwd
this.changedCwd = path.resolve(options.cwd) !== cwd
}
this.root = options.root =
options.root || path.resolve(cwd, "/")
this.root = options.root || path.resolve(this.cwd, "/")
this.root = path.resolve(this.root)
this.nomount = !!options.nomount
if (!pattern) {
throw new Error("must provide pattern")
}
// base-matching: just use globstar for that.
if (options.matchBase && -1 === pattern.indexOf("/")) {
if (options.noglobstar) {
throw new Error("base matching requires globstar")
}
pattern = "**/" + pattern
}
this.dot = !!options.dot
this.mark = !!options.mark
this.sync = !!options.sync
this.nounique = !!options.nounique
this.nonull = !!options.nonull
this.nosort = !!options.nosort
this.nocase = !!options.nocase
this.stat = !!options.stat
this.debug = !!options.debug || !!options.globDebug
this.silent = !!options.silent
var mm = this.minimatch = new Minimatch(pattern, options)
options = this.options = mm.options
this.options = mm.options
pattern = this.pattern = mm.pattern
this.error = null
this.aborted = false
this.matches = new FastList()
EE.call(this)
var me = this
this._checkedRoot = false
// process each pattern in the minimatch set
var n = this.minimatch.set.length
// if we have any patterns starting with /, then we need to
// start at the root. If we don't, then we can take a short
// cut and just start at the cwd.
var start = this.cwd
for (var i = 0, l = this.minimatch.set.length; i < l; i ++) {
if (this.minimatch.set[i].absolute) {
start = this.root
break
// The matches are stored as {<filename>: true,...} so that
// duplicates are automagically pruned.
// Later, we do an Object.keys() on these.
// Keep them as a list so we can fill in when nonull is set.
this.matches = new Array(n)
this.minimatch.set.forEach(iterator.bind(this))
function iterator (pattern, i, set) {
this._process(pattern, 0, i, function (er) {
if (er) this.emit("error", er)
if (-- n <= 0) this._finish()
}.bind(this))
}
}
if (me.options.debug) {
console.error("start =", start)
}
this._process(start, 1, this._finish.bind(this))
}
Glob.prototype._finish = _finish
function _finish () {
var me = this
if (me.options.debug) {
console.error("!!! GLOB top level cb", me)
Glob.prototype._finish = function () {
assert(this instanceof Glob)
var nou = this.nounique
, all = nou ? [] : {}
for (var i = 0, l = this.matches.length; i < l; i ++) {
var matches = this.matches[i]
if (this.debug) console.error("matches[%d] =", i, matches)
// do like the shell, and spit out the literal glob
if (!matches) {
if (this.nonull) {
var literal = this.minimatch.globSet[i]
if (nou) all.push(literal)
else nou[literal] = true
}
} else {
// had matches
var m = Object.keys(matches)
if (nou) all.push.apply(all, m)
else m.forEach(function (m) {
all[m] = true
})
}
if (me.options.nonull && me.matches.length === 0) {
return me.emit("end", [pattern])
}
var found = me.found = me.matches.slice()
if (!nou) all = Object.keys(all)
found = me.found = found.map(function (m) {
if (m.indexOf(me.options.cwd) === 0) {
m = m.substr(me.options.cwd.length + 1)
if (!this.nosort) {
all = all.sort(this.nocase ? alphasorti : alphasort)
}
if (this.mark) {
// at *some* point we statted all of these
all = all.map(function (m) {
var sc = this.statCache[m]
if (!sc) return m
if (m.slice(-1) !== "/" && (Array.isArray(sc) || sc === 2)) {
return m + "/"
}
if (m.slice(-1) === "/") {
return m.replace(/\/$/, "")
}
return m
})
if (!me.options.mark) return next()
// mark all directories with a /.
// This may involve some stat calls for things that are unknown.
var needStat = []
found = me.found = found.map(function (f) {
if (isDir[f] === undefined) needStat.push(f)
else if (isDir[f] && f.slice(-1) !== "/") f += "/"
return f
})
var c = needStat.length
if (c === 0) return next()
var stat = me.options.follow ? "stat" : "lstat"
needStat.forEach(function (f) {
if (me.options.sync) {
try {
afterStat(f)(null, fs[stat + "Sync"](f))
} catch (er) {
afterStat(f)(er)
}
} else fs[stat](f, afterStat(f))
})
function afterStat (f) { return function (er, st) {
// ignore errors. if the user only wants to show
// existing files, then set options.stat to exclude anything
// that doesn't exist.
if (st && st.isDirectory() && f.substr(-1) !== "/") {
var i = found.indexOf(f)
if (i !== -1) {
found.splice(i, 1, f + "/")
}
}
if (-- c <= 0) return next()
}}
if (this.debug) console.error("emitting end", all)
function next () {
if (!me.options.nosort) {
found = found.sort(alphasort)
}
me.emit("end", found)
}
this.found = all
this.emit("end", all)
}
function alphasorti (a, b) {
a = a.toLowerCase()
b = b.toLowerCase()
return alphasort(a, b)
}
function alphasort (a, b) {
a = a.toLowerCase()
b = b.toLowerCase()
return a > b ? 1 : a < b ? -1 : 0
}
Glob.prototype.abort = abort
function abort () {
Glob.prototype.abort = function () {
this.aborted = true
this.emit("abort")
}
Glob.prototype._process = _process
function _process (f, depth, cb) {
Glob.prototype._process = function (pattern, depth, index, cb) {
assert(this instanceof Glob)
cb = cb.bind(this)
if (this.aborted) return cb()
var me = this
if (depth > this.maxDepth) return cb()
// if f matches, then it's a match. emit it, move on.
// if it *partially* matches, then it might be a dir.
//
// possible optimization: don't just minimatch everything
// against the full pattern. if a bit of the pattern is
// not magical, it'd be good to reduce the number of stats
// that had to be made. so, in the pattern: "a/*/b", we could
// readdir a, then stat a/<child>/b in all of them.
//
// however, that'll require a lot of muddying between minimatch
// and glob, and at least for the time being, it's kind of nice to
// keep them a little bit separate.
// Get the first [n] parts of pattern that are all strings.
var n = 0
while (typeof pattern[n] === "string") {
n ++
}
// now n is the index of the first one that is *not* a string.
// if this thing is a match, then add to the matches list.
var match = me.minimatch.match(f)
if (!match) {
if (me.options.debug) {
console.error("not a match", f)
// see if there's anything else
var prefix
switch (n) {
// if not, then this is rather simple
case pattern.length:
prefix = pattern.join("/")
this._stat(prefix, function (exists, isDir) {
// either it's there, or it isn't.
// nothing more to do, either way.
if (exists) {
if (prefix.charAt(0) === "/" && !this.nomount) {
prefix = path.join(this.root, prefix)
}
return me._processPartial(f, depth, cb)
this.matches[index] = this.matches[index] || {}
this.matches[index][prefix] = true
this.emit("match", prefix)
}
if (match) {
if (me.options.debug) {
console.error(" %s matches %s", f, me.pattern)
}
// make sure it exists if asked.
if (me.options.stat) {
var stat = me.options.follow ? "stat" : "lstat"
if (me.options.sync) {
try {
afterStat(f)(null, fs[stat + "Sync"](f))
} catch (ex) {
afterStat(f)(ex)
}
} else fs[stat](f, afterStat(f))
} else if (me.options.sync) {
emitMatch()
} else {
process.nextTick(emitMatch)
}
return cb()
})
return
function afterStat (f) { return function (er, st) {
if (er) return cb()
isDir[f] = st.isDirectory()
emitMatch()
}}
case 0:
// pattern *starts* with some non-trivial item.
// going to readdir(cwd), but not include the prefix in matches.
prefix = null
break
function emitMatch () {
if (me.options.debug) {
console.error("emitting match", f)
}
me.matches.push(f)
me.emit("match", f)
// move on, since it might also be a partial match
// eg, a/**/c matches both a/c and a/c/d/c
me._processPartial(f, depth, cb)
}
default:
// pattern has some string bits in the front.
// whatever it starts with, whether that's "absolute" like /foo/bar,
// or "relative" like "../baz"
prefix = pattern.slice(0, n)
prefix = prefix.join("/")
break
}
}
// get the list of entries.
var read
if (prefix === null) read = "."
else if (isAbsolute(prefix)) {
read = prefix = path.join("/", prefix)
if (this.debug) console.error('absolute: ', prefix, this.root, pattern)
} else read = prefix
Glob.prototype._processPartial = _processPartial
function _processPartial (f, depth, cb) {
if (this.aborted) return cb()
var me = this
var partial = me.minimatch.match(f, true)
if (!partial) {
if (me.options.debug) {
console.error("not a partial", f)
}
// if not a match or partial match, just move on.
if (this.debug) console.error('readdir(%j)', read, this.cwd, this.root)
return this._readdir(read, function (er, entries) {
if (er) {
// not a directory!
// this means that, whatever else comes after this, it can never match
return cb()
}
// partial match
// however, this only matters if it's a dir.
//if (me.options.debug)
if (me.options.debug) {
console.error("got a partial", f)
}
me.emit("partial", f)
// globstar is special
if (pattern[n] === minimatch.GLOBSTAR) {
// test without the globstar, and with every child both below
// and replacing the globstar.
var s = [ pattern.slice(0, n).concat(pattern.slice(n + 1)) ]
entries.forEach(function (e) {
if (e.charAt(0) === "." && !this.dot) return
// instead of the globstar
s.push(pattern.slice(0, n).concat(e).concat(pattern.slice(n + 1)))
// below the globstar
s.push(pattern.slice(0, n).concat(e).concat(pattern.slice(n)))
}, this)
me._processDir(f, depth, cb)
}
// now asyncForEach over this
var l = s.length
, errState = null
s.forEach(function (gsPattern) {
this._process(gsPattern, depth + 1, index, function (er) {
if (errState) return
if (er) return cb(errState = er)
if (--l <= 0) return cb()
})
}, this)
Glob.prototype._processDir = _processDir
function _processDir (f, depth, cb) {
if (this.aborted) return cb()
// If we're already at the maximum depth, then don't read the dir.
if (depth >= this.options.maxDepth) return cb()
// if the path is at the maximum length, then don't proceed, either.
if (f.length >= this.options.maxLength) return cb()
// now the fun stuff.
// if it's a dir, then we'll read all the children, and process them.
// if it's not a dir, or we can't access it, then it'll fail.
// We log a warning for EACCES and EPERM, but ENOTDIR and ENOENT are
// expected and fine.
cb = this._afterReaddir(f, depth, cb)
if (this.options.sync) return this._processDirSync(f, depth, cb)
fs.readdir(f, cb)
}
Glob.prototype._processDirSync = _processDirSync
function _processDirSync (f, depth, cb) {
try {
cb(null, fs.readdirSync(f))
} catch (ex) {
cb(ex)
}
}
Glob.prototype._afterReaddir = _afterReaddir
function _afterReaddir (f, depth, cb) {
var me = this
return function afterReaddir (er, children) {
if (er) switch (er.code) {
case "UNKNOWN": // probably too deep
case "ENOTDIR": // completely expected and normal.
isDir[f] = false
return cb()
case "ENOENT": // should never happen.
default: // some other kind of problem.
if (!me.options.silent) console.error("glob error", er)
if (me.options.strict) return cb(er)
return cb()
return
}
// at this point, we know it's a dir, so save a stat later if
// mark is set.
isDir[f] = true
// not a globstar
// It will only match dot entries if it starts with a dot, or if
// dot is set. Stuff like @(.foo|.bar) isn't allowed.
var pn = pattern[n]
if (typeof pn === "string") {
var found = entries.indexOf(pn) !== -1
entries = found ? entries[pn] : []
} else {
var rawGlob = pattern[n]._glob
, dotOk = this.dot || rawGlob.charAt(0) === "."
me._processChildren(f, depth, children, cb)
}
}
Glob.prototype._processChildren = _processChildren
function _processChildren (f, depth, children, cb) {
var me = this
// note: the file ending with / might match, but only if
// it's a directory, which we know it is at this point.
// For example, /a/b/ or /a/b/** would match /a/b/ but not
// /a/b. Note: it'll get the trailing "/" strictly based
// on the "mark" param, but that happens later.
// This is slightly different from bash's glob.
if (!me.minimatch.match(f) && me.minimatch.match(f + "/")) {
me.matches.push(f)
me.emit("match", f)
entries = entries.filter(function (e) {
return (e.charAt(0) !== "." || dotOk) &&
(typeof pattern[n] === "string" && e === pattern[n] ||
e.match(pattern[n]))
})
}
if (-1 === children.indexOf(".")) children.push(".")
if (-1 === children.indexOf("..")) children.push("..")
var count = children.length
if (me.options.debug) {
console.error("count=%d %s", count, f, children)
// If n === pattern.length - 1, then there's no need for the extra stat
// *unless* the user has specified "mark" or "stat" explicitly.
// We know that they exist, since the readdir returned them.
if (n === pattern.length - 1 &&
!this.mark &&
!this.stat) {
entries.forEach(function (e) {
if (prefix) {
if (prefix !== "/") e = prefix + "/" + e
else e = prefix + e
}
if (e.charAt(0) === "/" && !this.nomount) {
e = path.join(this.root, e)
}
if (count === 0) {
if (me.options.debug) {
console.error("no children?", children, f)
}
return then()
this.matches[index] = this.matches[index] || {}
this.matches[index][e] = true
this.emit("match", e)
}, this)
return cb.call(this)
}
children.forEach(function (c) {
if (f === "/") c = f + c
else c = f + "/" + c
if (me.options.debug) {
console.error(" processing", c)
}
me._process(c, depth + 1, then)
// now test all the remaining entries as stand-ins for that part
// of the pattern.
var l = entries.length
, errState = null
if (l === 0) return cb() // no matches possible
entries.forEach(function (e) {
var p = pattern.slice(0, n).concat(e).concat(pattern.slice(n + 1))
this._process(p, depth + 1, index, function (er) {
if (errState) return
if (er) return cb(errState = er)
if (--l === 0) return cb.call(this)
}.bind(this))
}, this)
})
function then (er) {
count --
if (me.options.debug) {
console.error("%s THEN %s", f, count, count <= 0 ? "done" : "not done")
}
Glob.prototype._stat = function (f, cb) {
assert(this instanceof Glob)
var abs = f
if (f.charAt(0) === "/") {
abs = path.join(this.root, f)
} else if (this.changedCwd) {
abs = path.resolve(this.cwd, f)
}
if (me.error) return
if (er) return me.emit("error", me.error = er)
if (count <= 0) cb()
if (this.debug) console.error('stat', [this.cwd, f, '=', abs])
if (f.length > this.maxLength) {
var er = new Error("Path name too long")
er.code = "ENAMETOOLONG"
er.path = f
return this._afterStat(f, abs, cb, er)
}
if (this.statCache.hasOwnProperty(f)) {
var exists = this.statCache[f]
, isDir = exists && (Array.isArray(exists) || exists === 2)
if (this.sync) return cb.call(this, !!exists, isDir)
return process.nextTick(cb.bind(this, !!exists, isDir))
}
if (this.sync) {
var er, stat
try {
stat = fs.statSync(abs)
} catch (e) {
er = e
}
this._afterStat(f, abs, cb, er, stat)
} else {
fs.stat(abs, this._afterStat.bind(this, f, abs, cb))
}
}
Glob.prototype._afterStat = function (f, abs, cb, er, stat) {
assert(this instanceof Glob)
if (er || !stat) {
exists = false
} else {
exists = stat.isDirectory() ? 2 : 1
}
this.statCache[f] = this.statCache[f] || exists
cb.call(this, !!exists, exists === 2)
}
Glob.prototype._readdir = function (f, cb) {
assert(this instanceof Glob)
var abs = f
if (f.charAt(0) === "/") {
abs = path.join(this.root, f)
} else if (isAbsolute(f)) {
abs = f
} else if (this.changedCwd) {
abs = path.resolve(this.cwd, f)
}
if (this.debug) console.error('readdir', [this.cwd, f, abs])
if (f.length > this.maxLength) {
var er = new Error("Path name too long")
er.code = "ENAMETOOLONG"
er.path = f
return this._afterReaddir(f, abs, cb, er)
}
if (this.statCache.hasOwnProperty(f)) {
var c = this.statCache[f]
if (Array.isArray(c)) {
if (this.sync) return cb.call(this, null, c)
return process.nextTick(cb.bind(this, null, c))
}
if (!c || c === 1) {
// either ENOENT or ENOTDIR
var code = c ? "ENOTDIR" : "ENOENT"
, er = new Error((c ? "Not a directory" : "Not found") + ": " + f)
er.path = f
er.code = code
if (this.debug) console.error(f, er)
if (this.sync) return cb.call(this, er)
return process.nextTick(cb.bind(this, er))
}
// at this point, c === 2, meaning it's a dir, but we haven't
// had to read it yet, or c === true, meaning it's *something*
// but we don't have any idea what. Need to read it, either way.
}
if (this.sync) {
var er, entries
try {
entries = fs.readdirSync(abs)
} catch (e) {
er = e
}
return this._afterReaddir(f, abs, cb, er, entries)
}
fs.readdir(abs, this._afterReaddir.bind(this, f, abs, cb))
}
Glob.prototype._afterReaddir = function (f, abs, cb, er, entries) {
assert(this instanceof Glob)
if (entries && !er) {
this.statCache[f] = entries
// if we haven't asked to stat everything for suresies, then just
// assume that everything in there exists, so we can avoid
// having to stat it a second time. This also gets us one step
// further into ELOOP territory.
if (!this.mark && !this.stat) {
entries.forEach(function (e) {
if (f === "/") e = f + e
else e = f + "/" + e
this.statCache[e] = true
}, this)
}
return cb.call(this, er, entries)
}
// now handle errors, and cache the information
if (er) switch (er.code) {
case "ENOTDIR": // totally normal. means it *does* exist.
this.statCache[f] = 1
return cb.call(this, er)
case "ENOENT": // not terribly unusual
case "ELOOP":
case "ENAMETOOLONG":
case "UNKNOWN":
this.statCache[f] = false
return cb.call(this, er)
default: // some unusual error. Treat as failure.
this.statCache[f] = false
if (this.strict) this.emit("error", er)
if (!this.silent) console.error("glob error", er)
return cb.call(this, er)
}
}
var isAbsolute = process.platform === "win32" ? absWin : absUnix
function absWin (p) {
if (absUnix(p)) return true
// pull off the device/UNC bit from a windows path.
// from node's lib/path.js
var splitDeviceRe =
/^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/][^\\\/]+)?([\\\/])?/
, result = splitDeviceRe.exec(p)
, device = result[1] || ''
, isUnc = device && device.charAt(1) !== ':'
, isAbsolute = !!result[2] || isUnc // UNC paths are always absolute
return isAbsolute
}
function absUnix (p) {
return p.charAt(0) === "/" || p === ""
}

4
node_modules/glob/node_modules/minimatch/.travis.yml generated vendored Normal file
View file

@ -0,0 +1,4 @@
language: node_js
node_js:
- 0.4
- 0.6

23
node_modules/glob/node_modules/minimatch/LICENSE generated vendored Normal file
View file

@ -0,0 +1,23 @@
Copyright 2009, 2010, 2011 Isaac Z. Schlueter.
All rights reserved.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

212
node_modules/glob/node_modules/minimatch/README.md generated vendored Normal file
View file

@ -0,0 +1,212 @@
# minimatch
A minimal matching utility.
[![Build Status](https://secure.travis-ci.org/isaacs/minimatch.png)](http://travis-ci.org/isaacs/minimatch)
This is the matching library used internally by npm.
Eventually, it will replace the C binding in node-glob.
It works by converting glob expressions into JavaScript `RegExp`
objects.
## Usage
```javascript
var minimatch = require("minimatch")
minimatch("bar.foo", "*.foo") // true!
minimatch("bar.foo", "*.bar") // false!
```
## Features
Supports these glob features:
* Brace Expansion
* Extended glob matching
* "Globstar" `**` matching
See:
* `man sh`
* `man bash`
* `man 3 fnmatch`
* `man 5 gitignore`
### Comparisons to other fnmatch/glob implementations
While strict compliance with the existing standards is a worthwhile
goal, some discrepancies exist between minimatch and other
implementations, and are intentional.
If the pattern starts with a `!` character, then it is negated. Set the
`nonegate` flag to suppress this behavior, and treat leading `!`
characters normally. This is perhaps relevant if you wish to start the
pattern with a negative extglob pattern like `!(a|B)`. Multiple `!`
characters at the start of a pattern will negate the pattern multiple
times.
If a pattern starts with `#`, then it is treated as a comment, and
will not match anything. Use `\#` to match a literal `#` at the
start of a line, or set the `nocomment` flag to suppress this behavior.
The double-star character `**` is supported by default, unless the
`noglobstar` flag is set. This is supported in the manner of bsdglob
and bash 4.1, where `**` only has special significance if it is the only
thing in a path part. That is, `a/**/b` will match `a/x/y/b`, but
`a/**b` will not. **Note that this is different from the way that `**` is
handled by ruby's `Dir` class.**
If an escaped pattern has no matches, and the `null` flag is not set,
then minimatch.match returns the pattern as-provided, rather than
interpreting the character escapes. For example,
`minimatch.match([], "\\*a\\?")` will return `"\\*a\\?"` rather than
`"*a?"`.
If brace expansion is not disabled, then it is performed before any
other interpretation of the glob pattern. Thus, a pattern like
`+(a|{b),c)}`, which would not be valid in bash or zsh, is expanded
**first** into the set of `+(a|b)` and `+(a|c)`, and those patterns are
checked for validity. Since those two are valid, matching proceeds.
## Minimatch Class
Create a minimatch object by instanting the `minimatch.Minimatch` class.
```javascript
var Minimatch = require("minimatch").Minimatch
var mm = new Minimatch(pattern, options)
```
### Properties
* `pattern` The original pattern the minimatch object represents.
* `options` The options supplied to the constructor.
* `set` A 2-dimensional array of regexp or string expressions.
Each row in the
array corresponds to a brace-expanded pattern. Each item in the row
corresponds to a single path-part. For example, the pattern
`{a,b/c}/d` would expand to a set of patterns like:
[ [ a, d ]
, [ b, c, d ] ]
If a portion of the pattern doesn't have any "magic" in it
(that is, it's something like `"foo"` rather than `fo*o?`), then it
will be left as a string rather than converted to a regular
expression.
* `regexp` Created by the `makeRe` method. A single regular expression
expressing the entire pattern. This is useful in cases where you wish
to use the pattern somewhat like `fnmatch(3)` with `FNM_PATH` enabled.
* `negate` True if the pattern is negated.
* `comment` True if the pattern is a comment.
* `empty` True if the pattern is `""`.
### Methods
* `makeRe` Generate the `regexp` member if necessary, and return it.
Will return `false` if the pattern is invalid.
* `match(fname)` Return true if the filename matches the pattern, or
false otherwise.
* `matchOne(fileArray, patternArray, partial)` Take a `/`-split
filename, and match it against a single row in the `regExpSet`. This
method is mainly for internal use, but is exposed so that it can be
used by a glob-walker that needs to avoid excessive filesystem calls.
All other methods are internal, and will be called as necessary.
## Functions
The top-level exported function has a `cache` property, which is an LRU
cache set to store 100 items. So, calling these methods repeatedly
with the same pattern and options will use the same Minimatch object,
saving the cost of parsing it multiple times.
### minimatch(path, pattern, options)
Main export. Tests a path against the pattern using the options.
```javascript
var isJS = minimatch(file, "*.js", { matchBase: true })
```
### minimatch.filter(pattern, options)
Returns a function that tests its
supplied argument, suitable for use with `Array.filter`. Example:
```javascript
var javascripts = fileList.filter(minimatch.filter("*.js", {matchBase: true}))
```
### minimatch.match(list, pattern, options)
Match against the list of
files, in the style of fnmatch or glob. If nothing is matched, then
return the pattern (unless `{ null: true }` in the options.)
```javascript
var javascripts = minimatch.match(fileList, "*.js", {matchBase: true}))
```
### minimatch.makeRe(pattern, options)
Make a regular expression object from the pattern.
## Options
All options are `false` by default.
### debug
Dump a ton of stuff to stderr.
### nobrace
Do not expand `{a,b}` and `{1..3}` brace sets.
### noglobstar
Disable `**` matching against multiple folder names.
### dot
Allow patterns to match filenames starting with a period, even if
the pattern does not explicitly have a period in that spot.
Note that by default, `a/**/b` will **not** match `a/.d/b`, unless `dot`
is set.
### noext
Disable "extglob" style patterns like `+(a|b)`.
### nocase
Perform a case-insensitive match.
### nonull
When a match is not found by `minimatch.match`, return a list containing
the pattern itself. When set, an empty list is returned if there are
no matches.
### matchBase
If set, then patterns without slashes will be matched
against the basename of the path if it contains slashes. For example,
`a?b` would match the path `/xyz/123/acb`, but not `/xyz/acb/123`.
### nocomment
Suppress the behavior of treating `#` at the start of a pattern as a
comment.
### nonegate
Suppress the behavior of treating a leading `!` character as negation.

980
node_modules/glob/node_modules/minimatch/minimatch.js generated vendored Normal file
View file

@ -0,0 +1,980 @@
module.exports = minimatch
minimatch.Minimatch = Minimatch
var LRU = require("lru-cache")
, cache = minimatch.cache = new LRU(100)
, GLOBSTAR = minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {}
, pathSplit = process.platform === "win32" ? /\\|\// : "/"
var path = require("path")
// any single thing other than /
// don't need to escape / when using new RegExp()
, qmark = "[^/]"
// * => any number of characters
, star = qmark + "*?"
// ** when dots are allowed. Anything goes, except .. and .
// not (^ or / followed by one or two dots followed by $ or /),
// followed by anything, any number of times.
, twoStarDot = "(?:(?!(?:\\\/|^)(?:\\.{1,2})($|\\\/)).)*?"
// not a ^ or / followed by a dot,
// followed by anything, any number of times.
, twoStarNoDot = "(?:(?!(?:\\\/|^)\\.).)*?"
// characters that need to be escaped in RegExp.
, reSpecials = charSet("().*{}+?[]^$\\!")
// "abc" -> { a:true, b:true, c:true }
function charSet (s) {
return s.split("").reduce(function (set, c) {
set[c] = true
return set
}, {})
}
// normalizes slashes.
var slashSplit = /\/+/
minimatch.monkeyPatch = monkeyPatch
function monkeyPatch () {
var desc = Object.getOwnPropertyDescriptor(String.prototype, "match")
var orig = desc.value
desc.value = function (p) {
if (p instanceof Minimatch) return p.match(this)
return orig.call(this, p)
}
Object.defineProperty(String.prototype, desc)
}
minimatch.filter = filter
function filter (pattern, options) {
options = options || {}
return function (p, i, list) {
return minimatch(p, pattern, options)
}
}
function minimatch (p, pattern, options) {
if (typeof pattern !== "string") {
throw new TypeError("glob pattern string required")
}
if (!options) options = {}
// shortcut: comments match nothing.
if (!options.nocomment && pattern.charAt(0) === "#") {
return false
}
// "" only matches ""
if (pattern.trim() === "") return p === ""
return new Minimatch(pattern, options).match(p)
}
function Minimatch (pattern, options) {
if (!(this instanceof Minimatch)) {
return new Minimatch(pattern, options, cache)
}
if (typeof pattern !== "string") {
throw new TypeError("glob pattern string required")
}
if (!options) options = {}
pattern = pattern.trim()
// lru storage.
// these things aren't particularly big, but walking down the string
// and turning it into a regexp can get pretty costly.
var cacheKey = pattern + "\n" + Object.keys(options).filter(function (k) {
return options[k]
}).join(":")
var cached = minimatch.cache.get(cacheKey)
if (cached) return cached
minimatch.cache.set(cacheKey, this)
this.options = options
this.set = []
this.pattern = pattern
this.regexp = null
this.negate = false
this.comment = false
this.empty = false
// 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
// empty patterns and comments match nothing.
if (!options.nocomment && pattern.charAt(0) === "#") {
this.comment = true
return
}
if (!pattern) {
this.empty = true
return
}
// step 1: figure out negation, etc.
this.parseNegate()
// step 2: expand braces
var set = this.globSet = this.braceExpand()
if (options.debug) console.error(this.pattern, set)
// step 3: now we have a set, so turn each one into a series of path-portion
// matching patterns.
// These will be regexps, except in the case of "**", which is
// set to the GLOBSTAR object for globstar behavior,
// and will not contain any / characters
set = this.globParts = set.map(function (s) {
return s.split(slashSplit)
})
if (options.debug) console.error(this.pattern, set)
// glob --> regexps
set = set.map(function (s, si, set) {
return s.map(this.parse, this)
}, this)
if (options.debug) console.error(this.pattern, set)
// filter out everything that didn't compile properly.
set = set.filter(function (s) {
return -1 === s.indexOf(false)
})
if (options.debug) console.error(this.pattern, set)
this.set = set
}
Minimatch.prototype.parseNegate = parseNegate
function parseNegate () {
var pattern = this.pattern
, negate = false
, options = this.options
, negateOffset = 0
if (options.nonegate) return
for ( var i = 0, l = pattern.length
; i < l && pattern.charAt(i) === "!"
; i ++) {
negate = !negate
negateOffset ++
}
if (negateOffset) this.pattern = pattern.substr(negateOffset)
this.negate = negate
}
// Brace expansion:
// a{b,c}d -> abd acd
// a{b,}c -> abc ac
// a{0..3}d -> a0d a1d a2d a3d
// a{b,c{d,e}f}g -> abg acdfg acefg
// a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg
//
// Invalid sets are not expanded.
// a{2..}b -> a{2..}b
// a{b}c -> a{b}c
minimatch.braceExpand = function (pattern, options) {
return new Minimatch(pattern, options).braceExpand()
}
Minimatch.prototype.braceExpand = braceExpand
function braceExpand (pattern, options) {
options = options || this.options
pattern = typeof pattern === "undefined"
? this.pattern : pattern
if (typeof pattern === "undefined") {
throw new Error("undefined pattern")
}
if (options.nobrace ||
!pattern.match(/\{.*\}/)) {
// shortcut. no need to expand.
return [pattern]
}
var escaping = false
// examples and comments refer to this crazy pattern:
// a{b,c{d,e},{f,g}h}x{y,z}
// expected:
// abxy
// abxz
// acdxy
// acdxz
// acexy
// acexz
// afhxy
// afhxz
// aghxy
// aghxz
// everything before the first \{ is just a prefix.
// So, we pluck that off, and work with the rest,
// and then prepend it to everything we find.
if (pattern.charAt(0) !== "{") {
// console.error(pattern)
var prefix = null
for (var i = 0, l = pattern.length; i < l; i ++) {
var c = pattern.charAt(i)
// console.error(i, c)
if (c === "\\") {
escaping = !escaping
} else if (c === "{" && !escaping) {
prefix = pattern.substr(0, i)
break
}
}
// actually no sets, all { were escaped.
if (prefix === null) {
// console.error("no sets")
return [pattern]
}
var tail = braceExpand(pattern.substr(i), options)
return tail.map(function (t) {
return prefix + t
})
}
// now we have something like:
// {b,c{d,e},{f,g}h}x{y,z}
// walk through the set, expanding each part, until
// the set ends. then, we'll expand the suffix.
// If the set only has a single member, then'll put the {} back
// first, handle numeric sets, since they're easier
var numset = pattern.match(/^\{(-?[0-9]+)\.\.(-?[0-9]+)\}/)
if (numset) {
// console.error("numset", numset[1], numset[2])
var suf = braceExpand(pattern.substr(numset[0].length), options)
, start = +numset[1]
, end = +numset[2]
, inc = start > end ? -1 : 1
, set = []
for (var i = start; i != (end + inc); i += inc) {
// append all the suffixes
for (var ii = 0, ll = suf.length; ii < ll; ii ++) {
set.push(i + suf[ii])
}
}
return set
}
// ok, walk through the set
// We hope, somewhat optimistically, that there
// will be a } at the end.
// If the closing brace isn't found, then the pattern is
// interpreted as braceExpand("\\" + pattern) so that
// the leading \{ will be interpreted literally.
var i = 1 // skip the \{
, depth = 1
, set = []
, member = ""
, sawEnd = false
, escaping = false
function addMember () {
set.push(member)
member = ""
}
// console.error("Entering for")
FOR: for (i = 1, l = pattern.length; i < l; i ++) {
var c = pattern.charAt(i)
// console.error("", i, c)
if (escaping) {
escaping = false
member += "\\" + c
} else {
switch (c) {
case "\\":
escaping = true
continue
case "{":
depth ++
member += "{"
continue
case "}":
depth --
// if this closes the actual set, then we're done
if (depth === 0) {
addMember()
// pluck off the close-brace
i ++
break FOR
} else {
member += c
continue
}
case ",":
if (depth === 1) {
addMember()
} else {
member += c
}
continue
default:
member += c
continue
} // switch
} // else
} // for
// now we've either finished the set, and the suffix is
// pattern.substr(i), or we have *not* closed the set,
// and need to escape the leading brace
if (depth !== 0) {
// console.error("didn't close", pattern)
return braceExpand("\\" + pattern, options)
}
// x{y,z} -> ["xy", "xz"]
// console.error("set", set)
// console.error("suffix", pattern.substr(i))
var suf = braceExpand(pattern.substr(i), options)
// ["b", "c{d,e}","{f,g}h"] ->
// [["b"], ["cd", "ce"], ["fh", "gh"]]
var addBraces = set.length === 1
// console.error("set pre-expanded", set)
set = set.map(function (p) {
return braceExpand(p, options)
})
// console.error("set expanded", set)
// [["b"], ["cd", "ce"], ["fh", "gh"]] ->
// ["b", "cd", "ce", "fh", "gh"]
set = set.reduce(function (l, r) {
return l.concat(r)
})
if (addBraces) {
set = set.map(function (s) {
return "{" + s + "}"
})
}
// now attach the suffixes.
var ret = []
for (var i = 0, l = set.length; i < l; i ++) {
for (var ii = 0, ll = suf.length; ii < ll; ii ++) {
ret.push(set[i] + suf[ii])
}
}
return ret
}
// parse a component of the expanded set.
// At this point, no pattern may contain "/" in it
// so we're going to return a 2d array, where each entry is the full
// pattern, split on '/', and then turned into a regular expression.
// A regexp is made at the end which joins each array with an
// escaped /, and another full one which joins each regexp with |.
//
// Following the lead of Bash 4.1, note that "**" only has special meaning
// when it is the *only* thing in a path portion. Otherwise, any series
// of * is equivalent to a single *. Globstar behavior is enabled by
// default, and can be disabled by setting options.noglobstar.
Minimatch.prototype.parse = parse
var SUBPARSE = {}
function parse (pattern, isSub) {
var options = this.options
// shortcuts
if (!options.noglobstar && pattern === "**") return GLOBSTAR
if (pattern === "") return ""
var re = ""
, hasMagic = false
, escaping = false
// ? => one single character
, patternListStack = []
, plType
, stateChar
, inClass = false
, reClassStart = -1
, classStart = -1
// . and .. never match anything that doesn't start with .,
// even when options.dot is set.
, patternStart = pattern.charAt(0) === "." ? "" // anything
// not (start or / followed by . or .. followed by / or end)
: options.dot ? "(?!(?:^|\\\/)\\.{1,2}(?:$|\\\/))"
: "(?!\\.)"
function clearStateChar () {
if (stateChar) {
// we had some state-tracking character
// that wasn't consumed by this pass.
switch (stateChar) {
case "*":
re += star
hasMagic = true
break
case "?":
re += qmark
hasMagic = true
break
default:
re += "\\"+stateChar
break
}
stateChar = false
}
}
for ( var i = 0, len = pattern.length, c
; (i < len) && (c = pattern.charAt(i))
; i ++ ) {
if (options.debug) {
console.error("%s\t%s %s %j", pattern, i, re, c)
}
// skip over any that are escaped.
if (escaping && reSpecials[c]) {
re += "\\" + c
escaping = false
continue
}
SWITCH: switch (c) {
case "/":
// completely not allowed, even escaped.
// Should already be path-split by now.
return false
case "\\":
clearStateChar()
escaping = true
continue
// the various stateChar values
// for the "extglob" stuff.
case "?":
case "*":
case "+":
case "@":
case "!":
if (options.debug) {
console.error("%s\t%s %s %j <-- stateChar", pattern, i, re, c)
}
// all of those are literals inside a class, except that
// the glob [!a] means [^a] in regexp
if (inClass) {
if (c === "!" && i === classStart + 1) c = "^"
re += c
continue
}
// if we already have a stateChar, then it means
// that there was something like ** or +? in there.
// Handle the stateChar, then proceed with this one.
clearStateChar()
stateChar = c
// if extglob is disabled, then +(asdf|foo) isn't a thing.
// just clear the statechar *now*, rather than even diving into
// the patternList stuff.
if (options.noext) clearStateChar()
continue
case "(":
if (inClass) {
re += "("
continue
}
if (!stateChar) {
re += "\\("
continue
}
plType = stateChar
patternListStack.push({ type: plType
, start: i - 1
, reStart: re.length })
re += stateChar === "!" ? "(?!" : "(?:"
stateChar = false
continue
case ")":
if (inClass || !patternListStack.length) {
re += "\\)"
continue
}
hasMagic = true
re += ")"
plType = patternListStack.pop().type
switch (plType) {
case "?":
case "+":
case "*": re += plType
case "!": // already handled by the start
case "@": break // the default anyway
}
continue
case "|":
if (inClass || !patternListStack.length || escaping) {
re += "\\|"
escaping = false
continue
}
re += "|"
continue
// these are mostly the same in regexp and glob
case "[":
// swallow any state-tracking char before the [
clearStateChar()
if (inClass) {
re += "\\" + c
continue
}
inClass = true
classStart = i
reClassStart = re.length
re += c
continue
case "]":
// a right bracket shall lose its special
// meaning and represent itself in
// a bracket expression if it occurs
// first in the list. -- POSIX.2 2.8.3.2
if (i === classStart + 1 || !inClass) {
re += "\\" + c
escaping = false
continue
}
// finish up the class.
hasMagic = true
inClass = false
re += c
continue
default:
// swallow any state char that wasn't consumed
clearStateChar()
if (escaping) {
// no need
escaping = false
} else if (reSpecials[c]
&& !(c === "^" && inClass)) {
re += "\\"
}
re += c
} // switch
} // for
// handle the case where we left a class open.
// "[abc" is valid, equivalent to "\[abc"
if (inClass) {
// split where the last [ was, and escape it
// this is a huge pita. We now have to re-walk
// the contents of the would-be class to re-translate
// any characters that were passed through as-is
var cs = pattern.substr(classStart + 1)
, sp = this.parse(cs, SUBPARSE)
re = re.substr(0, reClassStart) + "\\[" + sp[0]
hasMagic = hasMagic || sp[1]
}
// handle the case where we had a +( thing at the *end*
// of the pattern.
// each pattern list stack adds 3 chars, and we need to go through
// and escape any | chars that were passed through as-is for the regexp.
// Go through and escape them, taking care not to double-escape any
// | chars that were already escaped.
var pl
while (pl = patternListStack.pop()) {
var tail = re.slice(pl.reStart + 3)
// maybe some even number of \, then maybe 1 \, followed by a |
tail = tail.replace(/((?:\\{2})*)(\\?)\|/g, function (_, $1, $2) {
if (!$2) {
// the | isn't already escaped, so escape it.
$2 = "\\"
}
// need to escape all those slashes *again*, without escaping the
// one that we need for escaping the | character. As it works out,
// escaping an even number of slashes can be done by simply repeating
// it exactly after itself. That's why this trick works.
//
// I am sorry that you have to see this.
return $1 + $1 + $2 + "|"
})
// console.error("tail=%j\n %s", tail, tail)
var t = pl.type === "*" ? star
: pl.type === "?" ? qmark
: "\\" + pl.type
hasMagic = true
re = re.slice(0, pl.reStart)
+ t + "\\("
+ tail
}
// handle trailing things that only matter at the very end.
clearStateChar()
if (escaping) {
// trailing \\
re += "\\\\"
}
// only need to apply the nodot start if the re starts with
// something that could conceivably capture a dot
var addPatternStart = false
switch (re.charAt(0)) {
case ".":
case "[":
case "(": addPatternStart = true
}
// if the re is not "" at this point, then we need to make sure
// it doesn't match against an empty path part.
// Otherwise a/* will match a/, which it should not.
if (re !== "" && hasMagic) re = "(?=.)" + re
if (addPatternStart) re = patternStart + re
// parsing just a piece of a larger pattern.
if (isSub === SUBPARSE) {
return [ re, hasMagic ]
}
// skip the regexp for non-magical patterns
// unescape anything in it, though, so that it'll be
// an exact match against a file etc.
if (!hasMagic) {
return globUnescape(pattern)
}
var flags = options.nocase ? "i" : ""
, regExp = new RegExp("^" + re + "$", flags)
regExp._glob = pattern
regExp._src = re
return regExp
}
minimatch.makeRe = function (pattern, options) {
return new Minimatch(pattern, options || {}).makeRe()
}
Minimatch.prototype.makeRe = makeRe
function makeRe () {
if (this.regexp || this.regexp === false) return this.regexp
// at this point, this.set is a 2d array of partial
// pattern strings, or "**".
//
// It's better to use .match(). This function shouldn't
// be used, really, but it's pretty convenient sometimes,
// when you just want to work with a regex.
var set = this.set
if (!set.length) return this.regexp = false
var options = this.options
var twoStar = options.noglobstar ? star
: options.dot ? twoStarDot
: twoStarNoDot
, flags = options.nocase ? "i" : ""
var re = set.map(function (pattern) {
return pattern.map(function (p) {
return (p === GLOBSTAR) ? twoStar
: (typeof p === "string") ? regExpEscape(p)
: p._src
}).join("\\\/")
}).join("|")
// must match entire pattern
// ending in a * or ** will make it less strict.
re = "^" + re + "$"
// can match anything, as long as it's not this.
if (this.negate) re = "^(?!" + re + ").*$"
try {
return this.regexp = new RegExp(re, flags)
} catch (ex) {
return this.regexp = false
}
}
minimatch.match = function (list, pattern, options) {
var mm = new Minimatch(pattern, options)
list = list.filter(function (f) {
return mm.match(f)
})
if (options.nonull && !list.length) {
list.push(pattern)
}
return list
}
Minimatch.prototype.match = match
function match (f, partial) {
// console.error("match", f, this.pattern)
// short-circuit in the case of busted things.
// comments, etc.
if (this.comment) return false
if (this.empty) return f === ""
if (f === "/" && partial) return true
var options = this.options
// first, normalize any slash-separated path parts.
// f = path.normalize(f)
// windows: need to use /, not \
// On other platforms, \ is a valid (albeit bad) filename char.
if (process.platform === "win32") {
f = f.split("\\").join("/")
}
// treat the test path as a set of pathparts.
f = f.split(slashSplit)
if (options.debug) {
console.error(this.pattern, "split", f)
}
// just ONE of the pattern sets in this.set needs to match
// in order for it to be valid. If negating, then just one
// match means that we have failed.
// Either way, return on the first hit.
var set = this.set
// console.error(this.pattern, "set", set)
for (var i = 0, l = set.length; i < l; i ++) {
var pattern = set[i]
var hit = this.matchOne(f, pattern, partial)
if (hit) {
return !this.negate
}
}
// didn't get any hits. this is success if it's a negative
// pattern, failure otherwise.
return this.negate
}
// set partial to true to test if, for example,
// "/a/b" matches the start of "/*/b/*/d"
// Partial means, if you run out of file before you run
// out of pattern, then that's fine, as long as all
// the parts match.
Minimatch.prototype.matchOne = function (file, pattern, partial) {
var options = this.options
if (options.debug) {
console.error("matchOne",
{ "this": this
, file: file
, pattern: pattern })
}
if (options.matchBase && pattern.length === 1) {
file = path.basename(file.join("/")).split("/")
}
if (options.debug) {
console.error("matchOne", file.length, pattern.length)
}
for ( var fi = 0
, pi = 0
, fl = file.length
, pl = pattern.length
; (fi < fl) && (pi < pl)
; fi ++, pi ++ ) {
if (options.debug) {
console.error("matchOne loop")
}
var p = pattern[pi]
, f = file[fi]
if (options.debug) {
console.error(pattern, p, f)
}
// should be impossible.
// some invalid regexp stuff in the set.
if (p === false) return false
if (p === GLOBSTAR) {
// "**"
// a/**/b/**/c would match the following:
// a/b/x/y/z/c
// a/x/y/z/b/c
// a/b/x/b/x/c
// a/b/c
// To do this, take the rest of the pattern after
// the **, and see if it would match the file remainder.
// If so, return success.
// If not, the ** "swallows" a segment, and try again.
// This is recursively awful.
// a/b/x/y/z/c
// - a matches a
// - doublestar
// - matchOne(b/x/y/z/c, b/**/c)
// - b matches b
// - doublestar
// - matchOne(x/y/z/c, c) -> no
// - matchOne(y/z/c, c) -> no
// - matchOne(z/c, c) -> no
// - matchOne(c, c) yes, hit
var fr = fi
, pr = pi + 1
if (pr === pl) {
// a ** at the end will just swallow the rest.
// We have found a match.
// however, it will not swallow /.x, unless
// options.dot is set.
// . and .. are *never* matched by **, for explosively
// exponential reasons.
for ( ; fi < fl; fi ++) {
if (file[fi] === "." || file[fi] === ".." ||
(!options.dot && file[fi].charAt(0) === ".")) return false
}
return true
}
// ok, let's see if we can swallow whatever we can.
WHILE: while (fr < fl) {
var swallowee = file[fr]
if (swallowee === "." || swallowee === ".." ||
(!options.dot && swallowee.charAt(0) === ".")) {
// console.error("dot detected!")
break WHILE
}
// XXX remove this slice. Just pass the start index.
if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) {
// found a match.
return true
} else {
// ** swallows a segment, and continue.
fr ++
}
}
// no match was found.
// However, in partial mode, we can't say this is necessarily over.
// If there's more *pattern* left, then
if (partial) {
// ran out of file
// console.error("\n>>> no match, partial?", file, fr, pattern, pr)
if (fr === fl) return true
}
return false
}
// something other than **
// non-magic patterns just have to match exactly
// 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
}
if (options.debug) {
console.error("string match", p, f, hit)
}
} else {
hit = f.match(p)
if (options.debug) {
console.error("pattern match", p, f, hit)
}
}
if (!hit) return false
}
// Note: ending in / means that we'll get a final ""
// at the end of the pattern. This can only match a
// corresponding "" at the end of the file.
// If the file ends in /, then it can only match a
// a pattern that ends in /, unless the pattern just
// doesn't have any more for it. But, a/b/ should *not*
// match "a/b/*", even though "" matches against the
// [^/]*? pattern, except in partial mode, where it might
// simply not be reached yet.
// However, a/b/ should still satisfy a/*
// now either we fell off the end of the pattern, or we're done.
if (fi === fl && pi === pl) {
// ran out of pattern and filename at the same time.
// an exact hit!
return true
} else if (fi === fl) {
// ran out of file, but still had pattern left.
// this is ok if we're doing the match as part of
// a glob fs traversal.
return partial
} 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
}
// should be unreachable.
throw new Error("wtf?")
}
// replace stuff like \* with *
function globUnescape (s) {
return s.replace(/\\(.)/g, "$1")
}
function regExpEscape (s) {
return s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&")
}

View file

@ -0,0 +1 @@
/node_modules

View file

@ -0,0 +1,23 @@
Copyright 2009, 2010, 2011 Isaac Z. Schlueter.
All rights reserved.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

View file

@ -0,0 +1,12 @@
# lru cache
A cache object that deletes the least-recently-used items.
Usage:
var LRU = require("lru-cache")
, cache = LRU(10) // max 10 items. default = Infinity
cache.set("key", "value")
cache.get("key") // "value"
RTFS for more info.

View file

@ -0,0 +1,100 @@
;(function () { // closure for web browsers
if (module) {
module.exports = LRUCache
} else {
// just set the global for non-node platforms.
;(function () { return this })().LRUCache = LRUCache
}
function hOP (obj, key) {
return Object.prototype.hasOwnProperty.call(obj, key)
}
function LRUCache (maxLength) {
if (!(this instanceof LRUCache)) {
return new LRUCache(maxLength)
}
var cache = {} // hash of items by key
, lruList = {} // list of items in order of use recency
, lru = 0 // least recently used
, mru = 0 // most recently used
, length = 0 // number of items in the list
// resize the cache when the maxLength changes.
Object.defineProperty(this, "maxLength",
{ set : function (mL) {
if (!mL || !(typeof mL === "number") || mL <= 0 ) mL = Infinity
maxLength = mL
// if it gets above double maxLength, trim right away.
// otherwise, do it whenever it's convenient.
if (length > maxLength) trim()
}
, get : function () { return maxLength }
, enumerable : true
})
this.maxLength = maxLength
Object.defineProperty(this, "length",
{ get : function () { return length }
, enumerable : true
})
this.reset = function () {
cache = {}
lruList = {}
lru = 0
mru = 0
length = 0
}
this.set = function (key, value) {
if (hOP(cache, key)) {
this.get(key)
cache[key].value = value
return undefined
}
var hit = {key:key, value:value, lu:mru++}
lruList[hit.lu] = cache[key] = hit
length ++
if (length > maxLength) trim()
}
this.get = function (key) {
if (!hOP(cache, key)) return undefined
var hit = cache[key]
delete lruList[hit.lu]
if (hit.lu === lru) lruWalk()
hit.lu = mru ++
lruList[hit.lu] = hit
return hit.value
}
this.del = function (key) {
if (!hOP(cache, key)) return undefined
var hit = cache[key]
delete cache[key]
delete lruList[hit.lu]
if (hit.lu === lru) lruWalk()
length --
}
function lruWalk () {
// lru has been deleted, hop up to the next hit.
lru = Object.keys(lruList).shift()
}
function trim () {
if (length <= maxLength) return undefined
var prune = Object.keys(lruList).slice(0, length - maxLength)
for (var i = 0, l = (length - maxLength); i < l; i ++) {
delete cache[ lruList[prune[i]].key ]
delete lruList[prune[i]]
}
length = maxLength
lruWalk()
}
}
})()

View file

@ -0,0 +1,13 @@
{ "name": "lru-cache"
, "description": "A cache object that deletes the least-recently-used items."
, "version": "1.0.5"
, "author": "Isaac Z. Schlueter <i@izs.me>"
, "scripts": { "test": "tap test" }
, "main": "lib/lru-cache.js"
, "repository": "git://github.com/isaacs/node-lru-cache.git"
, "devDependencies": { "tap": "0.1" }
, "license":
{ "type": "MIT"
, "url": "http://github.com/isaacs/node-lru-cache/raw/master/LICENSE"
}
}

View file

@ -0,0 +1,93 @@
var test = require('tap').test
, LRU = require('../')
test('basic', function (t) {
var cache = new LRU(10)
cache.set("key", "value")
t.equal(cache.get("key"), "value")
t.equal(cache.get("nada"), undefined)
t.equal(cache.length, 1)
t.equal(cache.maxLength, 10)
t.end()
})
test('least recently set', function (t) {
var cache = new LRU(2)
cache.set("a", "A")
cache.set("b", "B")
cache.set("c", "C")
t.equal(cache.get("c"), "C")
t.equal(cache.get("b"), "B")
t.equal(cache.get("a"), undefined)
t.end()
})
test('lru recently gotten', function (t) {
var cache = new LRU(2)
cache.set("a", "A")
cache.set("b", "B")
cache.get("a")
cache.set("c", "C")
t.equal(cache.get("c"), "C")
t.equal(cache.get("b"), undefined)
t.equal(cache.get("a"), "A")
t.end()
})
test('del', function (t) {
var cache = new LRU(2)
cache.set("a", "A")
cache.del("a")
t.equal(cache.get("a"), undefined)
t.end()
})
test('maxLength', function (t) {
var cache = new LRU(3)
// test changing the maxLength, verify that the LRU items get dropped.
cache.maxLength = 100
for (var i = 0; i < 100; i ++) cache.set(i, i)
t.equal(cache.length, 100)
for (var i = 0; i < 100; i ++) {
t.equal(cache.get(i), i)
}
cache.maxLength = 3
t.equal(cache.length, 3)
for (var i = 0; i < 97; i ++) {
t.equal(cache.get(i), undefined)
}
for (var i = 98; i < 100; i ++) {
t.equal(cache.get(i), i)
}
// now remove the maxLength restriction, and try again.
cache.maxLength = "hello"
for (var i = 0; i < 100; i ++) cache.set(i, i)
t.equal(cache.length, 100)
for (var i = 0; i < 100; i ++) {
t.equal(cache.get(i), i)
}
// should trigger an immediate resize
cache.maxLength = 3
t.equal(cache.length, 3)
for (var i = 0; i < 97; i ++) {
t.equal(cache.get(i), undefined)
}
for (var i = 98; i < 100; i ++) {
t.equal(cache.get(i), i)
}
t.end()
})
test('reset', function (t) {
var cache = new LRU(10)
cache.set("a", "A")
cache.set("b", "B")
cache.reset()
t.equal(cache.length, 0)
t.equal(cache.maxLength, 10)
t.equal(cache.get("a"), undefined)
t.equal(cache.get("b"), undefined)
t.end()
})

29
node_modules/glob/node_modules/minimatch/package.json generated vendored Normal file
View file

@ -0,0 +1,29 @@
{
"author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me)",
"name": "minimatch",
"description": "a glob matcher in javascript",
"version": "0.2.0",
"repository": {
"type": "git",
"url": "git://github.com/isaacs/minimatch.git"
},
"main": "minimatch.js",
"scripts": {
"test": "tap test"
},
"engines": {
"node": "*"
},
"dependencies": {
"lru-cache": "~1.0.5"
},
"devDependencies": {
"tap": "~0.1.3"
},
"licenses" : [
{
"type" : "MIT",
"url" : "http://github.com/isaacs/minimatch/raw/master/LICENSE"
}
]
}

261
node_modules/glob/node_modules/minimatch/test/basic.js generated vendored Normal file
View file

@ -0,0 +1,261 @@
// http://www.bashcookbook.com/bashinfo/source/bash-1.14.7/tests/glob-test
//
// TODO: Some of these tests do very bad things with backslashes, and will
// most likely fail badly on windows. They should probably be skipped.
var tap = require("tap")
, globalBefore = Object.keys(global)
, mm = require("../")
, files = [ "a", "b", "c", "d", "abc"
, "abd", "abe", "bb", "bcd"
, "ca", "cb", "dd", "de"
, "bdir/", "bdir/cfile"]
, next = files.concat([ "a-b", "aXb"
, ".x", ".y" ])
tap.test("basic tests", function (t) {
var start = Date.now()
// [ pattern, [matches], MM opts, files, TAP opts]
; [ "http://www.bashcookbook.com/bashinfo" +
"/source/bash-1.14.7/tests/glob-test"
, ["a*", ["a", "abc", "abd", "abe"]]
, ["X*", ["X*"], {nonull: true}]
// allow null glob expansion
, ["X*", []]
// isaacs: Slightly different than bash/sh/ksh
// \\* is not un-escaped to literal "*" in a failed match,
// but it does make it get treated as a literal star
, ["\\*", ["\\*"], {nonull: true}]
, ["\\**", ["\\**"], {nonull: true}]
, ["\\*\\*", ["\\*\\*"], {nonull: true}]
, ["b*/", ["bdir/"]]
, ["c*", ["c", "ca", "cb"]]
, ["**", files]
, ["\\.\\./*/", ["\\.\\./*/"], {nonull: true}]
, ["s/\\..*//", ["s/\\..*//"], {nonull: true}]
, "legendary larry crashes bashes"
, ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\\1/"
, ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\\1/"], {nonull: true}]
, ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\1/"
, ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\1/"], {nonull: true}]
, "character classes"
, ["[a-c]b*", ["abc", "abd", "abe", "bb", "cb"]]
, ["[a-y]*[^c]", ["abd", "abe", "bb", "bcd",
"bdir/", "ca", "cb", "dd", "de"]]
, ["a*[^c]", ["abd", "abe"]]
, function () { files.push("a-b", "aXb") }
, ["a[X-]b", ["a-b", "aXb"]]
, function () { files.push(".x", ".y") }
, ["[^a-c]*", ["d", "dd", "de"]]
, function () { files.push("a*b/", "a*b/ooo") }
, ["a\\*b/*", ["a*b/ooo"]]
, ["a\\*?/*", ["a*b/ooo"]]
, ["*\\\\!*", [], {null: true}, ["echo !7"]]
, ["*\\!*", ["echo !7"], null, ["echo !7"]]
, ["*.\\*", ["r.*"], null, ["r.*"]]
, ["a[b]c", ["abc"]]
, ["a[\\b]c", ["abc"]]
, ["a?c", ["abc"]]
, ["a\\*c", [], {null: true}, ["abc"]]
, ["", [""], { null: true }, [""]]
, "http://www.opensource.apple.com/source/bash/bash-23/" +
"bash/tests/glob-test"
, function () { files.push("man/", "man/man1/", "man/man1/bash.1") }
, ["*/man*/bash.*", ["man/man1/bash.1"]]
, ["man/man1/bash.1", ["man/man1/bash.1"]]
, ["a***c", ["abc"], null, ["abc"]]
, ["a*****?c", ["abc"], null, ["abc"]]
, ["?*****??", ["abc"], null, ["abc"]]
, ["*****??", ["abc"], null, ["abc"]]
, ["?*****?c", ["abc"], null, ["abc"]]
, ["?***?****c", ["abc"], null, ["abc"]]
, ["?***?****?", ["abc"], null, ["abc"]]
, ["?***?****", ["abc"], null, ["abc"]]
, ["*******c", ["abc"], null, ["abc"]]
, ["*******?", ["abc"], null, ["abc"]]
, ["a*cd**?**??k", ["abcdecdhjk"], null, ["abcdecdhjk"]]
, ["a**?**cd**?**??k", ["abcdecdhjk"], null, ["abcdecdhjk"]]
, ["a**?**cd**?**??k***", ["abcdecdhjk"], null, ["abcdecdhjk"]]
, ["a**?**cd**?**??***k", ["abcdecdhjk"], null, ["abcdecdhjk"]]
, ["a**?**cd**?**??***k**", ["abcdecdhjk"], null, ["abcdecdhjk"]]
, ["a****c**?**??*****", ["abcdecdhjk"], null, ["abcdecdhjk"]]
, ["[-abc]", ["-"], null, ["-"]]
, ["[abc-]", ["-"], null, ["-"]]
, ["\\", ["\\"], null, ["\\"]]
, ["[\\\\]", ["\\"], null, ["\\"]]
, ["[[]", ["["], null, ["["]]
, ["[", ["["], null, ["["]]
, ["[*", ["[abc"], null, ["[abc"]]
, "a right bracket shall lose its special meaning and\n" +
"represent itself in a bracket expression if it occurs\n" +
"first in the list. -- POSIX.2 2.8.3.2"
, ["[]]", ["]"], null, ["]"]]
, ["[]-]", ["]"], null, ["]"]]
, ["[a-\z]", ["p"], null, ["p"]]
, ["??**********?****?", [], { null: true }, ["abc"]]
, ["??**********?****c", [], { null: true }, ["abc"]]
, ["?************c****?****", [], { null: true }, ["abc"]]
, ["*c*?**", [], { null: true }, ["abc"]]
, ["a*****c*?**", [], { null: true }, ["abc"]]
, ["a********???*******", [], { null: true }, ["abc"]]
, ["[]", [], { null: true }, ["a"]]
, ["[abc", [], { null: true }, ["["]]
, "nocase tests"
, ["XYZ", ["xYz"], { nocase: true, null: true }
, ["xYz", "ABC", "IjK"]]
, ["ab*", ["ABC"], { nocase: true, null: true }
, ["xYz", "ABC", "IjK"]]
, ["[ia]?[ck]", ["ABC", "IjK"], { nocase: true, null: true }
, ["xYz", "ABC", "IjK"]]
// [ pattern, [matches], MM opts, files, TAP opts]
, "onestar/twostar"
, ["{/*,*}", [], {null: true}, ["/asdf/asdf/asdf"]]
, ["{/?,*}", ["/a", "bb"], {null: true}
, ["/a", "/b/b", "/a/b/c", "bb"]]
, "dots should not match unless requested"
, ["**", ["a/b"], {}, ["a/b", "a/.d", ".a/.d"]]
// .. and . can only match patterns starting with .,
// even when options.dot is set.
, function () {
files = ["a/./b", "a/../b", "a/c/b", "a/.d/b"]
}
, ["a/*/b", ["a/c/b", "a/.d/b"], {dot: true}]
, ["a/.*/b", ["a/./b", "a/../b", "a/.d/b"], {dot: true}]
, ["a/*/b", ["a/c/b"], {dot:false}]
, ["a/.*/b", ["a/./b", "a/../b", "a/.d/b"], {dot: false}]
// this also tests that changing the options needs
// to change the cache key, even if the pattern is
// the same!
, ["**", ["a/b","a/.d",".a/.d"], { dot: true }
, [ ".a/.d", "a/.d", "a/b"]]
, "paren sets cannot contain slashes"
, ["*(a/b)", ["*(a/b)"], {nonull: true}, ["a/b"]]
// brace sets trump all else.
//
// invalid glob pattern. fails on bash4 and bsdglob.
// however, in this implementation, it's easier just
// to do the intuitive thing, and let brace-expansion
// actually come before parsing any extglob patterns,
// like the documentation seems to say.
//
// XXX: if anyone complains about this, either fix it
// or tell them to grow up and stop complaining.
//
// bash/bsdglob says this:
// , ["*(a|{b),c)}", ["*(a|{b),c)}"], {}, ["a", "ab", "ac", "ad"]]
// but we do this instead:
, ["*(a|{b),c)}", ["a", "ab", "ac"], {}, ["a", "ab", "ac", "ad"]]
// test partial parsing in the presence of comment/negation chars
, ["[!a*", ["[!ab"], {}, ["[!ab", "[ab"]]
, ["[#a*", ["[#ab"], {}, ["[#ab", "[ab"]]
// like: {a,b|c\\,d\\\|e} except it's unclosed, so it has to be escaped.
, ["+(a|*\\|c\\\\|d\\\\\\|e\\\\\\\\|f\\\\\\\\\\|g"
, ["+(a|b\\|c\\\\|d\\\\|e\\\\\\\\|f\\\\\\\\|g"]
, {}
, ["+(a|b\\|c\\\\|d\\\\|e\\\\\\\\|f\\\\\\\\|g", "a", "b\\c"]]
// crazy nested {,,} and *(||) tests.
, function () {
files = [ "a", "b", "c", "d"
, "ab", "ac", "ad"
, "bc", "cb"
, "bc,d", "c,db", "c,d"
, "d)", "(b|c", "*(b|c"
, "b|c", "b|cc", "cb|c"
, "x(a|b|c)", "x(a|c)"
, "(a|b|c)", "(a|c)"]
}
, ["*(a|{b,c})", ["a", "b", "c", "ab", "ac"]]
, ["{a,*(b|c,d)}", ["a","(b|c", "*(b|c", "d)"]]
// a
// *(b|c)
// *(b|d)
, ["{a,*(b|{c,d})}", ["a","b", "bc", "cb", "c", "d"]]
, ["*(a|{b|c,c})", ["a", "b", "c", "ab", "ac", "bc", "cb"]]
// test various flag settings.
, [ "*(a|{b|c,c})", ["x(a|b|c)", "x(a|c)", "(a|b|c)", "(a|c)"]
, { noext: true } ]
, ["a?b", ["x/y/acb", "acb/"], {matchBase: true}
, ["x/y/acb", "acb/", "acb/d/e", "x/y/acb/d"] ]
, ["#*", ["#a", "#b"], {nocomment: true}, ["#a", "#b", "c#d"]]
// begin channelling Boole and deMorgan...
, "negation tests"
, function () {
files = ["d", "e", "!ab", "!abc", "a!b", "\\!a"]
}
// anything that is NOT a* matches.
, ["!a*", ["\\!a", "d", "e", "!ab", "!abc"]]
// anything that IS !a* matches.
, ["!a*", ["!ab", "!abc"], {nonegate: true}]
// anything that IS a* matches
, ["!!a*", ["a!b"]]
// anything that is NOT !a* matches
, ["!\\!a*", ["a!b", "d", "e", "\\!a"]]
].forEach(function (c) {
if (typeof c === "function") return c()
if (typeof c === "string") return t.comment(c)
var pattern = c[0]
, expect = c[1].sort(alpha)
, options = c[2] || {}
, f = c[3] || files
, tapOpts = c[4] || {}
// options.debug = true
var m = new mm.Minimatch(pattern, options)
var r = m.makeRe()
tapOpts.re = String(r) || JSON.stringify(r)
tapOpts.files = JSON.stringify(f)
tapOpts.pattern = pattern
tapOpts.set = m.set
tapOpts.negated = m.negate
var actual = mm.match(f, pattern, options)
actual.sort(alpha)
t.equivalent( actual, expect
, JSON.stringify(pattern) + " " + JSON.stringify(expect)
, tapOpts )
})
t.comment("time=" + (Date.now() - start) + "ms")
t.end()
})
tap.test("global leak test", function (t) {
var globalAfter = Object.keys(global)
t.equivalent(globalAfter, globalBefore, "no new globals, please")
t.end()
})
function alpha (a, b) {
return a > b ? 1 : -1
}

View file

@ -0,0 +1,33 @@
var tap = require("tap")
, minimatch = require("../")
tap.test("brace expansion", function (t) {
// [ pattern, [expanded] ]
; [ [ "a{b,c{d,e},{f,g}h}x{y,z}"
, [ "abxy"
, "abxz"
, "acdxy"
, "acdxz"
, "acexy"
, "acexz"
, "afhxy"
, "afhxz"
, "aghxy"
, "aghxz" ] ]
, [ "a{1..5}b"
, [ "a1b"
, "a2b"
, "a3b"
, "a4b"
, "a5b" ] ]
, [ "a{b}c", ["a{b}c"] ]
].forEach(function (tc) {
var p = tc[0]
, expect = tc[1]
t.equivalent(minimatch.braceExpand(p), expect, p)
})
console.error("ending")
t.end()
})

View file

@ -0,0 +1,14 @@
var Minimatch = require("../minimatch.js").Minimatch
var tap = require("tap")
tap.test("cache test", function (t) {
var mm1 = new Minimatch("a?b")
var mm2 = new Minimatch("a?b")
t.equal(mm1, mm2, "should get the same object")
// the lru should drop it after 100 entries
for (var i = 0; i < 100; i ++) {
new Minimatch("a"+i)
}
mm2 = new Minimatch("a?b")
t.notEqual(mm1, mm2, "cache should have dropped")
t.end()
})

5
node_modules/glob/package.json generated vendored
View file

@ -2,7 +2,7 @@
"author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me/)",
"name": "glob",
"description": "a little globber",
"version": "3.0.1",
"version": "3.1.4",
"repository": {
"type": "git",
"url": "git://github.com/isaacs/node-glob.git"
@ -12,8 +12,7 @@
"node": "*"
},
"dependencies": {
"fast-list":"1",
"minimatch": "0.1",
"minimatch": "0.2",
"graceful-fs": "~1.1.2",
"inherits": "1"
},

View file

@ -5,7 +5,8 @@ var tap = require("tap")
// put more patterns here.
, globs =
["test/a/*/+(c|g)/./d"
[
"test/a/*/+(c|g)/./d"
,"test/a/**/[cg]/../[cg]"
,"test/a/{b,c,d,e,f}/**/g"
,"test/a/b/**"
@ -64,12 +65,20 @@ globs.forEach(function (pattern) {
}).sort(alphasort).reduce(function (set, f) {
if (f !== set[set.length - 1]) set.push(f)
return set
}, [])
}, []).sort(alphasort)
}
next()
})
glob(pattern, function (er, matches) {
// sort and unpark, just to match the shell results
matches = matches.map(function (m) {
return m.replace(/\/+/g, "/").replace(/\/$/, "")
}).sort(alphasort).reduce(function (set, f) {
if (f !== set[set.length - 1]) set.push(f)
return set
}, []).sort(alphasort)
t.ifError(er, pattern + " should not error")
globResult = matches
next()
@ -84,7 +93,14 @@ globs.forEach(function (pattern) {
})
tap.test(pattern + " sync", function (t) {
t.deepEqual(glob.sync(pattern), echoOutput, "should match shell")
var matches = glob.sync(pattern).map(function (m) {
return m.replace(/\/+/g, "/").replace(/\/$/, "")
}).sort(alphasort).reduce(function (set, f) {
if (f !== set[set.length - 1]) set.push(f)
return set
}, []).sort(alphasort)
t.deepEqual(matches, echoOutput, "should match shell")
t.end()
})
})

55
node_modules/glob/test/cwd-test.js generated vendored Normal file
View file

@ -0,0 +1,55 @@
var tap = require("tap")
var origCwd = process.cwd()
process.chdir(__dirname)
tap.test("changing cwd and searching for **/d", function (t) {
var glob = require('glob')
var path = require('path')
t.test('.', function (t) {
glob('**/d', function (er, matches) {
t.ifError(er)
t.like(matches, [ 'a/b/c/d', 'a/c/d' ])
t.end()
})
})
t.test('a', function (t) {
glob('**/d', {cwd:path.resolve('a')}, function (er, matches) {
t.ifError(er)
t.like(matches, [ 'b/c/d', 'c/d' ])
t.end()
})
})
t.test('a/b', function (t) {
glob('**/d', {cwd:path.resolve('a/b')}, function (er, matches) {
t.ifError(er)
t.like(matches, [ 'c/d' ])
t.end()
})
})
t.test('a/b/', function (t) {
glob('**/d', {cwd:path.resolve('a/b/')}, function (er, matches) {
t.ifError(er)
t.like(matches, [ 'c/d' ])
t.end()
})
})
t.test('.', function (t) {
glob('**/d', {cwd: process.cwd()}, function (er, matches) {
t.ifError(er)
t.like(matches, [ 'a/b/c/d', 'a/c/d' ])
t.end()
})
})
t.test('cd -', function (t) {
process.chdir(origCwd)
t.end()
})
t.end()
})

39
node_modules/glob/test/root-nomount.js generated vendored Normal file
View file

@ -0,0 +1,39 @@
var tap = require("tap")
var origCwd = process.cwd()
process.chdir(__dirname)
tap.test("changing root and searching for /b*/**", function (t) {
var glob = require('glob')
var path = require('path')
t.test('.', function (t) {
glob('/b*/**', { globDebug: true, root: '.', nomount: true }, function (er, matches) {
t.ifError(er)
t.like(matches, [])
t.end()
})
})
t.test('a', function (t) {
glob('/b*/**', { globDebug: true, root: path.resolve('a'), nomount: true }, function (er, matches) {
t.ifError(er)
t.like(matches, [ '/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f' ])
t.end()
})
})
t.test('root=a, cwd=a/b', function (t) {
glob('/b*/**', { globDebug: true, root: 'a', cwd: path.resolve('a/b'), nomount: true }, function (er, matches) {
t.ifError(er)
t.like(matches, [ '/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f' ])
t.end()
})
})
t.test('cd -', function (t) {
process.chdir(origCwd)
t.end()
})
t.end()
})

43
node_modules/glob/test/root.js generated vendored Normal file
View file

@ -0,0 +1,43 @@
var tap = require("tap")
var origCwd = process.cwd()
process.chdir(__dirname)
tap.test("changing root and searching for /b*/**", function (t) {
var glob = require('glob')
var path = require('path')
t.test('.', function (t) {
glob('/b*/**', { globDebug: true, root: '.' }, function (er, matches) {
t.ifError(er)
t.like(matches, [])
t.end()
})
})
t.test('a', function (t) {
glob('/b*/**', { globDebug: true, root: path.resolve('a') }, function (er, matches) {
t.ifError(er)
t.like(matches, [ '/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f' ].map(function (m) {
return path.join(path.resolve('a'), m)
}))
t.end()
})
})
t.test('root=a, cwd=a/b', function (t) {
glob('/b*/**', { globDebug: true, root: 'a', cwd: path.resolve('a/b') }, function (er, matches) {
t.ifError(er)
t.like(matches, [ '/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f' ].map(function (m) {
return path.join(path.resolve('a'), m)
}))
t.end()
})
})
t.test('cd -', function (t) {
process.chdir(origCwd)
t.end()
})
t.end()
})