nx 21.0.0-canary.20250422-8619c1d → 21.0.0-canary.20250424-e23b25f
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +11 -11
- package/src/command-line/init/configure-plugins.js +5 -3
- package/src/command-line/init/implementation/utils.d.ts +2 -1
- package/src/command-line/init/implementation/utils.js +2 -1
- package/src/command-line/init/init-v2.js +8 -7
- package/src/core/graph/main.js +1 -1
- package/src/executors/run-commands/run-commands.impl.d.ts +1 -2
- package/src/executors/run-commands/run-commands.impl.js +1 -1
- package/src/executors/run-commands/running-tasks.d.ts +5 -2
- package/src/executors/run-commands/running-tasks.js +42 -6
- package/src/native/index.d.ts +4 -1
- package/src/native/nx.wasm32-wasi.wasm +0 -0
- package/src/tasks-runner/default-tasks-runner.js +1 -1
- package/src/tasks-runner/forked-process-task-runner.js +3 -0
- package/src/tasks-runner/init-tasks-runner.js +2 -1
- package/src/tasks-runner/life-cycle.d.ts +6 -2
- package/src/tasks-runner/life-cycle.js +16 -2
- package/src/tasks-runner/life-cycles/tui-summary-life-cycle.d.ts +2 -1
- package/src/tasks-runner/life-cycles/tui-summary-life-cycle.js +16 -10
- package/src/tasks-runner/run-command.d.ts +2 -1
- package/src/tasks-runner/run-command.js +14 -6
- package/src/tasks-runner/running-tasks/node-child-process.js +4 -11
- package/src/tasks-runner/running-tasks/running-task.d.ts +3 -0
- package/src/tasks-runner/running-tasks/shared-running-task.d.ts +14 -0
- package/src/tasks-runner/running-tasks/shared-running-task.js +30 -0
- package/src/tasks-runner/task-orchestrator.d.ts +6 -3
- package/src/tasks-runner/task-orchestrator.js +79 -23
- package/src/tasks-runner/tasks-runner.d.ts +1 -0
- package/src/tasks-runner/tasks-schedule.d.ts +1 -0
- package/src/tasks-runner/tasks-schedule.js +9 -0
- package/src/tasks-runner/utils.js +2 -0
@@ -1,5 +1,4 @@
|
|
1
1
|
import { ExecutorContext } from '../../config/misc-interfaces';
|
2
|
-
import { PseudoTtyProcess } from '../../tasks-runner/pseudo-terminal';
|
3
2
|
import { ParallelRunningTasks, SeriallyRunningTasks } from './running-tasks';
|
4
3
|
export declare const LARGE_BUFFER: number;
|
5
4
|
export type Json = {
|
@@ -55,5 +54,5 @@ export default function (options: RunCommandsOptions, context: ExecutorContext):
|
|
55
54
|
success: boolean;
|
56
55
|
terminalOutput: string;
|
57
56
|
}>;
|
58
|
-
export declare function runCommands(options: RunCommandsOptions, context: ExecutorContext): Promise<PseudoTtyProcess | ParallelRunningTasks | SeriallyRunningTasks>;
|
57
|
+
export declare function runCommands(options: RunCommandsOptions, context: ExecutorContext): Promise<import("../../tasks-runner/pseudo-terminal").PseudoTtyProcess | ParallelRunningTasks | SeriallyRunningTasks>;
|
59
58
|
export declare function interpolateArgsIntoCommand(command: string, opts: Pick<NormalizedRunCommandsOptions, 'args' | 'parsedArgs' | '__unparsed__' | 'unknownOptions' | 'unparsedCommandArgs'>, forwardAllArgs: boolean): string;
|
@@ -57,7 +57,7 @@ async function runCommands(options, context) {
|
|
57
57
|
const runningTask = isSingleCommandAndCanUsePseudoTerminal
|
58
58
|
? await (0, running_tasks_1.runSingleCommandWithPseudoTerminal)(normalized, context)
|
59
59
|
: options.parallel
|
60
|
-
? new running_tasks_1.ParallelRunningTasks(normalized, context
|
60
|
+
? new running_tasks_1.ParallelRunningTasks(normalized, context)
|
61
61
|
: new running_tasks_1.SeriallyRunningTasks(normalized, context, tuiEnabled);
|
62
62
|
return runningTask;
|
63
63
|
}
|
@@ -4,16 +4,17 @@ import { PseudoTtyProcess } from '../../tasks-runner/pseudo-terminal';
|
|
4
4
|
import { RunningTask } from '../../tasks-runner/running-tasks/running-task';
|
5
5
|
import { NormalizedRunCommandsOptions } from './run-commands.impl';
|
6
6
|
export declare class ParallelRunningTasks implements RunningTask {
|
7
|
-
private readonly tuiEnabled;
|
8
7
|
private readonly childProcesses;
|
9
8
|
private readyWhenStatus;
|
10
9
|
private readonly streamOutput;
|
11
10
|
private exitCallbacks;
|
12
|
-
|
11
|
+
private outputCallbacks;
|
12
|
+
constructor(options: NormalizedRunCommandsOptions, context: ExecutorContext);
|
13
13
|
getResults(): Promise<{
|
14
14
|
code: number;
|
15
15
|
terminalOutput: string;
|
16
16
|
}>;
|
17
|
+
onOutput(cb: (terminalOutput: string) => void): void;
|
17
18
|
onExit(cb: (code: number, terminalOutput: string) => void): void;
|
18
19
|
send(message: Serializable): void;
|
19
20
|
kill(signal?: NodeJS.Signals | number): Promise<void>;
|
@@ -26,12 +27,14 @@ export declare class SeriallyRunningTasks implements RunningTask {
|
|
26
27
|
private exitCallbacks;
|
27
28
|
private code;
|
28
29
|
private error;
|
30
|
+
private outputCallbacks;
|
29
31
|
constructor(options: NormalizedRunCommandsOptions, context: ExecutorContext, tuiEnabled: boolean);
|
30
32
|
getResults(): Promise<{
|
31
33
|
code: number;
|
32
34
|
terminalOutput: string;
|
33
35
|
}>;
|
34
36
|
onExit(cb: (code: number, terminalOutput: string) => void): void;
|
37
|
+
onOutput(cb: (terminalOutput: string) => void): void;
|
35
38
|
send(message: Serializable): void;
|
36
39
|
kill(signal?: NodeJS.Signals | number): void | Promise<void>;
|
37
40
|
private run;
|
@@ -12,9 +12,9 @@ const task_env_1 = require("../../tasks-runner/task-env");
|
|
12
12
|
const exit_codes_1 = require("../../utils/exit-codes");
|
13
13
|
const run_commands_impl_1 = require("./run-commands.impl");
|
14
14
|
class ParallelRunningTasks {
|
15
|
-
constructor(options, context
|
16
|
-
this.tuiEnabled = tuiEnabled;
|
15
|
+
constructor(options, context) {
|
17
16
|
this.exitCallbacks = [];
|
17
|
+
this.outputCallbacks = [];
|
18
18
|
this.childProcesses = options.commands.map((commandConfig) => new RunningNodeProcess(commandConfig, options.color, calculateCwd(options.cwd, context), options.env ?? {}, options.readyWhenStatus, options.streamOutput, options.envFile));
|
19
19
|
this.readyWhenStatus = options.readyWhenStatus;
|
20
20
|
this.streamOutput = options.streamOutput;
|
@@ -27,6 +27,9 @@ class ParallelRunningTasks {
|
|
27
27
|
});
|
28
28
|
});
|
29
29
|
}
|
30
|
+
onOutput(cb) {
|
31
|
+
this.outputCallbacks.push(cb);
|
32
|
+
}
|
30
33
|
onExit(cb) {
|
31
34
|
this.exitCallbacks.push(cb);
|
32
35
|
}
|
@@ -48,6 +51,11 @@ class ParallelRunningTasks {
|
|
48
51
|
async run() {
|
49
52
|
if (this.readyWhenStatus.length) {
|
50
53
|
let { childProcess, result: { code, terminalOutput }, } = await Promise.race(this.childProcesses.map((childProcess) => new Promise((res) => {
|
54
|
+
childProcess.onOutput((terminalOutput) => {
|
55
|
+
for (const cb of this.outputCallbacks) {
|
56
|
+
cb(terminalOutput);
|
57
|
+
}
|
58
|
+
});
|
51
59
|
childProcess.onExit((code, terminalOutput) => {
|
52
60
|
res({
|
53
61
|
childProcess,
|
@@ -67,10 +75,18 @@ class ParallelRunningTasks {
|
|
67
75
|
}
|
68
76
|
}
|
69
77
|
else {
|
70
|
-
const results = await Promise.all(this.childProcesses.map((childProcess) =>
|
71
|
-
childProcess
|
72
|
-
|
73
|
-
|
78
|
+
const results = await Promise.all(this.childProcesses.map(async (childProcess) => {
|
79
|
+
childProcess.onOutput((terminalOutput) => {
|
80
|
+
for (const cb of this.outputCallbacks) {
|
81
|
+
cb(terminalOutput);
|
82
|
+
}
|
83
|
+
});
|
84
|
+
const result = await childProcess.getResults();
|
85
|
+
return {
|
86
|
+
childProcess,
|
87
|
+
result,
|
88
|
+
};
|
89
|
+
}));
|
74
90
|
let terminalOutput = results
|
75
91
|
.map((r) => r.result.terminalOutput)
|
76
92
|
.join('\r\n');
|
@@ -103,6 +119,7 @@ class SeriallyRunningTasks {
|
|
103
119
|
this.currentProcess = null;
|
104
120
|
this.exitCallbacks = [];
|
105
121
|
this.code = 0;
|
122
|
+
this.outputCallbacks = [];
|
106
123
|
this.run(options, context)
|
107
124
|
.catch((e) => {
|
108
125
|
this.error = e;
|
@@ -128,6 +145,9 @@ class SeriallyRunningTasks {
|
|
128
145
|
onExit(cb) {
|
129
146
|
this.exitCallbacks.push(cb);
|
130
147
|
}
|
148
|
+
onOutput(cb) {
|
149
|
+
this.outputCallbacks.push(cb);
|
150
|
+
}
|
131
151
|
send(message) {
|
132
152
|
throw new Error('Not implemented');
|
133
153
|
}
|
@@ -138,6 +158,11 @@ class SeriallyRunningTasks {
|
|
138
158
|
for (const c of options.commands) {
|
139
159
|
const childProcess = await this.createProcess(c, options.color, calculateCwd(options.cwd, context), options.processEnv ?? options.env ?? {}, options.usePty, options.streamOutput, options.tty, options.envFile);
|
140
160
|
this.currentProcess = childProcess;
|
161
|
+
childProcess.onOutput((output) => {
|
162
|
+
for (const cb of this.outputCallbacks) {
|
163
|
+
cb(output);
|
164
|
+
}
|
165
|
+
});
|
141
166
|
let { code, terminalOutput } = await childProcess.getResults();
|
142
167
|
this.terminalOutput += terminalOutput;
|
143
168
|
this.code = code;
|
@@ -173,6 +198,7 @@ class RunningNodeProcess {
|
|
173
198
|
this.readyWhenStatus = readyWhenStatus;
|
174
199
|
this.terminalOutput = '';
|
175
200
|
this.exitCallbacks = [];
|
201
|
+
this.outputCallbacks = [];
|
176
202
|
env = processEnv(color, cwd, env, envFile);
|
177
203
|
this.command = commandConfig.command;
|
178
204
|
this.terminalOutput = chalk.dim('> ') + commandConfig.command + '\r\n\r\n';
|
@@ -194,6 +220,9 @@ class RunningNodeProcess {
|
|
194
220
|
});
|
195
221
|
});
|
196
222
|
}
|
223
|
+
onOutput(cb) {
|
224
|
+
this.outputCallbacks.push(cb);
|
225
|
+
}
|
197
226
|
onExit(cb) {
|
198
227
|
this.exitCallbacks.push(cb);
|
199
228
|
}
|
@@ -212,10 +241,16 @@ class RunningNodeProcess {
|
|
212
241
|
});
|
213
242
|
});
|
214
243
|
}
|
244
|
+
triggerOutputListeners(output) {
|
245
|
+
for (const cb of this.outputCallbacks) {
|
246
|
+
cb(output);
|
247
|
+
}
|
248
|
+
}
|
215
249
|
addListeners(commandConfig, streamOutput) {
|
216
250
|
this.childProcess.stdout.on('data', (data) => {
|
217
251
|
const output = addColorAndPrefix(data, commandConfig);
|
218
252
|
this.terminalOutput += output;
|
253
|
+
this.triggerOutputListeners(output);
|
219
254
|
if (streamOutput) {
|
220
255
|
process.stdout.write(output);
|
221
256
|
}
|
@@ -229,6 +264,7 @@ class RunningNodeProcess {
|
|
229
264
|
this.childProcess.stderr.on('data', (err) => {
|
230
265
|
const output = addColorAndPrefix(err, commandConfig);
|
231
266
|
this.terminalOutput += output;
|
267
|
+
this.triggerOutputListeners(output);
|
232
268
|
if (streamOutput) {
|
233
269
|
process.stderr.write(output);
|
234
270
|
}
|
package/src/native/index.d.ts
CHANGED
@@ -17,6 +17,8 @@ export declare class AppLifeCycle {
|
|
17
17
|
endCommand(): void
|
18
18
|
__init(doneCallback: () => any): void
|
19
19
|
registerRunningTask(taskId: string, parserAndWriter: ExternalObject<[ParserArc, WriterArc]>): void
|
20
|
+
registerRunningTaskWithEmptyParser(taskId: string): void
|
21
|
+
appendTaskOutput(taskId: string, output: string): void
|
20
22
|
setTaskStatus(taskId: string, status: TaskStatus): void
|
21
23
|
registerForcedShutdownCallback(forcedShutdownCallback: () => any): void
|
22
24
|
__setCloudMessage(message: string): Promise<void>
|
@@ -322,7 +324,8 @@ export declare const enum TaskStatus {
|
|
322
324
|
RemoteCache = 5,
|
323
325
|
NotStarted = 6,
|
324
326
|
InProgress = 7,
|
325
|
-
Shared = 8
|
327
|
+
Shared = 8,
|
328
|
+
Stopped = 9
|
326
329
|
}
|
327
330
|
|
328
331
|
export interface TaskTarget {
|
Binary file
|
@@ -65,7 +65,7 @@ const defaultTasksRunner = async (tasks, options, context) => {
|
|
65
65
|
};
|
66
66
|
exports.defaultTasksRunner = defaultTasksRunner;
|
67
67
|
async function runAllTasks(options, context) {
|
68
|
-
const orchestrator = new task_orchestrator_1.TaskOrchestrator(context.hasher, context.initiatingProject, context.projectGraph, context.taskGraph, context.nxJson, options, context.nxArgs?.nxBail, context.daemon, context.nxArgs?.outputStyle);
|
68
|
+
const orchestrator = new task_orchestrator_1.TaskOrchestrator(context.hasher, context.initiatingProject, context.initiatingTasks, context.projectGraph, context.taskGraph, context.nxJson, options, context.nxArgs?.nxBail, context.daemon, context.nxArgs?.outputStyle);
|
69
69
|
return orchestrator.run();
|
70
70
|
}
|
71
71
|
exports.default = exports.defaultTasksRunner;
|
@@ -140,6 +140,9 @@ class ForkedProcessTaskRunner {
|
|
140
140
|
}
|
141
141
|
this.pseudoTerminals.delete(pseudoTerminal);
|
142
142
|
this.processes.delete(p);
|
143
|
+
if (!streamOutput) {
|
144
|
+
this.options.lifeCycle.printTaskTerminalOutput(task, code === 0 ? 'success' : 'failure', terminalOutput);
|
145
|
+
}
|
143
146
|
this.writeTerminalOutput(temporaryOutputPath, terminalOutput);
|
144
147
|
});
|
145
148
|
return p;
|
@@ -61,6 +61,7 @@ async function initTasksRunner(nxArgs) {
|
|
61
61
|
nxArgs: { ...nxArgs, parallel: opts.parallel },
|
62
62
|
loadDotEnvFiles: true,
|
63
63
|
initiatingProject: null,
|
64
|
+
initiatingTasks: [],
|
64
65
|
});
|
65
66
|
return {
|
66
67
|
status: Object.values(taskResults).some((taskResult) => taskResult.status === 'failure' || taskResult.status === 'skipped')
|
@@ -98,7 +99,7 @@ async function createOrchestrator(tasks, projectGraph, taskGraphForHashing, nxJs
|
|
98
99
|
return acc;
|
99
100
|
}, {}),
|
100
101
|
};
|
101
|
-
const orchestrator = new task_orchestrator_1.TaskOrchestrator(hasher, null, projectGraph, taskGraph, nxJson, { ...options, parallel: tasks.length, lifeCycle: compositedLifeCycle }, false, client_1.daemonClient, undefined, taskGraphForHashing);
|
102
|
+
const orchestrator = new task_orchestrator_1.TaskOrchestrator(hasher, null, [], projectGraph, taskGraph, nxJson, { ...options, parallel: tasks.length, lifeCycle: compositedLifeCycle }, false, client_1.daemonClient, undefined, taskGraphForHashing);
|
102
103
|
await orchestrator.init();
|
103
104
|
await Promise.all(tasks.map((task) => orchestrator.processTask(task.id)));
|
104
105
|
return orchestrator;
|
@@ -36,7 +36,9 @@ export interface LifeCycle {
|
|
36
36
|
startTasks?(task: Task[], metadata: TaskMetadata): void | Promise<void>;
|
37
37
|
endTasks?(taskResults: TaskResult[], metadata: TaskMetadata): void | Promise<void>;
|
38
38
|
printTaskTerminalOutput?(task: Task, status: TaskStatus, output: string): void;
|
39
|
-
registerRunningTask?(taskId: string, parserAndWriter: ExternalObject<[any, any]>):
|
39
|
+
registerRunningTask?(taskId: string, parserAndWriter: ExternalObject<[any, any]>): void;
|
40
|
+
registerRunningTaskWithEmptyParser?(taskId: string): void;
|
41
|
+
appendTaskOutput?(taskId: string, output: string): void;
|
40
42
|
setTaskStatus?(taskId: string, status: NativeTaskStatus): void;
|
41
43
|
registerForcedShutdownCallback?(callback: () => void): void;
|
42
44
|
}
|
@@ -51,7 +53,9 @@ export declare class CompositeLifeCycle implements LifeCycle {
|
|
51
53
|
startTasks(tasks: Task[], metadata: TaskMetadata): Promise<void>;
|
52
54
|
endTasks(taskResults: TaskResult[], metadata: TaskMetadata): Promise<void>;
|
53
55
|
printTaskTerminalOutput(task: Task, status: TaskStatus, output: string): void;
|
54
|
-
registerRunningTask(taskId: string, parserAndWriter: ExternalObject<[any, any]>):
|
56
|
+
registerRunningTask(taskId: string, parserAndWriter: ExternalObject<[any, any]>): void;
|
57
|
+
registerRunningTaskWithEmptyParser(taskId: string): void;
|
58
|
+
appendTaskOutput(taskId: string, output: string): void;
|
55
59
|
setTaskStatus(taskId: string, status: NativeTaskStatus): void;
|
56
60
|
registerForcedShutdownCallback(callback: () => void): void;
|
57
61
|
}
|
@@ -67,10 +67,24 @@ class CompositeLifeCycle {
|
|
67
67
|
}
|
68
68
|
}
|
69
69
|
}
|
70
|
-
|
70
|
+
registerRunningTask(taskId, parserAndWriter) {
|
71
71
|
for (let l of this.lifeCycles) {
|
72
72
|
if (l.registerRunningTask) {
|
73
|
-
|
73
|
+
l.registerRunningTask(taskId, parserAndWriter);
|
74
|
+
}
|
75
|
+
}
|
76
|
+
}
|
77
|
+
registerRunningTaskWithEmptyParser(taskId) {
|
78
|
+
for (let l of this.lifeCycles) {
|
79
|
+
if (l.registerRunningTaskWithEmptyParser) {
|
80
|
+
l.registerRunningTaskWithEmptyParser(taskId);
|
81
|
+
}
|
82
|
+
}
|
83
|
+
}
|
84
|
+
appendTaskOutput(taskId, output) {
|
85
|
+
for (let l of this.lifeCycles) {
|
86
|
+
if (l.appendTaskOutput) {
|
87
|
+
l.appendTaskOutput(taskId, output);
|
74
88
|
}
|
75
89
|
}
|
76
90
|
}
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import { Task } from '../../config/task-graph';
|
2
2
|
import type { LifeCycle } from '../life-cycle';
|
3
|
-
export declare function getTuiTerminalSummaryLifeCycle({ projectNames, tasks, args, overrides, initiatingProject, resolveRenderIsDonePromise, }: {
|
3
|
+
export declare function getTuiTerminalSummaryLifeCycle({ projectNames, tasks, args, overrides, initiatingProject, initiatingTasks, resolveRenderIsDonePromise, }: {
|
4
4
|
projectNames: string[];
|
5
5
|
tasks: Task[];
|
6
6
|
args: {
|
@@ -10,6 +10,7 @@ export declare function getTuiTerminalSummaryLifeCycle({ projectNames, tasks, ar
|
|
10
10
|
};
|
11
11
|
overrides: Record<string, unknown>;
|
12
12
|
initiatingProject: string;
|
13
|
+
initiatingTasks: Task[];
|
13
14
|
resolveRenderIsDonePromise: (value: void) => void;
|
14
15
|
}): {
|
15
16
|
lifeCycle: Partial<LifeCycle>;
|
@@ -10,7 +10,7 @@ const figures = require("figures");
|
|
10
10
|
const LEFT_PAD = ` `;
|
11
11
|
const SPACER = ` `;
|
12
12
|
const EXTENDED_LEFT_PAD = ` `;
|
13
|
-
function getTuiTerminalSummaryLifeCycle({ projectNames, tasks, args, overrides, initiatingProject, resolveRenderIsDonePromise, }) {
|
13
|
+
function getTuiTerminalSummaryLifeCycle({ projectNames, tasks, args, overrides, initiatingProject, initiatingTasks, resolveRenderIsDonePromise, }) {
|
14
14
|
const lifeCycle = {};
|
15
15
|
const start = process.hrtime();
|
16
16
|
const targets = args.targets;
|
@@ -19,6 +19,7 @@ function getTuiTerminalSummaryLifeCycle({ projectNames, tasks, args, overrides,
|
|
19
19
|
let totalSuccessfulTasks = 0;
|
20
20
|
let totalFailedTasks = 0;
|
21
21
|
let totalCompletedTasks = 0;
|
22
|
+
let totalStoppedTasks = 0;
|
22
23
|
let timeTakenText;
|
23
24
|
const failedTasks = new Set();
|
24
25
|
const inProgressTasks = new Set();
|
@@ -30,14 +31,19 @@ function getTuiTerminalSummaryLifeCycle({ projectNames, tasks, args, overrides,
|
|
30
31
|
}
|
31
32
|
};
|
32
33
|
lifeCycle.printTaskTerminalOutput = (task, taskStatus, terminalOutput) => {
|
33
|
-
tasksToTerminalOutputs[task.id] = { terminalOutput, taskStatus };
|
34
34
|
taskIdsInOrderOfCompletion.push(task.id);
|
35
|
+
tasksToTerminalOutputs[task.id] = { terminalOutput, taskStatus };
|
36
|
+
};
|
37
|
+
lifeCycle.setTaskStatus = (taskId, taskStatus) => {
|
38
|
+
if (taskStatus === 9 /* NativeTaskStatus.Stopped */) {
|
39
|
+
totalStoppedTasks++;
|
40
|
+
}
|
35
41
|
};
|
36
42
|
lifeCycle.endTasks = (taskResults) => {
|
37
|
-
for (
|
43
|
+
for (const { task, status } of taskResults) {
|
38
44
|
totalCompletedTasks++;
|
39
|
-
inProgressTasks.delete(
|
40
|
-
switch (
|
45
|
+
inProgressTasks.delete(task.id);
|
46
|
+
switch (status) {
|
41
47
|
case 'remote-cache':
|
42
48
|
case 'local-cache':
|
43
49
|
case 'local-cache-kept-existing':
|
@@ -49,7 +55,7 @@ function getTuiTerminalSummaryLifeCycle({ projectNames, tasks, args, overrides,
|
|
49
55
|
break;
|
50
56
|
case 'failure':
|
51
57
|
totalFailedTasks++;
|
52
|
-
failedTasks.add(
|
58
|
+
failedTasks.add(task.id);
|
53
59
|
break;
|
54
60
|
}
|
55
61
|
}
|
@@ -75,7 +81,7 @@ function getTuiTerminalSummaryLifeCycle({ projectNames, tasks, args, overrides,
|
|
75
81
|
};
|
76
82
|
const printRunOneSummary = () => {
|
77
83
|
let lines = [];
|
78
|
-
const failure = totalSuccessfulTasks !== totalTasks;
|
84
|
+
const failure = totalSuccessfulTasks + totalStoppedTasks !== totalTasks;
|
79
85
|
// Prints task outputs in the order they were completed
|
80
86
|
// above the summary, since run-one should print all task results.
|
81
87
|
for (const taskId of taskIdsInOrderOfCompletion) {
|
@@ -99,7 +105,7 @@ function getTuiTerminalSummaryLifeCycle({ projectNames, tasks, args, overrides,
|
|
99
105
|
}
|
100
106
|
lines = [output_1.output.colors.green(lines.join(node_os_1.EOL))];
|
101
107
|
}
|
102
|
-
else if (totalCompletedTasks === totalTasks) {
|
108
|
+
else if (totalCompletedTasks + totalStoppedTasks === totalTasks) {
|
103
109
|
let text = `Ran target ${output_1.output.bold(targets[0])} for project ${output_1.output.bold(initiatingProject)}`;
|
104
110
|
if (tasks.length > 1) {
|
105
111
|
text += ` and ${output_1.output.bold(tasks.length - 1)} task(s) they depend on`;
|
@@ -137,7 +143,7 @@ function getTuiTerminalSummaryLifeCycle({ projectNames, tasks, args, overrides,
|
|
137
143
|
const printRunManySummary = () => {
|
138
144
|
console.log('');
|
139
145
|
const lines = [];
|
140
|
-
const failure = totalSuccessfulTasks !== totalTasks;
|
146
|
+
const failure = totalSuccessfulTasks + totalStoppedTasks !== totalTasks;
|
141
147
|
for (const taskId of taskIdsInOrderOfCompletion) {
|
142
148
|
const { terminalOutput, taskStatus } = tasksToTerminalOutputs[taskId];
|
143
149
|
if (taskStatus === 'failure') {
|
@@ -149,7 +155,7 @@ function getTuiTerminalSummaryLifeCycle({ projectNames, tasks, args, overrides,
|
|
149
155
|
}
|
150
156
|
}
|
151
157
|
lines.push(...output_1.output.getVerticalSeparatorLines(failure ? 'red' : 'green'));
|
152
|
-
if (totalSuccessfulTasks === totalTasks) {
|
158
|
+
if (totalSuccessfulTasks + totalStoppedTasks === totalTasks) {
|
153
159
|
const successSummaryRows = [];
|
154
160
|
const text = `Successfully ran ${(0, formatting_utils_1.formatTargetsAndProjects)(projectNames, targets, tasks)}`;
|
155
161
|
const taskOverridesRows = [];
|
@@ -17,7 +17,7 @@ export declare function runCommandForTasks(projectsToRun: ProjectGraphProjectNod
|
|
17
17
|
excludeTaskDependencies: boolean;
|
18
18
|
loadDotEnvFiles: boolean;
|
19
19
|
}): Promise<TaskResults>;
|
20
|
-
export declare function invokeTasksRunner({ tasks, projectGraph, taskGraph, lifeCycle, nxJson, nxArgs, loadDotEnvFiles, initiatingProject, }: {
|
20
|
+
export declare function invokeTasksRunner({ tasks, projectGraph, taskGraph, lifeCycle, nxJson, nxArgs, loadDotEnvFiles, initiatingProject, initiatingTasks, }: {
|
21
21
|
tasks: Task[];
|
22
22
|
projectGraph: ProjectGraph;
|
23
23
|
taskGraph: TaskGraph;
|
@@ -26,6 +26,7 @@ export declare function invokeTasksRunner({ tasks, projectGraph, taskGraph, life
|
|
26
26
|
nxArgs: NxArgs;
|
27
27
|
loadDotEnvFiles: boolean;
|
28
28
|
initiatingProject: string | null;
|
29
|
+
initiatingTasks: Task[];
|
29
30
|
}): Promise<{
|
30
31
|
[id: string]: TaskResult;
|
31
32
|
}>;
|
@@ -46,7 +46,7 @@ const originalStdoutWrite = process.stdout.write.bind(process.stdout);
|
|
46
46
|
const originalStderrWrite = process.stderr.write.bind(process.stderr);
|
47
47
|
const originalConsoleLog = console.log.bind(console);
|
48
48
|
const originalConsoleError = console.error.bind(console);
|
49
|
-
async function getTerminalOutputLifeCycle(initiatingProject, projectNames, tasks, taskGraph, nxArgs, nxJson, overrides) {
|
49
|
+
async function getTerminalOutputLifeCycle(initiatingProject, initiatingTasks, projectNames, tasks, taskGraph, nxArgs, nxJson, overrides) {
|
50
50
|
const overridesWithoutHidden = { ...overrides };
|
51
51
|
delete overridesWithoutHidden['__overrides_unparsed__'];
|
52
52
|
if ((0, is_tui_enabled_1.isTuiEnabled)(nxJson)) {
|
@@ -82,7 +82,7 @@ async function getTerminalOutputLifeCycle(initiatingProject, projectNames, tasks
|
|
82
82
|
const projectText = projectNames.length === 1 ? 'project' : 'projects';
|
83
83
|
let titleText = '';
|
84
84
|
if (isRunOne) {
|
85
|
-
const mainTaskId =
|
85
|
+
const mainTaskId = initiatingTasks[0].id;
|
86
86
|
pinnedTasks.push(mainTaskId);
|
87
87
|
const mainContinuousDependencies = taskGraph.continuousDependencies[mainTaskId];
|
88
88
|
if (mainContinuousDependencies.length > 0) {
|
@@ -111,6 +111,7 @@ async function getTerminalOutputLifeCycle(initiatingProject, projectNames, tasks
|
|
111
111
|
args: nxArgs,
|
112
112
|
overrides: overridesWithoutHidden,
|
113
113
|
initiatingProject,
|
114
|
+
initiatingTasks,
|
114
115
|
resolveRenderIsDonePromise,
|
115
116
|
});
|
116
117
|
if (tasks.length === 0) {
|
@@ -120,7 +121,6 @@ async function getTerminalOutputLifeCycle(initiatingProject, projectNames, tasks
|
|
120
121
|
process.stderr.write = originalStderrWrite;
|
121
122
|
console.log = originalConsoleLog;
|
122
123
|
console.error = originalConsoleError;
|
123
|
-
printSummary();
|
124
124
|
});
|
125
125
|
}
|
126
126
|
const lifeCycles = [tsLifeCycle];
|
@@ -183,7 +183,6 @@ async function getTerminalOutputLifeCycle(initiatingProject, projectNames, tasks
|
|
183
183
|
process.stderr.write = originalStderrWrite;
|
184
184
|
console.log = originalConsoleLog;
|
185
185
|
console.error = originalConsoleError;
|
186
|
-
printSummary();
|
187
186
|
// Print the intercepted Nx Cloud logs
|
188
187
|
for (const log of interceptedNxCloudLogs) {
|
189
188
|
const logString = log.toString().trimStart();
|
@@ -196,6 +195,7 @@ async function getTerminalOutputLifeCycle(initiatingProject, projectNames, tasks
|
|
196
195
|
}
|
197
196
|
return {
|
198
197
|
lifeCycle: new life_cycle_1.CompositeLifeCycle(lifeCycles),
|
198
|
+
printSummary,
|
199
199
|
renderIsDone,
|
200
200
|
};
|
201
201
|
}
|
@@ -285,9 +285,12 @@ async function runCommand(projectsToRun, currentProjectGraph, { nxJson }, nxArgs
|
|
285
285
|
}
|
286
286
|
async function runCommandForTasks(projectsToRun, currentProjectGraph, { nxJson }, nxArgs, overrides, initiatingProject, extraTargetDependencies, extraOptions) {
|
287
287
|
const projectNames = projectsToRun.map((t) => t.name);
|
288
|
+
const projectNameSet = new Set(projectNames);
|
288
289
|
const { projectGraph, taskGraph } = await ensureWorkspaceIsInSyncAndGetGraphs(currentProjectGraph, nxJson, projectNames, nxArgs, overrides, extraTargetDependencies, extraOptions);
|
289
290
|
const tasks = Object.values(taskGraph.tasks);
|
290
|
-
const
|
291
|
+
const initiatingTasks = tasks.filter((t) => projectNameSet.has(t.target.project) &&
|
292
|
+
nxArgs.targets.includes(t.target.target));
|
293
|
+
const { lifeCycle, renderIsDone, printSummary } = await getTerminalOutputLifeCycle(initiatingProject, initiatingTasks, projectNames, tasks, taskGraph, nxArgs, nxJson, overrides);
|
291
294
|
const taskResults = await invokeTasksRunner({
|
292
295
|
tasks,
|
293
296
|
projectGraph,
|
@@ -297,8 +300,12 @@ async function runCommandForTasks(projectsToRun, currentProjectGraph, { nxJson }
|
|
297
300
|
nxArgs,
|
298
301
|
loadDotEnvFiles: extraOptions.loadDotEnvFiles,
|
299
302
|
initiatingProject,
|
303
|
+
initiatingTasks,
|
300
304
|
});
|
301
305
|
await renderIsDone;
|
306
|
+
if (printSummary) {
|
307
|
+
printSummary();
|
308
|
+
}
|
302
309
|
await (0, nx_key_1.printNxKey)();
|
303
310
|
return taskResults;
|
304
311
|
}
|
@@ -535,7 +542,7 @@ function setEnvVarsBasedOnArgs(nxArgs, loadDotEnvFiles) {
|
|
535
542
|
process.env.NX_LOAD_DOT_ENV_FILES = 'true';
|
536
543
|
}
|
537
544
|
}
|
538
|
-
async function invokeTasksRunner({ tasks, projectGraph, taskGraph, lifeCycle, nxJson, nxArgs, loadDotEnvFiles, initiatingProject, }) {
|
545
|
+
async function invokeTasksRunner({ tasks, projectGraph, taskGraph, lifeCycle, nxJson, nxArgs, loadDotEnvFiles, initiatingProject, initiatingTasks, }) {
|
539
546
|
setEnvVarsBasedOnArgs(nxArgs, loadDotEnvFiles);
|
540
547
|
// this needs to be done before we start to run the tasks
|
541
548
|
const taskDetails = (0, hash_task_1.getTaskDetails)();
|
@@ -555,6 +562,7 @@ async function invokeTasksRunner({ tasks, projectGraph, taskGraph, lifeCycle, nx
|
|
555
562
|
lifeCycle: compositedLifeCycle,
|
556
563
|
}, {
|
557
564
|
initiatingProject: nxArgs.outputStyle === 'compact' ? null : initiatingProject,
|
565
|
+
initiatingTasks,
|
558
566
|
projectGraph,
|
559
567
|
nxJson,
|
560
568
|
nxArgs,
|
@@ -153,18 +153,11 @@ class NodeChildProcessWithDirectOutput {
|
|
153
153
|
this.exitCallbacks.push(cb);
|
154
154
|
}
|
155
155
|
async getResults() {
|
156
|
-
|
157
|
-
|
158
|
-
return Promise.resolve({
|
159
|
-
code: this.exitCode,
|
160
|
-
terminalOutput,
|
161
|
-
});
|
156
|
+
if (!this.exited) {
|
157
|
+
await this.waitForExit();
|
162
158
|
}
|
163
|
-
|
164
|
-
return
|
165
|
-
code: this.exitCode,
|
166
|
-
terminalOutput,
|
167
|
-
});
|
159
|
+
const terminalOutput = this.getTerminalOutput();
|
160
|
+
return { code: this.exitCode, terminalOutput };
|
168
161
|
}
|
169
162
|
waitForExit() {
|
170
163
|
return new Promise((res) => {
|
@@ -1,3 +1,4 @@
|
|
1
|
+
import type { Serializable } from 'child_process';
|
1
2
|
export declare abstract class RunningTask {
|
2
3
|
abstract getResults(): Promise<{
|
3
4
|
code: number;
|
@@ -5,4 +6,6 @@ export declare abstract class RunningTask {
|
|
5
6
|
}>;
|
6
7
|
abstract onExit(cb: (code: number) => void): void;
|
7
8
|
abstract kill(signal?: NodeJS.Signals | number): Promise<void> | void;
|
9
|
+
abstract onOutput?(cb: (output: string) => void): void;
|
10
|
+
abstract send?(message: Serializable): void;
|
8
11
|
}
|
@@ -0,0 +1,14 @@
|
|
1
|
+
import { RunningTask } from './running-task';
|
2
|
+
import { RunningTasksService } from '../../native';
|
3
|
+
export declare class SharedRunningTask implements RunningTask {
|
4
|
+
private runningTasksService;
|
5
|
+
private exitCallbacks;
|
6
|
+
constructor(runningTasksService: RunningTasksService, taskId: string);
|
7
|
+
getResults(): Promise<{
|
8
|
+
code: number;
|
9
|
+
terminalOutput: string;
|
10
|
+
}>;
|
11
|
+
kill(): void;
|
12
|
+
onExit(cb: (code: number) => void): void;
|
13
|
+
private waitForTaskToFinish;
|
14
|
+
}
|
@@ -0,0 +1,30 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.SharedRunningTask = void 0;
|
4
|
+
class SharedRunningTask {
|
5
|
+
constructor(runningTasksService, taskId) {
|
6
|
+
this.runningTasksService = runningTasksService;
|
7
|
+
this.exitCallbacks = [];
|
8
|
+
this.waitForTaskToFinish(taskId).then(() => {
|
9
|
+
// notify exit callbacks
|
10
|
+
this.exitCallbacks.forEach((cb) => cb(0));
|
11
|
+
});
|
12
|
+
}
|
13
|
+
async getResults() {
|
14
|
+
throw new Error('Results cannot be retrieved from a shared task');
|
15
|
+
}
|
16
|
+
kill() {
|
17
|
+
this.exitCallbacks.forEach((cb) => cb(0));
|
18
|
+
}
|
19
|
+
onExit(cb) {
|
20
|
+
this.exitCallbacks.push(cb);
|
21
|
+
}
|
22
|
+
async waitForTaskToFinish(taskId) {
|
23
|
+
console.log(`Waiting for ${taskId} in another nx process`);
|
24
|
+
// wait for the running task to finish
|
25
|
+
do {
|
26
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
27
|
+
} while (this.runningTasksService.getRunningTasks([taskId]).length);
|
28
|
+
}
|
29
|
+
}
|
30
|
+
exports.SharedRunningTask = SharedRunningTask;
|
@@ -7,9 +7,11 @@ import { NxArgs } from '../utils/command-line-utils';
|
|
7
7
|
import { DefaultTasksRunnerOptions } from './default-tasks-runner';
|
8
8
|
import { RunningTask } from './running-tasks/running-task';
|
9
9
|
import { TaskStatus } from './tasks-runner';
|
10
|
+
import { SharedRunningTask } from './running-tasks/shared-running-task';
|
10
11
|
export declare class TaskOrchestrator {
|
11
12
|
private readonly hasher;
|
12
13
|
private readonly initiatingProject;
|
14
|
+
private readonly initiatingTasks;
|
13
15
|
private readonly projectGraph;
|
14
16
|
private readonly taskGraph;
|
15
17
|
private readonly nxJson;
|
@@ -26,6 +28,7 @@ export declare class TaskOrchestrator {
|
|
26
28
|
private tasksSchedule;
|
27
29
|
private batchEnv;
|
28
30
|
private reverseTaskDeps;
|
31
|
+
private initializingTaskIds;
|
29
32
|
private processedTasks;
|
30
33
|
private processedBatches;
|
31
34
|
private completedTasks;
|
@@ -33,8 +36,7 @@ export declare class TaskOrchestrator {
|
|
33
36
|
private groups;
|
34
37
|
private bailed;
|
35
38
|
private runningContinuousTasks;
|
36
|
-
|
37
|
-
constructor(hasher: TaskHasher, initiatingProject: string | undefined, projectGraph: ProjectGraph, taskGraph: TaskGraph, nxJson: NxJsonConfiguration, options: NxArgs & DefaultTasksRunnerOptions, bail: boolean, daemon: DaemonClient, outputStyle: string, taskGraphForHashing?: TaskGraph);
|
39
|
+
constructor(hasher: TaskHasher, initiatingProject: string | undefined, initiatingTasks: Task[], projectGraph: ProjectGraph, taskGraph: TaskGraph, nxJson: NxJsonConfiguration, options: NxArgs & DefaultTasksRunnerOptions, bail: boolean, daemon: DaemonClient, outputStyle: string, taskGraphForHashing?: TaskGraph);
|
38
40
|
init(): Promise<void>;
|
39
41
|
run(): Promise<{
|
40
42
|
[id: string]: TaskStatus;
|
@@ -55,7 +57,7 @@ export declare class TaskOrchestrator {
|
|
55
57
|
}>;
|
56
58
|
private runTask;
|
57
59
|
private runTaskInForkedProcess;
|
58
|
-
startContinuousTask(task: Task, groupId: number): Promise<RunningTask>;
|
60
|
+
startContinuousTask(task: Task, groupId: number): Promise<RunningTask | SharedRunningTask>;
|
59
61
|
private preRunSteps;
|
60
62
|
private postRunSteps;
|
61
63
|
private scheduleNextTasksAndReleaseThreads;
|
@@ -67,5 +69,6 @@ export declare class TaskOrchestrator {
|
|
67
69
|
private shouldCopyOutputsFromCache;
|
68
70
|
private recordOutputsHash;
|
69
71
|
private cleanup;
|
72
|
+
private cleanUpUnneededContinuousTasks;
|
70
73
|
}
|
71
74
|
export declare function getThreadCount(options: NxArgs & DefaultTasksRunnerOptions, taskGraph: TaskGraph): number;
|