feat(core): support matching projects specifiers in dependsOn (#16675)

This commit is contained in:
Craigory Coppola 2023-05-02 17:00:12 -04:00 committed by GitHub
parent d084e678bd
commit ef63dcb69b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 84 additions and 30 deletions

View File

@ -1443,4 +1443,62 @@ describe('createTaskGraph', () => {
},
});
});
it('should handle glob patterns in dependsOn', () => {
const graph: ProjectGraph = {
nodes: {
app1: {
name: 'app1',
type: 'app',
data: {
root: 'app1-root',
files: [],
targets: {
build: {
executor: 'nx:run-commands',
dependsOn: [{ target: 'build', projects: 'lib*' }],
},
},
},
},
lib1: {
name: 'lib1',
type: 'lib',
data: {
root: 'lib1-root',
files: [],
targets: {
build: {
executor: 'nx:run-commands',
},
},
},
},
lib2: {
name: 'lib2',
type: 'lib',
data: {
root: 'lib2-root',
files: [],
targets: {
build: {
executor: 'nx:run-commands',
},
},
},
},
},
dependencies: {
app1: [],
},
};
const taskGraph = createTaskGraph(graph, {}, ['app1'], ['build'], null, {});
expect(taskGraph.tasks).toHaveProperty('app1:build');
expect(taskGraph.tasks).toHaveProperty('lib1:build');
expect(taskGraph.tasks).toHaveProperty('lib2:build');
expect(taskGraph.dependencies['app1:build']).toEqual([
'lib1:build',
'lib2:build',
]);
});
});

View File

@ -7,6 +7,8 @@ import {
import { Task, TaskGraph } from '../config/task-graph';
import { TargetDependencies } from '../config/nx-json';
import { TargetDependencyConfig } from '../devkit-exports';
import { findMatchingProjects } from '../utils/find-matching-projects';
import { output } from '../utils/output';
export class ProcessTasks {
private readonly seen = new Set<string>();
@ -168,20 +170,33 @@ export class ProcessTasks {
// Since we need to maintain support for dependencies, it is more coherent
// that we also support self.
// TODO(@agentender): Remove this part in v17
const projectName =
const matchingProjects =
/** LERNA SUPPORT START - Remove in v17 */
projectSpecifier === 'self' &&
!this.projectGraph.nodes[projectSpecifier]
? task.target.project
: projectSpecifier;
? [task.target.project]
: /** LERNA SUPPORT END */
findMatchingProjects([projectSpecifier], this.projectGraph.nodes);
this.processTasksForSingleProject(
task,
projectName,
dependencyConfig,
configuration,
taskOverrides,
overrides
);
if (matchingProjects.length === 0) {
output.warn({
title: `\`dependsOn\` is misconfigured for ${task.target.project}:${task.target.target}`,
bodyLines: [
`Project pattern "${projectSpecifier}" does not match any projects.`,
],
});
}
for (const projectName of matchingProjects) {
this.processTasksForSingleProject(
task,
projectName,
dependencyConfig,
configuration,
taskOverrides,
overrides
);
}
}
}
}

View File

@ -37,25 +37,6 @@ export function getDependencyConfigs(
: config
);
for (const dependencyConfig of dependencyConfigs) {
const specifiers =
typeof dependencyConfig.projects === 'string'
? [dependencyConfig.projects]
: dependencyConfig.projects;
for (const specifier of specifiers ?? []) {
if (
!(specifier in projectGraph.nodes) &&
// Todo(@agentender): Remove the check for self / dependencies in v17
!['self', 'dependencies'].includes(specifier)
) {
output.error({
title: `dependsOn is improperly configured for ${project}:${target}`,
bodyLines: [
`${specifier} in dependsOn.projects is invalid. It should be "self", "dependencies", or a project name.`,
],
});
process.exit(1);
}
}
if (dependencyConfig.projects && dependencyConfig.dependencies) {
output.error({
title: `dependsOn is improperly configured for ${project}:${target}`,