nx 20.5.0-canary.20250201-05e0679 → 21.0.0-beta.0

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.
Files changed (44) hide show
  1. package/package.json +12 -11
  2. package/plugins/package-json.js +2 -1
  3. package/schemas/nx-schema.json +7 -0
  4. package/src/command-line/graph/graph.js +2 -0
  5. package/src/commands-runner/get-command-projects.js +17 -2
  6. package/src/config/schema-utils.js +4 -4
  7. package/src/config/task-graph.d.ts +5 -0
  8. package/src/config/workspace-json-project-json.d.ts +6 -0
  9. package/src/executors/run-commands/run-commands.impl.d.ts +16 -13
  10. package/src/executors/run-commands/run-commands.impl.js +24 -263
  11. package/src/executors/run-commands/running-tasks.d.ts +38 -0
  12. package/src/executors/run-commands/running-tasks.js +349 -0
  13. package/src/native/index.d.ts +1 -0
  14. package/src/native/nx.wasm32-wasi.wasm +0 -0
  15. package/src/plugins/js/project-graph/build-dependencies/target-project-locator.d.ts +2 -1
  16. package/src/plugins/js/project-graph/build-dependencies/target-project-locator.js +11 -3
  17. package/src/plugins/js/utils/packages.d.ts +6 -1
  18. package/src/plugins/js/utils/packages.js +59 -12
  19. package/src/plugins/package-json/create-nodes.d.ts +3 -3
  20. package/src/plugins/package-json/create-nodes.js +8 -12
  21. package/src/project-graph/file-utils.js +2 -1
  22. package/src/project-graph/plugins/resolve-plugin.js +11 -2
  23. package/src/tasks-runner/create-task-graph.d.ts +3 -0
  24. package/src/tasks-runner/create-task-graph.js +36 -5
  25. package/src/tasks-runner/forked-process-task-runner.d.ts +6 -12
  26. package/src/tasks-runner/forked-process-task-runner.js +110 -263
  27. package/src/tasks-runner/init-tasks-runner.js +4 -0
  28. package/src/tasks-runner/pseudo-terminal.d.ts +7 -1
  29. package/src/tasks-runner/pseudo-terminal.js +26 -12
  30. package/src/tasks-runner/running-tasks/batch-process.d.ts +14 -0
  31. package/src/tasks-runner/running-tasks/batch-process.js +70 -0
  32. package/src/tasks-runner/running-tasks/node-child-process.d.ts +36 -0
  33. package/src/tasks-runner/running-tasks/node-child-process.js +184 -0
  34. package/src/tasks-runner/running-tasks/noop-child-process.d.ts +15 -0
  35. package/src/tasks-runner/running-tasks/noop-child-process.js +19 -0
  36. package/src/tasks-runner/running-tasks/running-task.d.ts +8 -0
  37. package/src/tasks-runner/running-tasks/running-task.js +6 -0
  38. package/src/tasks-runner/task-orchestrator.d.ts +7 -1
  39. package/src/tasks-runner/task-orchestrator.js +137 -82
  40. package/src/tasks-runner/tasks-schedule.js +5 -1
  41. package/src/tasks-runner/utils.d.ts +0 -8
  42. package/src/tasks-runner/utils.js +12 -4
  43. package/src/utils/package-json.d.ts +1 -1
  44. package/src/utils/package-json.js +4 -2
@@ -78,28 +78,42 @@ class PseudoTtyProcess {
78
78
  this.childProcess = childProcess;
79
79
  this.isAlive = true;
80
80
  this.exitCallbacks = [];
81
+ this.outputCallbacks = [];
82
+ this.terminalOutput = '';
83
+ childProcess.onOutput((output) => {
84
+ this.terminalOutput += output;
85
+ this.outputCallbacks.forEach((cb) => cb(output));
86
+ });
81
87
  childProcess.onExit((message) => {
82
88
  this.isAlive = false;
83
- const exitCode = messageToCode(message);
84
- this.exitCallbacks.forEach((cb) => cb(exitCode));
89
+ const code = messageToCode(message);
90
+ childProcess.cleanup();
91
+ this.exitCallbacks.forEach((cb) => cb(code));
92
+ });
93
+ }
94
+ async getResults() {
95
+ return new Promise((res) => {
96
+ this.onExit((code) => {
97
+ res({ code, terminalOutput: this.terminalOutput });
98
+ });
85
99
  });
86
100
  }
