Skip to content

Commit

Permalink
feat(core): add support for wildcards in dependsOn
Browse files Browse the repository at this point in the history
Now it is possible to define targets like this:

```
{
  "targets": {
    "build-css": {},
    "build-js": {},
    "test": {
      "dependsOn": ["build-*"]
    },
  }
}
```
  • Loading branch information
fxposter authored and AgentEnder committed Jul 3, 2024
1 parent 6e84cbf commit a22df96
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 40 deletions.
91 changes: 68 additions & 23 deletions packages/nx/src/tasks-runner/utils.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -443,17 +443,19 @@ describe('utils', () => {

describe('expandDependencyConfigSyntaxSugar', () => {
it('should expand syntax for simple target names', () => {
const result = expandDependencyConfigSyntaxSugar('build', {
const result = expandDependencyConfigSyntaxSugar('build', 'any', {
dependencies: {},
nodes: {},
});
expect(result).toEqual({
target: 'build',
});
expect(result).toEqual([
{
target: 'build',
},
]);
});

it('should assume target of self if simple target also matches project name', () => {
const result = expandDependencyConfigSyntaxSugar('build', {
const result = expandDependencyConfigSyntaxSugar('build', 'any', {
dependencies: {},
nodes: {
build: {
Expand All @@ -465,24 +467,28 @@ describe('utils', () => {
},
},
});
expect(result).toEqual({
target: 'build',
});
expect(result).toEqual([
{
target: 'build',
},
]);
});

it('should expand syntax for simple target names targetting dependencies', () => {
const result = expandDependencyConfigSyntaxSugar('^build', {
const result = expandDependencyConfigSyntaxSugar('^build', 'any', {
dependencies: {},
nodes: {},
});
expect(result).toEqual({
target: 'build',
dependencies: true,
});
expect(result).toEqual([
{
target: 'build',
dependencies: true,
},
]);
});

it('should expand syntax for strings like project:target if project is a valid project', () => {
const result = expandDependencyConfigSyntaxSugar('project:build', {
const result = expandDependencyConfigSyntaxSugar('project:build', 'any', {
dependencies: {},
nodes: {
project: {
Expand All @@ -494,20 +500,59 @@ describe('utils', () => {
},
},
});
expect(result).toEqual({
target: 'build',
projects: ['project'],
});
expect(result).toEqual([
{
target: 'build',
projects: ['project'],
},
]);
});

it('should expand syntax for strings like target:with:colons', () => {
const result = expandDependencyConfigSyntaxSugar('target:with:colons', {
const result = expandDependencyConfigSyntaxSugar(
'target:with:colons',
'any',
{
dependencies: {},
nodes: {},
}
);
expect(result).toEqual([
{
target: 'target:with:colons',
},
]);
});

it('supports wildcards in targets', () => {
const result = expandDependencyConfigSyntaxSugar('build-*', 'project', {
dependencies: {},
nodes: {},
});
expect(result).toEqual({
target: 'target:with:colons',
nodes: {
project: {
name: 'project',
type: 'app',
data: {
root: 'libs/project',
targets: {
build: {},
'build-css': {},
'build-js': {},
'then-build-something-else': {},
},
},
},
},
});
expect(result).toEqual([
{
target: 'build-css',
projects: ['project'],
},
{
target: 'build-js',
projects: ['project'],
},
]);
});
});

Expand Down
63 changes: 46 additions & 17 deletions packages/nx/src/tasks-runner/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@ export function getDependencyConfigs(
// This is passed into `run-command` from programmatic invocations
extraTargetDependencies[target] ??
[]
).map((config) =>
).flatMap((config) =>
typeof config === 'string'
? expandDependencyConfigSyntaxSugar(config, projectGraph)
: config
? expandDependencyConfigSyntaxSugar(config, project, projectGraph)
: [config]
);
for (const dependencyConfig of dependencyConfigs) {
if (dependencyConfig.projects && dependencyConfig.dependencies) {
Expand All @@ -47,37 +47,66 @@ export function getDependencyConfigs(

export function expandDependencyConfigSyntaxSugar(
dependencyConfigString: string,
currentProject: string,
graph: ProjectGraph
): TargetDependencyConfig {
): TargetDependencyConfig[] {
const [dependencies, targetString] = dependencyConfigString.startsWith('^')
? [true, dependencyConfigString.substring(1)]
: [false, dependencyConfigString];

// Support for `project:target` syntax doesn't make sense for
// dependencies, so we only support `target` syntax for dependencies.
if (dependencies) {
return {
target: targetString,
dependencies: true,
};
return [
{
target: targetString,
dependencies: true,
},
];
}

// Support for both `project:target` and `target:with:colons` syntax
const [maybeProject, ...segments] = splitByColons(targetString);

// if no additional segments are provided, then the string references
// a target of the same project
let target, projects;
if (!segments.length) {
return { target: maybeProject };
}

return {
// if no additional segments are provided, then the string references
// a target of the same project
target = maybeProject;
} else if (maybeProject in graph.nodes) {
// Only the first segment could be a project. If it is, the rest is a target.
// If its not, then the whole targetString was a target with colons in its name.
target: maybeProject in graph.nodes ? segments.join(':') : targetString,
target = segments.join(':');
projects = [maybeProject];
} else {
// If the first segment is a project, then we have a specific project. Otherwise, we don't.
projects: maybeProject in graph.nodes ? [maybeProject] : undefined,
};
target = targetString;
}

// handle target wildcards
if (target.indexOf('*') >= 0) {
const matches: TargetDependencyConfig[] = [];
const targetMatch = new RegExp('^' + target.replaceAll('*', '.*') + '$');
const projectsToCheck = projects ? projects : [currentProject];
for (const project of projectsToCheck) {
const projectTargets = graph.nodes[project].data?.targets;
if (projectTargets) {
for (const target in projectTargets) {
if (target.match(targetMatch)) {
matches.push({ target, projects: [project] });
}
}
}
}
return matches;
}

return [
{
target,
projects,
},
];
}

export function getOutputs(
Expand Down

0 comments on commit a22df96

Please sign in to comment.