Skip to content

Commit

Permalink
feat(core): add an option to run-many by tags
Browse files Browse the repository at this point in the history
`nx run-many --target=deploy --tags=foo` runs the given target for all
projects that have a tag `foo` configured in nx.json.

Closes #2675.
  • Loading branch information
Schibum committed Apr 6, 2021
1 parent 2612268 commit 5cf9e11
Show file tree
Hide file tree
Showing 8 changed files with 87 additions and 7 deletions.
10 changes: 10 additions & 0 deletions docs/angular/cli/run-many.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ Build proj1 and proj2 and all their dependencies.:
nx run-many --target=test --projects=proj1,proj2 --with-deps
```

Test all projects that are tagged with foo or bar.:

```bash
nx run-many --target=test --tags=foo,bar
```

## Options

### all
Expand Down Expand Up @@ -78,6 +84,10 @@ Default: `false`

Rerun the tasks even when the results are available in the cache

### tags

Run projects having any of the given tags (comma delimited)

### target

Task to run for affected projects
Expand Down
10 changes: 10 additions & 0 deletions docs/node/cli/run-many.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ Build proj1 and proj2 and all their dependencies.:
nx run-many --target=test --projects=proj1,proj2 --with-deps
```

Test all projects that are tagged with foo or bar.:

```bash
nx run-many --target=test --tags=foo,bar
```

## Options

### all
Expand Down Expand Up @@ -78,6 +84,10 @@ Default: `false`

Rerun the tasks even when the results are available in the cache

### tags

Run projects having any of the given tags (comma delimited)

### target

