Comparing version 3.1.2 to 3.1.3
171
glob.js
@@ -46,2 +46,3 @@ // Approach: | ||
, isDir = {} | ||
, assert = require("assert") | ||
@@ -57,9 +58,4 @@ function glob (pattern, options, cb) { | ||
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 | ||
} | ||
@@ -103,10 +99,16 @@ | ||
if (!options.hasOwnProperty("maxDepth")) options.maxDepth = 1000 | ||
if (!options.hasOwnProperty("maxLength")) options.maxLength = Infinity | ||
if (!options.hasOwnProperty("statCache")) options.statCache = {} | ||
if (!options.hasOwnProperty("cwd")) options.cwd = process.cwd() | ||
if (!options.hasOwnProperty("root")) { | ||
options.root = path.resolve(options.cwd, "/") | ||
this.maxDepth = options.maxDepth || 1000 | ||
this.maxLength = options.maxLength || Infinity | ||
this.statCache = options.statCache || {} | ||
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 || path.resolve(this.cwd, "/") | ||
if (!pattern) { | ||
@@ -124,4 +126,15 @@ throw new Error("must provide 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 | ||
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 | ||
@@ -153,4 +166,5 @@ | ||
Glob.prototype._finish = function () { | ||
assert(this instanceof Glob) | ||
var nou = this.options.nounique | ||
var nou = this.nounique | ||
, all = nou ? [] : {} | ||
@@ -160,6 +174,6 @@ | ||
var matches = this.matches[i] | ||
// console.error("matches[%d] =", i, matches) | ||
if (this.debug) console.error("matches[%d] =", i, matches) | ||
// do like the shell, and spit out the literal glob | ||
if (!matches) { | ||
if (this.options.nonull) { | ||
if (this.nonull) { | ||
var literal = this.minimatch.globSet[i] | ||
@@ -181,7 +195,7 @@ if (nou) all.push(literal) | ||
if (!this.options.nosort) { | ||
all = all.sort(this.options.nocase ? alphasorti : alphasort) | ||
if (!this.nosort) { | ||
all = all.sort(this.nocase ? alphasorti : alphasort) | ||
} | ||
if (this.options.mark) { | ||
if (this.mark) { | ||
// at *some* point we statted all of these | ||
@@ -201,3 +215,3 @@ all = all.map(function (m) { | ||
// console.error("emitting end", all) | ||
if (this.debug) console.error("emitting end", all) | ||
@@ -218,4 +232,3 @@ this.found = all | ||
Glob.prototype.abort = abort | ||
function abort () { | ||
Glob.prototype.abort = function () { | ||
this.aborted = true | ||
@@ -226,8 +239,8 @@ this.emit("abort") | ||
Glob.prototype._process = _process | ||
function _process (pattern, depth, index, cb) { | ||
Glob.prototype._process = function (pattern, depth, index, cb) { | ||
assert(this instanceof Glob) | ||
cb = cb.bind(this) | ||
if (this.aborted) return cb() | ||
if (depth > this.options.maxDepth) return cb() | ||
if (depth > this.maxDepth) return cb() | ||
@@ -242,6 +255,7 @@ // Get the first [n] parts of pattern that are all strings. | ||
// see if there's anything else | ||
var prefix | ||
switch (n) { | ||
// if not, then this is rather simple | ||
case pattern.length: | ||
var prefix = pattern.join("/") | ||
prefix = pattern.join("/") | ||
this._stat(prefix, function (exists, isDir) { | ||
@@ -262,3 +276,3 @@ // either it's there, or it isn't. | ||
// going to readdir(cwd), but not include the prefix in matches. | ||
var prefix = null | ||
prefix = null | ||
break | ||
@@ -270,5 +284,5 @@ | ||
// or "relative" like "../baz" | ||
var prefix = pattern.slice(0, n) | ||
prefix = pattern.slice(0, n) | ||
prefix = prefix.join("/") | ||
// console.error("prefix=%s", prefix) | ||
if (this.debug) console.error("prefix=%s", prefix) | ||
break | ||
@@ -279,7 +293,6 @@ } | ||
if (prefix !== null && (prefix.charAt(0) === "/" || prefix === "")) { | ||
prefix = path.join(this.options.root, prefix) | ||
prefix = path.join(this.root, prefix) | ||
} | ||
var read = prefix || this.options.cwd | ||
return this._readdir(prefix || process.cwd(), function (er, entries) { | ||
// console.error("back from readdir", prefix || process.cwd(), er, entries) | ||
var read = prefix || this.cwd | ||
return this._readdir(read, function (er, entries) { | ||
if (er) { | ||
@@ -293,4 +306,2 @@ // not a directory! | ||
if (pattern[n] === minimatch.GLOBSTAR) { | ||
// console.error("globstar!", pattern, n) | ||
// console.error("entries", prefix, entries) | ||
// test without the globstar, and with every child both below | ||
@@ -300,3 +311,3 @@ // and replacing the globstar. | ||
entries.forEach(function (e) { | ||
if (e.charAt(0) === "." && !this.options.dot) return | ||
if (e.charAt(0) === "." && !this.dot) return | ||
// instead of the globstar | ||
@@ -324,3 +335,3 @@ s.push(pattern.slice(0, n).concat(e).concat(pattern.slice(n + 1))) | ||
// It will only match dot entries if it starts with a dot, or if | ||
// options.dot is set. Stuff like @(.foo|.bar) isn't allowed. | ||
// dot is set. Stuff like @(.foo|.bar) isn't allowed. | ||
var pn = pattern[n] | ||
@@ -332,5 +343,4 @@ if (typeof pn === "string") { | ||
var rawGlob = pattern[n]._glob | ||
, dotOk = this.options.dot || rawGlob.charAt(0) === "." | ||
, dotOk = this.dot || rawGlob.charAt(0) === "." | ||
// console.error("pattern", pattern, n, pattern[n]) | ||
entries = entries.filter(function (e) { | ||
@@ -347,4 +357,4 @@ return (e.charAt(0) !== "." || dotOk) && | ||
if (n === pattern.length - 1 && | ||
!this.options.mark && | ||
!this.options.stat) { | ||
!this.mark && | ||
!this.stat) { | ||
entries.forEach(function (e) { | ||
@@ -363,5 +373,2 @@ if (prefix) { | ||
// console.error("entries", prefix, entries) | ||
// now test all the remaining entries as stand-ins for that part | ||
@@ -374,5 +381,3 @@ // of the pattern. | ||
var p = pattern.slice(0, n).concat(e).concat(pattern.slice(n + 1)) | ||
// console.error("new pattern!", p) | ||
this._process(p, depth + 1, index, function (er) { | ||
// console.error("Back from processing", this.matches) | ||
if (errState) return | ||
@@ -388,30 +393,34 @@ if (er) return cb(errState = er) | ||
Glob.prototype._stat = function (f, cb) { | ||
if (f.length > this.options.maxLength) { | ||
assert(this instanceof Glob) | ||
var abs = this.changedCwd ? path.resolve(this.cwd, f) : f | ||
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, cb, er) | ||
return this._afterStat(f, abs, cb, er) | ||
} | ||
if (this.options.statCache.hasOwnProperty(f)) { | ||
var exists = this.options.statCache[f] | ||
if (this.statCache.hasOwnProperty(f)) { | ||
var exists = this.statCache[f] | ||
, isDir = exists && (Array.isArray(exists) || exists === 2) | ||
if (this.options.sync) return cb.call(this, !!exists, isDir) | ||
if (this.sync) return cb.call(this, !!exists, isDir) | ||
return process.nextTick(cb.bind(this, !!exists, isDir)) | ||
} | ||
if (this.options.sync) { | ||
if (this.sync) { | ||
var er, stat | ||
try { | ||
stat = fs.statSync(f) | ||
stat = fs.statSync(abs) | ||
} catch (e) { | ||
er = e | ||
} | ||
this._afterStat(f, cb, er, stat) | ||
this._afterStat(f, abs, cb, er, stat) | ||
} else { | ||
fs.stat(f, this._afterStat.bind(this, f, cb)) | ||
fs.stat(abs, this._afterStat.bind(this, f, abs, cb)) | ||
} | ||
} | ||
Glob.prototype._afterStat = function (f, cb, er, stat) { | ||
Glob.prototype._afterStat = function (f, abs, cb, er, stat) { | ||
assert(this instanceof Glob) | ||
if (er || !stat) { | ||
@@ -422,3 +431,3 @@ exists = false | ||
} | ||
this.options.statCache[f] = this.options.statCache[f] || exists | ||
this.statCache[f] = this.statCache[f] || exists | ||
cb.call(this, !!exists, exists === 2) | ||
@@ -428,13 +437,16 @@ } | ||
Glob.prototype._readdir = function (f, cb) { | ||
if (f.length > this.options.maxLength) { | ||
assert(this instanceof Glob) | ||
var abs = this.changedCwd ? path.resolve(this.cwd, f) : 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, cb, er) | ||
return this._afterReaddir(f, abs, cb, er) | ||
} | ||
if (this.options.statCache.hasOwnProperty(f)) { | ||
var c = this.options.statCache[f] | ||
if (this.statCache.hasOwnProperty(f)) { | ||
var c = this.statCache[f] | ||
if (Array.isArray(c)) { | ||
if (this.options.sync) return cb.call(this, null, c) | ||
if (this.sync) return cb.call(this, null, c) | ||
return process.nextTick(cb.bind(this, null, c)) | ||
@@ -445,3 +457,2 @@ } | ||
// either ENOENT or ENOTDIR | ||
// console.error("enoent or enotdir?") | ||
var code = c ? "ENOTDIR" : "ENOENT" | ||
@@ -451,4 +462,4 @@ , er = new Error((c ? "Not a directory" : "Not found") + ": " + f) | ||
er.code = code | ||
// console.error(f, er) | ||
if (this.options.sync) return cb.call(this, er) | ||
if (this.debug) console.error(f, er) | ||
if (this.sync) return cb.call(this, er) | ||
return process.nextTick(cb.bind(this, er)) | ||
@@ -462,19 +473,19 @@ } | ||
if (this.options.sync) { | ||
if (this.sync) { | ||
var er, entries | ||
try { | ||
entries = fs.readdirSync(f) | ||
entries = fs.readdirSync(abs) | ||
} catch (e) { | ||
er = e | ||
} | ||
return this._afterReaddir(f, cb, er, entries) | ||
return this._afterReaddir(f, abs, cb, er, entries) | ||
} | ||
fs.readdir(f, this._afterReaddir.bind(this, f, cb)) | ||
fs.readdir(abs, this._afterReaddir.bind(this, f, abs, cb)) | ||
} | ||
Glob.prototype._afterReaddir = function (f, cb, er, entries) { | ||
Glob.prototype._afterReaddir = function (f, abs, cb, er, entries) { | ||
assert(this instanceof Glob) | ||
if (entries && !er) { | ||
// console.error("has entries, and no er", f, er, entries) | ||
this.options.statCache[f] = entries | ||
this.statCache[f] = entries | ||
// if we haven't asked to stat everything for suresies, then just | ||
@@ -484,7 +495,7 @@ // assume that everything in there exists, so we can avoid | ||
// further into ELOOP territory. | ||
if (!this.options.mark && !this.options.stat) { | ||
if (!this.mark && !this.stat) { | ||
entries.forEach(function (e) { | ||
if (f === "/") e = f + e | ||
else e = f + "/" + e | ||
this.options.statCache[e] = true | ||
this.statCache[e] = true | ||
}, this) | ||
@@ -499,3 +510,3 @@ } | ||
case "ENOTDIR": // totally normal. means it *does* exist. | ||
this.options.statCache[f] = 1 | ||
this.statCache[f] = 1 | ||
return cb.call(this, er) | ||
@@ -506,10 +517,10 @@ case "ENOENT": // not terribly unusual | ||
case "UNKNOWN": | ||
this.options.statCache[f] = false | ||
this.statCache[f] = false | ||
return cb.call(this, er) | ||
default: // some unusual error. Treat as failure. | ||
this.options.statCache[f] = false | ||
if (this.options.strict) this.emit("error", er) | ||
if (!this.options.silent) console.error("glob error", er) | ||
this.statCache[f] = false | ||
if (this.strict) this.emit("error", er) | ||
if (!this.silent) console.error("glob error", er) | ||
return cb.call(this, er) | ||
} | ||
} |
@@ -5,3 +5,3 @@ { | ||
"description": "a little globber", | ||
"version": "3.1.2", | ||
"version": "3.1.3", | ||
"repository": { | ||
@@ -8,0 +8,0 @@ "type": "git", |
24670
11
654