123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238 |
- exports.setopts = setopts
- exports.ownProp = ownProp
- exports.makeAbs = makeAbs
- exports.finish = finish
- exports.mark = mark
- exports.isIgnored = isIgnored
- exports.childrenIgnored = childrenIgnored
-
- function ownProp (obj, field) {
- return Object.prototype.hasOwnProperty.call(obj, field)
- }
-
- var fs = require("fs")
- var path = require("path")
- var minimatch = require("minimatch")
- var isAbsolute = require("path-is-absolute")
- var Minimatch = minimatch.Minimatch
-
- function alphasort (a, b) {
- return a.localeCompare(b, 'en')
- }
-
- function setupIgnores (self, options) {
- self.ignore = options.ignore || []
-
- if (!Array.isArray(self.ignore))
- self.ignore = [self.ignore]
-
- if (self.ignore.length) {
- self.ignore = self.ignore.map(ignoreMap)
- }
- }
-
- // ignore patterns are always in dot:true mode.
- function ignoreMap (pattern) {
- var gmatcher = null
- if (pattern.slice(-3) === '/**') {
- var gpattern = pattern.replace(/(\/\*\*)+$/, '')
- gmatcher = new Minimatch(gpattern, { dot: true })
- }
-
- return {
- matcher: new Minimatch(pattern, { dot: true }),
- gmatcher: gmatcher
- }
- }
-
- function setopts (self, pattern, options) {
- if (!options)
- options = {}
-
- // base-matching: just use globstar for that.
- if (options.matchBase && -1 === pattern.indexOf("/")) {
- if (options.noglobstar) {
- throw new Error("base matching requires globstar")
- }
- pattern = "**/" + pattern
- }
-
- self.silent = !!options.silent
- 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
- if (self.nodir)
- self.mark = true
- self.sync = !!options.sync
- self.nounique = !!options.nounique
- self.nonull = !!options.nonull
- self.nosort = !!options.nosort
- self.nocase = !!options.nocase
- self.stat = !!options.stat
- self.noprocess = !!options.noprocess
- self.absolute = !!options.absolute
- self.fs = options.fs || fs
-
- self.maxLength = options.maxLength || Infinity
- self.cache = options.cache || Object.create(null)
- self.statCache = options.statCache || Object.create(null)
- self.symlinks = options.symlinks || Object.create(null)
-
- setupIgnores(self, options)
-
- self.changedCwd = false
- var cwd = process.cwd()
- if (!ownProp(options, "cwd"))
- self.cwd = cwd
- else {
- self.cwd = path.resolve(options.cwd)
- self.changedCwd = self.cwd !== cwd
- }
-
- self.root = options.root || path.resolve(self.cwd, "/")
- self.root = path.resolve(self.root)
- if (process.platform === "win32")
- self.root = self.root.replace(/\\/g, "/")
-
- // TODO: is an absolute `cwd` supposed to be resolved against `root`?
- // e.g. { cwd: '/test', root: __dirname } === path.join(__dirname, '/test')
- self.cwdAbs = isAbsolute(self.cwd) ? self.cwd : makeAbs(self, self.cwd)
- if (process.platform === "win32")
- self.cwdAbs = self.cwdAbs.replace(/\\/g, "/")
- self.nomount = !!options.nomount
-
- // disable comments and negation in Minimatch.
- // Note that they are not supported in Glob itself anyway.
- options.nonegate = true
- options.nocomment = true
- // always treat \ in patterns as escapes, not path separators
- options.allowWindowsEscape = false
-
- self.minimatch = new Minimatch(pattern, options)
- self.options = self.minimatch.options
- }
-
- 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 || Object.keys(matches).length === 0) {
- if (self.nonull) {
- // do like the shell, and spit out the literal glob
- var literal = self.minimatch.globSet[i]
- if (nou)
- all.push(literal)
- else
- all[literal] = true
- }
- } else {
- // had matches
- var m = Object.keys(matches)
- if (nou)
- all.push.apply(all, m)
- else
- m.forEach(function (m) {
- all[m] = true
- })
- }
- }
-
- if (!nou)
- all = Object.keys(all)
-
- if (!self.nosort)
- all = all.sort(alphasort)
-
- // at *some* point we statted all of these
- if (self.mark) {
- for (var i = 0; i < all.length; i++) {
- all[i] = self._mark(all[i])
- }
- if (self.nodir) {
- all = all.filter(function (e) {
- var notDir = !(/\/$/.test(e))
- var c = self.cache[e] || self.cache[makeAbs(self, e)]
- if (notDir && c)
- notDir = c !== 'DIR' && !Array.isArray(c)
- return notDir
- })
- }
- }
-
- if (self.ignore.length)
- all = all.filter(function(m) {
- return !isIgnored(self, m)
- })
-
- self.found = all
- }
-
- function mark (self, p) {
- var abs = makeAbs(self, p)
- var c = self.cache[abs]
- var m = p
- if (c) {
- var isDir = c === 'DIR' || Array.isArray(c)
- var slash = p.slice(-1) === '/'
-
- if (isDir && !slash)
- m += '/'
- else if (!isDir && slash)
- m = m.slice(0, -1)
-
- if (m !== p) {
- var mabs = makeAbs(self, m)
- self.statCache[mabs] = self.statCache[abs]
- self.cache[mabs] = self.cache[abs]
- }
- }
-
- return m
- }
-
- // lotta situps...
- function makeAbs (self, f) {
- var abs = f
- if (f.charAt(0) === '/') {
- abs = path.join(self.root, f)
- } else if (isAbsolute(f) || f === '') {
- abs = f
- } else if (self.changedCwd) {
- abs = path.resolve(self.cwd, f)
- } else {
- abs = path.resolve(f)
- }
-
- if (process.platform === 'win32')
- abs = abs.replace(/\\/g, '/')
-
- return abs
- }
-
-
- // Return true, if pattern ends with globstar '**', for the accompanying parent directory.
- // Ex:- If node_modules/** is the pattern, add 'node_modules' to ignore list along with it's contents
- function isIgnored (self, path) {
- if (!self.ignore.length)
- return false
-
- return self.ignore.some(function(item) {
- return item.matcher.match(path) || !!(item.gmatcher && item.gmatcher.match(path))
- })
- }
-
- function childrenIgnored (self, path) {
- if (!self.ignore.length)
- return false
-
- return self.ignore.some(function(item) {
- return !!(item.gmatcher && item.gmatcher.match(path))
- })
- }
|