Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 28 additions & 12 deletions lib/internal/fs/glob.js
Original file line number Diff line number Diff line change
Expand Up @@ -442,7 +442,18 @@ class Glob {
const fromSymlink = pattern.symlinks.has(index);

if (current === lazyMinimatch().GLOBSTAR) {
if (entry.name[0] === '.' || (this.#exclude && this.#exclude(this.#withFileTypes ? entry : entry.name))) {
const isDot = entry.name[0] === '.';
const nextMatches = pattern.test(nextIndex, entry.name);

let nextNonGlobIndex = nextIndex;
while (pattern.at(nextNonGlobIndex) === lazyMinimatch().GLOBSTAR) {
nextNonGlobIndex++;
}

const matchesDot = isDot && pattern.test(nextNonGlobIndex, entry.name);

if ((isDot && !matchesDot) ||
(this.#exclude && this.#exclude(this.#withFileTypes ? entry : entry.name))) {
continue;
}
if (!fromSymlink && entry.isDirectory()) {
Expand All @@ -455,7 +466,6 @@ class Glob {

// Any pattern after ** is also a potential pattern
// so we can already test it here
const nextMatches = pattern.test(nextIndex, entry.name);
if (nextMatches && nextIndex === last && !isLast) {
// If next pattern is the last one, add to results
this.#results.add(entryPath);
Expand Down Expand Up @@ -642,30 +652,36 @@ class Glob {
const fromSymlink = pattern.symlinks.has(index);

if (current === lazyMinimatch().GLOBSTAR) {
if (entry.name[0] === '.' || (this.#exclude && this.#exclude(this.#withFileTypes ? entry : entry.name))) {
const isDot = entry.name[0] === '.';
const nextMatches = pattern.test(nextIndex, entry.name);

let nextNonGlobIndex = nextIndex;
while (pattern.at(nextNonGlobIndex) === lazyMinimatch().GLOBSTAR) {
nextNonGlobIndex++;
}

const matchesDot = isDot && pattern.test(nextNonGlobIndex, entry.name);

if ((isDot && !matchesDot) ||
(this.#exclude && this.#exclude(this.#withFileTypes ? entry : entry.name))) {
continue;
}
if (!fromSymlink && entry.isDirectory()) {
// If directory, add ** to its potential patterns
subPatterns.add(index);
} else if (!fromSymlink && index === last) {
// If ** is last, add to results
if (!this.#results.has(entryPath)) {
if (this.#results.add(entryPath)) {
yield this.#withFileTypes ? entry : entryPath;
}
if (!this.#results.has(entryPath) && this.#results.add(entryPath)) {
yield this.#withFileTypes ? entry : entryPath;
}
}

// Any pattern after ** is also a potential pattern
// so we can already test it here
const nextMatches = pattern.test(nextIndex, entry.name);
if (nextMatches && nextIndex === last && !isLast) {
// If next pattern is the last one, add to results
if (!this.#results.has(entryPath)) {
if (this.#results.add(entryPath)) {
yield this.#withFileTypes ? entry : entryPath;
}
if (!this.#results.has(entryPath) && this.#results.add(entryPath)) {
yield this.#withFileTypes ? entry : entryPath;
}
} else if (nextMatches && entry.isDirectory()) {
// Pattern matched, meaning two patterns forward
Expand Down
5 changes: 5 additions & 0 deletions test/parallel/test-fs-glob.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ async function setup() {
'a/cb/e/f',
'a/x/.y/b',
'a/z/.y/b',
'a/.b',
'a/b/.b',
].map((f) => resolve(fixtureDir, f));

const symlinkTo = resolve(fixtureDir, 'a/symlink/a/b/c');
Expand Down Expand Up @@ -188,6 +190,9 @@ const patterns = {
],
'*/*/*/f': ['a/bc/e/f', 'a/cb/e/f'],
'./**/f': ['a/bc/e/f', 'a/cb/e/f'],
'**/.b': ['a/.b', 'a/b/.b'],
'./**/.b': ['a/.b', 'a/b/.b'],
'a/**/.b': ['a/.b', 'a/b/.b'],
'a/symlink/a/b/c/a/b/c/a/b/c//a/b/c////a/b/c/**/b/c/**': common.isWindows ? [] : [
'a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c',
'a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a',
Expand Down
Loading