1 exports.alphasort = alphasort
2 exports.alphasorti = alphasorti
3 exports.setopts = setopts
4 exports.ownProp = ownProp
5 exports.makeAbs = makeAbs
6 exports.finish = finish
8 exports.isIgnored = isIgnored
9 exports.childrenIgnored = childrenIgnored
11 function ownProp (obj, field) {
12 return Object.prototype.hasOwnProperty.call(obj, field)
15 var path = require("path")
16 var minimatch = require("minimatch")
17 var isAbsolute = require("path-is-absolute")
18 var Minimatch = minimatch.Minimatch
20 function alphasorti (a, b) {
21 return a.toLowerCase().localeCompare(b.toLowerCase())
24 function alphasort (a, b) {
25 return a.localeCompare(b)
28 function setupIgnores (self, options) {
29 self.ignore = options.ignore || []
31 if (!Array.isArray(self.ignore))
32 self.ignore = [self.ignore]
34 if (self.ignore.length) {
35 self.ignore = self.ignore.map(ignoreMap)
39 function ignoreMap (pattern) {
41 if (pattern.slice(-3) === '/**') {
42 var gpattern = pattern.replace(/(\/\*\*)+$/, '')
43 gmatcher = new Minimatch(gpattern)
47 matcher: new Minimatch(pattern),
52 function setopts (self, pattern, options) {
56 // base-matching: just use globstar for that.
57 if (options.matchBase && -1 === pattern.indexOf("/")) {
58 if (options.noglobstar) {
59 throw new Error("base matching requires globstar")
61 pattern = "**/" + pattern
64 self.silent = !!options.silent
65 self.pattern = pattern
66 self.strict = options.strict !== false
67 self.realpath = !!options.realpath
68 self.realpathCache = options.realpathCache || Object.create(null)
69 self.follow = !!options.follow
70 self.dot = !!options.dot
71 self.mark = !!options.mark
72 self.nodir = !!options.nodir
75 self.sync = !!options.sync
76 self.nounique = !!options.nounique
77 self.nonull = !!options.nonull
78 self.nosort = !!options.nosort
79 self.nocase = !!options.nocase
80 self.stat = !!options.stat
81 self.noprocess = !!options.noprocess
83 self.maxLength = options.maxLength || Infinity
84 self.cache = options.cache || Object.create(null)
85 self.statCache = options.statCache || Object.create(null)
86 self.symlinks = options.symlinks || Object.create(null)
88 setupIgnores(self, options)
90 self.changedCwd = false
91 var cwd = process.cwd()
92 if (!ownProp(options, "cwd"))
95 self.cwd = options.cwd
96 self.changedCwd = path.resolve(options.cwd) !== cwd
99 self.root = options.root || path.resolve(self.cwd, "/")
100 self.root = path.resolve(self.root)
101 if (process.platform === "win32")
102 self.root = self.root.replace(/\\/g, "/")
104 self.nomount = !!options.nomount
106 // disable comments and negation unless the user explicitly
107 // passes in false as the option.
108 options.nonegate = options.nonegate === false ? false : true
109 options.nocomment = options.nocomment === false ? false : true
110 deprecationWarning(options)
112 self.minimatch = new Minimatch(pattern, options)
113 self.options = self.minimatch.options
116 // TODO(isaacs): remove entirely in v6
117 // exported to reset in tests
118 exports.deprecationWarned
119 function deprecationWarning(options) {
120 if (!options.nonegate || !options.nocomment) {
121 if (process.noDeprecation !== true && !exports.deprecationWarned) {
122 var msg = 'glob WARNING: comments and negation will be disabled in v6'
123 if (process.throwDeprecation)
125 else if (process.traceDeprecation)
130 exports.deprecationWarned = true
135 function finish (self) {
136 var nou = self.nounique
137 var all = nou ? [] : Object.create(null)
139 for (var i = 0, l = self.matches.length; i < l; i ++) {
140 var matches = self.matches[i]
141 if (!matches || Object.keys(matches).length === 0) {
143 // do like the shell, and spit out the literal glob
144 var literal = self.minimatch.globSet[i]
152 var m = Object.keys(matches)
154 all.push.apply(all, m)
156 m.forEach(function (m) {
163 all = Object.keys(all)
166 all = all.sort(self.nocase ? alphasorti : alphasort)
168 // at *some* point we statted all of these
170 for (var i = 0; i < all.length; i++) {
171 all[i] = self._mark(all[i])
174 all = all.filter(function (e) {
175 return !(/\/$/.test(e))
180 if (self.ignore.length)
181 all = all.filter(function(m) {
182 return !isIgnored(self, m)
188 function mark (self, p) {
189 var abs = makeAbs(self, p)
190 var c = self.cache[abs]
193 var isDir = c === 'DIR' || Array.isArray(c)
194 var slash = p.slice(-1) === '/'
198 else if (!isDir && slash)
202 var mabs = makeAbs(self, m)
203 self.statCache[mabs] = self.statCache[abs]
204 self.cache[mabs] = self.cache[abs]
212 function makeAbs (self, f) {
214 if (f.charAt(0) === '/') {
215 abs = path.join(self.root, f)
216 } else if (isAbsolute(f) || f === '') {
218 } else if (self.changedCwd) {
219 abs = path.resolve(self.cwd, f)
221 abs = path.resolve(f)
227 // Return true, if pattern ends with globstar '**', for the accompanying parent directory.
228 // Ex:- If node_modules/** is the pattern, add 'node_modules' to ignore list along with it's contents
229 function isIgnored (self, path) {
230 if (!self.ignore.length)
233 return self.ignore.some(function(item) {
234 return item.matcher.match(path) || !!(item.gmatcher && item.gmatcher.match(path))
238 function childrenIgnored (self, path) {
239 if (!self.ignore.length)
242 return self.ignore.some(function(item) {
243 return !!(item.gmatcher && item.gmatcher.match(path))