nx 21.0.0-rc.2 → 21.0.0-rc.4
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/bin/nx.js +6 -0
- package/package.json +11 -11
- package/src/command-line/init/configure-plugins.js +9 -7
- package/src/command-line/init/init-v1.js +1 -1
- package/src/command-line/release/publish.js +3 -3
- package/src/command-line/release/version/release-group-processor.js +21 -5
- package/src/command-line/release/version/test-utils.d.ts +1 -1
- package/src/command-line/release/version/test-utils.js +4 -4
- package/src/command-line/release/version/version-actions.d.ts +2 -2
- package/src/command-line/release/version/version-actions.js +12 -6
- package/src/command-line/reset/reset.js +17 -1
- package/src/command-line/yargs-utils/shared-options.d.ts +6 -4
- package/src/command-line/yargs-utils/shared-options.js +1 -2
- package/src/core/graph/main.js +1 -1
- package/src/native/nx.wasm32-wasi.wasm +0 -0
- package/src/nx-cloud/update-manager.d.ts +1 -0
- package/src/nx-cloud/update-manager.js +1 -0
- package/src/nx-cloud/utilities/client.d.ts +1 -1
- package/src/nx-cloud/utilities/client.js +10 -3
- package/src/tasks-runner/life-cycles/tui-summary-life-cycle.d.ts +3 -2
- package/src/tasks-runner/life-cycles/tui-summary-life-cycle.js +36 -25
- package/src/tasks-runner/run-command.d.ts +4 -1
- package/src/tasks-runner/run-command.js +52 -15
- package/src/tasks-runner/task-graph-utils.d.ts +1 -0
- package/src/tasks-runner/task-graph-utils.js +28 -0
- package/src/tasks-runner/task-orchestrator.d.ts +1 -0
- package/src/tasks-runner/task-orchestrator.js +27 -12
Binary file
|
@@ -2,6 +2,7 @@
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
3
|
exports.NxCloudClientUnavailableError = exports.NxCloudEnterpriseOutdatedError = void 0;
|
4
4
|
exports.verifyOrUpdateNxCloudClient = verifyOrUpdateNxCloudClient;
|
5
|
+
exports.getBundleInstallDefaultLocation = getBundleInstallDefaultLocation;
|
5
6
|
const fs_1 = require("fs");
|
6
7
|
const zlib_1 = require("zlib");
|
7
8
|
const path_1 = require("path");
|
@@ -5,6 +5,6 @@ export declare class UnknownCommandError extends Error {
|
|
5
5
|
constructor(command: string, availableCommands: string[]);
|
6
6
|
}
|
7
7
|
export declare function getCloudClient(options: CloudTaskRunnerOptions): Promise<{
|
8
|
-
invoke: (command: string) => void;
|
8
|
+
invoke: (command: string, exit?: boolean) => void;
|
9
9
|
availableCommands: string[];
|
10
10
|
}>;
|
@@ -17,13 +17,20 @@ async function getCloudClient(options) {
|
|
17
17
|
const paths = (0, resolution_helpers_1.findAncestorNodeModules)(__dirname, []);
|
18
18
|
nxCloudClient.configureLightClientRequire()(paths);
|
19
19
|
return {
|
20
|
-
invoke: (command) => {
|
20
|
+
invoke: (command, exit = true) => {
|
21
21
|
if (command in nxCloudClient.commands) {
|
22
22
|
nxCloudClient.commands[command]()
|
23
|
-
.then(() =>
|
23
|
+
.then(() => {
|
24
|
+
if (exit) {
|
25
|
+
process.exit(0);
|
26
|
+
}
|
27
|
+
})
|
24
28
|
.catch((e) => {
|
25
29
|
console.error(e);
|
26
|
-
|
30
|
+
if (exit) {
|
31
|
+
process.exit(1);
|
32
|
+
}
|
33
|
+
throw e;
|
27
34
|
});
|
28
35
|
}
|
29
36
|
else {
|
@@ -1,8 +1,9 @@
|
|
1
|
-
import { Task } from '../../config/task-graph';
|
1
|
+
import { Task, TaskGraph } from '../../config/task-graph';
|
2
2
|
import type { LifeCycle } from '../life-cycle';
|
3
|
-
export declare function getTuiTerminalSummaryLifeCycle({ projectNames, tasks, args, overrides, initiatingProject, initiatingTasks, resolveRenderIsDonePromise, }: {
|
3
|
+
export declare function getTuiTerminalSummaryLifeCycle({ projectNames, tasks, taskGraph, args, overrides, initiatingProject, initiatingTasks, resolveRenderIsDonePromise, }: {
|
4
4
|
projectNames: string[];
|
5
5
|
tasks: Task[];
|
6
|
+
taskGraph: TaskGraph;
|
6
7
|
args: {
|
7
8
|
targets?: string[];
|
8
9
|
configuration?: string;
|
@@ -8,10 +8,11 @@ const pretty_time_1 = require("./pretty-time");
|
|
8
8
|
const view_logs_utils_1 = require("./view-logs-utils");
|
9
9
|
const figures = require("figures");
|
10
10
|
const task_history_life_cycle_1 = require("./task-history-life-cycle");
|
11
|
+
const task_graph_utils_1 = require("../task-graph-utils");
|
11
12
|
const LEFT_PAD = ` `;
|
12
13
|
const SPACER = ` `;
|
13
14
|
const EXTENDED_LEFT_PAD = ` `;
|
14
|
-
function getTuiTerminalSummaryLifeCycle({ projectNames, tasks, args, overrides, initiatingProject, initiatingTasks, resolveRenderIsDonePromise, }) {
|
15
|
+
function getTuiTerminalSummaryLifeCycle({ projectNames, tasks, taskGraph, args, overrides, initiatingProject, initiatingTasks, resolveRenderIsDonePromise, }) {
|
15
16
|
const lifeCycle = {};
|
16
17
|
const start = process.hrtime();
|
17
18
|
const targets = args.targets;
|
@@ -74,17 +75,32 @@ function getTuiTerminalSummaryLifeCycle({ projectNames, tasks, args, overrides,
|
|
74
75
|
console.log(`\n${output_1.output.applyNxPrefix('gray', 'No tasks were run')}\n`);
|
75
76
|
return;
|
76
77
|
}
|
78
|
+
const failure = totalSuccessfulTasks + stoppedTasks.size !== totalTasks;
|
79
|
+
const cancelled =
|
80
|
+
// Some tasks were in progress...
|
81
|
+
inProgressTasks.size > 0 ||
|
82
|
+
// or some tasks had not started yet
|
83
|
+
totalTasks !== tasks.length ||
|
84
|
+
// the run had a continous task as a leaf...
|
85
|
+
// this is needed because continous tasks get marked as stopped when the process is interrupted
|
86
|
+
[...(0, task_graph_utils_1.getLeafTasks)(taskGraph)].filter((t) => taskGraph.tasks[t].continuous)
|
87
|
+
.length > 0;
|
77
88
|
if (isRunOne) {
|
78
|
-
printRunOneSummary(
|
89
|
+
printRunOneSummary({
|
90
|
+
failure,
|
91
|
+
cancelled,
|
92
|
+
});
|
79
93
|
}
|
80
94
|
else {
|
81
|
-
printRunManySummary(
|
95
|
+
printRunManySummary({
|
96
|
+
failure,
|
97
|
+
cancelled,
|
98
|
+
});
|
82
99
|
}
|
83
100
|
(0, task_history_life_cycle_1.getTasksHistoryLifeCycle)()?.printFlakyTasksMessage();
|
84
101
|
};
|
85
|
-
const printRunOneSummary = () => {
|
102
|
+
const printRunOneSummary = ({ failure, cancelled, }) => {
|
86
103
|
let lines = [];
|
87
|
-
const failure = totalSuccessfulTasks + stoppedTasks.size !== totalTasks;
|
88
104
|
// Prints task outputs in the order they were completed
|
89
105
|
// above the summary, since run-one should print all task results.
|
90
106
|
for (const taskId of taskIdsInOrderOfCompletion) {
|
@@ -92,7 +108,7 @@ function getTuiTerminalSummaryLifeCycle({ projectNames, tasks, args, overrides,
|
|
92
108
|
output_1.output.logCommandOutput(taskId, taskStatus, terminalOutput);
|
93
109
|
}
|
94
110
|
lines.push(...output_1.output.getVerticalSeparatorLines(failure ? 'red' : 'green'));
|
95
|
-
if (!failure) {
|
111
|
+
if (!failure && !cancelled) {
|
96
112
|
const text = `Successfully ran ${(0, formatting_utils_1.formatTargetsAndProjects)([initiatingProject], targets, tasks)}`;
|
97
113
|
const taskOverridesLines = [];
|
98
114
|
if (Object.keys(overrides).length > 0) {
|
@@ -108,7 +124,7 @@ function getTuiTerminalSummaryLifeCycle({ projectNames, tasks, args, overrides,
|
|
108
124
|
}
|
109
125
|
lines = [output_1.output.colors.green(lines.join(node_os_1.EOL))];
|
110
126
|
}
|
111
|
-
else if (
|
127
|
+
else if (!cancelled) {
|
112
128
|
let text = `Ran target ${output_1.output.bold(targets[0])} for project ${output_1.output.bold(initiatingProject)}`;
|
113
129
|
if (tasks.length > 1) {
|
114
130
|
text += ` and ${output_1.output.bold(tasks.length - 1)} task(s) they depend on`;
|
@@ -122,35 +138,30 @@ function getTuiTerminalSummaryLifeCycle({ projectNames, tasks, args, overrides,
|
|
122
138
|
.forEach((arg) => taskOverridesLines.push(arg));
|
123
139
|
}
|
124
140
|
const viewLogs = (0, view_logs_utils_1.viewLogsFooterRows)(totalFailedTasks);
|
125
|
-
lines
|
126
|
-
output_1.output.colors.red(
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
].join(node_os_1.EOL)),
|
134
|
-
];
|
141
|
+
lines.push(output_1.output.colors.red([
|
142
|
+
output_1.output.applyNxPrefix('red', output_1.output.colors.red(text) + output_1.output.dim(` (${timeTakenText})`)),
|
143
|
+
...taskOverridesLines,
|
144
|
+
'',
|
145
|
+
`${LEFT_PAD}${output_1.output.colors.red(figures.cross)}${SPACER}${totalFailedTasks}${`/${totalCompletedTasks}`} failed`,
|
146
|
+
`${LEFT_PAD}${output_1.output.dim(figures.tick)}${SPACER}${totalSuccessfulTasks}${`/${totalCompletedTasks}`} succeeded ${output_1.output.dim(`[${totalCachedTasks} read from cache]`)}`,
|
147
|
+
...viewLogs,
|
148
|
+
].join(node_os_1.EOL)));
|
135
149
|
}
|
136
150
|
else {
|
137
|
-
lines
|
138
|
-
...output_1.output.getVerticalSeparatorLines('red'),
|
139
|
-
output_1.output.applyNxPrefix('red', output_1.output.colors.red(`Cancelled running target ${output_1.output.bold(targets[0])} for project ${output_1.output.bold(initiatingProject)}`) + output_1.output.dim(` (${timeTakenText})`)),
|
140
|
-
];
|
151
|
+
lines.push(output_1.output.applyNxPrefix('red', output_1.output.colors.red(`Cancelled running target ${output_1.output.bold(targets[0])} for project ${output_1.output.bold(initiatingProject)}`) + output_1.output.dim(` (${timeTakenText})`)));
|
141
152
|
}
|
142
153
|
// adds some vertical space after the summary to avoid bunching against terminal
|
143
154
|
lines.push('');
|
144
155
|
console.log(lines.join(node_os_1.EOL));
|
145
156
|
};
|
146
|
-
const printRunManySummary = () => {
|
157
|
+
const printRunManySummary = ({ failure, cancelled, }) => {
|
147
158
|
console.log('');
|
148
|
-
const lines = [];
|
149
|
-
const failure = totalSuccessfulTasks + stoppedTasks.size !== totalTasks;
|
159
|
+
const lines = [''];
|
150
160
|
for (const taskId of taskIdsInOrderOfCompletion) {
|
151
161
|
const { terminalOutput, taskStatus } = tasksToTerminalOutputs[taskId];
|
152
162
|
if (taskStatus === 'failure') {
|
153
163
|
output_1.output.logCommandOutput(taskId, taskStatus, terminalOutput);
|
164
|
+
output_1.output.addNewline();
|
154
165
|
lines.push(`${LEFT_PAD}${output_1.output.colors.red(figures.cross)}${SPACER}${output_1.output.colors.gray('nx run ')}${taskId}`);
|
155
166
|
}
|
156
167
|
else {
|
@@ -179,7 +190,7 @@ function getTuiTerminalSummaryLifeCycle({ projectNames, tasks, args, overrides,
|
|
179
190
|
lines.push(successSummaryRows.join(node_os_1.EOL));
|
180
191
|
}
|
181
192
|
else {
|
182
|
-
const text = `${
|
193
|
+
const text = `${cancelled ? 'Cancelled while running' : 'Ran'} ${(0, formatting_utils_1.formatTargetsAndProjects)(projectNames, targets, tasks)}`;
|
183
194
|
const taskOverridesRows = [];
|
184
195
|
if (Object.keys(overrides).length > 0) {
|
185
196
|
taskOverridesRows.push('');
|
@@ -16,7 +16,10 @@ export declare function runCommandForTasks(projectsToRun: ProjectGraphProjectNod
|
|
16
16
|
}, nxArgs: NxArgs, overrides: any, initiatingProject: string | null, extraTargetDependencies: Record<string, (TargetDependencyConfig | string)[]>, extraOptions: {
|
17
17
|
excludeTaskDependencies: boolean;
|
18
18
|
loadDotEnvFiles: boolean;
|
19
|
-
}): Promise<
|
19
|
+
}): Promise<{
|
20
|
+
taskResults: TaskResults;
|
21
|
+
completed: boolean;
|
22
|
+
}>;
|
20
23
|
export declare function setEnvVarsBasedOnArgs(nxArgs: NxArgs, loadDotEnvFiles: boolean): void;
|
21
24
|
export declare function invokeTasksRunner({ tasks, projectGraph, taskGraph, lifeCycle, nxJson, nxArgs, loadDotEnvFiles, initiatingProject, initiatingTasks, }: {
|
22
25
|
tasks: Task[];
|
@@ -40,6 +40,7 @@ const tui_summary_life_cycle_1 = require("./life-cycles/tui-summary-life-cycle")
|
|
40
40
|
const task_graph_utils_1 = require("./task-graph-utils");
|
41
41
|
const utils_1 = require("./utils");
|
42
42
|
const chalk = require("chalk");
|
43
|
+
const exit_codes_1 = require("../utils/exit-codes");
|
43
44
|
const originalStdoutWrite = process.stdout.write.bind(process.stdout);
|
44
45
|
const originalStderrWrite = process.stderr.write.bind(process.stderr);
|
45
46
|
const originalConsoleLog = console.log.bind(console);
|
@@ -107,6 +108,7 @@ async function getTerminalOutputLifeCycle(initiatingProject, initiatingTasks, pr
|
|
107
108
|
const { lifeCycle: tsLifeCycle, printSummary } = (0, tui_summary_life_cycle_1.getTuiTerminalSummaryLifeCycle)({
|
108
109
|
projectNames,
|
109
110
|
tasks,
|
111
|
+
taskGraph,
|
110
112
|
args: nxArgs,
|
111
113
|
overrides: overridesWithoutHidden,
|
112
114
|
initiatingProject,
|
@@ -168,20 +170,14 @@ async function getTerminalOutputLifeCycle(initiatingProject, initiatingTasks, pr
|
|
168
170
|
// The cloud client calls console.log when NX_VERBOSE_LOGGING is set to true
|
169
171
|
console.log = createPatchedConsoleMethod(originalConsoleLog);
|
170
172
|
console.error = createPatchedConsoleMethod(originalConsoleError);
|
171
|
-
|
172
|
-
appLifeCycle.__init(() => {
|
173
|
-
resolve();
|
174
|
-
});
|
175
|
-
})
|
176
|
-
.then(() => {
|
173
|
+
globalThis.tuiOnProcessExit = () => {
|
177
174
|
restoreTerminal();
|
178
|
-
})
|
179
|
-
.finally(() => {
|
180
175
|
// Revert the patched methods
|
181
176
|
process.stdout.write = originalStdoutWrite;
|
182
177
|
process.stderr.write = originalStderrWrite;
|
183
178
|
console.log = originalConsoleLog;
|
184
179
|
console.error = originalConsoleError;
|
180
|
+
process.stdout.write('\n');
|
185
181
|
// Print the intercepted Nx Cloud logs
|
186
182
|
for (const log of interceptedNxCloudLogs) {
|
187
183
|
const logString = log.toString().trimStart();
|
@@ -190,6 +186,18 @@ async function getTerminalOutputLifeCycle(initiatingProject, initiatingTasks, pr
|
|
190
186
|
process.stdout.write('\n');
|
191
187
|
}
|
192
188
|
}
|
189
|
+
};
|
190
|
+
renderIsDone = new Promise((resolve) => {
|
191
|
+
appLifeCycle.__init(() => {
|
192
|
+
resolve();
|
193
|
+
});
|
194
|
+
}).finally(() => {
|
195
|
+
restoreTerminal();
|
196
|
+
// Revert the patched methods
|
197
|
+
process.stdout.write = originalStdoutWrite;
|
198
|
+
process.stderr.write = originalStderrWrite;
|
199
|
+
console.log = originalConsoleLog;
|
200
|
+
console.error = originalConsoleError;
|
193
201
|
});
|
194
202
|
}
|
195
203
|
return {
|
@@ -271,21 +279,23 @@ async function runCommand(projectsToRun, currentProjectGraph, { nxJson }, nxArgs
|
|
271
279
|
workspaceRoot: workspace_root_1.workspaceRoot,
|
272
280
|
nxJsonConfiguration: nxJson,
|
273
281
|
});
|
274
|
-
const taskResults = await runCommandForTasks(projectsToRun, currentProjectGraph, { nxJson }, {
|
282
|
+
const { taskResults, completed } = await runCommandForTasks(projectsToRun, currentProjectGraph, { nxJson }, {
|
275
283
|
...nxArgs,
|
276
284
|
skipNxCache: nxArgs.skipNxCache ||
|
277
285
|
process.env.NX_SKIP_NX_CACHE === 'true' ||
|
278
286
|
process.env.NX_DISABLE_NX_CACHE === 'true',
|
279
287
|
}, overrides, initiatingProject, extraTargetDependencies, extraOptions);
|
280
|
-
const
|
281
|
-
?
|
282
|
-
:
|
288
|
+
const exitCode = !completed
|
289
|
+
? (0, exit_codes_1.signalToCode)('SIGINT')
|
290
|
+
: Object.values(taskResults).some((taskResult) => taskResult.status === 'failure' || taskResult.status === 'skipped')
|
291
|
+
? 1
|
292
|
+
: 0;
|
283
293
|
await (0, tasks_execution_hooks_1.runPostTasksExecution)({
|
284
294
|
taskResults,
|
285
295
|
workspaceRoot: workspace_root_1.workspaceRoot,
|
286
296
|
nxJsonConfiguration: nxJson,
|
287
297
|
});
|
288
|
-
return
|
298
|
+
return exitCode;
|
289
299
|
});
|
290
300
|
return status;
|
291
301
|
}
|
@@ -314,7 +324,10 @@ async function runCommandForTasks(projectsToRun, currentProjectGraph, { nxJson }
|
|
314
324
|
printSummary();
|
315
325
|
}
|
316
326
|
await (0, nx_key_1.printNxKey)();
|
317
|
-
return
|
327
|
+
return {
|
328
|
+
taskResults,
|
329
|
+
completed: didCommandComplete(tasks, taskGraph, taskResults),
|
330
|
+
};
|
318
331
|
}
|
319
332
|
catch (e) {
|
320
333
|
if (restoreTerminal) {
|
@@ -323,6 +336,30 @@ async function runCommandForTasks(projectsToRun, currentProjectGraph, { nxJson }
|
|
323
336
|
throw e;
|
324
337
|
}
|
325
338
|
}
|
339
|
+
function didCommandComplete(tasks, taskGraph, taskResults) {
|
340
|
+
// If no tasks, then we can consider it complete
|
341
|
+
if (tasks.length === 0) {
|
342
|
+
return true;
|
343
|
+
}
|
344
|
+
let continousLeafTasks = false;
|
345
|
+
const leafTasks = (0, task_graph_utils_1.getLeafTasks)(taskGraph);
|
346
|
+
for (const task of tasks) {
|
347
|
+
if (!task.continuous) {
|
348
|
+
// If any discrete task does not have a result then it did not run
|
349
|
+
if (!taskResults[task.id]) {
|
350
|
+
return false;
|
351
|
+
}
|
352
|
+
}
|
353
|
+
else {
|
354
|
+
if (leafTasks.has(task.id)) {
|
355
|
+
continousLeafTasks = true;
|
356
|
+
}
|
357
|
+
}
|
358
|
+
}
|
359
|
+
// If a leaf task is continous, we must have cancelled it.
|
360
|
+
// Otherwise, we've looped through all the discrete tasks and they have results
|
361
|
+
return !continousLeafTasks;
|
362
|
+
}
|
326
363
|
async function ensureWorkspaceIsInSyncAndGetGraphs(projectGraph, nxJson, projectNames, nxArgs, overrides, extraTargetDependencies, extraOptions) {
|
327
364
|
let taskGraph = createTaskGraphAndRunValidations(projectGraph, extraTargetDependencies ?? {}, projectNames, nxArgs, overrides, extraOptions);
|
328
365
|
if (nxArgs.skipSync || (0, is_ci_1.isCI)()) {
|
@@ -575,7 +612,7 @@ async function invokeTasksRunner({ tasks, projectGraph, taskGraph, lifeCycle, nx
|
|
575
612
|
...runnerOptions,
|
576
613
|
lifeCycle: compositedLifeCycle,
|
577
614
|
}, {
|
578
|
-
initiatingProject
|
615
|
+
initiatingProject,
|
579
616
|
initiatingTasks,
|
580
617
|
projectGraph,
|
581
618
|
nxJson,
|
@@ -22,3 +22,4 @@ export declare function makeAcyclic(graph: {
|
|
22
22
|
}): void;
|
23
23
|
export declare function validateNoAtomizedTasks(taskGraph: TaskGraph, projectGraph: ProjectGraph): void;
|
24
24
|
export declare function assertTaskGraphDoesNotContainInvalidTargets(taskGraph: TaskGraph): void;
|
25
|
+
export declare function getLeafTasks(taskGraph: TaskGraph): Set<string>;
|
@@ -5,6 +5,7 @@ exports.findCycles = findCycles;
|
|
5
5
|
exports.makeAcyclic = makeAcyclic;
|
6
6
|
exports.validateNoAtomizedTasks = validateNoAtomizedTasks;
|
7
7
|
exports.assertTaskGraphDoesNotContainInvalidTargets = assertTaskGraphDoesNotContainInvalidTargets;
|
8
|
+
exports.getLeafTasks = getLeafTasks;
|
8
9
|
const output_1 = require("../utils/output");
|
9
10
|
function _findCycle(graph, id, visited, path) {
|
10
11
|
if (visited[id])
|
@@ -138,3 +139,30 @@ class NonParallelTaskDependsOnContinuousTasksError extends Error {
|
|
138
139
|
this.name = 'NonParallelTaskDependsOnContinuousTasksError';
|
139
140
|
}
|
140
141
|
}
|
142
|
+
function getLeafTasks(taskGraph) {
|
143
|
+
const reversed = reverseTaskGraph(taskGraph);
|
144
|
+
const leafTasks = new Set();
|
145
|
+
for (const [taskId, dependencies] of Object.entries(reversed.dependencies)) {
|
146
|
+
if (dependencies.length === 0) {
|
147
|
+
leafTasks.add(taskId);
|
148
|
+
}
|
149
|
+
}
|
150
|
+
return leafTasks;
|
151
|
+
}
|
152
|
+
function reverseTaskGraph(taskGraph) {
|
153
|
+
const reversed = {
|
154
|
+
tasks: taskGraph.tasks,
|
155
|
+
dependencies: Object.fromEntries(Object.entries(taskGraph.tasks).map(([taskId]) => [taskId, []])),
|
156
|
+
};
|
157
|
+
for (const [taskId, dependencies] of Object.entries(taskGraph.dependencies)) {
|
158
|
+
for (const dependency of dependencies) {
|
159
|
+
reversed.dependencies[dependency].push(taskId);
|
160
|
+
}
|
161
|
+
}
|
162
|
+
for (const [taskId, dependencies] of Object.entries(taskGraph.continuousDependencies)) {
|
163
|
+
for (const dependency of dependencies) {
|
164
|
+
reversed.dependencies[dependency].push(taskId);
|
165
|
+
}
|
166
|
+
}
|
167
|
+
return reversed;
|
168
|
+
}
|
@@ -38,6 +38,7 @@ export declare class TaskOrchestrator {
|
|
38
38
|
private groups;
|
39
39
|
private bailed;
|
40
40
|
private runningContinuousTasks;
|
41
|
+
private runningRunCommandsTasks;
|
41
42
|
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);
|
42
43
|
init(): Promise<void>;
|
43
44
|
run(): Promise<{
|
@@ -55,6 +55,7 @@ class TaskOrchestrator {
|
|
55
55
|
this.groups = [];
|
56
56
|
this.bailed = false;
|
57
57
|
this.runningContinuousTasks = new Map();
|
58
|
+
this.runningRunCommandsTasks = new Map();
|
58
59
|
}
|
59
60
|
async init() {
|
60
61
|
// Init the ForkedProcessTaskRunner, TasksSchedule, and Cache
|
@@ -324,6 +325,10 @@ class TaskOrchestrator {
|
|
324
325
|
const runningTask = await (0, run_commands_impl_1.runCommands)(runCommandsOptions, {
|
325
326
|
root: workspace_root_1.workspaceRoot, // only root is needed in runCommands
|
326
327
|
});
|
328
|
+
this.runningRunCommandsTasks.set(task.id, runningTask);
|
329
|
+
runningTask.onExit(() => {
|
330
|
+
this.runningRunCommandsTasks.delete(task.id);
|
331
|
+
});
|
327
332
|
if (this.tuiEnabled) {
|
328
333
|
if (runningTask instanceof pseudo_terminal_1.PseudoTtyProcess) {
|
329
334
|
// This is an external of a the pseudo terminal where a task is running and can be passed to the TUI
|
@@ -640,18 +645,28 @@ class TaskOrchestrator {
|
|
640
645
|
}
|
641
646
|
// endregion utils
|
642
647
|
async cleanup() {
|
643
|
-
await Promise.all(
|
644
|
-
|
645
|
-
|
646
|
-
|
647
|
-
|
648
|
-
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
|
654
|
-
|
648
|
+
await Promise.all([
|
649
|
+
...Array.from(this.runningContinuousTasks).map(async ([taskId, t]) => {
|
650
|
+
try {
|
651
|
+
await t.kill();
|
652
|
+
this.options.lifeCycle.setTaskStatus(taskId, 9 /* NativeTaskStatus.Stopped */);
|
653
|
+
}
|
654
|
+
catch (e) {
|
655
|
+
console.error(`Unable to terminate ${taskId}\nError:`, e);
|
656
|
+
}
|
657
|
+
finally {
|
658
|
+
this.runningTasksService.removeRunningTask(taskId);
|
659
|
+
}
|
660
|
+
}),
|
661
|
+
...Array.from(this.runningRunCommandsTasks).map(async ([taskId, t]) => {
|
662
|
+
try {
|
663
|
+
await t.kill();
|
664
|
+
}
|
665
|
+
catch (e) {
|
666
|
+
console.error(`Unable to terminate ${taskId}\nError:`, e);
|
667
|
+
}
|
668
|
+
}),
|
669
|
+
]);
|
655
670
|
}
|
656
671
|
cleanUpUnneededContinuousTasks() {
|
657
672
|
const incompleteTasks = this.tasksSchedule.getIncompleteTasks();
|