fix(core): negative patterns do not work for root project

This commit is contained in:
Victor Savkin 2022-11-30 10:31:53 -05:00
parent 8bfc0b5527
commit db85c62240
2 changed files with 54 additions and 33 deletions

View File

@ -845,57 +845,72 @@ describe('Hasher', () => {
describe('filterUsingGlobPatterns', () => { describe('filterUsingGlobPatterns', () => {
it('should OR all positive patterns and AND all negative patterns (when positive and negative patterns)', () => { it('should OR all positive patterns and AND all negative patterns (when positive and negative patterns)', () => {
const filtered = filterUsingGlobPatterns( const filtered = filterUsingGlobPatterns(
'/root', 'root',
[ [
{ file: '/root/a.ts' }, { file: 'root/a.ts' },
{ file: '/root/b.js' }, { file: 'root/b.js' },
{ file: '/root/c.spec.ts' }, { file: 'root/c.spec.ts' },
{ file: '/root/d.md' }, { file: 'root/d.md' },
] as any, ] as any,
[ [
'/root/**/*.ts', '{projectRoot}/**/*.ts',
'/root/**/*.js', '{projectRoot}/**/*.js',
'!/root/**/*.spec.ts', '!{projectRoot}/**/*.spec.ts',
'!/root/**/*.md', '!{projectRoot}/**/*.md',
] ]
); );
expect(filtered.map((f) => f.file)).toEqual(['/root/a.ts', '/root/b.js']); expect(filtered.map((f) => f.file)).toEqual(['root/a.ts', 'root/b.js']);
}); });
it('should OR all positive patterns and AND all negative patterns (when negative patterns)', () => { it('should OR all positive patterns and AND all negative patterns (when negative patterns)', () => {
const filtered = filterUsingGlobPatterns( const filtered = filterUsingGlobPatterns(
'/root', 'root',
[ [
{ file: '/root/a.ts' }, { file: 'root/a.ts' },
{ file: '/root/b.js' }, { file: 'root/b.js' },
{ file: '/root/c.spec.ts' }, { file: 'root/c.spec.ts' },
{ file: '/root/d.md' }, { file: 'root/d.md' },
] as any, ] as any,
['!/root/**/*.spec.ts', '!/root/**/*.md'] ['!{projectRoot}/**/*.spec.ts', '!{projectRoot}/**/*.md']
); );
expect(filtered.map((f) => f.file)).toEqual(['/root/a.ts', '/root/b.js']); expect(filtered.map((f) => f.file)).toEqual(['root/a.ts', 'root/b.js']);
}); });
it('should OR all positive patterns and AND all negative patterns (when positive patterns)', () => { it('should OR all positive patterns and AND all negative patterns (when positive patterns)', () => {
const filtered = filterUsingGlobPatterns( const filtered = filterUsingGlobPatterns(
'/root', 'root',
[ [
{ file: '/root/a.ts' }, { file: 'root/a.ts' },
{ file: '/root/b.js' }, { file: 'root/b.js' },
{ file: '/root/c.spec.ts' }, { file: 'root/c.spec.ts' },
{ file: '/root/d.md' }, { file: 'root/d.md' },
] as any, ] as any,
['/root/**/*.ts', '/root/**/*.js'] ['{projectRoot}/**/*.ts', '{projectRoot}/**/*.js']
); );
expect(filtered.map((f) => f.file)).toEqual([ expect(filtered.map((f) => f.file)).toEqual([
'/root/a.ts', 'root/a.ts',
'/root/b.js', 'root/b.js',
'/root/c.spec.ts', 'root/c.spec.ts',
]); ]);
}); });
it('should handle projects with the root set to .', () => {
const filtered = filterUsingGlobPatterns(
'.',
[
{ file: 'a.ts' },
{ file: 'b.md' },
{ file: 'dir/a.ts' },
{ file: 'dir/b.md' },
] as any,
['{projectRoot}/**/*.ts', '!{projectRoot}/**/*.md']
);
expect(filtered.map((f) => f.file)).toEqual(['a.ts', 'dir/a.ts']);
});
}); });
}); });

View File

@ -489,13 +489,10 @@ class TaskHasher {
if (!this.filesetHashes[mapKey]) { if (!this.filesetHashes[mapKey]) {
this.filesetHashes[mapKey] = new Promise(async (res) => { this.filesetHashes[mapKey] = new Promise(async (res) => {
const p = this.projectGraph.nodes[projectName]; const p = this.projectGraph.nodes[projectName];
const filesetWithExpandedProjectRoot = filesetPatterns.map((f) =>
f.replace('{projectRoot}', p.data.root)
);
const filteredFiles = filterUsingGlobPatterns( const filteredFiles = filterUsingGlobPatterns(
p.data.root, p.data.root,
p.data.files, p.data.files,
filesetWithExpandedProjectRoot filesetPatterns
); );
const fileNames = filteredFiles.map((f) => f.file); const fileNames = filteredFiles.map((f) => f.file);
const values = filteredFiles.map((f) => f.hash); const values = filteredFiles.map((f) => f.hash);
@ -640,13 +637,22 @@ export function expandNamedInput(
} }
export function filterUsingGlobPatterns( export function filterUsingGlobPatterns(
projectRoot: string, root: string,
files: FileData[], files: FileData[],
patterns: string[] patterns: string[]
): FileData[] { ): FileData[] {
const filesetWithExpandedProjectRoot = patterns
.map((f) => f.replace('{projectRoot}', root))
.map((r) => {
// handling root level projects that create './' pattern that doesn't work with minimatch
if (r.startsWith('./')) return r.substring(2);
if (r.startsWith('!./')) return '!' + r.substring(3);
return r;
});
const positive = []; const positive = [];
const negative = []; const negative = [];
for (const p of patterns) { for (const p of filesetWithExpandedProjectRoot) {
if (p.startsWith('!')) { if (p.startsWith('!')) {
negative.push(p); negative.push(p);
} else { } else {
@ -662,7 +668,7 @@ export function filterUsingGlobPatterns(
let matchedPositive = false; let matchedPositive = false;
if ( if (
positive.length === 0 || positive.length === 0 ||
(positive.length === 1 && positive[0] === `${projectRoot}/**/*`) (positive.length === 1 && positive[0] === `${root}/**/*`)
) { ) {
matchedPositive = true; matchedPositive = true;
} else { } else {