diff options
author | Forrest L Norvell <forrest@npmjs.com> | 2015-03-20 10:00:06 +0300 |
---|---|---|
committer | Forrest L Norvell <forrest@npmjs.com> | 2015-03-20 10:00:06 +0300 |
commit | bd72c47ce8c58e287d496902c11845c8fea420d6 (patch) | |
tree | 70f8946341e4aa4303b0a74d6f22a781c6d630dd /node_modules/glob | |
parent | 4bfbaa2d8b9dc7067d999de8f55676db3a4f4196 (diff) |
glob@5.0.3
Diffstat (limited to 'node_modules/glob')
-rw-r--r-- | node_modules/glob/README.md | 62 | ||||
-rw-r--r-- | node_modules/glob/common.js | 44 | ||||
-rw-r--r-- | node_modules/glob/glob.js | 148 | ||||
-rw-r--r-- | node_modules/glob/package.json | 18 | ||||
-rw-r--r-- | node_modules/glob/sync.js | 81 |
5 files changed, 255 insertions, 98 deletions
diff --git a/node_modules/glob/README.md b/node_modules/glob/README.md index ba95474c2..fa993dcb6 100644 --- a/node_modules/glob/README.md +++ b/node_modules/glob/README.md @@ -79,7 +79,8 @@ with a matching basename. For example, `*.js` would match The intent for negation would be for a pattern starting with `!` to match everything that *doesn't* match the supplied pattern. However, the implementation is weird, and for the time being, this should be -avoided. The behavior will change or be deprecated in version 5. +avoided. The behavior is deprecated in version 5, and will be removed +entirely in version 6. ### Empty Sets @@ -159,8 +160,6 @@ be immediately available on the `g.found` member. * `aborted` Boolean which is set to true when calling `abort()`. There 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. -* `statCache` Collection of all the stat results the glob search - performed. * `cache` Convenience object. Each field has the following possible values: * `false` - Path does not exist @@ -173,6 +172,9 @@ be immediately available on the `g.found` member. path multiple times. * `symlinks` A record of which paths are symbolic links, which is relevant in resolving `**` patterns. +* `realpathCache` An optional object which is passed to `fs.realpath` + to minimize unnecessary syscalls. It is stored on the instantiated + Glob object, and may be re-used. ### Events @@ -204,9 +206,9 @@ All options are added to the Glob object, as well. If you are running many `glob` operations, you can pass a Glob object as the `options` argument to a subsequent operation to shortcut some `stat` and `readdir` calls. At the very least, you may pass in shared -`symlinks`, `statCache`, and `cache` options, so that parallel glob -operations will be sped up by sharing information about the -filesystem. +`symlinks`, `statCache`, `realpathCache`, and `cache` options, so that +parallel glob operations will be sped up by sharing information about +the filesystem. * `cwd` The current working directory in which to search. Defaults to `process.cwd()`. @@ -242,7 +244,7 @@ filesystem. * `symlinks` A cache of known symbolic links. You may pass in a previously generated `symlinks` object to save `lstat` calls when resolving `**` matches. -* `sync` Perform a synchronous glob search. +* `sync` DEPRECATED: use `glob.sync(pattern, opts)` instead. * `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 @@ -260,11 +262,21 @@ filesystem. * `matchBase` Perform a basename-only match if the pattern does not contain any slash characters. That is, `*.js` would be treated as equivalent to `**/*.js`, matching all js files in all directories. -* `nonegate` Suppress `negate` behavior. (See below.) -* `nocomment` Suppress `comment` behavior. (See below.) * `nonull` Return the pattern when no matches are found. -* `nodir` Do not match directories, only files. +* `nodir` Do not match directories, only files. (Note: to match + *only* directories, simply put a `/` at the end of the pattern.) * `ignore` Add a pattern or an array of patterns to exclude matches. +* `follow` Follow symlinked directories when expanding `**` patterns. + Note that this can result in a lot of duplicate references in the + presence of cyclic links. +* `realpath` Set to true to call `fs.realpath` on all of the results. + In the case of a symlink that cannot be resolved, the full absolute + path to the matched entry is returned (though it will usually be a + broken symlink) +* `nonegate` Suppress deprecated `negate` behavior. (See below.) + Default=true +* `nocomment` Suppress deprecated `comment` behavior. (See below.) + Default=true ## Comparisons to other fnmatch/glob implementations @@ -272,17 +284,6 @@ 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.3, where `**` only has special significance if it is the only @@ -306,6 +307,25 @@ other interpretation of the glob pattern. Thus, a pattern like **first** into the set of `+(a|b)` and `+(a|c)`, and those patterns are checked for validity. Since those two are valid, matching proceeds. +### Comments and Negation + +**Note**: In version 5 of this module, negation and comments are +**disabled** by default. You can explicitly set `nonegate:false` or +`nocomment:false` to re-enable them. They are going away entirely in +version 6. + +The intent for negation would be for a pattern starting with `!` to +match everything that *doesn't* match the supplied pattern. However, +the implementation is weird. It is better to use the `ignore` option +to set a pattern or set of patterns to exclude from matches. If you +want the "everything except *x*" type of behavior, you can use `**` as +the main pattern, and set an `ignore` for the things to exclude. + +The comments feature is added in minimatch, primarily to more easily +support use cases like ignore files, where a `#` at the start of a +line makes the pattern "empty". However, in the context of a +straightforward filesystem globber, "comments" don't make much sense. + ## Windows **Please only use forward-slashes in glob expressions.** diff --git a/node_modules/glob/common.js b/node_modules/glob/common.js index 491b9730b..d6389591d 100644 --- a/node_modules/glob/common.js +++ b/node_modules/glob/common.js @@ -58,11 +58,11 @@ function ignoreMap (pattern) { var gmatcher = null if (pattern.slice(-3) === '/**') { var gpattern = pattern.replace(/(\/\*\*)+$/, '') - gmatcher = new Minimatch(gpattern, { nonegate: true }) + gmatcher = new Minimatch(gpattern) } return { - matcher: new Minimatch(pattern, { nonegate: true }), + matcher: new Minimatch(pattern), gmatcher: gmatcher } } @@ -81,6 +81,9 @@ function setopts (self, pattern, options) { self.pattern = pattern self.strict = options.strict !== false + self.realpath = !!options.realpath + self.realpathCache = options.realpathCache || Object.create(null) + self.follow = !!options.follow self.dot = !!options.dot self.mark = !!options.mark self.nodir = !!options.nodir @@ -117,17 +120,42 @@ function setopts (self, pattern, options) { self.nomount = !!options.nomount + // disable comments and negation unless the user explicitly + // passes in false as the option. + options.nonegate = options.nonegate === false ? false : true + options.nocomment = options.nocomment === false ? false : true + deprecationWarning(options) + self.minimatch = new Minimatch(pattern, options) self.options = self.minimatch.options } +// TODO(isaacs): remove entirely in v6 +// exported to reset in tests +exports.deprecationWarned +function deprecationWarning(options) { + if (!options.nonegate || !options.nocomment) { + if (process.noDeprecation !== true && !exports.deprecationWarned) { + var msg = 'glob WARNING: comments and negation will be disabled in v6' + if (process.throwDeprecation) + throw new Error(msg) + else if (process.traceDeprecation) + console.trace(msg) + else + console.error(msg) + + exports.deprecationWarned = true + } + } +} + function finish (self) { var nou = self.nounique var all = nou ? [] : Object.create(null) for (var i = 0, l = self.matches.length; i < l; i ++) { var matches = self.matches[i] - if (!matches) { + if (!matches || Object.keys(matches).length === 0) { if (self.nonull) { // do like the shell, and spit out the literal glob var literal = self.minimatch.globSet[i] @@ -175,7 +203,8 @@ function finish (self) { } function mark (self, p) { - var c = self.cache[p] + var abs = makeAbs(self, p) + var c = self.cache[abs] var m = p if (c) { var isDir = c === 'DIR' || Array.isArray(c) @@ -187,8 +216,9 @@ function mark (self, p) { m = m.slice(0, -1) if (m !== p) { - self.statCache[m] = self.statCache[p] - self.cache[m] = self.cache[p] + var mabs = makeAbs(self, m) + self.statCache[mabs] = self.statCache[abs] + self.cache[mabs] = self.cache[abs] } } @@ -204,6 +234,8 @@ function makeAbs (self, f) { abs = f } else if (self.changedCwd) { abs = path.resolve(self.cwd, f) + } else { + abs = path.resolve(f) } return abs } diff --git a/node_modules/glob/glob.js b/node_modules/glob/glob.js index e1a5c9ece..eac0693cc 100644 --- a/node_modules/glob/glob.js +++ b/node_modules/glob/glob.js @@ -114,6 +114,7 @@ function Glob (pattern, options, cb) { return new Glob(pattern, options, cb) setopts(this, pattern, options) + this._didRealPath = false // process each pattern in the minimatch set var n = this.minimatch.set.length @@ -163,11 +164,67 @@ Glob.prototype._finish = function () { if (this.aborted) return - //console.error('FINISH', this.matches) + if (this.realpath && !this._didRealpath) + return this._realpath() + common.finish(this) this.emit('end', this.found) } +Glob.prototype._realpath = function () { + if (this._didRealpath) + return + + this._didRealpath = true + + var n = this.matches.length + if (n === 0) + return this._finish() + + var self = this + for (var i = 0; i < this.matches.length; i++) + this._realpathSet(i, next) + + function next () { + if (--n === 0) + self._finish() + } +} + +Glob.prototype._realpathSet = function (index, cb) { + var matchset = this.matches[index] + if (!matchset) + return cb() + + var found = Object.keys(matchset) + var self = this + var n = found.length + + if (n === 0) + return cb() + + var set = this.matches[index] = Object.create(null) + found.forEach(function (p, i) { + // If there's a problem with the stat, then it means that + // one or more of the links in the realpath couldn't be + // resolved. just return the abs value in that case. + p = self._makeAbs(p) + fs.realpath(p, self.realpathCache, function (er, real) { + if (!er) + set[real] = true + else if (er.syscall === 'stat') + set[p] = true + else + self.emit('error', er) // srsly wtf right here + + if (--n === 0) { + self.matches[index] = set + cb() + } + }) + }) +} + Glob.prototype._mark = function (p) { return common.mark(this, p) } @@ -372,34 +429,43 @@ Glob.prototype._emitMatch = function (index, e) { if (this.aborted) return - if (!this.matches[index][e]) { - if (this.paused) { - this._emitQueue.push([index, e]) - return - } + if (this.matches[index][e]) + return - if (this.nodir) { - var c = this.cache[this._makeAbs(e)] - if (c === 'DIR' || Array.isArray(c)) - return - } + if (this.paused) { + this._emitQueue.push([index, e]) + return + } - this.matches[index][e] = true - if (!this.stat && !this.mark) - return this.emit('match', e) + var abs = this._makeAbs(e) - var self = this - this._stat(this._makeAbs(e), function (er, c, st) { - self.emit('stat', e, st) - self.emit('match', e) - }) + if (this.nodir) { + var c = this.cache[abs] + if (c === 'DIR' || Array.isArray(c)) + return } + + if (this.mark) + e = this._mark(e) + + this.matches[index][e] = true + + var st = this.statCache[abs] + if (st) + this.emit('stat', e, st) + + this.emit('match', e) } Glob.prototype._readdirInGlobStar = function (abs, cb) { if (this.aborted) return + // follow all symlinked directories forever + // just proceed as if this is a non-globstar situation + if (this.follow) + return this._readdir(abs, false, cb) + var lstatkey = 'lstat\0' + abs var self = this var lstatcb = inflight(lstatkey, lstatcb_) @@ -487,18 +553,18 @@ Glob.prototype._readdirError = function (f, er, cb) { // handle errors, and cache the information switch (er.code) { case 'ENOTDIR': // totally normal. means it *does* exist. - this.cache[f] = 'FILE' + this.cache[this._makeAbs(f)] = 'FILE' break case 'ENOENT': // not terribly unusual case 'ELOOP': case 'ENAMETOOLONG': case 'UNKNOWN': - this.cache[f] = false + this.cache[this._makeAbs(f)] = false break default: // some unusual error. Treat as failure. - this.cache[f] = false + this.cache[this._makeAbs(f)] = false if (this.strict) return this.emit('error', er) if (!this.silent) console.error('glob error', er) break @@ -594,27 +660,27 @@ Glob.prototype._processSimple2 = function (prefix, index, er, exists, cb) { // Returns either 'DIR', 'FILE', or false Glob.prototype._stat = function (f, cb) { - var abs = f - if (f.charAt(0) === '/') - abs = path.join(this.root, f) - else if (this.changedCwd) - abs = path.resolve(this.cwd, f) - + var abs = this._makeAbs(f) + var needDir = f.slice(-1) === '/' if (f.length > this.maxLength) return cb() - if (!this.stat && ownProp(this.cache, f)) { - var c = this.cache[f] + if (!this.stat && ownProp(this.cache, abs)) { + var c = this.cache[abs] if (Array.isArray(c)) c = 'DIR' - // It exists, but not how we need it - if (abs.slice(-1) === '/' && c !== 'DIR') + // It exists, but maybe not how we need it + if (!needDir || c === 'DIR') + return cb(null, c) + + if (needDir && c === 'FILE') return cb() - return cb(null, c) + // otherwise we have to stat, because maybe c=true + // if we know it exists, but not what it is. } var exists @@ -622,8 +688,13 @@ Glob.prototype._stat = function (f, cb) { if (stat !== undefined) { if (stat === false) return cb(null, stat) - else - return cb(null, stat.isDirectory() ? 'DIR' : 'FILE', stat) + else { + var type = stat.isDirectory() ? 'DIR' : 'FILE' + if (needDir && type === 'FILE') + return cb() + else + return cb(null, type, stat) + } } var self = this @@ -653,12 +724,17 @@ Glob.prototype._stat2 = function (f, abs, er, stat, cb) { return cb() } + var needDir = f.slice(-1) === '/' this.statCache[abs] = stat if (abs.slice(-1) === '/' && !stat.isDirectory()) return cb(null, false, stat) var c = stat.isDirectory() ? 'DIR' : 'FILE' - this.cache[f] = this.cache[f] || c + this.cache[abs] = this.cache[abs] || c + + if (needDir && c !== 'DIR') + return cb() + return cb(null, c, stat) } diff --git a/node_modules/glob/package.json b/node_modules/glob/package.json index 59eff1188..cf31a8ded 100644 --- a/node_modules/glob/package.json +++ b/node_modules/glob/package.json @@ -6,7 +6,7 @@ }, "name": "glob", "description": "a little globber", - "version": "4.4.2", + "version": "5.0.3", "repository": { "type": "git", "url": "git://github.com/isaacs/node-glob.git" @@ -42,15 +42,15 @@ "benchclean": "bash benchclean.sh" }, "license": "ISC", - "gitHead": "c13abc0df649ec29f8cfec42f818412887736aa1", + "gitHead": "2f63d487885fbb51ec8fcb21229bebd0e515c3fb", "bugs": { "url": "https://github.com/isaacs/node-glob/issues" }, "homepage": "https://github.com/isaacs/node-glob", - "_id": "glob@4.4.2", - "_shasum": "3ef93e297ee096c1b9b3ffb1d21025c78ab60548", - "_from": "glob@>=4.4.2 <4.5.0", - "_npmVersion": "2.6.0", + "_id": "glob@5.0.3", + "_shasum": "15528c1c727e474a8e7731541c00b00ec802952d", + "_from": "glob@>=5.0.3 <5.1.0", + "_npmVersion": "2.7.1", "_nodeVersion": "1.4.2", "_npmUser": { "name": "isaacs", @@ -63,10 +63,10 @@ } ], "dist": { - "shasum": "3ef93e297ee096c1b9b3ffb1d21025c78ab60548", - "tarball": "http://registry.npmjs.org/glob/-/glob-4.4.2.tgz" + "shasum": "15528c1c727e474a8e7731541c00b00ec802952d", + "tarball": "http://registry.npmjs.org/glob/-/glob-5.0.3.tgz" }, "directories": {}, - "_resolved": "https://registry.npmjs.org/glob/-/glob-4.4.2.tgz", + "_resolved": "https://registry.npmjs.org/glob/-/glob-5.0.3.tgz", "readme": "ERROR: No README data found!" } diff --git a/node_modules/glob/sync.js b/node_modules/glob/sync.js index 315fbfb0b..f4f5e36d4 100644 --- a/node_modules/glob/sync.js +++ b/node_modules/glob/sync.js @@ -50,6 +50,24 @@ function GlobSync (pattern, options) { GlobSync.prototype._finish = function () { assert(this instanceof GlobSync) + if (this.realpath) { + var self = this + this.matches.forEach(function (matchset, index) { + var set = self.matches[index] = Object.create(null) + for (var p in matchset) { + try { + p = self._makeAbs(p) + var real = fs.realpathSync(p, this.realpathCache) + set[real] = true + } catch (er) { + if (er.syscall === 'stat') + set[self._makeAbs(p)] = true + else + throw er + } + } + }) + } common.finish(this) } @@ -190,21 +208,31 @@ GlobSync.prototype._processReaddir = function (prefix, read, abs, remain, index, GlobSync.prototype._emitMatch = function (index, e) { - if (!this.matches[index][e]) { - if (this.nodir) { - var c = this.cache[this._makeAbs(e)] - if (c === 'DIR' || Array.isArray(c)) - return - } + var abs = this._makeAbs(e) + if (this.mark) + e = this._mark(e) + + if (this.matches[index][e]) + return - this.matches[index][e] = true - if (this.stat || this.mark) - this._stat(this._makeAbs(e)) + if (this.nodir) { + var c = this.cache[this._makeAbs(e)] + if (c === 'DIR' || Array.isArray(c)) + return } + + this.matches[index][e] = true + if (this.stat) + this._stat(e) } GlobSync.prototype._readdirInGlobStar = function (abs) { + // follow all symlinked directories forever + // just proceed as if this is a non-globstar situation + if (this.follow) + return this._readdir(abs, false) + var entries var lstat var stat @@ -276,18 +304,18 @@ GlobSync.prototype._readdirError = function (f, er) { // handle errors, and cache the information switch (er.code) { case 'ENOTDIR': // totally normal. means it *does* exist. - this.cache[f] = 'FILE' + this.cache[this._makeAbs(f)] = 'FILE' break case 'ENOENT': // not terribly unusual case 'ELOOP': case 'ENAMETOOLONG': case 'UNKNOWN': - this.cache[f] = false + this.cache[this._makeAbs(f)] = false break default: // some unusual error. Treat as failure. - this.cache[f] = false + this.cache[this._makeAbs(f)] = false if (this.strict) throw er if (!this.silent) console.error('glob error', er) break @@ -365,27 +393,27 @@ GlobSync.prototype._processSimple = function (prefix, index) { // Returns either 'DIR', 'FILE', or false GlobSync.prototype._stat = function (f) { - var abs = f - if (f.charAt(0) === '/') - abs = path.join(this.root, f) - else if (this.changedCwd) - abs = path.resolve(this.cwd, f) - + var abs = this._makeAbs(f) + var needDir = f.slice(-1) === '/' if (f.length > this.maxLength) return false - if (!this.stat && ownProp(this.cache, f)) { - var c = this.cache[f] + if (!this.stat && ownProp(this.cache, abs)) { + var c = this.cache[abs] if (Array.isArray(c)) c = 'DIR' - // It exists, but not how we need it - if (abs.slice(-1) === '/' && c !== 'DIR') + // It exists, but maybe not how we need it + if (!needDir || c === 'DIR') + return c + + if (needDir && c === 'FILE') return false - return c + // otherwise we have to stat, because maybe c=true + // if we know it exists, but not what it is. } var exists @@ -411,11 +439,12 @@ GlobSync.prototype._stat = function (f) { this.statCache[abs] = stat - if (abs.slice(-1) === '/' && !stat.isDirectory()) + var c = stat.isDirectory() ? 'DIR' : 'FILE' + this.cache[abs] = this.cache[abs] || c + + if (needDir && c !== 'DIR') return false - var c = stat.isDirectory() ? 'DIR' : 'FILE' - this.cache[f] = this.cache[f] || c return c } |