Task to run for affected projects
Expand Down
10 changes: 10 additions & 0 deletions docs/react/cli/run-many.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ Build proj1 and proj2 and all their dependencies.:
nx run-many --target=test --projects=proj1,proj2 --with-deps
```

Test all projects that are tagged with foo or bar.:

```bash
nx run-many --target=test --tags=foo,bar
```

## Options

### all
Expand Down Expand Up @@ -78,6 +84,10 @@ Default: `false`

Rerun the tasks even when the results are available in the cache

### tags

Run projects having any of the given tags (comma delimited)

### target

Task to run for affected projects
Expand Down
16 changes: 16 additions & 0 deletions e2e/workspace/src/workspace.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,13 +80,20 @@ describe('run-many', () => {
const libB = uniq('libb-rand');
const libC = uniq('libc-rand');
const libD = uniq('libd-rand');
const tagA = uniq('taga-rand');

runCLI(`generate @nrwl/angular:app ${appA}`);
runCLI(`generate @nrwl/angular:lib ${libA} --buildable --defaults`);
runCLI(`generate @nrwl/angular:lib ${libB} --buildable --defaults`);
runCLI(`generate @nrwl/angular:lib ${libC} --buildable --defaults`);
runCLI(`generate @nrwl/angular:lib ${libD} --defaults`);

// Add tagA to libA and libB
const nxJson: NxJson = readJson('nx.json');
nxJson.projects[libA].tags = [tagA];
nxJson.projects[libB].tags = [tagA];
updateFile('nx.json', JSON.stringify(nxJson));

// libA depends on libC
updateFile(
`libs/${libA}/src/lib/${libA}.module.spec.ts`,
Expand All @@ -111,6 +118,15 @@ describe('run-many', () => {
expect(buildParallel).not.toContain(`- ${libD}`);
expect(buildParallel).toContain('Running target "build" succeeded');

// testing run many tags starting
const buildTags = runCLI(`run-many --target=build --tags="${tagA}"`);
expect(buildTags).toContain(`Running target build for projects:`);
expect(buildTags).toContain(`- ${libA}`);
expect(buildTags).toContain(`- ${libB}`);
expect(buildTags).not.toContain(`- ${libC}`);
expect(buildTags).not.toContain(`- ${libD}`);
expect(buildTags).toContain('Running target "build" succeeded');

// testing run many --all starting
const buildAllParallel = runCLI(`run-many --target=build --all`);
expect(buildAllParallel).toContain(`Running target build for projects:`);
Expand Down
16 changes: 12 additions & 4 deletions packages/workspace/src/command-line/nx-commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -320,15 +320,23 @@ function withRunManyOptions(yargs: yargs.Argv): yargs.Argv {
describe: 'Projects to run (comma delimited)',
type: 'string',
})
.option('tags', {
describe: 'Run projects having any of the given tags (comma delimited)',
type: 'string',
})
.option('all', {
describe: 'Run the target on all projects in the workspace',
type: 'boolean',
default: undefined,
})
.check(({ all, projects }) => {
if ((all && projects) || (!all && !projects))
throw new Error('You must provide either --all or --projects');
return true;
.check(({ all, projects, tags }) => {
const suppliedArgs = +!!all + +!!projects + +!!tags;
if (suppliedArgs === 1) {
return true;
}
throw new Error(
'You must provide either --all or --projects or --tags'
);
})
.options('runner', {
describe: 'Override the tasks runner in `nx.json`',
Expand Down
18 changes: 16 additions & 2 deletions packages/workspace/src/command-line/run-many.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
ProjectGraphNode,
withDeps,
} from '../core/project-graph';
import { readEnvironment } from '../core/file-utils';
import { readEnvironment, readNxJson } from '../core/file-utils';
import { DefaultReporter } from '../tasks-runner/default-reporter';
import { projectHasTarget } from '../utilities/project-graph-utils';
import { output } from '../utilities/output';
Expand Down Expand Up @@ -43,14 +43,28 @@ export async function runMany(parsedArgs: yargs.Arguments) {
);
}

function selectProjectsFromTags(tags: string[]): string[] {
let nxJson = readNxJson();
return Object.entries(nxJson.projects)
.filter(([name, project]) => {
let projectTags = project.tags || [];
return tags.some((tag) => projectTags.includes(tag));
})
.map(([name]) => name);
}

function projectsToRun(nxArgs: NxArgs, projectGraph: ProjectGraph) {
const allProjects = Object.values(projectGraph.nodes);
if (nxArgs.all) {
return runnableForTarget(allProjects, nxArgs.target);
} else {
let projects = nxArgs.projects;
if (projects.length === 0) {
projects = selectProjectsFromTags(nxArgs.tags);
}
checkForInvalidProjects(nxArgs, allProjects);
let selectedProjects = allProjects.filter(
(p) => nxArgs.projects.indexOf(p.name) > -1
(p) => projects.indexOf(p.name) > -1
);
if (nxArgs.withDeps) {
selectedProjects = Object.values(
Expand Down
10 changes: 9 additions & 1 deletion packages/workspace/src/command-line/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const runOne = [
'scan',
];

const runMany = [...runOne, 'projects', 'quiet', 'all', 'verbose'];
const runMany = [...runOne, 'projects', 'tags', 'quiet', 'all', 'verbose'];

const runAffected = [
...runOne,
Expand Down Expand Up @@ -65,6 +65,7 @@ export interface NxArgs {
withDeps?: boolean;
'with-deps'?: boolean;
projects?: string[];
tags?: string[];
select?: string;
skipNxCache?: boolean;
'skip-nx-cache'?: boolean;
Expand Down Expand Up @@ -102,6 +103,13 @@ export function splitArgsIntoNxArgsAndOverrides(
.split(',')
.map((p: string) => p.trim());
}
if (!nxArgs.tags) {
nxArgs.tags = [];
} else {
nxArgs.tags = (args.tags as string)
.split(',')
.map((p: string) => p.trim());
}
}

if (nxArgs.prod) {
Expand Down
4 changes: 4 additions & 0 deletions scripts/documentation/generate-cli-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,10 @@ const examples = {
command: 'run-many --target=test --projects=proj1,proj2 --with-deps',
description: 'Build proj1 and proj2 and all their dependencies.',
},
{
command: 'run-many --target=test --tags=foo,bar',
description: 'Test all projects that are tagged with foo or bar.',
},
],
migrate: [
{
Expand Down

0 comments on commit 5cf9e11

Please sign in to comment.