1 | const fs = require('fs');
|
2 | const globrex = require('globrex');
|
3 | const globalyzer = require('globalyzer');
|
4 | const { join, resolve, relative } = require('path');
|
5 | const isHidden = /(^|[\\\/])\.[^\\\/\.]/g;
|
6 |
|
7 | let CACHE = {};
|
8 |
|
9 | function walk(output, prefix, lexer, opts, dirname='', level=0) {
|
10 | const rgx = lexer.segments[level];
|
11 | const dir = join(opts.cwd, prefix, dirname);
|
12 | const files = fs.readdirSync(dir);
|
13 | const { dot, filesOnly } = opts;
|
14 |
|
15 | let i=0, len=files.length, file;
|
16 | let fullpath, relpath, stats, isMatch;
|
17 |
|
18 | for (; i < len; i++) {
|
19 | fullpath = join(dir, file=files[i]);
|
20 | relpath = dirname ? join(dirname, file) : file;
|
21 | if (!dot && isHidden.test(relpath)) continue;
|
22 | isMatch = lexer.regex.test(relpath);
|
23 |
|
24 | if ((stats=CACHE[relpath]) === void 0) {
|
25 | CACHE[relpath] = stats = fs.lstatSync(fullpath);
|
26 | }
|
27 |
|
28 | if (!stats.isDirectory()) {
|
29 | isMatch && output.push(relative(opts.cwd, fullpath));
|
30 | continue;
|
31 | }
|
32 |
|
33 | if (rgx && !rgx.test(file)) continue;
|
34 | !filesOnly && isMatch && output.push(join(prefix, relpath));
|
35 |
|
36 | walk(output, prefix, lexer, opts, relpath, rgx && rgx.toString() !== lexer.globstar && ++level);
|
37 | }
|
38 | }
|
39 |
|
40 |
|
41 |
|
42 |
|
43 |
|
44 |
|
45 |
|
46 |
|
47 |
|
48 |
|
49 |
|
50 |
|
51 | module.exports = function (str, opts={}) {
|
52 | let glob = globalyzer(str);
|
53 |
|
54 | if (!glob.isGlob) return fs.existsSync(str) ? [str] : [];
|
55 | if (opts.flush) CACHE = {};
|
56 |
|
57 | let matches = [];
|
58 | opts.cwd = opts.cwd || '.';
|
59 | const { path } = globrex(glob.glob, { filepath:true, globstar:true, extended:true });
|
60 |
|
61 | path.globstar = path.globstar.toString();
|
62 | walk(matches, glob.base, path, opts, '.', 0);
|
63 |
|
64 | return opts.absolute ? matches.map(x => resolve(opts.cwd, x)) : matches;
|
65 | };
|