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
37 changes: 34 additions & 3 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,17 +109,39 @@ function processPatterns(
}
}

const transformed: string[] = [];
for (const pattern of patterns) {
if (!pattern.startsWith('!') || pattern[1] === '(') {
const newPattern = normalizePattern(pattern, expandDirectories, cwd, properties, false);
matchPatterns.push(newPattern);
const split = newPattern.split('/');
if (split[split.length - 1] === '**') {
if (split[split.length - 2] !== '..') {
split[split.length - 2] = '**';
split.pop();
}
transformed.push(split.length ? split.join('/') : '*');
} else {
transformed.push(split.length > 1 ? split.slice(0, -1).join('/') : split.join('/'));
}

for (let i = split.length - 2; i > 0; i--) {
const part = split.slice(0, i);
if (part[part.length - 1] === '**') {
part.pop();
if (part.length > 1) {
part.pop();
}
}
transformed.push(part.join('/'));
}
} else if (pattern[1] !== '!' || pattern[2] === '(') {
const newPattern = normalizePattern(pattern.slice(1), expandDirectories, cwd, properties, true);
ignorePatterns.push(newPattern);
}
}

return { match: matchPatterns, ignore: ignorePatterns };
return { match: matchPatterns, ignore: ignorePatterns, transformed };
}

// TODO: this is slow, find a better way to do this
Expand Down Expand Up @@ -158,15 +180,24 @@ function crawl(options: GlobOptions, cwd: string, sync: boolean) {
ignore: processed.ignore
});

const exclude = picomatch(processed.ignore, {
const ignore = picomatch(processed.ignore, {
dot: options.dot,
nocase: options.caseSensitiveMatch === false
});

const exclude = picomatch('*(../)**', {
dot: true,
nocase: options.caseSensitiveMatch === false,
ignore: processed.transformed
});

const fdirOptions: Partial<FdirOptions> = {
// use relative paths in the matcher
filters: [(p, isDirectory) => matcher(processPath(p, cwd, properties.root, isDirectory, options.absolute))],
exclude: (_, p) => exclude(processPath(p, cwd, properties.root, true, true)),
exclude: (_, p) => {
const relativePath = processPath(p, cwd, properties.root, true, true);
return ignore(relativePath) || exclude(relativePath);
},
pathSeparator: '/',
relativePaths: true,
resolveSymlinks: true
Expand Down
5 changes: 5 additions & 0 deletions test/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ test('empty array matches nothing', async () => {
assert.deepEqual(files.sort(), []);
});

test('only double star', async () => {
const files = await glob({ patterns: ['**'], cwd });
assert.deepEqual(files.sort(), ['a/a.txt', 'a/b.txt', 'b/a.txt', 'b/b.txt']);
});

test('no directory expansion if expandDirectories is set to false', async () => {
const files = await glob({ patterns: ['a'], expandDirectories: false, cwd });
assert.deepEqual(files.sort(), []);
Expand Down