|
const fs = require('fs'); |
|
const globrex = require('globrex'); |
|
const globalyzer = require('globalyzer'); |
|
const { join, resolve, relative } = require('path'); |
|
const isHidden = /(^|[\\\/])\.[^\\\/\.]/g; |
|
|
|
let CACHE = {}; |
|
|
|
function walk(output, prefix, lexer, opts, dirname='', level=0) { |
|
const rgx = lexer.segments[level]; |
|
const dir = resolve(opts.cwd, prefix, dirname); |
|
const files = fs.readdirSync(dir); |
|
const { dot, filesOnly } = opts; |
|
|
|
let i=0, len=files.length, file; |
|
let fullpath, relpath, stats, isMatch; |
|
|
|
for (; i < len; i++) { |
|
fullpath = join(dir, file=files[i]); |
|
relpath = dirname ? join(dirname, file) : file; |
|
if (!dot && isHidden.test(relpath)) continue; |
|
isMatch = lexer.regex.test(relpath); |
|
|
|
if ((stats=CACHE[relpath]) === void 0) { |
|
CACHE[relpath] = stats = fs.lstatSync(fullpath); |
|
} |
|
|
|
if (!stats.isDirectory()) { |
|
isMatch && output.push(relative(opts.cwd, fullpath)); |
|
continue; |
|
} |
|
|
|
if (rgx && !rgx.test(file)) continue; |
|
!filesOnly && isMatch && output.push(join(prefix, relpath)); |
|
|
|
walk(output, prefix, lexer, opts, relpath, rgx && rgx.toString() !== lexer.globstar && level + 1); |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
module.exports = function (str, opts={}) { |
|
if (!str) return []; |
|
|
|
let glob = globalyzer(str); |
|
|
|
opts.cwd = opts.cwd || '.'; |
|
|
|
if (!glob.isGlob) { |
|
try { |
|
let resolved = resolve(opts.cwd, str); |
|
let dirent = fs.statSync(resolved); |
|
if (opts.filesOnly && !dirent.isFile()) return []; |
|
|
|
return opts.absolute ? [resolved] : [str]; |
|
} catch (err) { |
|
if (err.code != 'ENOENT') throw err; |
|
|
|
return []; |
|
} |
|
} |
|
|
|
if (opts.flush) CACHE = {}; |
|
|
|
let matches = []; |
|
const { path } = globrex(glob.glob, { filepath:true, globstar:true, extended:true }); |
|
|
|
path.globstar = path.globstar.toString(); |
|
walk(matches, glob.base, path, opts, '.', 0); |
|
|
|
return opts.absolute ? matches.map(x => resolve(opts.cwd, x)) : matches; |
|
}; |
|
|