import * as yargs from 'yargs'; import { runCommand } from '../tasks-runner/run-command'; import { NxArgs, splitArgsIntoNxArgsAndOverrides } from './utils'; import { createProjectGraph, isWorkspaceProject, onlyWorkspaceProjects, ProjectGraph, ProjectGraphNode, withDeps, } from '../core/project-graph'; import { readEnvironment } from '../core/file-utils'; import { DefaultReporter } from '../tasks-runner/default-reporter'; import { projectHasTarget } from '../utils/project-graph-utils'; import { output } from '../utils/output'; import { promptForNxCloud } from './prompt-for-nx-cloud'; export async function runMany(parsedArgs: yargs.Arguments) { const { nxArgs, overrides } = splitArgsIntoNxArgsAndOverrides( parsedArgs, 'run-many' ); await promptForNxCloud(nxArgs.scan); const projectGraph = createProjectGraph(); const projects = projectsToRun(nxArgs, projectGraph); const projectMap: Record = {}; projects.forEach((proj) => { projectMap[proj.name] = proj; }); const env = readEnvironment(nxArgs.target, projectMap); const filteredProjects = Object.values(projects).filter( (n) => !parsedArgs.onlyFailed || !env.workspaceResults.getResult(n.name) ); runCommand( filteredProjects, projectGraph, env, nxArgs, overrides, new DefaultReporter(), null ); } function projectsToRun(nxArgs: NxArgs, projectGraph: ProjectGraph) { const allProjects = Object.values(projectGraph.nodes); if (nxArgs.all) { return runnableForTarget(allProjects, nxArgs.target); } else { checkForInvalidProjects(nxArgs, allProjects); let selectedProjects = allProjects.filter( (p) => nxArgs.projects.indexOf(p.name) > -1 ); if (nxArgs.withDeps) { selectedProjects = Object.values( withDeps(projectGraph, selectedProjects).nodes ); } return runnableForTarget(selectedProjects, nxArgs.target, true); } } function checkForInvalidProjects( nxArgs: NxArgs, allProjects: ProjectGraphNode[] ) { const invalid = nxArgs.projects.filter( (name) => !allProjects.find((p) => p.name === name) ); if (invalid.length !== 0) { throw new Error(`Invalid projects: ${invalid.join(', ')}`); } } function runnableForTarget( projects: ProjectGraphNode[], target: string, strict = false ): ProjectGraphNode[] { const notRunnable = [] as ProjectGraphNode[]; const runnable = [] as ProjectGraphNode[]; for (let project of projects) { if (projectHasTarget(project, target)) { runnable.push(project); } else if (isWorkspaceProject(project)) { notRunnable.push(project); } } if (strict && notRunnable.length) { output.warn({ title: `the following do not have configuration for "${target}"`, bodyLines: notRunnable.map((p) => '- ' + p.name), }); } return runnable; }