Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(core): adjust how findMatchingProjects works when provided additive patterns after an exclusion to be more intuitive #19295

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
14 changes: 9 additions & 5 deletions packages/nx/src/utils/find-matching-projects.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ describe('findMatchingProjects', () => {
'c',
'nested',
]);
expect(findMatchingProjects(['!*', 'a'], projectGraph)).toEqual([]);
expect(findMatchingProjects(['a', '!*'], projectGraph)).toEqual([]);
});

it('should expand generic glob patterns', () => {
Expand Down Expand Up @@ -124,10 +124,14 @@ describe('findMatchingProjects', () => {
});

it('should support negation "!" for tags', () => {
expect(findMatchingProjects(['*', '!tag:api'], projectGraph)).toEqual([
'b',
'nested',
]);
// Picks everything, except things tagged API, unless those also
// have the tag theme2 in which case we still want them.
const matches = findMatchingProjects(
['*', '!tag:api', 'tag:theme2'],
projectGraph
);
expect(matches).toEqual(expect.arrayContaining(['a', 'b', 'nested']));
expect(matches.length).toEqual(3);
});

it('should expand generic glob patterns for tags', () => {
Expand Down
71 changes: 37 additions & 34 deletions packages/nx/src/utils/find-matching-projects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,7 @@ export function findMatchingProjects(

const projectNames = Object.keys(projects);

const selectedProjects: Set<string> = new Set();
const excludedProjects: Set<string> = new Set();
const matchedProjects: Set<string> = new Set();

for (const stringPattern of patterns) {
if (!stringPattern.length) {
Expand All @@ -52,9 +51,9 @@ export function findMatchingProjects(
if (pattern.value === '*') {
for (const projectName of projectNames) {
if (pattern.exclude) {
excludedProjects.add(projectName);
matchedProjects.delete(projectName);
} else {
selectedProjects.add(projectName);
matchedProjects.add(projectName);
}
}
continue;
Expand All @@ -66,8 +65,7 @@ export function findMatchingProjects(
projectNames,
projects,
pattern,
excludedProjects,
selectedProjects
matchedProjects
);
continue;
}
Expand All @@ -76,8 +74,7 @@ export function findMatchingProjects(
projectNames,
projects,
pattern,
excludedProjects,
selectedProjects
matchedProjects
);
continue;
}
Expand All @@ -86,8 +83,7 @@ export function findMatchingProjects(
projectNames,
projects,
pattern,
excludedProjects,
selectedProjects
matchedProjects
);
continue;
}
Expand All @@ -97,26 +93,24 @@ export function findMatchingProjects(
// The size of the selected and excluded projects set, before we
// start updating it with this pattern. If the size changes, we
// know we found a match and can skip the other types.
const originalSize = selectedProjects.size + excludedProjects.size;
const originalSize = matchedProjects.size;
addMatchingProjectsByName(
projectNames,
projects,
pattern,
excludedProjects,
selectedProjects
matchedProjects
);
if (selectedProjects.size + excludedProjects.size > originalSize) {
if (matchedProjects.size !== originalSize) {
// There was some match by name, don't check other types
continue;
}
addMatchingProjectsByDirectory(
projectNames,
projects,
pattern,
excludedProjects,
selectedProjects
matchedProjects
);
if (selectedProjects.size + excludedProjects.size > originalSize) {
if (matchedProjects.size !== originalSize) {
// There was some match by directory, don't check other types
// Note - this doesn't do anything currently, but preps for future
// types
Expand All @@ -126,24 +120,23 @@ export function findMatchingProjects(
}
}

for (const project of excludedProjects) {
selectedProjects.delete(project);
}

return Array.from(selectedProjects);
return Array.from(matchedProjects);
}

function addMatchingProjectsByDirectory(
projectNames: string[],
projects: Record<string, ProjectGraphProjectNode>,
pattern: ProjectPattern,
excludedProjects: Set<string>,
selectedProjects: Set<string>
matchedProjects: Set<string>
) {
for (const projectName of projectNames) {
const root = projects[projectName].data.root;
if (getMatchingStringsWithCache(pattern.value, [root]).length > 0) {
(pattern.exclude ? excludedProjects : selectedProjects).add(projectName);
if (pattern.exclude) {
matchedProjects.delete(projectName);
} else {
matchedProjects.add(projectName);
}
}
}
}
Expand All @@ -152,11 +145,14 @@ function addMatchingProjectsByName(
projectNames: string[],
projects: Record<string, ProjectGraphProjectNode>,
pattern: ProjectPattern,
excludedProjects: Set<string>,
selectedProjects: Set<string>
matchedProjects: Set<string>
) {
if (projects[pattern.value]) {
(pattern.exclude ? excludedProjects : selectedProjects).add(pattern.value);
if (pattern.exclude) {
matchedProjects.delete(pattern.value);
} else {
matchedProjects.add(pattern.value);
}
return;
}

Expand All @@ -170,9 +166,9 @@ function addMatchingProjectsByName(
);
for (const projectName of matchedProjectNames) {
if (pattern.exclude) {
excludedProjects.add(projectName);
matchedProjects.delete(projectName);
} else {
selectedProjects.add(projectName);
matchedProjects.add(projectName);
}
}
}
Expand All @@ -181,14 +177,17 @@ function addMatchingProjectsByTag(
projectNames: string[],
projects: Record<string, ProjectGraphProjectNode>,
pattern: ProjectPattern,
excludedProjects: Set<string>,
selectedProjects: Set<string>
matchedProjects: Set<string>
) {
for (const projectName of projectNames) {
const tags = projects[projectName].data.tags || [];

if (tags.includes(pattern.value)) {
(pattern.exclude ? excludedProjects : selectedProjects).add(projectName);
if (pattern.exclude) {
matchedProjects.delete(projectName);
} else {
matchedProjects.add(projectName);
}
continue;
}

Expand All @@ -197,7 +196,11 @@ function addMatchingProjectsByTag(
}

if (getMatchingStringsWithCache(pattern.value, tags).length) {
(pattern.exclude ? excludedProjects : selectedProjects).add(projectName);
if (pattern.exclude) {
matchedProjects.delete(projectName);
} else {
matchedProjects.add(projectName);
}
}
}
}
Expand Down