Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/npm/cli.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorisaacs <i@izs.me>2013-04-29 19:57:26 +0400
committerisaacs <i@izs.me>2013-04-29 19:58:36 +0400
commitcc05907323b88e965d0f95f2389f2f7dcb9e98d2 (patch)
treea54218be49a8e8cee1963a16cc0f7b1049dbf284 /node_modules/glob/glob.js
parent62347d400ee78c1f1274f2489a42d6eb7a1a7827 (diff)
glob@3.2.1
Diffstat (limited to 'node_modules/glob/glob.js')
-rw-r--r--node_modules/glob/glob.js98
1 files changed, 65 insertions, 33 deletions
diff --git a/node_modules/glob/glob.js b/node_modules/glob/glob.js
index 891c88360..f0118a4f4 100644
--- a/node_modules/glob/glob.js
+++ b/node_modules/glob/glob.js
@@ -98,6 +98,7 @@ function Glob (pattern, options, cb) {
this.maxDepth = options.maxDepth || 1000
this.maxLength = options.maxLength || Infinity
+ this.cache = options.cache || {}
this.statCache = options.statCache || {}
this.changedCwd = false
@@ -150,6 +151,10 @@ function Glob (pattern, options, cb) {
this.error = null
this.aborted = false
+ // list of all the patterns that ** has resolved do, so
+ // we can avoid visiting multiple times.
+ this._globstars = {}
+
EE.call(this)
// process each pattern in the minimatch set
@@ -207,7 +212,7 @@ Glob.prototype._finish = function () {
if (this.mark) {
// at *some* point we statted all of these
all = all.map(function (m) {
- var sc = this.statCache[m]
+ var sc = this.cache[m]
if (!sc)
return m
var isDir = (Array.isArray(sc) || sc === 2)
@@ -261,8 +266,17 @@ Glob.prototype.resume = function () {
}
Glob.prototype.emitMatch = function (m) {
- this._emitQueue.push(m)
- this._processEmitQueue()
+ if (!this.stat || this.statCache[m] || m === this.EOF) {
+ this._emitQueue.push(m)
+ this._processEmitQueue()
+ } else {
+ this._stat(m, function(exists, isDir) {
+ if (exists) {
+ this._emitQueue.push(m)
+ this._processEmitQueue()
+ }
+ })
+ }
}
Glob.prototype._processEmitQueue = function (m) {
@@ -324,11 +338,11 @@ Glob.prototype._process = function (pattern, depth, index, cb_) {
// nothing more to do, either way.
if (exists) {
if (prefix && isAbsolute(prefix) && !this.nomount) {
- if (prefix.charAt(0) === "/") {
+ if (prefix.charAt(0) === "/") {
prefix = path.join(this.root, prefix)
- } else {
- prefix = path.resolve(this.root, prefix)
- }
+ } else {
+ prefix = path.resolve(this.root, prefix)
+ }
}
if (process.platform === "win32")
@@ -396,6 +410,16 @@ Glob.prototype._process = function (pattern, depth, index, cb_) {
s.push(pattern.slice(0, n).concat(e).concat(pattern.slice(n)))
}, this)
+ s = s.filter(function (pattern) {
+ var key = gsKey(pattern)
+ var seen = !this._globstars[key]
+ this._globstars[key] = true
+ return seen
+ }, this)
+
+ if (!s.length)
+ return cb()
+
// now asyncForEach over this
var l = s.length
, errState = null
@@ -414,19 +438,13 @@ Glob.prototype._process = function (pattern, depth, index, cb_) {
// 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) === "."
+ var rawGlob = pattern[n]._glob
+ , dotOk = this.dot || rawGlob.charAt(0) === "."
- entries = entries.filter(function (e) {
- return (e.charAt(0) !== "." || dotOk) &&
- (typeof pattern[n] === "string" && e === pattern[n] ||
- e.match(pattern[n]))
- })
- }
+ entries = entries.filter(function (e) {
+ return (e.charAt(0) !== "." || dotOk) &&
+ e.match(pattern[n])
+ })
// If n === pattern.length - 1, then there's no need for the extra stat
// *unless* the user has specified "mark" or "stat" explicitly.
@@ -471,6 +489,12 @@ Glob.prototype._process = function (pattern, depth, index, cb_) {
}
+function gsKey (pattern) {
+ return '**' + pattern.map(function (p) {
+ return (p === minimatch.GLOBSTAR) ? '**' : (''+p)
+ }).join('/')
+}
+
Glob.prototype._stat = function (f, cb) {
assert(this instanceof Glob)
var abs = f
@@ -479,7 +503,7 @@ Glob.prototype._stat = function (f, cb) {
} else if (this.changedCwd) {
abs = path.resolve(this.cwd, f)
}
- this.log('stat', [this.cwd, f, '=', abs])
+
if (f.length > this.maxLength) {
var er = new Error("Path name too long")
er.code = "ENAMETOOLONG"
@@ -487,15 +511,18 @@ Glob.prototype._stat = function (f, cb) {
return this._afterStat(f, abs, cb, er)
}
- if (this.statCache.hasOwnProperty(f)) {
- var exists = this.statCache[f]
+ this.log('stat', [this.cwd, f, '=', abs])
+
+ if (!this.stat && this.cache.hasOwnProperty(f)) {
+ var exists = this.cache[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
+ var stat = this.statCache[abs]
+ if (this.sync || stat) {
+ var er
try {
stat = fs.statSync(abs)
} catch (e) {
@@ -520,12 +547,17 @@ Glob.prototype._afterStat = function (f, abs, cb, er, stat) {
stat = null
}
+ var emit = !this.statCache[abs]
+ this.statCache[abs] = stat
+
if (er || !stat) {
exists = false
} else {
exists = stat.isDirectory() ? 2 : 1
+ if (emit)
+ this.emit('stat', f, stat)
}
- this.statCache[f] = this.statCache[f] || exists
+ this.cache[f] = this.cache[f] || exists
cb.call(this, !!exists, exists === 2)
}
@@ -540,7 +572,6 @@ Glob.prototype._readdir = function (f, cb) {
abs = path.resolve(this.cwd, f)
}
- this.log('readdir', [this.cwd, f, abs])
if (f.length > this.maxLength) {
var er = new Error("Path name too long")
er.code = "ENAMETOOLONG"
@@ -548,8 +579,9 @@ Glob.prototype._readdir = function (f, cb) {
return this._afterReaddir(f, abs, cb, er)
}
- if (this.statCache.hasOwnProperty(f)) {
- var c = this.statCache[f]
+ this.log('readdir', [this.cwd, f, abs])
+ if (this.cache.hasOwnProperty(f)) {
+ var c = this.cache[f]
if (Array.isArray(c)) {
if (this.sync) return cb.call(this, null, c)
return process.nextTick(cb.bind(this, null, c))
@@ -587,7 +619,7 @@ Glob.prototype._readdir = function (f, cb) {
Glob.prototype._afterReaddir = function (f, abs, cb, er, entries) {
assert(this instanceof Glob)
if (entries && !er) {
- this.statCache[f] = entries
+ this.cache[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
@@ -596,7 +628,7 @@ Glob.prototype._afterReaddir = function (f, abs, cb, er, entries) {
entries.forEach(function (e) {
if (f === "/") e = f + e
else e = f + "/" + e
- this.statCache[e] = true
+ this.cache[e] = true
}, this)
}
@@ -606,16 +638,16 @@ Glob.prototype._afterReaddir = function (f, abs, cb, 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
+ this.cache[f] = 1
return cb.call(this, er)
case "ENOENT": // not terribly unusual
case "ELOOP":
case "ENAMETOOLONG":
case "UNKNOWN":
- this.statCache[f] = false
+ this.cache[f] = false
return cb.call(this, er)
default: // some unusual error. Treat as failure.
- this.statCache[f] = false
+ this.cache[f] = false
if (this.strict) this.emit("error", er)
if (!this.silent) console.error("glob error", er)
return cb.call(this, er)