forked from nrwl/nx
/
print-affected.ts
136 lines (126 loc) · 4.17 KB
/
print-affected.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
import { getCommandAsString, getOutputs } from '../tasks-runner/utils';
import * as yargs from 'yargs';
import type { NxArgs } from '../utils/command-line-utils';
import { ProjectGraph, ProjectGraphProjectNode } from '../config/project-graph';
import { Task } from '../config/task-graph';
import { ProcessTasks } from '../tasks-runner/create-task-graph';
import { NxJsonConfiguration } from '../config/nx-json';
import { Workspaces } from '../config/workspaces';
import { Hasher } from '../hasher/hasher';
import { hashTask } from '../hasher/hash-task';
import { workspaceRoot } from '../utils/workspace-root';
import { getPackageManagerCommand } from 'nx/src/utils/package-manager';
export async function printAffected(
affectedProjectsWithTargetAndConfig: ProjectGraphProjectNode[],
affectedProjects: ProjectGraphProjectNode[],
projectGraph: ProjectGraph,
{ nxJson }: { nxJson: NxJsonConfiguration },
nxArgs: NxArgs,
overrides: yargs.Arguments
) {
const projectNames = affectedProjects
.filter((p) => (nxArgs.type ? p.type === nxArgs.type : true))
.map((p) => p.name);
const tasksJson = await createTasks(
affectedProjectsWithTargetAndConfig.filter((p) =>
nxArgs.type ? p.type === nxArgs.type : true
),
projectGraph,
nxArgs,
nxJson,
overrides
);
const result = {
tasks: tasksJson,
projects: projectNames,
projectGraph: serializeProjectGraph(projectGraph),
};
if (nxArgs.select) {
console.log(selectPrintAffected(result, nxArgs.select));
} else {
console.log(JSON.stringify(selectPrintAffected(result, null), null, 2));
}
}
async function createTasks(
affectedProjectsWithTargetAndConfig: ProjectGraphProjectNode[],
projectGraph: ProjectGraph,
nxArgs: NxArgs,
nxJson: NxJsonConfiguration,
overrides: yargs.Arguments
) {
const workspaces = new Workspaces(workspaceRoot);
const hasher = new Hasher(projectGraph, nxJson, {});
const execCommand = getPackageManagerCommand().exec;
const tasks: Task[] = affectedProjectsWithTargetAndConfig.map(
(affectedProject) => {
const p = new ProcessTasks({}, projectGraph);
const resolvedConfiguration = p.resolveConfiguration(
affectedProject,
nxArgs.target,
nxArgs.configuration
);
return p.createTask(
p.getId(affectedProject.name, nxArgs.target, resolvedConfiguration),
affectedProject,
nxArgs.target,
resolvedConfiguration,
overrides
);
}
);
await Promise.all(
tasks.map((t) => hashTask(workspaces, hasher, projectGraph, {} as any, t))
);
return tasks.map((task, index) => ({
id: task.id,
overrides,
target: task.target,
hash: task.hash,
command: getCommandAsString(execCommand, task),
outputs: getOutputs(projectGraph.nodes, task),
}));
}
function serializeProjectGraph(projectGraph: ProjectGraph) {
const nodes = Object.values(projectGraph.nodes).map((n) => n.name);
const dependencies = {};
// we don't need external dependencies' dependencies for print-affected
// having them included makes the output unreadable
Object.keys(projectGraph.dependencies).forEach((key) => {
if (!key.startsWith('npm:')) {
dependencies[key] = projectGraph.dependencies[key];
}
});
return { nodes, dependencies };
}
export function selectPrintAffected(wholeJson: any, wholeSelect: string) {
if (!wholeSelect) return wholeJson;
return _select(wholeJson, wholeSelect);
function _select(json: any, select: string) {
if (select.indexOf('.') > -1) {
const [firstKey, ...restKeys] = select.split('.');
const first = json[firstKey];
throwIfEmpty(wholeSelect, first);
const rest = restKeys.join('.');
if (Array.isArray(first)) {
return first.map((q) => _select(q, rest)).join(', ');
} else {
return _select(first, rest);
}
} else {
const res = json[select];
throwIfEmpty(wholeSelect, res);
if (Array.isArray(res)) {
return res.join(', ');
} else {
return res;
}
}
}
}
function throwIfEmpty(select: string, value: any) {
if (value === undefined) {
throw new Error(
`Cannot select '${select}' in the results of print-affected.`
);
}
}