nx 19.0.0-canary.20240419-e617e54 → 19.0.0-canary.20240420-9ca53b7

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.
@@ -7,17 +7,10 @@ const yargsParser = require("yargs-parser");
7
7
  const npm_run_path_1 = require("npm-run-path");
8
8
  const chalk = require("chalk");
9
9
  const pseudo_terminal_1 = require("../../tasks-runner/pseudo-terminal");
10
+ const exit_codes_1 = require("../../utils/exit-codes");
10
11
  exports.LARGE_BUFFER = 1024 * 1000000;
11
- const exitListeners = new Set();
12
- function processExitListener() {
13
- for (const listener of exitListeners) {
14
- listener();
15
- }
16
- }
17
- process.on('exit', processExitListener);
18
- process.on('SIGTERM', processExitListener);
19
- process.on('SIGINT', processExitListener);
20
- process.on('SIGQUIT', processExitListener);
12
+ let pseudoTerminal;
13
+ const childProcesses = new Set();
21
14
  async function loadEnvVars(path) {
22
15
  if (path) {
23
16
  const result = (await Promise.resolve().then(() => require('dotenv'))).config({ path });
@@ -48,6 +41,7 @@ const propKeys = [
48
41
  'verbose',
49
42
  ];
50
43
  async function default_1(options, context) {
44
+ registerProcessListener();
51
45
  await loadEnvVars(options.envFile);
52
46
  const normalized = normalizeOptions(options);
53
47
  if (options.readyWhen && !options.parallel) {
@@ -146,9 +140,7 @@ function normalizeOptions(options) {
146
140
  return options;
147
141
  }
148
142
  async function runSerially(options, context) {
149
- const pseudoTerminal = pseudo_terminal_1.PseudoTerminal.isSupported()
150
- ? (0, pseudo_terminal_1.getPseudoTerminal)()
151
- : null;
143
+ pseudoTerminal ??= pseudo_terminal_1.PseudoTerminal.isSupported() ? (0, pseudo_terminal_1.getPseudoTerminal)() : null;
152
144
  let terminalOutput = '';
153
145
  for (const c of options.commands) {
154
146
  const result = await createProcess(pseudoTerminal, c, undefined, options.color, calculateCwd(options.cwd, context), options.env ?? {}, false, options.usePty, options.streamOutput);
@@ -182,6 +174,7 @@ async function createProcess(pseudoTerminal, commandConfig, readyWhen, color, cw
182
174
  jsEnv: env,
183
175
  quiet: !streamOutput,
184
176
  });
177
+ childProcesses.add(cp);
185
178
  return new Promise((res) => {
186
179
  cp.onOutput((output) => {
187
180
  terminalOutput += output;
@@ -212,11 +205,7 @@ function nodeProcess(commandConfig, cwd, env, readyWhen, streamOutput = true) {
212
205
  env,
213
206
  cwd,
214
207
  });
215
- /**
216
- * Ensure the child process is killed when the parent exits
217
- */
218
- const childProcessKiller = (signal) => childProcess.kill(signal);
219
- exitListeners.add(childProcessKiller);
208
+ childProcesses.add(childProcess);
220
209
  childProcess.stdout.on('data', (data) => {
221
210
  const output = addColorAndPrefix(data, commandConfig);
222
211
  terminalOutput += output;
@@ -246,7 +235,7 @@ function nodeProcess(commandConfig, cwd, env, readyWhen, streamOutput = true) {
246
235
  res({ success: false, terminalOutput });
247
236
  });
248
237
  childProcess.on('exit', (code) => {
249
- exitListeners.delete(childProcessKiller);
238
+ childProcesses.delete(childProcess);
250
239
  if (!readyWhen) {
251
240
  res({ success: code === 0, terminalOutput });
252
241
  }
@@ -369,3 +358,57 @@ function filterPropKeysFromUnParsedOptions(__unparsed__, unparsedCommandArgs = {
369
358
  }
370
359
  return parsedOptions;
371
360
  }
361
+ let registered = false;
362
+ function registerProcessListener() {
363
+ if (registered) {
364
+ return;
365
+ }
366
+ registered = true;
367
+ // When the nx process gets a message, it will be sent into the task's process
368
+ process.on('message', (message) => {
369
+ // this.publisher.publish(message.toString());
370
+ if (pseudoTerminal) {
371
+ pseudoTerminal.sendMessageToChildren(message);
372
+ }
373
+ childProcesses.forEach((p) => {
374
+ if ('connected' in p && p.connected) {
375
+ p.send(message);
376
+ }
377
+ });
378
+ });
379
+ // Terminate any task processes on exit
380
+ process.on('exit', () => {
381
+ childProcesses.forEach((p) => {
382
+ if ('connected' in p ? p.connected : p.isAlive) {
383
+ p.kill();
384
+ }
385
+ });
386
+ });
387
+ process.on('SIGINT', () => {
388
+ childProcesses.forEach((p) => {
389
+ if ('connected' in p ? p.connected : p.isAlive) {
390
+ p.kill('SIGTERM');
391
+ }
392
+ });
393
+ // we exit here because we don't need to write anything to cache.
394
+ process.exit((0, exit_codes_1.signalToCode)('SIGINT'));
395
+ });
396
+ process.on('SIGTERM', () => {
397
+ childProcesses.forEach((p) => {
398
+ if ('connected' in p ? p.connected : p.isAlive) {
399
+ p.kill('SIGTERM');
400
+ }
401
+ });
402
+ // no exit here because we expect child processes to terminate which
403
+ // will store results to the cache and will terminate this process
404
+ });
405
+ process.on('SIGHUP', () => {
406
+ childProcesses.forEach((p) => {
407
+ if ('connected' in p ? p.connected : p.isAlive) {
408
+ p.kill('SIGTERM');
409
+ }
410
+ });
411
+ // no exit here because we expect child processes to terminate which
412
+ // will store results to the cache and will terminate this process
413
+ });
414
+ }
@@ -24,6 +24,10 @@ const EXTENDED_LEFT_PAD = ` `;
24
24
  */
25
25
  async function createRunManyDynamicOutputRenderer({ projectNames, tasks, args, overrides, }) {
26
26
  cliCursor.hide();
27
+ // Show the cursor again after the process exits
28
+ process.on('exit', () => {
29
+ cliCursor.show();
30
+ });
27
31
  let resolveRenderIsDonePromise;
28
32
  const renderIsDone = new Promise((resolve) => (resolveRenderIsDonePromise = resolve)).then(() => {
29
33
  clearRenderInterval();
@@ -24,6 +24,10 @@ const EXTENDED_LEFT_PAD = ` `;
24
24
  */
25
25
  async function createRunOneDynamicOutputRenderer({ initiatingProject, tasks, args, overrides, }) {
26
26
  cliCursor.hide();
27
+ // Show the cursor again after the process exits
28
+ process.on('exit', () => {
29
+ cliCursor.show();
30
+ });
27
31
  let resolveRenderIsDonePromise;
28
32
  const renderIsDone = new Promise((resolve) => (resolveRenderIsDonePromise = resolve)).then(() => {
29
33
  clearRenderInterval();
@@ -142,6 +142,12 @@ function supportedPtyPlatform() {
142
142
  if (process.platform !== 'win32') {
143
143
  return true;
144
144
  }
145
+ // TODO: Re-enable Windows support when it's stable
146
+ // Currently, there's an issue with control chars.
147
+ // See: https://github.com/nrwl/nx/issues/22358
148
+ if (process.env.NX_WINDOWS_PTY_SUPPORT !== 'true') {
149
+ return false;
150
+ }
145
151
  let windowsVersion = os.release().split('.');
146
152
  let windowsBuild = windowsVersion[2];
147
153
  if (!windowsBuild) {