"Fossies" - the Fresh Open Source Software Archive

Member "Atom/resources/app/apm/node_modules/npm/node_modules/glob/sync.js" (8 Mar 2017, 11701 Bytes) of archive /windows/misc/atom-windows.zip:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Javascript source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 module.exports = globSync
    2 globSync.GlobSync = GlobSync
    3 
    4 var fs = require('fs')
    5 var rp = require('fs.realpath')
    6 var minimatch = require('minimatch')
    7 var Minimatch = minimatch.Minimatch
    8 var Glob = require('./glob.js').Glob
    9 var util = require('util')
   10 var path = require('path')
   11 var assert = require('assert')
   12 var isAbsolute = require('path-is-absolute')
   13 var common = require('./common.js')
   14 var alphasort = common.alphasort
   15 var alphasorti = common.alphasorti
   16 var setopts = common.setopts
   17 var ownProp = common.ownProp
   18 var childrenIgnored = common.childrenIgnored
   19 
   20 function globSync (pattern, options) {
   21   if (typeof options === 'function' || arguments.length === 3)
   22     throw new TypeError('callback provided to sync glob\n'+
   23                         'See: https://github.com/isaacs/node-glob/issues/167')
   24 
   25   return new GlobSync(pattern, options).found
   26 }
   27 
   28 function GlobSync (pattern, options) {
   29   if (!pattern)
   30     throw new Error('must provide pattern')
   31 
   32   if (typeof options === 'function' || arguments.length === 3)
   33     throw new TypeError('callback provided to sync glob\n'+
   34                         'See: https://github.com/isaacs/node-glob/issues/167')
   35 
   36   if (!(this instanceof GlobSync))
   37     return new GlobSync(pattern, options)
   38 
   39   setopts(this, pattern, options)
   40 
   41   if (this.noprocess)
   42     return this
   43 
   44   var n = this.minimatch.set.length
   45   this.matches = new Array(n)
   46   for (var i = 0; i < n; i ++) {
   47     this._process(this.minimatch.set[i], i, false)
   48   }
   49   this._finish()
   50 }
   51 
   52 GlobSync.prototype._finish = function () {
   53   assert(this instanceof GlobSync)
   54   if (this.realpath) {
   55     var self = this
   56     this.matches.forEach(function (matchset, index) {
   57       var set = self.matches[index] = Object.create(null)
   58       for (var p in matchset) {
   59         try {
   60           p = self._makeAbs(p)
   61           var real = rp.realpathSync(p, self.realpathCache)
   62           set[real] = true
   63         } catch (er) {
   64           if (er.syscall === 'stat')
   65             set[self._makeAbs(p)] = true
   66           else
   67             throw er
   68         }
   69       }
   70     })
   71   }
   72   common.finish(this)
   73 }
   74 
   75 
   76 GlobSync.prototype._process = function (pattern, index, inGlobStar) {
   77   assert(this instanceof GlobSync)
   78 
   79   // Get the first [n] parts of pattern that are all strings.
   80   var n = 0
   81   while (typeof pattern[n] === 'string') {
   82     n ++
   83   }
   84   // now n is the index of the first one that is *not* a string.
   85 
   86   // See if there's anything else
   87   var prefix
   88   switch (n) {
   89     // if not, then this is rather simple
   90     case pattern.length:
   91       this._processSimple(pattern.join('/'), index)
   92       return
   93 
   94     case 0:
   95       // pattern *starts* with some non-trivial item.
   96       // going to readdir(cwd), but not include the prefix in matches.
   97       prefix = null
   98       break
   99 
  100     default:
  101       // pattern has some string bits in the front.
  102       // whatever it starts with, whether that's 'absolute' like /foo/bar,
  103       // or 'relative' like '../baz'
  104       prefix = pattern.slice(0, n).join('/')
  105       break
  106   }
  107 
  108   var remain = pattern.slice(n)
  109 
  110   // get the list of entries.
  111   var read
  112   if (prefix === null)
  113     read = '.'
  114   else if (isAbsolute(prefix) || isAbsolute(pattern.join('/'))) {
  115     if (!prefix || !isAbsolute(prefix))
  116       prefix = '/' + prefix
  117     read = prefix
  118   } else
  119     read = prefix
  120 
  121   var abs = this._makeAbs(read)
  122 
  123   //if ignored, skip processing
  124   if (childrenIgnored(this, read))
  125     return
  126 
  127   var isGlobStar = remain[0] === minimatch.GLOBSTAR
  128   if (isGlobStar)
  129     this._processGlobStar(prefix, read, abs, remain, index, inGlobStar)
  130   else
  131     this._processReaddir(prefix, read, abs, remain, index, inGlobStar)
  132 }
  133 
  134 
  135 GlobSync.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar) {
  136   var entries = this._readdir(abs, inGlobStar)
  137 
  138   // if the abs isn't a dir, then nothing can match!
  139   if (!entries)
  140     return
  141 
  142   // It will only match dot entries if it starts with a dot, or if
  143   // dot is set.  Stuff like @(.foo|.bar) isn't allowed.
  144   var pn = remain[0]
  145   var negate = !!this.minimatch.negate
  146   var rawGlob = pn._glob
  147   var dotOk = this.dot || rawGlob.charAt(0) === '.'
  148 
  149   var matchedEntries = []
  150   for (var i = 0; i < entries.length; i++) {
  151     var e = entries[i]
  152     if (e.charAt(0) !== '.' || dotOk) {
  153       var m
  154       if (negate && !prefix) {
  155         m = !e.match(pn)
  156       } else {
  157         m = e.match(pn)
  158       }
  159       if (m)
  160         matchedEntries.push(e)
  161     }
  162   }
  163 
  164   var len = matchedEntries.length
  165   // If there are no matched entries, then nothing matches.
  166   if (len === 0)
  167     return
  168 
  169   // if this is the last remaining pattern bit, then no need for
  170   // an additional stat *unless* the user has specified mark or
  171   // stat explicitly.  We know they exist, since readdir returned
  172   // them.
  173 
  174   if (remain.length === 1 && !this.mark && !this.stat) {
  175     if (!this.matches[index])
  176       this.matches[index] = Object.create(null)
  177 
  178     for (var i = 0; i < len; i ++) {
  179       var e = matchedEntries[i]
  180       if (prefix) {
  181         if (prefix.slice(-1) !== '/')
  182           e = prefix + '/' + e
  183         else
  184           e = prefix + e
  185       }
  186 
  187       if (e.charAt(0) === '/' && !this.nomount) {
  188         e = path.join(this.root, e)
  189       }
  190       this.matches[index][e] = true
  191     }
  192     // This was the last one, and no stats were needed
  193     return
  194   }
  195 
  196   // now test all matched entries as stand-ins for that part
  197   // of the pattern.
  198   remain.shift()
  199   for (var i = 0; i < len; i ++) {
  200     var e = matchedEntries[i]
  201     var newPattern
  202     if (prefix)
  203       newPattern = [prefix, e]
  204     else
  205       newPattern = [e]
  206     this._process(newPattern.concat(remain), index, inGlobStar)
  207   }
  208 }
  209 
  210 
  211 GlobSync.prototype._emitMatch = function (index, e) {
  212   var abs = this._makeAbs(e)
  213   if (this.mark)
  214     e = this._mark(e)
  215 
  216   if (this.matches[index][e])
  217     return
  218 
  219   if (this.nodir) {
  220     var c = this.cache[this._makeAbs(e)]
  221     if (c === 'DIR' || Array.isArray(c))
  222       return
  223   }
  224 
  225   this.matches[index][e] = true
  226   if (this.stat)
  227     this._stat(e)
  228 }
  229 
  230 
  231 GlobSync.prototype._readdirInGlobStar = function (abs) {
  232   // follow all symlinked directories forever
  233   // just proceed as if this is a non-globstar situation
  234   if (this.follow)
  235     return this._readdir(abs, false)
  236 
  237   var entries
  238   var lstat
  239   var stat
  240   try {
  241     lstat = fs.lstatSync(abs)
  242   } catch (er) {
  243     // lstat failed, doesn't exist
  244     return null
  245   }
  246 
  247   var isSym = lstat.isSymbolicLink()
  248   this.symlinks[abs] = isSym
  249 
  250   // If it's not a symlink or a dir, then it's definitely a regular file.
  251   // don't bother doing a readdir in that case.
  252   if (!isSym && !lstat.isDirectory())
  253     this.cache[abs] = 'FILE'
  254   else
  255     entries = this._readdir(abs, false)
  256 
  257   return entries
  258 }
  259 
  260 GlobSync.prototype._readdir = function (abs, inGlobStar) {
  261   var entries
  262 
  263   if (inGlobStar && !ownProp(this.symlinks, abs))
  264     return this._readdirInGlobStar(abs)
  265 
  266   if (ownProp(this.cache, abs)) {
  267     var c = this.cache[abs]
  268     if (!c || c === 'FILE')
  269       return null
  270 
  271     if (Array.isArray(c))
  272       return c
  273   }
  274 
  275   try {
  276     return this._readdirEntries(abs, fs.readdirSync(abs))
  277   } catch (er) {
  278     this._readdirError(abs, er)
  279     return null
  280   }
  281 }
  282 
  283 GlobSync.prototype._readdirEntries = function (abs, entries) {
  284   // if we haven't asked to stat everything, then just
  285   // assume that everything in there exists, so we can avoid
  286   // having to stat it a second time.
  287   if (!this.mark && !this.stat) {
  288     for (var i = 0; i < entries.length; i ++) {
  289       var e = entries[i]
  290       if (abs === '/')
  291         e = abs + e
  292       else
  293         e = abs + '/' + e
  294       this.cache[e] = true
  295     }
  296   }
  297 
  298   this.cache[abs] = entries
  299 
  300   // mark and cache dir-ness
  301   return entries
  302 }
  303 
  304 GlobSync.prototype._readdirError = function (f, er) {
  305   // handle errors, and cache the information
  306   switch (er.code) {
  307     case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205
  308     case 'ENOTDIR': // totally normal. means it *does* exist.
  309       var abs = this._makeAbs(f)
  310       this.cache[abs] = 'FILE'
  311       if (abs === this.cwdAbs) {
  312         var error = new Error(er.code + ' invalid cwd ' + this.cwd)
  313         error.path = this.cwd
  314         error.code = er.code
  315         throw error
  316       }
  317       break
  318 
  319     case 'ENOENT': // not terribly unusual
  320     case 'ELOOP':
  321     case 'ENAMETOOLONG':
  322     case 'UNKNOWN':
  323       this.cache[this._makeAbs(f)] = false
  324       break
  325 
  326     default: // some unusual error.  Treat as failure.
  327       this.cache[this._makeAbs(f)] = false
  328       if (this.strict)
  329         throw er
  330       if (!this.silent)
  331         console.error('glob error', er)
  332       break
  333   }
  334 }
  335 
  336 GlobSync.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar) {
  337 
  338   var entries = this._readdir(abs, inGlobStar)
  339 
  340   // no entries means not a dir, so it can never have matches
  341   // foo.txt/** doesn't match foo.txt
  342   if (!entries)
  343     return
  344 
  345   // test without the globstar, and with every child both below
  346   // and replacing the globstar.
  347   var remainWithoutGlobStar = remain.slice(1)
  348   var gspref = prefix ? [ prefix ] : []
  349   var noGlobStar = gspref.concat(remainWithoutGlobStar)
  350 
  351   // the noGlobStar pattern exits the inGlobStar state
  352   this._process(noGlobStar, index, false)
  353 
  354   var len = entries.length
  355   var isSym = this.symlinks[abs]
  356 
  357   // If it's a symlink, and we're in a globstar, then stop
  358   if (isSym && inGlobStar)
  359     return
  360 
  361   for (var i = 0; i < len; i++) {
  362     var e = entries[i]
  363     if (e.charAt(0) === '.' && !this.dot)
  364       continue
  365 
  366     // these two cases enter the inGlobStar state
  367     var instead = gspref.concat(entries[i], remainWithoutGlobStar)
  368     this._process(instead, index, true)
  369 
  370     var below = gspref.concat(entries[i], remain)
  371     this._process(below, index, true)
  372   }
  373 }
  374 
  375 GlobSync.prototype._processSimple = function (prefix, index) {
  376   // XXX review this.  Shouldn't it be doing the mounting etc
  377   // before doing stat?  kinda weird?
  378   var exists = this._stat(prefix)
  379 
  380   if (!this.matches[index])
  381     this.matches[index] = Object.create(null)
  382 
  383   // If it doesn't exist, then just mark the lack of results
  384   if (!exists)
  385     return
  386 
  387   if (prefix && isAbsolute(prefix) && !this.nomount) {
  388     var trail = /[\/\\]$/.test(prefix)
  389     if (prefix.charAt(0) === '/') {
  390       prefix = path.join(this.root, prefix)
  391     } else {
  392       prefix = path.resolve(this.root, prefix)
  393       if (trail)
  394         prefix += '/'
  395     }
  396   }
  397 
  398   if (process.platform === 'win32')
  399     prefix = prefix.replace(/\\/g, '/')
  400 
  401   // Mark this as a match
  402   this.matches[index][prefix] = true
  403 }
  404 
  405 // Returns either 'DIR', 'FILE', or false
  406 GlobSync.prototype._stat = function (f) {
  407   var abs = this._makeAbs(f)
  408   var needDir = f.slice(-1) === '/'
  409 
  410   if (f.length > this.maxLength)
  411     return false
  412 
  413   if (!this.stat && ownProp(this.cache, abs)) {
  414     var c = this.cache[abs]
  415 
  416     if (Array.isArray(c))
  417       c = 'DIR'
  418 
  419     // It exists, but maybe not how we need it
  420     if (!needDir || c === 'DIR')
  421       return c
  422 
  423     if (needDir && c === 'FILE')
  424       return false
  425 
  426     // otherwise we have to stat, because maybe c=true
  427     // if we know it exists, but not what it is.
  428   }
  429 
  430   var exists
  431   var stat = this.statCache[abs]
  432   if (!stat) {
  433     var lstat
  434     try {
  435       lstat = fs.lstatSync(abs)
  436     } catch (er) {
  437       return false
  438     }
  439 
  440     if (lstat.isSymbolicLink()) {
  441       try {
  442         stat = fs.statSync(abs)
  443       } catch (er) {
  444         stat = lstat
  445       }
  446     } else {
  447       stat = lstat
  448     }
  449   }
  450 
  451   this.statCache[abs] = stat
  452 
  453   var c = stat.isDirectory() ? 'DIR' : 'FILE'
  454   this.cache[abs] = this.cache[abs] || c
  455 
  456   if (needDir && c !== 'DIR')
  457     return false
  458 
  459   return c
  460 }
  461 
  462 GlobSync.prototype._mark = function (p) {
  463   return common.mark(this, p)
  464 }
  465 
  466 GlobSync.prototype._makeAbs = function (f) {
  467   return common.makeAbs(this, f)
  468 }