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/glob.js | |
parent | 4bfbaa2d8b9dc7067d999de8f55676db3a4f4196 (diff) |
glob@5.0.3
Diffstat (limited to 'node_modules/glob/glob.js')
-rw-r--r-- | node_modules/glob/glob.js | 148 |
1 files changed, 112 insertions, 36 deletions
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) } |