diff --git a/e2e/run-many.test.ts b/e2e/run-many.test.ts index 274117a1ec06b..c0fa9627d5f17 100644 --- a/e2e/run-many.test.ts +++ b/e2e/run-many.test.ts @@ -13,11 +13,13 @@ forEachCli(() => { describe('Run Many', () => { it('should build specific and all projects', () => { newProject(); + const appA = uniq('appa-rand'); const libA = uniq('liba-rand'); const libB = uniq('libb-rand'); const libC = uniq('libc-rand'); const libD = uniq('libd-rand'); + l(runCLI(`generate @nrwl/angular:app ${appA}`)); l(runCLI(`generate @nrwl/angular:lib ${libA} --publishable --defaults`)); l(runCLI(`generate @nrwl/angular:lib ${libB} --publishable --defaults`)); l(runCLI(`generate @nrwl/angular:lib ${libC} --publishable --defaults`)); @@ -75,6 +77,20 @@ forEachCli(() => { expect(buildWithDeps).toContain('Running target "build" succeeded'); l('=======> testing run many --with-deps complete'); + + l('=======> testing run many --configuration'); + + const buildConfig = l( + runCLI( + `run-many --target=build --projects="${appA},${libA}" --configuration=production` + ) + ); + expect(buildConfig).toContain(`Running target build for projects:`); + expect(buildConfig).toContain(`build ${appA} --configuration production`); + expect(buildConfig).toContain(`build ${libA}`); + expect(buildConfig).toContain('Running target "build" succeeded'); + + l('=======> testing run many --configuration'); }, 1000000); }); }); diff --git a/e2e/tasks-runner-v2.test.ts b/e2e/tasks-runner-v2.test.ts index eca9c0ab418e2..b329f91d46450 100644 --- a/e2e/tasks-runner-v2.test.ts +++ b/e2e/tasks-runner-v2.test.ts @@ -13,7 +13,7 @@ import { forEachCli(() => { describe('Task Runner V2', () => { describe('run-one with deps', () => { - it('should be able to run tasks in parallel', () => { + it('should be able to run the task for the specified project and its dependencies', () => { newProject(); updateFile('nx.json', c => { diff --git a/packages/tao/src/commands/run.ts b/packages/tao/src/commands/run.ts index 32153cfd3eca4..800f8f2d5ec31 100644 --- a/packages/tao/src/commands/run.ts +++ b/packages/tao/src/commands/run.ts @@ -103,13 +103,14 @@ export function validateTargetAndConfiguration( } const targets = architect.targets; + const availableTargets = [...targets.keys()]; const target = targets.get(opts.target); if (!target) { throw new Error( `Could not find target "${opts.target}" in the ${ opts.project } project. Valid targets are: ${terminal.bold( - Object.keys(targets).join(', ') + availableTargets.join(', ') )}` ); } diff --git a/packages/workspace/src/command-line/affected.ts b/packages/workspace/src/command-line/affected.ts index 0017383c32021..1cf81279b6626 100644 --- a/packages/workspace/src/command-line/affected.ts +++ b/packages/workspace/src/command-line/affected.ts @@ -14,7 +14,7 @@ import { } from '../core/project-graph'; import { calculateFileChanges, readEnvironment } from '../core/file-utils'; import { printAffected } from './print-affected'; -import { projectHasTargetAndConfiguration } from '../utils/project-has-target-and-configuration'; +import { projectHasTarget } from '../utils/project-graph-utils'; import { DefaultReporter } from '../tasks-runner/default-reporter'; export function affected(command: string, parsedArgs: yargs.Arguments): void { @@ -87,12 +87,12 @@ export function affected(command: string, parsedArgs: yargs.Arguments): void { case 'print-affected': if (nxArgs.target) { - const projectWithTargetAndConfig = allProjectsWithTargetAndConfiguration( + const projectsWithTarget = allProjectsWithTarget( affectedProjects, nxArgs ); printAffected( - projectWithTargetAndConfig, + projectsWithTarget, affectedProjects, projectGraph, nxArgs, @@ -104,13 +104,13 @@ export function affected(command: string, parsedArgs: yargs.Arguments): void { break; case 'affected': { - const projectWithTargetAndConfig = allProjectsWithTargetAndConfiguration( + const projectsWithTarget = allProjectsWithTarget( affectedProjects, nxArgs ); printArgsWarning(nxArgs); runCommand( - projectWithTargetAndConfig, + projectsWithTarget, projectGraph, env, nxArgs, @@ -126,13 +126,8 @@ export function affected(command: string, parsedArgs: yargs.Arguments): void { } } -function allProjectsWithTargetAndConfiguration( - projects: ProjectGraphNode[], - nxArgs: NxArgs -) { - return projects.filter(p => - projectHasTargetAndConfiguration(p, nxArgs.target, nxArgs.configuration) - ); +function allProjectsWithTarget(projects: ProjectGraphNode[], nxArgs: NxArgs) { + return projects.filter(p => projectHasTarget(p, nxArgs.target)); } function printError(e: any, verbose?: boolean) { diff --git a/packages/workspace/src/command-line/run-many.ts b/packages/workspace/src/command-line/run-many.ts index f39fb36f38798..f6591e82324b7 100644 --- a/packages/workspace/src/command-line/run-many.ts +++ b/packages/workspace/src/command-line/run-many.ts @@ -1,7 +1,6 @@ import * as yargs from 'yargs'; import { runCommand } from '../tasks-runner/run-command'; -import { splitArgsIntoNxArgsAndOverrides, NxArgs } from './utils'; -import { output } from '../utils/output'; +import { NxArgs, splitArgsIntoNxArgsAndOverrides } from './utils'; import { createProjectGraph, ProjectGraph, @@ -9,8 +8,9 @@ import { withDeps } from '../core/project-graph'; import { readEnvironment } from '../core/file-utils'; -import { projectHasTargetAndConfiguration } from '../utils/project-has-target-and-configuration'; import { DefaultReporter } from '../tasks-runner/default-reporter'; +import { projectHasTarget } from '../utils/project-graph-utils'; +import { output } from '@nrwl/workspace'; export function runMany(parsedArgs: yargs.Arguments): void { const { nxArgs, overrides } = splitArgsIntoNxArgsAndOverrides( @@ -37,11 +37,7 @@ export function runMany(parsedArgs: yargs.Arguments): void { function projectsToRun(nxArgs: NxArgs, projectGraph: ProjectGraph) { const allProjects = Object.values(projectGraph.nodes); if (nxArgs.all) { - return runnableForTargetAndConfiguration( - allProjects, - nxArgs.target, - nxArgs.configuration - ); + return runnableForTarget(allProjects, nxArgs.target); } else { checkForInvalidProjects(nxArgs, allProjects); let selectedProjects = allProjects.filter( @@ -52,12 +48,7 @@ function projectsToRun(nxArgs: NxArgs, projectGraph: ProjectGraph) { withDeps(projectGraph, selectedProjects).nodes ); } - return runnableForTargetAndConfiguration( - selectedProjects, - nxArgs.target, - nxArgs.configuration, - true - ); + return runnableForTarget(selectedProjects, nxArgs.target, true); } } @@ -73,17 +64,16 @@ function checkForInvalidProjects( } } -function runnableForTargetAndConfiguration( +function runnableForTarget( projects: ProjectGraphNode[], target: string, - configuration?: string, strict = false ): ProjectGraphNode[] { const notRunnable = []; const runnable = []; for (let project of projects) { - if (projectHasTargetAndConfiguration(project, target, configuration)) { + if (projectHasTarget(project, target)) { runnable.push(project); } else { notRunnable.push(project); diff --git a/packages/workspace/src/command-line/run-one.ts b/packages/workspace/src/command-line/run-one.ts index 09c5b950357bd..82e97556c1d9f 100644 --- a/packages/workspace/src/command-line/run-one.ts +++ b/packages/workspace/src/command-line/run-one.ts @@ -1,14 +1,9 @@ import { runCommand } from '../tasks-runner/run-command'; -import { - createProjectGraph, - onlyWorkspaceProjects, - ProjectGraph, - withDeps -} from '../core/project-graph'; +import { createProjectGraph, ProjectGraph } from '../core/project-graph'; import { readEnvironment } from '../core/file-utils'; import { EmptyReporter } from '../tasks-runner/empty-reporter'; import { splitArgsIntoNxArgsAndOverrides } from './utils'; -import { DefaultReporter } from '../tasks-runner/default-reporter'; +import { projectHasTarget } from '../utils/project-graph-utils'; export function runOne(opts: { project: string; @@ -30,11 +25,12 @@ export function runOne(opts: { const { projects, projectsMap } = getProjects( projectGraph, nxArgs.withDeps, - opts.project + opts.project, + opts.target ); const env = readEnvironment(opts.target, projectsMap); const reporter = nxArgs.withDeps - ? new DefaultReporter() + ? new (require(`../tasks-runner/default-reporter`)).DefaultReporter() : new EmptyReporter(); runCommand(projects, projectGraph, env, nxArgs, overrides, reporter); @@ -43,20 +39,24 @@ export function runOne(opts: { function getProjects( projectGraph: ProjectGraph, includeDeps: boolean, - project: string -) { + project: string, + target: string +): any { let projects = [projectGraph.nodes[project]]; let projectsMap = { [project]: projectGraph.nodes[project] }; if (includeDeps) { - const projectWithDeps = onlyWorkspaceProjects( - withDeps(projectGraph, projects) - ).nodes; + const s = require(`../core/project-graph`); + const deps = s.onlyWorkspaceProjects(s.withDeps(projectGraph, projects)) + .nodes; + const projectsWithTarget = Object.values(deps).filter((p: any) => + projectHasTarget(p, target) + ); return { - projects: Object.values(projectWithDeps), - projectsMap: projectWithDeps + projects: projectsWithTarget, + projectsMap: deps }; } else { return { projects, projectsMap }; diff --git a/packages/workspace/src/core/project-graph/project-graph-models.ts b/packages/workspace/src/core/project-graph/project-graph-models.ts index 95dd525b00dad..2d203e42d2653 100644 --- a/packages/workspace/src/core/project-graph/project-graph-models.ts +++ b/packages/workspace/src/core/project-graph/project-graph-models.ts @@ -16,7 +16,11 @@ export enum DependencyType { export interface ProjectGraphNode { type: string; name: string; - data: T & { files: FileData[]; [k: string]: any }; + data: T & { + architect?: { [k: string]: any }; + files: FileData[]; + [k: string]: any; + }; } export type ProjectGraphNodeRecords = Record; diff --git a/packages/workspace/src/tasks-runner/run-command.ts b/packages/workspace/src/tasks-runner/run-command.ts index e71c2098e0610..ca872d02e52e4 100644 --- a/packages/workspace/src/tasks-runner/run-command.ts +++ b/packages/workspace/src/tasks-runner/run-command.ts @@ -8,6 +8,7 @@ import { Environment, NxJson } from '../core/shared-interfaces'; import { NxArgs } from '@nrwl/workspace/src/command-line/utils'; import { isRelativePath } from '../utils/fileutils'; import { Hasher } from './hasher'; +import { projectHasTargetAndConfiguration } from '../utils/project-graph-utils'; type RunArgs = yargs.Arguments & ReporterArgs; @@ -26,14 +27,14 @@ export async function runCommand( ...overrides }); - const tasks: Task[] = projectsToRun.map(project => - createTask({ + const tasks: Task[] = projectsToRun.map(project => { + return createTask({ project, target: nxArgs.target, configuration: nxArgs.configuration, overrides: overrides - }) - ); + }); + }); if (tasksRunner !== require('./default-tasks-runner').defaultTasksRunner) { const hasher = new Hasher(projectGraph, nxJson, tasksOptions); @@ -96,10 +97,17 @@ export function createTask({ configuration, overrides }: TaskParams): Task { + const config = projectHasTargetAndConfiguration( + project, + target, + configuration + ) + ? configuration + : undefined; const qualifiedTarget = { project: project.name, target, - configuration + configuration: config }; return { id: getId(qualifiedTarget), diff --git a/packages/workspace/src/utils/project-graph-utils.ts b/packages/workspace/src/utils/project-graph-utils.ts new file mode 100644 index 0000000000000..699d97015f039 --- /dev/null +++ b/packages/workspace/src/utils/project-graph-utils.ts @@ -0,0 +1,19 @@ +import { ProjectGraphNode } from '../core/project-graph/project-graph-models'; + +export function projectHasTarget(project: ProjectGraphNode, target: string) { + return ( + project.data && project.data.architect && project.data.architect[target] + ); +} + +export function projectHasTargetAndConfiguration( + project: ProjectGraphNode, + target: string, + configuration: string +) { + return ( + projectHasTarget(project, target) && + project.data.architect[target].configurations && + project.data.architect[target].configurations[configuration] + ); +} diff --git a/packages/workspace/src/utils/project-has-target-and-configuration.ts b/packages/workspace/src/utils/project-has-target-and-configuration.ts deleted file mode 100644 index fe21fbecfcad9..0000000000000 --- a/packages/workspace/src/utils/project-has-target-and-configuration.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { ProjectGraphNode } from '@nrwl/workspace/src/core/project-graph'; - -export function projectHasTargetAndConfiguration( - project: ProjectGraphNode, - target: string, - configuration?: string -) { - if ( - !project.data || - !project.data.architect || - !project.data.architect[target] - ) { - return false; - } - - if (!configuration) { - return !!project.data.architect[target]; - } else { - return ( - project.data.architect[target].configurations && - project.data.architect[target].configurations[configuration] - ); - } -}