Permalink
Cannot retrieve contributors at this time
483 lines (393 sloc)
11.7 KB
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
codeql-action/node_modules/rimraf/node_modules/glob/sync.js
Go to fileThis commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module.exports = globSync | |
globSync.GlobSync = GlobSync | |
var rp = require('fs.realpath') | |
var minimatch = require('minimatch') | |
var Minimatch = minimatch.Minimatch | |
var Glob = require('./glob.js').Glob | |
var util = require('util') | |
var path = require('path') | |
var assert = require('assert') | |
var isAbsolute = require('path-is-absolute') | |
var common = require('./common.js') | |
var setopts = common.setopts | |
var ownProp = common.ownProp | |
var childrenIgnored = common.childrenIgnored | |
var isIgnored = common.isIgnored | |
function globSync (pattern, options) { | |
if (typeof options === 'function' || arguments.length === 3) | |
throw new TypeError('callback provided to sync glob\n'+ | |
'See: https://github.com/isaacs/node-glob/issues/167') | |
return new GlobSync(pattern, options).found | |
} | |
function GlobSync (pattern, options) { | |
if (!pattern) | |
throw new Error('must provide pattern') | |
if (typeof options === 'function' || arguments.length === 3) | |
throw new TypeError('callback provided to sync glob\n'+ | |
'See: https://github.com/isaacs/node-glob/issues/167') | |
if (!(this instanceof GlobSync)) | |
return new GlobSync(pattern, options) | |
setopts(this, pattern, options) | |
if (this.noprocess) | |
return this | |
var n = this.minimatch.set.length | |
this.matches = new Array(n) | |
for (var i = 0; i < n; i ++) { | |
this._process(this.minimatch.set[i], i, false) | |
} | |
this._finish() | |
} | |
GlobSync.prototype._finish = function () { | |
assert(this instanceof GlobSync) | |
if (this.realpath) { | |
var self = this | |
this.matches.forEach(function (matchset, index) { | |
var set = self.matches[index] = Object.create(null) | |
for (var p in matchset) { | |
try { | |
p = self._makeAbs(p) | |
var real = rp.realpathSync(p, self.realpathCache) | |
set[real] = true | |
} catch (er) { | |
if (er.syscall === 'stat') | |
set[self._makeAbs(p)] = true | |
else | |
throw er | |
} | |
} | |
}) | |
} | |
common.finish(this) | |
} | |
GlobSync.prototype._process = function (pattern, index, inGlobStar) { | |
assert(this instanceof GlobSync) | |
// Get the first [n] parts of pattern that are all strings. | |
var n = 0 | |
while (typeof pattern[n] === 'string') { | |
n ++ | |
} | |
// now n is the index of the first one that is *not* a string. | |
// See if there's anything else | |
var prefix | |
switch (n) { | |
// if not, then this is rather simple | |
case pattern.length: | |
this._processSimple(pattern.join('/'), index) | |
return | |
case 0: | |
// pattern *starts* with some non-trivial item. | |
// going to readdir(cwd), but not include the prefix in matches. | |
prefix = null | |
break | |
default: | |
// pattern has some string bits in the front. | |
// whatever it starts with, whether that's 'absolute' like /foo/bar, | |
// or 'relative' like '../baz' | |
prefix = pattern.slice(0, n).join('/') | |
break | |
} | |
var remain = pattern.slice(n) | |
// get the list of entries. | |
var read | |
if (prefix === null) | |
read = '.' | |
else if (isAbsolute(prefix) || isAbsolute(pattern.join('/'))) { | |
if (!prefix || !isAbsolute(prefix)) | |
prefix = '/' + prefix | |
read = prefix | |
} else | |
read = prefix | |
var abs = this._makeAbs(read) | |
//if ignored, skip processing | |
if (childrenIgnored(this, read)) | |
return | |
var isGlobStar = remain[0] === minimatch.GLOBSTAR | |
if (isGlobStar) | |
this._processGlobStar(prefix, read, abs, remain, index, inGlobStar) | |
else | |
this._processReaddir(prefix, read, abs, remain, index, inGlobStar) | |
} | |
GlobSync.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar) { | |
var entries = this._readdir(abs, inGlobStar) | |
// if the abs isn't a dir, then nothing can match! | |
if (!entries) | |
return | |
// 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 = remain[0] | |
var negate = !!this.minimatch.negate | |
var rawGlob = pn._glob | |
var dotOk = this.dot || rawGlob.charAt(0) === '.' | |
var matchedEntries = [] | |
for (var i = 0; i < entries.length; i++) { | |
var e = entries[i] | |
if (e.charAt(0) !== '.' || dotOk) { | |
var m | |
if (negate && !prefix) { | |
m = !e.match(pn) | |
} else { | |
m = e.match(pn) | |
} | |
if (m) | |
matchedEntries.push(e) | |
} | |
} | |
var len = matchedEntries.length | |
// If there are no matched entries, then nothing matches. | |
if (len === 0) | |
return | |
// if this is the last remaining pattern bit, then no need for | |
// an additional stat *unless* the user has specified mark or | |
// stat explicitly. We know they exist, since readdir returned | |
// them. | |
if (remain.length === 1 && !this.mark && !this.stat) { | |
if (!this.matches[index]) | |
this.matches[index] = Object.create(null) | |
for (var i = 0; i < len; i ++) { | |
var e = matchedEntries[i] | |
if (prefix) { | |
if (prefix.slice(-1) !== '/') | |
e = prefix + '/' + e | |
else | |
e = prefix + e | |
} | |
if (e.charAt(0) === '/' && !this.nomount) { | |
e = path.join(this.root, e) | |
} | |
this._emitMatch(index, e) | |
} | |
// This was the last one, and no stats were needed | |
return | |
} | |
// now test all matched entries as stand-ins for that part | |
// of the pattern. | |
remain.shift() | |
for (var i = 0; i < len; i ++) { | |
var e = matchedEntries[i] | |
var newPattern | |
if (prefix) | |
newPattern = [prefix, e] | |
else | |
newPattern = [e] | |
this._process(newPattern.concat(remain), index, inGlobStar) | |
} | |
} | |
GlobSync.prototype._emitMatch = function (index, e) { | |
if (isIgnored(this, e)) | |
return | |
var abs = this._makeAbs(e) | |
if (this.mark) | |
e = this._mark(e) | |
if (this.absolute) { | |
e = abs | |
} | |
if (this.matches[index][e]) | |
return | |
if (this.nodir) { | |
var c = this.cache[abs] | |
if (c === 'DIR' || Array.isArray(c)) | |
return | |
} | |
this.matches[index][e] = true | |
if (this.stat) | |
this._stat(e) | |
} | |
GlobSync.prototype._readdirInGlobStar = function (abs) { | |
// follow all symlinked directories forever | |
// just proceed as if this is a non-globstar situation | |
if (this.follow) | |
return this._readdir(abs, false) | |
var entries | |
var lstat | |
var stat | |
try { | |
lstat = this.fs.lstatSync(abs) | |
} catch (er) { | |
if (er.code === 'ENOENT') { | |
// lstat failed, doesn't exist | |
return null | |
} | |
} | |
var isSym = lstat && lstat.isSymbolicLink() | |
this.symlinks[abs] = isSym | |
// If it's not a symlink or a dir, then it's definitely a regular file. | |
// don't bother doing a readdir in that case. | |
if (!isSym && lstat && !lstat.isDirectory()) | |
this.cache[abs] = 'FILE' | |
else | |
entries = this._readdir(abs, false) | |
return entries | |
} | |
GlobSync.prototype._readdir = function (abs, inGlobStar) { | |
var entries | |
if (inGlobStar && !ownProp(this.symlinks, abs)) | |
return this._readdirInGlobStar(abs) | |
if (ownProp(this.cache, abs)) { | |
var c = this.cache[abs] | |
if (!c || c === 'FILE') | |
return null | |
if (Array.isArray(c)) | |
return c | |
} | |
try { | |
return this._readdirEntries(abs, this.fs.readdirSync(abs)) | |
} catch (er) { | |
this._readdirError(abs, er) | |
return null | |
} | |
} | |
GlobSync.prototype._readdirEntries = function (abs, entries) { | |
// if we haven't asked to stat everything, then just | |
// assume that everything in there exists, so we can avoid | |
// having to stat it a second time. | |
if (!this.mark && !this.stat) { | |
for (var i = 0; i < entries.length; i ++) { | |
var e = entries[i] | |
if (abs === '/') | |
e = abs + e | |
else | |
e = abs + '/' + e | |
this.cache[e] = true | |
} | |
} | |
this.cache[abs] = entries | |
// mark and cache dir-ness | |
return entries | |
} | |
GlobSync.prototype._readdirError = function (f, er) { | |
// handle errors, and cache the information | |
switch (er.code) { | |
case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205 | |
case 'ENOTDIR': // totally normal. means it *does* exist. | |
var abs = this._makeAbs(f) | |
this.cache[abs] = 'FILE' | |
if (abs === this.cwdAbs) { | |
var error = new Error(er.code + ' invalid cwd ' + this.cwd) | |
error.path = this.cwd | |
error.code = er.code | |
throw error | |
} | |
break | |
case 'ENOENT': // not terribly unusual | |
case 'ELOOP': | |
case 'ENAMETOOLONG': | |
case 'UNKNOWN': | |
this.cache[this._makeAbs(f)] = false | |
break | |
default: // some unusual error. Treat as failure. | |
this.cache[this._makeAbs(f)] = false | |
if (this.strict) | |
throw er | |
if (!this.silent) | |
console.error('glob error', er) | |
break | |
} | |
} | |
GlobSync.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar) { | |
var entries = this._readdir(abs, inGlobStar) | |
// no entries means not a dir, so it can never have matches | |
// foo.txt/** doesn't match foo.txt | |
if (!entries) | |
return | |
// test without the globstar, and with every child both below | |
// and replacing the globstar. | |
var remainWithoutGlobStar = remain.slice(1) | |
var gspref = prefix ? [ prefix ] : [] | |
var noGlobStar = gspref.concat(remainWithoutGlobStar) | |
// the noGlobStar pattern exits the inGlobStar state | |
this._process(noGlobStar, index, false) | |
var len = entries.length | |
var isSym = this.symlinks[abs] | |
// If it's a symlink, and we're in a globstar, then stop | |
if (isSym && inGlobStar) | |
return | |
for (var i = 0; i < len; i++) { | |
var e = entries[i] | |
if (e.charAt(0) === '.' && !this.dot) | |
continue | |
// these two cases enter the inGlobStar state | |
var instead = gspref.concat(entries[i], remainWithoutGlobStar) | |
this._process(instead, index, true) | |
var below = gspref.concat(entries[i], remain) | |
this._process(below, index, true) | |
} | |
} | |
GlobSync.prototype._processSimple = function (prefix, index) { | |
// XXX review this. Shouldn't it be doing the mounting etc | |
// before doing stat? kinda weird? | |
var exists = this._stat(prefix) | |
if (!this.matches[index]) | |
this.matches[index] = Object.create(null) | |
// If it doesn't exist, then just mark the lack of results | |
if (!exists) | |
return | |
if (prefix && isAbsolute(prefix) && !this.nomount) { | |
var trail = /[\/\\]$/.test(prefix) | |
if (prefix.charAt(0) === '/') { | |
prefix = path.join(this.root, prefix) | |
} else { | |
prefix = path.resolve(this.root, prefix) | |
if (trail) | |
prefix += '/' | |
} | |
} | |
if (process.platform === 'win32') | |
prefix = prefix.replace(/\\/g, '/') | |
// Mark this as a match | |
this._emitMatch(index, prefix) | |
} | |
// Returns either 'DIR', 'FILE', or false | |
GlobSync.prototype._stat = function (f) { | |
var abs = this._makeAbs(f) | |
var needDir = f.slice(-1) === '/' | |
if (f.length > this.maxLength) | |
return false | |
if (!this.stat && ownProp(this.cache, abs)) { | |
var c = this.cache[abs] | |
if (Array.isArray(c)) | |
c = 'DIR' | |
// It exists, but maybe not how we need it | |
if (!needDir || c === 'DIR') | |
return c | |
if (needDir && c === 'FILE') | |
return false | |
// otherwise we have to stat, because maybe c=true | |
// if we know it exists, but not what it is. | |
} | |
var exists | |
var stat = this.statCache[abs] | |
if (!stat) { | |
var lstat | |
try { | |
lstat = this.fs.lstatSync(abs) | |
} catch (er) { | |
if (er && (er.code === 'ENOENT' || er.code === 'ENOTDIR')) { | |
this.statCache[abs] = false | |
return false | |
} | |
} | |
if (lstat && lstat.isSymbolicLink()) { | |
try { | |
stat = this.fs.statSync(abs) | |
} catch (er) { | |
stat = lstat | |
} | |
} else { | |
stat = lstat | |
} | |
} | |
this.statCache[abs] = stat | |
var c = true | |
if (stat) | |
c = stat.isDirectory() ? 'DIR' : 'FILE' | |
this.cache[abs] = this.cache[abs] || c | |
if (needDir && c === 'FILE') | |
return false | |
return c | |
} | |
GlobSync.prototype._mark = function (p) { | |
return common.mark(this, p) | |
} | |
GlobSync.prototype._makeAbs = function (f) { | |
return common.makeAbs(this, f) | |
} |