/
static-run-one-terminal-output-life-cycle.ts
124 lines (113 loc) · 3.52 KB
/
static-run-one-terminal-output-life-cycle.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
import type { Task } from '@nrwl/devkit';
import { output } from '../../utilities/output';
import { TaskStatus } from '../tasks-runner';
import { getCommandArgsForTask } from '../utils';
import type { LifeCycle } from '../life-cycle';
/**
* The following life cycle's outputs are static, meaning no previous content
* is rewritten or modified as new outputs are added. It is therefore intended
* for use in CI environments.
*
* For the common case of a user executing a command on their local machine,
* the dynamic equivalent of this life cycle is usually preferable.
*/
export class StaticRunOneTerminalOutputLifeCycle implements LifeCycle {
failedTasks = [] as Task[];
cachedTasks = [] as Task[];
constructor(
private readonly initiatingProject: string,
private readonly projectNames: string[],
private readonly tasks: Task[],
private readonly args: {
target?: string;
configuration?: string;
}
) {}
startCommand(): void {
if (process.env.NX_INVOKED_BY_RUNNER) {
return;
}
const numberOfDeps = this.tasks.length - 1;
if (numberOfDeps > 0) {
output.log({
color: 'cyan',
title: `Running target ${output.bold(
this.args.target
)} for project ${output.bold(this.initiatingProject)} and ${output.bold(
numberOfDeps
)} task(s) it depends on`,
});
output.addVerticalSeparatorWithoutNewLines('cyan');
}
}
endCommand(): void {
// Silent for a single task
if (process.env.NX_INVOKED_BY_RUNNER) {
return;
}
output.addNewline();
if (this.failedTasks.length === 0) {
output.addVerticalSeparatorWithoutNewLines('green');
const bodyLines =
this.cachedTasks.length > 0
? [
output.dim(
`Nx read the output from the cache instead of running the command for ${this.cachedTasks.length} out of ${this.tasks.length} tasks.`
),
]
: [];
output.success({
title: `Successfully ran target ${output.bold(
this.args.target
)} for project ${output.bold(this.initiatingProject)}`,
bodyLines,
});
} else {
output.addVerticalSeparatorWithoutNewLines('red');
const bodyLines = [
output.dim('Failed tasks:'),
'',
...this.failedTasks.map((task) => `${output.dim('-')} ${task.id}`),
'',
`${output.dim('Hint: run the command with')} --verbose ${output.dim(
'for more details.'
)}`,
];
output.error({
title: `Running target "${this.initiatingProject}:${this.args.target}" failed`,
bodyLines,
});
}
}
endTasks(
taskResults: { task: Task; status: TaskStatus; code: number }[]
): void {
for (let t of taskResults) {
if (t.status === 'failure') {
this.failedTasks.push(t.task);
} else if (t.status === 'local-cache') {
this.cachedTasks.push(t.task);
} else if (t.status === 'local-cache-kept-existing') {
this.cachedTasks.push(t.task);
} else if (t.status === 'remote-cache') {
this.cachedTasks.push(t.task);
}
}
}
printTaskTerminalOutput(
task: Task,
status: TaskStatus,
terminalOutput: string
) {
if (
status === 'success' ||
status === 'failure' ||
task.target.project === this.initiatingProject
) {
const args = getCommandArgsForTask(task);
output.logCommand(args.join(' '), status);
output.addNewline();
process.stdout.write(terminalOutput);
}
}
}