87
101
  onExit(callback) {
88
102
  this.exitCallbacks.push(callback);
89
103
  }
90
104
  onOutput(callback) {
91
- this.childProcess.onOutput(callback);
105
+ this.outputCallbacks.push(callback);
92
106
  }
93
107
  kill() {
94
- try {
95
- this.childProcess.kill();
96
- }
97
- catch {
98
- // when the child process completes before we explicitly call kill, this will throw
99
- // do nothing
100
- }
101
- finally {
102
- if (this.isAlive == true) {
108
+ if (this.isAlive) {
109
+ try {
110
+ this.childProcess.kill();
111
+ }
112
+ catch {
113
+ // when the child process completes before we explicitly call kill, this will throw
114
+ // do nothing
115
+ }
116
+ finally {
103
117
  this.isAlive = false;
104
118
  }
105
119
  }
@@ -0,0 +1,14 @@
1
+ import { BatchResults } from '../batch/batch-messages';
2
+ import { ChildProcess, Serializable } from 'child_process';
3
+ export declare class BatchProcess {
4
+ private childProcess;
5
+ private executorName;
6
+ private exitCallbacks;
7
+ private resultsCallbacks;
8
+ constructor(childProcess: ChildProcess, executorName: string);
9
+ onExit(cb: (code: number) => void): void;
10
+ onResults(cb: (results: BatchResults) => void): void;
11
+ getResults(): Promise<BatchResults>;
12
+ send(message: Serializable): void;
13
+ kill(signal?: NodeJS.Signals | number): void;
14
+ }
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BatchProcess = void 0;
4
+ const batch_messages_1 = require("../batch/batch-messages");
5
+ const exit_codes_1 = require("../../utils/exit-codes");
6
+ class BatchProcess {
7
+ constructor(childProcess, executorName) {
8
+ this.childProcess = childProcess;
9
+ this.executorName = executorName;
10
+ this.exitCallbacks = [];
11
+ this.resultsCallbacks = [];
12
+ this.childProcess.on('message', (message) => {
13
+ switch (message.type) {
14
+ case batch_messages_1.BatchMessageType.CompleteBatchExecution: {
15
+ for (const cb of this.resultsCallbacks) {
16
+ cb(message.results);
17
+ }
18
+ break;
19
+ }
20
+ case batch_messages_1.BatchMessageType.RunTasks: {
21
+ break;
22
+ }
23
+ default: {
24
+ // Re-emit any non-batch messages from the task process
25
+ if (process.send) {
26
+ process.send(message);
27
+ }
28
+ }
29
+ }
30
+ });
31
+ this.childProcess.once('exit', (code, signal) => {
32
+ if (code === null)
33
+ code = (0, exit_codes_1.signalToCode)(signal);
34
+ for (const cb of this.exitCallbacks) {
35
+ cb(code);
36
+ }
37
+ });
38
+ }
39
+ onExit(cb) {
40
+ this.exitCallbacks.push(cb);
41
+ }
42
+ onResults(cb) {
43
+ this.resultsCallbacks.push(cb);
44
+ }
45
+ async getResults() {
46
+ return Promise.race([
47
+ new Promise((_, rej) => {
48
+ this.onExit((code) => {
49
+ if (code !== 0) {
50
+ rej(new Error(`"${this.executorName}" exited unexpectedly with code: ${code}`));
51
+ }
52
+ });
53
+ }),
54
+ new Promise((res) => {
55
+ this.onResults(res);
56
+ }),
57
+ ]);
58
+ }
59
+ send(message) {
60
+ if (this.childProcess.connected) {
61
+ this.childProcess.send(message);
62
+ }
63
+ }
64
+ kill(signal) {
65
+ if (this.childProcess.connected) {
66
+ this.childProcess.kill(signal);
67
+ }
68
+ }
69
+ }
70
+ exports.BatchProcess = BatchProcess;
@@ -0,0 +1,36 @@
1
+ import { ChildProcess, Serializable } from 'child_process';
2
+ import { RunningTask } from './running-task';
3
+ export declare class NodeChildProcessWithNonDirectOutput implements RunningTask {
4
+ private childProcess;
5
+ private terminalOutput;
6
+ private exitCallbacks;
7
+ constructor(childProcess: ChildProcess, { streamOutput, prefix }: {
8
+ streamOutput: boolean;
9
+ prefix: string;
10
+ });
11
+ onExit(cb: (code: number, terminalOutput: string) => void): void;
12
+ getResults(): Promise<{
13
+ code: number;
14
+ terminalOutput: string;
15
+ }>;
16
+ send(message: Serializable): void;
17
+ kill(signal?: NodeJS.Signals | number): void;
18
+ }
19
+ export declare class NodeChildProcessWithDirectOutput implements RunningTask {
20
+ private childProcess;
21
+ private temporaryOutputPath;
22
+ private terminalOutput;
23
+ private exitCallbacks;
24
+ private exited;
25
+ private exitCode;
26
+ constructor(childProcess: ChildProcess, temporaryOutputPath: string);
27
+ send(message: Serializable): void;
28
+ onExit(cb: (code: number, signal: NodeJS.Signals) => void): void;
29
+ getResults(): Promise<{
30
+ code: number;
31
+ terminalOutput: string;
32
+ }>;
33
+ waitForExit(): Promise<void>;
34
+ getTerminalOutput(): string;
35
+ kill(signal?: NodeJS.Signals | number): void;
36
+ }
@@ -0,0 +1,184 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NodeChildProcessWithDirectOutput = exports.NodeChildProcessWithNonDirectOutput = void 0;
4
+ const exit_codes_1 = require("../../utils/exit-codes");
5
+ const stream_1 = require("stream");
6
+ const chalk = require("chalk");
7
+ const fs_1 = require("fs");
8
+ class NodeChildProcessWithNonDirectOutput {
9
+ constructor(childProcess, { streamOutput, prefix }) {
10
+ this.childProcess = childProcess;
11
+ this.terminalOutput = '';
12
+ this.exitCallbacks = [];
13
+ if (streamOutput) {
14
+ if (process.env.NX_PREFIX_OUTPUT === 'true') {
15
+ const color = getColor(prefix);
16
+ const prefixText = `${prefix}:`;
17
+ this.childProcess.stdout
18
+ .pipe(logClearLineToPrefixTransformer(color.bold(prefixText) + ' '))
19
+ .pipe(addPrefixTransformer(color.bold(prefixText)))
20
+ .pipe(process.stdout);
21
+ this.childProcess.stderr
22
+ .pipe(logClearLineToPrefixTransformer(color(prefixText) + ' '))
23
+ .pipe(addPrefixTransformer(color(prefixText)))
24
+ .pipe(process.stderr);
25
+ }
26
+ else {
27
+ this.childProcess.stdout
28
+ .pipe(addPrefixTransformer())
29
+ .pipe(process.stdout);
30
+ this.childProcess.stderr
31
+ .pipe(addPrefixTransformer())
32
+ .pipe(process.stderr);
33
+ }
34
+ }
35
+ this.childProcess.on('exit', (code, signal) => {
36
+ if (code === null)
37
+ code = (0, exit_codes_1.signalToCode)(signal);
38
+ for (const cb of this.exitCallbacks) {
39
+ cb(code, this.terminalOutput);
40
+ }
41
+ });
42
+ // Re-emit any messages from the task process
43
+ this.childProcess.on('message', (message) => {
44
+ if (process.send) {
45
+ process.send(message);
46
+ }
47
+ });
48
+ this.childProcess.stdout.on('data', (chunk) => {
49
+ this.terminalOutput += chunk.toString();
50
+ });
51
+ this.childProcess.stderr.on('data', (chunk) => {
52
+ this.terminalOutput += chunk.toString();
53
+ });
54
+ }
55
+ onExit(cb) {
56
+ this.exitCallbacks.push(cb);
57
+ }
58
+ async getResults() {
59
+ return new Promise((res) => {
60
+ this.onExit((code, terminalOutput) => {
61
+ res({ code, terminalOutput });
62
+ });
63
+ });
64
+ }
65
+ send(message) {
66
+ if (this.childProcess.connected) {
67
+ this.childProcess.send(message);
68
+ }
69
+ }
70
+ kill(signal) {
71
+ if (this.childProcess.connected) {
72
+ this.childProcess.kill(signal);
73
+ }
74
+ }
75
+ }
76
+ exports.NodeChildProcessWithNonDirectOutput = NodeChildProcessWithNonDirectOutput;
77
+ function addPrefixTransformer(prefix) {
78
+ const newLineSeparator = process.platform.startsWith('win') ? '\r\n' : '\n';
79
+ return new stream_1.Transform({
80
+ transform(chunk, _encoding, callback) {
81
+ const list = chunk.toString().split(/\r\n|[\n\v\f\r\x85\u2028\u2029]/g);
82
+ list
83
+ .filter(Boolean)
84
+ .forEach((m) => this.push(prefix ? prefix + ' ' + m + newLineSeparator : m + newLineSeparator));
85
+ callback();
86
+ },
87
+ });
88
+ }
89
+ const colors = [
90
+ chalk.green,
91
+ chalk.greenBright,
92
+ chalk.red,
93
+ chalk.redBright,
94
+ chalk.cyan,
95
+ chalk.cyanBright,
96
+ chalk.yellow,
97
+ chalk.yellowBright,
98
+ chalk.magenta,
99
+ chalk.magentaBright,
100
+ ];
101
+ function getColor(projectName) {
102
+ let code = 0;
103
+ for (let i = 0; i < projectName.length; ++i) {
104
+ code += projectName.charCodeAt(i);
105
+ }
106
+ const colorIndex = code % colors.length;
107
+ return colors[colorIndex];
108
+ }
109
+ /**
110
+ * Prevents terminal escape sequence from clearing line prefix.
111
+ */
112
+ function logClearLineToPrefixTransformer(prefix) {
113
+ let prevChunk = null;
114
+ return new stream_1.Transform({
115
+ transform(chunk, _encoding, callback) {
116
+ if (prevChunk && prevChunk.toString() === '\x1b[2K') {
117
+ chunk = chunk.toString().replace(/\x1b\[1G/g, (m) => m + prefix);
118
+ }
119
+ this.push(chunk);
120
+ prevChunk = chunk;
121
+ callback();
122
+ },
123
+ });
124
+ }
125
+ class NodeChildProcessWithDirectOutput {
126
+ constructor(childProcess, temporaryOutputPath) {
127
+ this.childProcess = childProcess;
128
+ this.temporaryOutputPath = temporaryOutputPath;
129
+ this.exitCallbacks = [];
130
+ this.exited = false;
131
+ // Re-emit any messages from the task process
132
+ this.childProcess.on('message', (message) => {
133
+ if (process.send) {
134
+ process.send(message);
135
+ }
136
+ });
137
+ this.childProcess.on('exit', (code, signal) => {
138
+ if (code === null)
139
+ code = (0, exit_codes_1.signalToCode)(signal);
140
+ this.exited = true;
141
+ this.exitCode = code;
142
+ for (const cb of this.exitCallbacks) {
143
+ cb(code, signal);
144
+ }
145
+ });
146
+ }
147
+ send(message) {
148
+ if (this.childProcess.connected) {
149
+ this.childProcess.send(message);
150
+ }
151
+ }
152
+ onExit(cb) {
153
+ this.exitCallbacks.push(cb);
154
+ }
155
+ async getResults() {
156
+ const terminalOutput = this.getTerminalOutput();
157
+ if (this.exited) {
158
+ return Promise.resolve({
159
+ code: this.exitCode,
160
+ terminalOutput,
161
+ });
162
+ }
163
+ await this.waitForExit();
164
+ return Promise.resolve({
165
+ code: this.exitCode,
166
+ terminalOutput,
167
+ });
168
+ }
169
+ waitForExit() {
170
+ return new Promise((res) => {
171
+ this.onExit(() => res());
172
+ });
173
+ }
174
+ getTerminalOutput() {
175
+ this.terminalOutput ??= (0, fs_1.readFileSync)(this.temporaryOutputPath).toString();
176
+ return this.terminalOutput;
177
+ }
178
+ kill(signal) {
179
+ if (this.childProcess.connected) {
180
+ this.childProcess.kill(signal);
181
+ }
182
+ }
183
+ }
184
+ exports.NodeChildProcessWithDirectOutput = NodeChildProcessWithDirectOutput;
@@ -0,0 +1,15 @@
1
+ import { RunningTask } from './running-task';
2
+ export declare class NoopChildProcess implements RunningTask {
3
+ private results;
4
+ constructor(results: {
5
+ code: number;
6
+ terminalOutput: string;
7
+ });
8
+ send(): void;
9
+ getResults(): Promise<{
10
+ code: number;
11
+ terminalOutput: string;
12
+ }>;
13
+ kill(): void;
14
+ onExit(cb: (code: number) => void): void;
15
+ }
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NoopChildProcess = void 0;
4
+ class NoopChildProcess {
5
+ constructor(results) {
6
+ this.results = results;
7
+ }
8
+ send() { }
9
+ async getResults() {
10
+ return this.results;
11
+ }
12
+ kill() {
13
+ return;
14
+ }
15
+ onExit(cb) {
16
+ cb(this.results.code);
17
+ }
18
+ }
19
+ exports.NoopChildProcess = NoopChildProcess;
@@ -0,0 +1,8 @@
1
+ export declare abstract class RunningTask {
2
+ abstract getResults(): Promise<{
3
+ code: number;
4
+ terminalOutput: string;
5
+ }>;
6
+ abstract onExit(cb: (code: number) => void): void;
7
+ abstract kill(signal?: NodeJS.Signals | number): Promise<void> | void;
8
+ }
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RunningTask = void 0;
4
+ class RunningTask {
5
+ }
6
+ exports.RunningTask = RunningTask;
@@ -5,6 +5,7 @@ import { ProjectGraph } from '../config/project-graph';
5
5
  import { TaskGraph } from '../config/task-graph';
6
6
  import { DaemonClient } from '../daemon/client/client';
7
7
  import { NxJsonConfiguration } from '../config/nx-json';
8
+ import { NxArgs } from '../utils/command-line-utils';
8
9
  export declare class TaskOrchestrator {
9
10
  private readonly hasher;
10
11
  private readonly initiatingProject;
@@ -27,7 +28,9 @@ export declare class TaskOrchestrator {
27
28
  private waitingForTasks;
28
29
  private groups;
29
30
  private bailed;
30
- constructor(hasher: TaskHasher, initiatingProject: string | undefined, projectGraph: ProjectGraph, taskGraph: TaskGraph, nxJson: NxJsonConfiguration, options: DefaultTasksRunnerOptions, bail: boolean, daemon: DaemonClient, outputStyle: string);
31
+ private runningContinuousTasks;
32
+ private cleaningUp;
33
+ constructor(hasher: TaskHasher, initiatingProject: string | undefined, projectGraph: ProjectGraph, taskGraph: TaskGraph, nxJson: NxJsonConfiguration, options: NxArgs & DefaultTasksRunnerOptions, bail: boolean, daemon: DaemonClient, outputStyle: string);
31
34
  run(): Promise<{
32
35
  [id: string]: TaskStatus;
33
36
  }>;
@@ -40,7 +43,9 @@ export declare class TaskOrchestrator {
40
43
  private applyFromCacheOrRunBatch;
41
44
  private runBatch;
42
45
  private applyFromCacheOrRunTask;
46
+ private runTask;
43
47
  private runTaskInForkedProcess;
48
+ private startContinuousTask;
44
49
  private preRunSteps;
45
50
  private postRunSteps;
46
51
  private complete;
@@ -50,4 +55,5 @@ export declare class TaskOrchestrator {
50
55
  private openGroup;
51
56
  private shouldCopyOutputsFromCache;
52
57
  private recordOutputsHash;
58
+ private cleanup;
53
59
  }