nx 21.0.0-beta.1 → 21.0.0-beta.2

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 (198) hide show
  1. package/.eslintrc.json +5 -1
  2. package/package.json +12 -12
  3. package/release/index.d.ts +1 -1
  4. package/release/index.js +2 -1
  5. package/schemas/nx-schema.json +186 -35
  6. package/src/adapter/compat.d.ts +1 -1
  7. package/src/adapter/compat.js +3 -0
  8. package/src/command-line/add/add.js +6 -16
  9. package/src/command-line/affected/command-object.js +6 -6
  10. package/src/command-line/examples.js +0 -4
  11. package/src/command-line/exec/command-object.js +1 -1
  12. package/src/command-line/generate/generator-utils.js +8 -3
  13. package/src/command-line/import/import.js +1 -1
  14. package/src/command-line/init/command-object.js +18 -6
  15. package/src/command-line/init/configure-plugins.d.ts +6 -7
  16. package/src/command-line/init/configure-plugins.js +47 -35
  17. package/src/command-line/init/implementation/add-nx-to-turborepo.d.ts +4 -0
  18. package/src/command-line/init/implementation/add-nx-to-turborepo.js +49 -0
  19. package/src/command-line/init/implementation/check-compatible-with-plugins.js +7 -1
  20. package/src/command-line/init/implementation/deduce-default-base.d.ts +1 -0
  21. package/src/command-line/init/implementation/deduce-default-base.js +53 -0
  22. package/src/command-line/init/implementation/react/add-vite-commands-to-package-scripts.js +6 -4
  23. package/src/command-line/init/implementation/react/index.d.ts +1 -1
  24. package/src/command-line/init/implementation/react/index.js +32 -185
  25. package/src/command-line/init/implementation/react/write-vite-config.js +19 -3
  26. package/src/command-line/init/implementation/utils.d.ts +4 -1
  27. package/src/command-line/init/implementation/utils.js +108 -44
  28. package/src/command-line/init/init-v1.js +1 -1
  29. package/src/command-line/init/init-v2.d.ts +1 -0
  30. package/src/command-line/init/init-v2.js +68 -38
  31. package/src/command-line/nx-commands.js +19 -5
  32. package/src/command-line/register/command-object.d.ts +6 -0
  33. package/src/command-line/{activate-powerpack → register}/command-object.js +9 -9
  34. package/src/command-line/register/register.d.ts +2 -0
  35. package/src/command-line/register/register.js +9 -0
  36. package/src/command-line/release/changelog.js +18 -15
  37. package/src/command-line/release/command-object.d.ts +2 -0
  38. package/src/command-line/release/command-object.js +9 -0
  39. package/src/command-line/release/config/config.d.ts +8 -7
  40. package/src/command-line/release/config/config.js +129 -42
  41. package/src/command-line/release/config/use-legacy-versioning.d.ts +2 -0
  42. package/src/command-line/release/config/use-legacy-versioning.js +9 -0
  43. package/src/command-line/release/index.d.ts +4 -0
  44. package/src/command-line/release/index.js +6 -1
  45. package/src/command-line/release/plan-check.js +6 -3
  46. package/src/command-line/release/plan.js +7 -3
  47. package/src/command-line/release/publish.js +7 -3
  48. package/src/command-line/release/release.js +8 -3
  49. package/src/command-line/release/utils/batch-projects-by-generator-config.js +6 -3
  50. package/src/command-line/release/utils/git.d.ts +3 -2
  51. package/src/command-line/release/utils/git.js +65 -9
  52. package/src/command-line/release/utils/github.js +3 -1
  53. package/src/command-line/release/utils/resolve-semver-specifier.d.ts +2 -1
  54. package/src/command-line/release/utils/resolve-semver-specifier.js +2 -1
  55. package/src/command-line/release/utils/semver.d.ts +8 -0
  56. package/src/command-line/release/utils/semver.js +8 -0
  57. package/src/command-line/release/utils/shared-legacy.d.ts +25 -0
  58. package/src/command-line/release/utils/shared-legacy.js +2 -0
  59. package/src/command-line/release/utils/shared.d.ts +11 -17
  60. package/src/command-line/release/version/derive-specifier-from-conventional-commits.d.ts +7 -0
  61. package/src/command-line/release/version/derive-specifier-from-conventional-commits.js +47 -0
  62. package/src/command-line/release/version/deriver-specifier-from-version-plans.d.ts +8 -0
  63. package/src/command-line/release/version/deriver-specifier-from-version-plans.js +59 -0
  64. package/src/command-line/release/version/project-logger.d.ts +8 -0
  65. package/src/command-line/release/version/project-logger.js +45 -0
  66. package/src/command-line/release/version/release-group-processor.d.ts +251 -0
  67. package/src/command-line/release/version/release-group-processor.js +1040 -0
  68. package/src/command-line/release/version/resolve-current-version.d.ts +32 -0
  69. package/src/command-line/release/version/resolve-current-version.js +241 -0
  70. package/src/command-line/release/version/test-utils.d.ts +95 -0
  71. package/src/command-line/release/version/test-utils.js +416 -0
  72. package/src/command-line/release/version/topological-sort.d.ts +9 -0
  73. package/src/command-line/release/version/topological-sort.js +41 -0
  74. package/src/command-line/release/version/version-actions.d.ts +170 -0
  75. package/src/command-line/release/version/version-actions.js +183 -0
  76. package/src/command-line/release/version-legacy.d.ts +46 -0
  77. package/src/command-line/release/version-legacy.js +453 -0
  78. package/src/command-line/release/version.d.ts +0 -40
  79. package/src/command-line/release/version.js +80 -262
  80. package/src/command-line/report/report.d.ts +7 -3
  81. package/src/command-line/report/report.js +52 -18
  82. package/src/command-line/run/command-object.js +2 -2
  83. package/src/command-line/run/run.js +1 -1
  84. package/src/command-line/run-many/command-object.js +2 -2
  85. package/src/command-line/yargs-utils/shared-options.d.ts +4 -0
  86. package/src/command-line/yargs-utils/shared-options.js +20 -0
  87. package/src/config/nx-json.d.ts +153 -15
  88. package/src/config/project-graph.d.ts +4 -2
  89. package/src/config/project-graph.js +8 -0
  90. package/src/config/workspace-json-project-json.d.ts +2 -2
  91. package/src/core/graph/main.js +1 -1
  92. package/src/core/graph/runtime.js +1 -1
  93. package/src/core/graph/styles.css +2 -2
  94. package/src/core/graph/styles.js +1 -1
  95. package/src/daemon/client/client.d.ts +2 -0
  96. package/src/daemon/client/client.js +15 -0
  97. package/src/daemon/message-types/glob.d.ts +7 -0
  98. package/src/daemon/message-types/glob.js +9 -1
  99. package/src/daemon/message-types/hash-glob.d.ts +6 -0
  100. package/src/daemon/message-types/hash-glob.js +9 -1
  101. package/src/daemon/server/handle-glob.d.ts +1 -0
  102. package/src/daemon/server/handle-glob.js +8 -0
  103. package/src/daemon/server/handle-hash-glob.d.ts +1 -0
  104. package/src/daemon/server/handle-hash-glob.js +8 -0
  105. package/src/daemon/server/logger.js +2 -1
  106. package/src/daemon/server/server.js +7 -0
  107. package/src/devkit-internals.d.ts +2 -1
  108. package/src/devkit-internals.js +4 -1
  109. package/src/executors/run-commands/run-commands.impl.d.ts +3 -5
  110. package/src/executors/run-commands/run-commands.impl.js +14 -42
  111. package/src/executors/run-commands/running-tasks.d.ts +7 -5
  112. package/src/executors/run-commands/running-tasks.js +64 -27
  113. package/src/executors/run-script/run-script.impl.js +3 -3
  114. package/src/generators/internal-utils/format-changed-files-with-prettier-if-available.js +8 -0
  115. package/src/generators/testing-utils/create-tree.js +5 -1
  116. package/src/native/index.d.ts +93 -19
  117. package/src/native/native-bindings.js +6 -0
  118. package/src/native/nx.wasi-browser.js +20 -19
  119. package/src/native/nx.wasi.cjs +20 -19
  120. package/src/native/nx.wasm32-wasi.wasm +0 -0
  121. package/src/nx-cloud/nx-cloud-tasks-runner-shell.js +3 -3
  122. package/src/plugins/js/lock-file/lock-file.js +28 -13
  123. package/src/plugins/js/lock-file/utils/package-json.d.ts +1 -1
  124. package/src/plugins/js/lock-file/utils/package-json.js +2 -1
  125. package/src/plugins/js/lock-file/yarn-parser.js +85 -39
  126. package/src/plugins/js/project-graph/affected/lock-file-changes.js +1 -0
  127. package/src/plugins/js/project-graph/build-dependencies/explicit-project-dependencies.js +1 -1
  128. package/src/plugins/js/project-graph/build-dependencies/target-project-locator.d.ts +10 -1
  129. package/src/plugins/js/project-graph/build-dependencies/target-project-locator.js +59 -6
  130. package/src/plugins/js/utils/packages.js +22 -3
  131. package/src/plugins/js/utils/register.js +1 -0
  132. package/src/plugins/js/utils/typescript.js +3 -3
  133. package/src/plugins/package-json/create-nodes.js +3 -1
  134. package/src/project-graph/affected/locators/project-glob-changes.js +2 -2
  135. package/src/project-graph/error-types.js +32 -2
  136. package/src/project-graph/plugins/get-plugins.js +2 -1
  137. package/src/project-graph/plugins/in-process-loader.js +1 -1
  138. package/src/project-graph/plugins/isolation/plugin-worker.js +12 -6
  139. package/src/project-graph/plugins/loaded-nx-plugin.d.ts +2 -1
  140. package/src/project-graph/plugins/utils.d.ts +2 -2
  141. package/src/project-graph/plugins/utils.js +2 -2
  142. package/src/project-graph/project-graph.js +1 -1
  143. package/src/project-graph/utils/project-configuration-utils.d.ts +1 -1
  144. package/src/project-graph/utils/project-configuration-utils.js +25 -11
  145. package/src/project-graph/utils/retrieve-workspace-files.d.ts +1 -1
  146. package/src/project-graph/utils/retrieve-workspace-files.js +14 -18
  147. package/src/tasks-runner/batch/batch-messages.d.ts +2 -0
  148. package/src/tasks-runner/batch/run-batch.js +2 -3
  149. package/src/tasks-runner/cache.d.ts +20 -6
  150. package/src/tasks-runner/cache.js +104 -20
  151. package/src/tasks-runner/create-task-graph.d.ts +1 -1
  152. package/src/tasks-runner/create-task-graph.js +12 -11
  153. package/src/tasks-runner/default-tasks-runner.js +4 -13
  154. package/src/tasks-runner/forked-process-task-runner.d.ts +6 -3
  155. package/src/tasks-runner/forked-process-task-runner.js +29 -28
  156. package/src/tasks-runner/init-tasks-runner.d.ts +15 -1
  157. package/src/tasks-runner/init-tasks-runner.js +55 -2
  158. package/src/tasks-runner/is-tui-enabled.d.ts +2 -0
  159. package/src/tasks-runner/is-tui-enabled.js +58 -0
  160. package/src/tasks-runner/life-cycle.d.ts +10 -3
  161. package/src/tasks-runner/life-cycle.js +23 -2
  162. package/src/tasks-runner/life-cycles/task-history-life-cycle-old.js +7 -2
  163. package/src/tasks-runner/life-cycles/task-history-life-cycle.js +6 -1
  164. package/src/tasks-runner/life-cycles/tui-summary-life-cycle.d.ts +17 -0
  165. package/src/tasks-runner/life-cycles/tui-summary-life-cycle.js +221 -0
  166. package/src/tasks-runner/pseudo-terminal.d.ts +10 -7
  167. package/src/tasks-runner/pseudo-terminal.js +37 -35
  168. package/src/tasks-runner/run-command.d.ts +1 -0
  169. package/src/tasks-runner/run-command.js +180 -23
  170. package/src/tasks-runner/task-env.d.ts +1 -4
  171. package/src/tasks-runner/task-env.js +2 -0
  172. package/src/tasks-runner/task-orchestrator.d.ts +21 -9
  173. package/src/tasks-runner/task-orchestrator.js +126 -44
  174. package/src/tasks-runner/utils.d.ts +2 -2
  175. package/src/tasks-runner/utils.js +15 -11
  176. package/src/utils/child-process.d.ts +4 -0
  177. package/src/utils/child-process.js +23 -30
  178. package/src/utils/command-line-utils.d.ts +1 -1
  179. package/src/utils/find-matching-projects.js +2 -2
  180. package/src/utils/handle-errors.js +15 -0
  181. package/src/utils/is-ci.js +4 -1
  182. package/src/utils/is-using-prettier.d.ts +3 -0
  183. package/src/utils/is-using-prettier.js +62 -0
  184. package/src/utils/nx-key.d.ts +7 -0
  185. package/src/utils/nx-key.js +52 -0
  186. package/src/utils/package-manager.js +2 -2
  187. package/src/utils/path.js +1 -1
  188. package/src/utils/require-nx-key.d.ts +1 -0
  189. package/src/utils/require-nx-key.js +22 -0
  190. package/src/utils/workspace-context.d.ts +2 -0
  191. package/src/utils/workspace-context.js +16 -0
  192. package/src/command-line/activate-powerpack/activate-powerpack.d.ts +0 -2
  193. package/src/command-line/activate-powerpack/activate-powerpack.js +0 -34
  194. package/src/command-line/activate-powerpack/command-object.d.ts +0 -6
  195. package/src/command-line/init/implementation/react/write-craco-config.d.ts +0 -1
  196. package/src/command-line/init/implementation/react/write-craco-config.js +0 -61
  197. package/src/utils/powerpack.d.ts +0 -5
  198. package/src/utils/powerpack.js +0 -33
@@ -1,24 +1,29 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.TaskOrchestrator = void 0;
4
+ exports.getThreadCount = getThreadCount;
4
5
  const events_1 = require("events");
5
- const perf_hooks_1 = require("perf_hooks");
6
- const path_1 = require("path");
7
6
  const fs_1 = require("fs");
7
+ const path_1 = require("path");
8
+ const perf_hooks_1 = require("perf_hooks");
8
9
  const run_commands_impl_1 = require("../executors/run-commands/run-commands.impl");
9
- const forked_process_task_runner_1 = require("./forked-process-task-runner");
10
- const cache_1 = require("./cache");
11
- const utils_1 = require("./utils");
12
- const tasks_schedule_1 = require("./tasks-schedule");
13
10
  const hash_task_1 = require("../hasher/hash-task");
14
- const task_env_1 = require("./task-env");
15
- const workspace_root_1 = require("../utils/workspace-root");
11
+ const native_1 = require("../native");
12
+ const db_connection_1 = require("../utils/db-connection");
16
13
  const output_1 = require("../utils/output");
17
14
  const params_1 = require("../utils/params");
15
+ const workspace_root_1 = require("../utils/workspace-root");
16
+ const cache_1 = require("./cache");
17
+ const forked_process_task_runner_1 = require("./forked-process-task-runner");
18
+ const is_tui_enabled_1 = require("./is-tui-enabled");
19
+ const pseudo_terminal_1 = require("./pseudo-terminal");
18
20
  const noop_child_process_1 = require("./running-tasks/noop-child-process");
21
+ const task_env_1 = require("./task-env");
22
+ const tasks_schedule_1 = require("./tasks-schedule");
23
+ const utils_1 = require("./utils");
19
24
  class TaskOrchestrator {
20
25
  // endregion internal state
21
- constructor(hasher, initiatingProject, projectGraph, taskGraph, nxJson, options, bail, daemon, outputStyle) {
26
+ constructor(hasher, initiatingProject, projectGraph, taskGraph, nxJson, options, bail, daemon, outputStyle, taskGraphForHashing = taskGraph) {
22
27
  this.hasher = hasher;
23
28
  this.initiatingProject = initiatingProject;
24
29
  this.projectGraph = projectGraph;
@@ -28,9 +33,12 @@ class TaskOrchestrator {
28
33
  this.bail = bail;
29
34
  this.daemon = daemon;
30
35
  this.outputStyle = outputStyle;
36
+ this.taskGraphForHashing = taskGraphForHashing;
31
37
  this.taskDetails = (0, hash_task_1.getTaskDetails)();
32
38
  this.cache = (0, cache_1.getCache)(this.options);
33
- this.forkedProcessTaskRunner = new forked_process_task_runner_1.ForkedProcessTaskRunner(this.options);
39
+ this.tuiEnabled = (0, is_tui_enabled_1.isTuiEnabled)(this.nxJson);
40
+ this.forkedProcessTaskRunner = new forked_process_task_runner_1.ForkedProcessTaskRunner(this.options, this.tuiEnabled);
41
+ this.runningTasksService = new native_1.RunningTasksService((0, db_connection_1.getDbConnection)());
34
42
  this.tasksSchedule = new tasks_schedule_1.TasksSchedule(this.projectGraph, this.taskGraph, this.options);
35
43
  // region internal state
36
44
  this.batchEnv = (0, task_env_1.getEnvVariablesForBatchProcess)(this.options.skipNxCache, this.options.captureStderr);
@@ -44,18 +52,20 @@ class TaskOrchestrator {
44
52
  this.runningContinuousTasks = new Map();
45
53
  this.cleaningUp = false;
46
54
  }
47
- async run() {
55
+ async init() {
48
56
  // Init the ForkedProcessTaskRunner, TasksSchedule, and Cache
49
57
  await Promise.all([
50
58
  this.forkedProcessTaskRunner.init(),
51
59
  this.tasksSchedule.init(),
52
60
  'init' in this.cache ? this.cache.init() : null,
53
61
  ]);
62
+ }
63
+ async run() {
64
+ await this.init();
54
65
  // initial scheduling
55
66
  await this.tasksSchedule.scheduleNextTasks();
56
67
  perf_hooks_1.performance.mark('task-execution:start');
57
- const threadCount = this.options.parallel +
58
- Object.values(this.taskGraph.tasks).filter((t) => t.continuous).length;
68
+ const threadCount = getThreadCount(this.options, this.taskGraph);
59
69
  const threads = [];
60
70
  process.stdout.setMaxListeners(threadCount + events_1.defaultMaxListeners);
61
71
  process.stderr.setMaxListeners(threadCount + events_1.defaultMaxListeners);
@@ -63,7 +73,15 @@ class TaskOrchestrator {
63
73
  for (let i = 0; i < threadCount; ++i) {
64
74
  threads.push(this.executeNextBatchOfTasksUsingTaskSchedule());
65
75
  }
66
- await Promise.all(threads);
76
+ await Promise.race([
77
+ Promise.all(threads),
78
+ new Promise((resolve) => {
79
+ this.options.lifeCycle.registerForcedShutdownCallback(() => {
80
+ // The user force quit the TUI with ctrl+c, so proceed onto cleanup
81
+ resolve(undefined);
82
+ });
83
+ }),
84
+ ]);
67
85
  perf_hooks_1.performance.mark('task-execution:end');
68
86
  perf_hooks_1.performance.measure('task-execution', 'task-execution:start', 'task-execution:end');
69
87
  this.cache.removeOldCacheRecords();
@@ -101,11 +119,11 @@ class TaskOrchestrator {
101
119
  return new Promise((res) => this.waitingForTasks.push(res)).then(() => this.executeNextBatchOfTasksUsingTaskSchedule());
102
120
  }
103
121
  // region Processing Scheduled Tasks
104
- async processScheduledTask(taskId) {
122
+ async processTask(taskId) {
105
123
  const task = this.taskGraph.tasks[taskId];
106
124
  const taskSpecificEnv = (0, task_env_1.getTaskSpecificEnv)(task);
107
125
  if (!task.hash) {
108
- await (0, hash_task_1.hashTask)(this.hasher, this.projectGraph, this.taskGraph, task, taskSpecificEnv, this.taskDetails);
126
+ await (0, hash_task_1.hashTask)(this.hasher, this.projectGraph, this.taskGraphForHashing, task, taskSpecificEnv, this.taskDetails);
109
127
  }
110
128
  await this.options.lifeCycle.scheduleTask(task);
111
129
  return taskSpecificEnv;
@@ -113,7 +131,7 @@ class TaskOrchestrator {
113
131
  async processScheduledBatch(batch) {
114
132
  await Promise.all(Object.values(batch.taskGraph.tasks).map(async (task) => {
115
133
  if (!task.hash) {
116
- await (0, hash_task_1.hashTask)(this.hasher, this.projectGraph, this.taskGraph, task, this.batchEnv, this.taskDetails);
134
+ await (0, hash_task_1.hashTask)(this.hasher, this.projectGraph, this.taskGraphForHashing, task, this.batchEnv, this.taskDetails);
117
135
  }
118
136
  await this.options.lifeCycle.scheduleTask(task);
119
137
  }));
@@ -126,7 +144,7 @@ class TaskOrchestrator {
126
144
  for (const taskId of scheduledTasks) {
127
145
  // Task is already handled or being handled
128
146
  if (!this.processedTasks.has(taskId)) {
129
- this.processedTasks.set(taskId, this.processScheduledTask(taskId));
147
+ this.processedTasks.set(taskId, this.processTask(taskId));
130
148
  }
131
149
  }
132
150
  }
@@ -142,7 +160,12 @@ class TaskOrchestrator {
142
160
  if (!cachedResult || cachedResult.code !== 0)
143
161
  return null;
144
162
  const outputs = task.outputs;
145
- const shouldCopyOutputsFromCache = !!outputs.length &&
163
+ const shouldCopyOutputsFromCache =
164
+ // No output files to restore
165
+ !!outputs.length &&
166
+ // Remote caches are restored to output dirs when applied and using db cache
167
+ (!cachedResult.remote || !(0, cache_1.dbCacheEnabled)(this.nxJson)) &&
168
+ // Output files have not been touched since last run
146
169
  (await this.shouldCopyOutputsFromCache(outputs, task.hash));
147
170
  if (shouldCopyOutputsFromCache) {
148
171
  await this.cache.copyFilesFromCache(task.hash, cachedResult, outputs);
@@ -154,6 +177,7 @@ class TaskOrchestrator {
154
177
  : 'local-cache-kept-existing';
155
178
  this.options.lifeCycle.printTaskTerminalOutput(task, status, cachedResult.terminalOutput);
156
179
  return {
180
+ code: cachedResult.code,
157
181
  task,
158
182
  status,
159
183
  };
@@ -188,7 +212,7 @@ class TaskOrchestrator {
188
212
  }
189
213
  async runBatch(batch, env) {
190
214
  try {
191
- const batchProcess = await this.forkedProcessTaskRunner.forkProcessForBatch(batch, this.taskGraph, env);
215
+ const batchProcess = await this.forkedProcessTaskRunner.forkProcessForBatch(batch, this.projectGraph, this.taskGraph, env);
192
216
  const results = await batchProcess.getResults();
193
217
  const batchResultEntries = Object.entries(results);
194
218
  return batchResultEntries.map(([taskId, result]) => ({
@@ -233,11 +257,13 @@ class TaskOrchestrator {
233
257
  const { code, terminalOutput } = await childProcess.getResults();
234
258
  results.push({
235
259
  task,
260
+ code,
236
261
  status: code === 0 ? 'success' : 'failure',
237
262
  terminalOutput,
238
263
  });
239
264
  }
240
265
  await this.postRunSteps([task], results, doNotSkipCache, { groupId });
266
+ return results[0];
241
267
  }
242
268
  async runTask(task, streamOutput, env, temporaryOutputPath, pipeOutput) {
243
269
  const shouldPrefix = streamOutput && process.env.NX_PREFIX_OUTPUT === 'true';
@@ -247,7 +273,6 @@ class TaskOrchestrator {
247
273
  !shouldPrefix) {
248
274
  try {
249
275
  const { schema } = (0, utils_1.getExecutorForTask)(task, this.projectGraph);
250
- const isRunOne = this.initiatingProject != null;
251
276
  const combinedOptions = (0, params_1.combineOptionsForExecutor)(task.overrides, task.target.configuration ?? targetConfiguration.defaultConfiguration, targetConfiguration, schema, task.target.project, (0, path_1.relative)(task.projectRoot ?? workspace_root_1.workspaceRoot, process.cwd()), process.env.NX_VERBOSE_LOGGING === 'true');
252
277
  if (combinedOptions.env) {
253
278
  env = {
@@ -259,22 +284,40 @@ class TaskOrchestrator {
259
284
  const args = (0, utils_1.getPrintableCommandArgsForTask)(task);
260
285
  output_1.output.logCommand(args.join(' '));
261
286
  }
262
- const runningTask = await (0, run_commands_impl_1.runCommands)({
287
+ const runCommandsOptions = {
263
288
  ...combinedOptions,
264
289
  env,
265
- usePty: isRunOne &&
266
- !this.tasksSchedule.hasTasks() &&
267
- this.runningContinuousTasks.size === 0,
290
+ usePty: this.tuiEnabled ||
291
+ (!this.tasksSchedule.hasTasks() &&
292
+ this.runningContinuousTasks.size === 0),
268
293
  streamOutput,
269
- }, {
294
+ };
295
+ const runningTask = await (0, run_commands_impl_1.runCommands)(runCommandsOptions, {
270
296
  root: workspace_root_1.workspaceRoot, // only root is needed in runCommands
271
297
  });
272
- runningTask.onExit((code, terminalOutput) => {
273
- if (!streamOutput) {
274
- this.options.lifeCycle.printTaskTerminalOutput(task, code === 0 ? 'success' : 'failure', terminalOutput);
275
- (0, fs_1.writeFileSync)(temporaryOutputPath, terminalOutput);
298
+ if (this.tuiEnabled && runningTask instanceof pseudo_terminal_1.PseudoTtyProcess) {
299
+ // This is an external of a the pseudo terminal where a task is running and can be passed to the TUI
300
+ this.options.lifeCycle.registerRunningTask(task.id, runningTask.getParserAndWriter());
301
+ }
302
+ if (!streamOutput) {
303
+ if (runningTask instanceof pseudo_terminal_1.PseudoTtyProcess) {
304
+ // TODO: shouldn't this be checking if the task is continuous before writing anything to disk or calling printTaskTerminalOutput?
305
+ let terminalOutput = '';
306
+ runningTask.onOutput((data) => {
307
+ terminalOutput += data;
308
+ });
309
+ runningTask.onExit((code) => {
310
+ this.options.lifeCycle.printTaskTerminalOutput(task, code === 0 ? 'success' : 'failure', terminalOutput);
311
+ (0, fs_1.writeFileSync)(temporaryOutputPath, terminalOutput);
312
+ });
276
313
  }
277
- });
314
+ else {
315
+ runningTask.onExit((code, terminalOutput) => {
316
+ this.options.lifeCycle.printTaskTerminalOutput(task, code === 0 ? 'success' : 'failure', terminalOutput);
317
+ (0, fs_1.writeFileSync)(temporaryOutputPath, terminalOutput);
318
+ });
319
+ }
320
+ }
278
321
  return runningTask;
279
322
  }
280
323
  catch (e) {
@@ -286,6 +329,10 @@ class TaskOrchestrator {
286
329
  }
287
330
  const terminalOutput = e.stack ?? e.message ?? '';
288
331
  (0, fs_1.writeFileSync)(temporaryOutputPath, terminalOutput);
332
+ return new noop_child_process_1.NoopChildProcess({
333
+ code: 1,
334
+ terminalOutput,
335
+ });
289
336
  }
290
337
  }
291
338
  else if (targetConfiguration.executor === 'nx:noop') {
@@ -297,14 +344,19 @@ class TaskOrchestrator {
297
344
  }
298
345
  else {
299
346
  // cache prep
300
- return await this.runTaskInForkedProcess(task, env, pipeOutput, temporaryOutputPath, streamOutput);
347
+ const runningTask = await this.runTaskInForkedProcess(task, env, pipeOutput, temporaryOutputPath, streamOutput);
348
+ if (this.tuiEnabled && runningTask instanceof pseudo_terminal_1.PseudoTtyProcess) {
349
+ // This is an external of a the pseudo terminal where a task is running and can be passed to the TUI
350
+ this.options.lifeCycle.registerRunningTask(task.id, runningTask.getParserAndWriter());
351
+ }
352
+ return runningTask;
301
353
  }
302
354
  }
303
355
  async runTaskInForkedProcess(task, env, pipeOutput, temporaryOutputPath, streamOutput) {
304
356
  try {
305
357
  const usePtyFork = process.env.NX_NATIVE_COMMAND_RUNNER !== 'false';
306
358
  // Disable the pseudo terminal if this is a run-many or when running a continuous task as part of a run-one
307
- const disablePseudoTerminal = !this.initiatingProject || task.continuous;
359
+ const disablePseudoTerminal = !this.tuiEnabled && (!this.initiatingProject || task.continuous);
308
360
  // execution
309
361
  const childProcess = usePtyFork
310
362
  ? await this.forkedProcessTaskRunner.forkProcess(task, {
@@ -335,6 +387,21 @@ class TaskOrchestrator {
335
387
  }
336
388
  }
337
389
  async startContinuousTask(task, groupId) {
390
+ if (this.runningTasksService.getRunningTasks([task.id]).length) {
391
+ await this.preRunSteps([task], { groupId });
392
+ if (this.tuiEnabled) {
393
+ this.options.lifeCycle.setTaskStatus(task.id, 8 /* NativeTaskStatus.Shared */);
394
+ }
395
+ // task is already running by another process, we schedule the next tasks
396
+ // and release the threads
397
+ await this.scheduleNextTasksAndReleaseThreads();
398
+ // wait for the running task to finish
399
+ do {
400
+ console.log(`Waiting for ${task.id} in another nx process`);
401
+ await new Promise((resolve) => setTimeout(resolve, 100));
402
+ } while (this.runningTasksService.getRunningTasks([task.id]).length);
403
+ return;
404
+ }
338
405
  const taskSpecificEnv = await this.processedTasks.get(task.id);
339
406
  await this.preRunSteps([task], { groupId });
340
407
  const pipeOutput = await this.pipeOutputCapture(task);
@@ -349,14 +416,10 @@ class TaskOrchestrator {
349
416
  : process.env.FORCE_COLOR, this.options.skipNxCache, this.options.captureStderr, null, null)
350
417
  : (0, task_env_1.getEnvVariablesForTask)(task, taskSpecificEnv, undefined, this.options.skipNxCache, this.options.captureStderr, temporaryOutputPath, streamOutput);
351
418
  const childProcess = await this.runTask(task, streamOutput, env, temporaryOutputPath, pipeOutput);
419
+ this.runningTasksService.addRunningTask(task.id);
352
420
  this.runningContinuousTasks.set(task.id, childProcess);
353
- childProcess.onExit((code) => {
354
- if (!this.cleaningUp) {
355
- console.error(`Task "${task.id}" is continuous but exited with code ${code}`);
356
- this.cleanup().then(() => {
357
- process.exit(1);
358
- });
359
- }
421
+ childProcess.onExit(() => {
422
+ this.runningTasksService.removeRunningTask(task.id);
360
423
  });
361
424
  if (this.initiatingProject === task.target.project &&
362
425
  this.options.targets.length === 1 &&
@@ -364,10 +427,7 @@ class TaskOrchestrator {
364
427
  await childProcess.getResults();
365
428
  }
366
429
  else {
367
- await this.tasksSchedule.scheduleNextTasks();
368
- // release blocked threads
369
- this.waitingForTasks.forEach((f) => f(null));
370
- this.waitingForTasks.length = 0;
430
+ await this.scheduleNextTasksAndReleaseThreads();
371
431
  }
372
432
  return childProcess;
373
433
  }
@@ -430,6 +490,9 @@ class TaskOrchestrator {
430
490
  status,
431
491
  };
432
492
  }));
493
+ await this.scheduleNextTasksAndReleaseThreads();
494
+ }
495
+ async scheduleNextTasksAndReleaseThreads() {
433
496
  await this.tasksSchedule.scheduleNextTasks();
434
497
  // release blocked threads
435
498
  this.waitingForTasks.forEach((f) => f(null));
@@ -511,7 +574,26 @@ class TaskOrchestrator {
511
574
  catch (e) {
512
575
  console.error(`Unable to terminate ${taskId}\nError:`, e);
513
576
  }
577
+ finally {
578
+ this.runningTasksService.removeRunningTask(taskId);
579
+ }
514
580
  }));
515
581
  }
516
582
  }
517
583
  exports.TaskOrchestrator = TaskOrchestrator;
584
+ function getThreadCount(options, taskGraph) {
585
+ if (options['parallel'] === 'false' ||
586
+ options['parallel'] === false) {
587
+ options['parallel'] = 1;
588
+ }
589
+ else if (options['parallel'] === 'true' ||
590
+ options['parallel'] === true ||
591
+ options['parallel'] === undefined ||
592
+ options['parallel'] === '') {
593
+ options['parallel'] = Number(options['maxParallel'] || 3);
594
+ }
595
+ const maxParallel = options['parallel'] +
596
+ Object.values(taskGraph.tasks).filter((t) => t.continuous).length;
597
+ const totalTasks = Object.keys(taskGraph.tasks).length;
598
+ return Math.min(maxParallel, totalTasks);
599
+ }
@@ -1,7 +1,7 @@
1
- import { Task, TaskGraph } from '../config/task-graph';
1
+ import { CustomHasher, ExecutorConfig } from '../config/misc-interfaces';
2
2
  import { ProjectGraph, ProjectGraphProjectNode } from '../config/project-graph';
3
+ import { Task, TaskGraph } from '../config/task-graph';
3
4
  import { TargetConfiguration, TargetDependencyConfig } from '../config/workspace-json-project-json';
4
- import { CustomHasher, ExecutorConfig } from '../config/misc-interfaces';
5
5
  export type NormalizedTargetDependencyConfig = TargetDependencyConfig & {
6
6
  projects: string[];
7
7
  };
@@ -24,19 +24,20 @@ exports.getSerializedArgsForTask = getSerializedArgsForTask;
24
24
  exports.shouldStreamOutput = shouldStreamOutput;
25
25
  exports.isCacheableTask = isCacheableTask;
26
26
  exports.unparse = unparse;
27
- const path_1 = require("path");
28
- const posix_1 = require("path/posix");
29
- const workspace_root_1 = require("../utils/workspace-root");
30
- const path_2 = require("../utils/path");
31
- const fileutils_1 = require("../utils/fileutils");
32
- const serialize_overrides_into_command_line_1 = require("../utils/serialize-overrides-into-command-line");
33
- const split_target_1 = require("../utils/split-target");
27
+ const minimatch_1 = require("minimatch");
28
+ const node_path_1 = require("node:path");
29
+ const posix_1 = require("node:path/posix");
34
30
  const executor_utils_1 = require("../command-line/run/executor-utils");
31
+ const native_1 = require("../native");
35
32
  const project_graph_1 = require("../project-graph/project-graph");
33
+ const fileutils_1 = require("../utils/fileutils");
36
34
  const find_matching_projects_1 = require("../utils/find-matching-projects");
37
- const minimatch_1 = require("minimatch");
38
35
  const globs_1 = require("../utils/globs");
39
- const native_1 = require("../native");
36
+ const path_1 = require("../utils/path");
37
+ const serialize_overrides_into_command_line_1 = require("../utils/serialize-overrides-into-command-line");
38
+ const split_target_1 = require("../utils/split-target");
39
+ const workspace_root_1 = require("../utils/workspace-root");
40
+ const is_tui_enabled_1 = require("./is-tui-enabled");
40
41
  function getDependencyConfigs({ project, target }, extraTargetDependencies, projectGraph, allTargetNames) {
41
42
  const dependencyConfigs = (projectGraph.nodes[project].data?.targets[target]?.dependsOn ??
42
43
  // This is passed into `run-command` from programmatic invocations
@@ -193,10 +194,10 @@ function transformLegacyOutputs(projectRoot, outputs) {
193
194
  : [false, output];
194
195
  const relativePath = (0, fileutils_1.isRelativePath)(outputPath)
195
196
  ? output
196
- : (0, path_1.relative)(projectRoot, outputPath);
197
+ : (0, node_path_1.relative)(projectRoot, outputPath);
197
198
  const isWithinProject = !relativePath.startsWith('..');
198
199
  return ((isNegated ? '!' : '') +
199
- (0, path_2.joinPathFragments)(isWithinProject ? '{projectRoot}' : '{workspaceRoot}', isWithinProject ? relativePath : outputPath));
200
+ (0, path_1.joinPathFragments)(isWithinProject ? '{projectRoot}' : '{workspaceRoot}', isWithinProject ? relativePath : outputPath));
200
201
  });
201
202
  }
202
203
  /**
@@ -368,6 +369,9 @@ function getSerializedArgsForTask(task, isVerbose) {
368
369
  ];
369
370
  }
370
371
  function shouldStreamOutput(task, initiatingProject) {
372
+ // For now, disable streaming output on the JS side when running the TUI
373
+ if ((0, is_tui_enabled_1.isTuiEnabled)())
374
+ return false;
371
375
  if (process.env.NX_STREAM_OUTPUT === 'true')
372
376
  return true;
373
377
  if (longRunningTask(task))
@@ -1,11 +1,15 @@
1
1
  import { type ExecOptions, type ExecSyncOptions } from 'child_process';
2
+ import { PackageManagerCommands } from './package-manager';
2
3
  import { ChildProcess } from '../native';
4
+ export declare function getRunNxBaseCommand(packageManagerCommand?: PackageManagerCommands, cwd?: string): string;
3
5
  export declare function runNxSync(cmd: string, options?: ExecSyncOptions & {
4
6
  cwd?: string;
7
+ packageManagerCommand?: PackageManagerCommands;
5
8
  }): void;
6
9
  export declare function runNxAsync(cmd: string, options?: ExecOptions & {
7
10
  cwd?: string;
8
11
  silent?: boolean;
12
+ packageManagerCommand?: PackageManagerCommands;
9
13
  }): Promise<void>;
10
14
  export declare class PseudoTtyProcess {
11
15
  private childProcess;
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.PseudoTtyProcess = void 0;
4
+ exports.getRunNxBaseCommand = getRunNxBaseCommand;
4
5
  exports.runNxSync = runNxSync;
5
6
  exports.runNxAsync = runNxAsync;
6
7
  const child_process_1 = require("child_process");
@@ -8,46 +9,38 @@ const fs_1 = require("fs");
8
9
  const path_1 = require("path");
9
10
  const package_manager_1 = require("./package-manager");
10
11
  const workspace_root_1 = require("./workspace-root");
11
- function runNxSync(cmd, options) {
12
- let baseCmd;
12
+ function getRunNxBaseCommand(packageManagerCommand, cwd = process.cwd()) {
13
13
  if ((0, fs_1.existsSync)((0, path_1.join)(workspace_root_1.workspaceRoot, 'package.json'))) {
14
- baseCmd = `${(0, package_manager_1.getPackageManagerCommand)().exec} nx`;
14
+ if (!packageManagerCommand) {
15
+ const pm = (0, package_manager_1.detectPackageManager)();
16
+ packageManagerCommand = (0, package_manager_1.getPackageManagerCommand)(pm);
17
+ }
18
+ return `${packageManagerCommand.exec} nx`;
15
19
  }
16
20
  else {
17
- options ??= {};
18
- options.cwd ??= process.cwd();
19
- options.windowsHide ??= true;
20
- const offsetFromRoot = (0, path_1.relative)(options.cwd, (0, workspace_root_1.workspaceRootInner)(options.cwd, null));
21
+ const offsetFromRoot = (0, path_1.relative)(cwd, (0, workspace_root_1.workspaceRootInner)(cwd, null));
21
22
  if (process.platform === 'win32') {
22
- baseCmd = '.\\' + (0, path_1.join)(`${offsetFromRoot}`, 'nx.bat');
23
+ return '.\\' + (0, path_1.join)(`${offsetFromRoot}`, 'nx.bat');
23
24
  }
24
25
  else {
25
- baseCmd = './' + (0, path_1.join)(`${offsetFromRoot}`, 'nx');
26
+ return './' + (0, path_1.join)(`${offsetFromRoot}`, 'nx');
26
27
  }
27
28
  }
28
- (0, child_process_1.execSync)(`${baseCmd} ${cmd}`, options);
29
+ }
30
+ function runNxSync(cmd, options) {
31
+ let { packageManagerCommand, ...execSyncOptions } = options ?? {};
32
+ execSyncOptions.cwd ??= process.cwd();
33
+ execSyncOptions.windowsHide ??= true;
34
+ const baseCmd = getRunNxBaseCommand(packageManagerCommand, execSyncOptions.cwd);
35
+ (0, child_process_1.execSync)(`${baseCmd} ${cmd}`, execSyncOptions);
29
36
  }
30
37
  async function runNxAsync(cmd, options) {
31
- let baseCmd;
32
- if ((0, fs_1.existsSync)((0, path_1.join)(workspace_root_1.workspaceRoot, 'package.json'))) {
33
- baseCmd = `${(0, package_manager_1.getPackageManagerCommand)().exec} nx`;
34
- }
35
- else {
36
- options ??= {};
37
- options.cwd ??= process.cwd();
38
- options.windowsHide ??= true;
39
- const offsetFromRoot = (0, path_1.relative)(options.cwd, (0, workspace_root_1.workspaceRootInner)(options.cwd, null));
40
- if (process.platform === 'win32') {
41
- baseCmd = '.\\' + (0, path_1.join)(`${offsetFromRoot}`, 'nx.bat');
42
- }
43
- else {
44
- baseCmd = './' + (0, path_1.join)(`${offsetFromRoot}`, 'nx');
45
- }
46
- }
47
- const silent = options?.silent ?? true;
48
- if (options?.silent) {
49
- delete options.silent;
50
- }
38
+ options ??= {};
39
+ options.cwd ??= process.cwd();
40
+ options.windowsHide ??= true;
41
+ let { silent, packageManagerCommand, ...execSyncOptions } = options;
42
+ silent ??= true;
43
+ const baseCmd = getRunNxBaseCommand(packageManagerCommand, execSyncOptions.cwd);
51
44
  return new Promise((resolve, reject) => {
52
45
  const child = (0, child_process_1.exec)(`${baseCmd} ${cmd}`, options, (error, stdout, stderr) => {
53
46
  if (error) {
@@ -8,7 +8,7 @@ export interface NxArgs {
8
8
  targets?: string[];
9
9
  configuration?: string;
10
10
  /**
11
- * @deprecated Custom task runners will no longer be supported in Nx 21. Use Nx Cloud or Nx Powerpack instead.
11
+ * @deprecated Custom task runners will be replaced by a new API starting with Nx 21. More info: https://nx.dev/deprecated/custom-tasks-runner
12
12
  */
13
13
  runner?: string;
14
14
  parallel?: number;
@@ -112,8 +112,8 @@ function addMatchingProjectsByName(projectNames, projects, pattern, matchedProje
112
112
  return;
113
113
  }
114
114
  if (!(0, globs_1.isGlobPattern)(pattern.value)) {
115
- // Custom regex that is basically \b without underscores, so "foo" pattern matches "foo_bar".
116
- const regex = new RegExp(`(?<![a-zA-Z0-9])${pattern.value}(?![a-zA-Z0-9])`, 'i');
115
+ // Custom regex that is basically \b but includes hyphens (-) and excludes underscores (_), so "foo" pattern matches "foo_bar" but not "foo-e2e".
116
+ const regex = new RegExp(`(?<![a-zA-Z0-9-])${pattern.value}(?![a-zA-Z0-9-])`, 'i');
117
117
  const matchingProjects = Object.keys(projects).filter((name) => regex.test(name));
118
118
  for (const projectName of matchingProjects) {
119
119
  if (pattern.exclude) {
@@ -31,6 +31,21 @@ async function handleErrors(isVerbose, fn) {
31
31
  : projectGraphError.getErrors().map((e) => e.message),
32
32
  });
33
33
  }
34
+ else if (err.name === 'ProjectConfigurationsError') {
35
+ const projectConfigurationsError = err;
36
+ let title = projectConfigurationsError.message;
37
+ if (projectConfigurationsError.cause &&
38
+ typeof projectConfigurationsError.cause === 'object' &&
39
+ 'message' in projectConfigurationsError.cause) {
40
+ title += ' ' + projectConfigurationsError.cause.message + '.';
41
+ }
42
+ output_1.output.error({
43
+ title,
44
+ bodyLines: isVerbose
45
+ ? formatErrorStackAndCause(projectConfigurationsError, isVerbose)
46
+ : projectConfigurationsError.errors.map((e) => e.message),
47
+ });
48
+ }
34
49
  else {
35
50
  const lines = (err.message ? err.message : err.toString()).split('\n');
36
51
  const bodyLines = lines.slice(1);
@@ -15,6 +15,9 @@ function isCI() {
15
15
  !!process.env.GITLAB_CI ||
16
16
  !!process.env.HEROKU_TEST_RUN_ID ||
17
17
  !!process.env.BUILD_ID ||
18
+ !!process.env.BUILD_NUMBER ||
18
19
  !!process.env.BUILD_BUILDID ||
19
- !!process.env.TEAMCITY_VERSION);
20
+ !!process.env.TEAMCITY_VERSION ||
21
+ !!process.env.JENKINS_URL ||
22
+ !!process.env.HUDSON_URL);
20
23
  }
@@ -0,0 +1,3 @@
1
+ import type { Tree } from '../generators/tree';
2
+ export declare function isUsingPrettier(root: string): boolean;
3
+ export declare function isUsingPrettierInTree(tree: Tree): boolean;
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isUsingPrettier = isUsingPrettier;
4
+ exports.isUsingPrettierInTree = isUsingPrettierInTree;
5
+ const node_fs_1 = require("node:fs");
6
+ const node_path_1 = require("node:path");
7
+ const json_1 = require("../generators/utils/json");
8
+ const fileutils_1 = require("./fileutils");
9
+ /**
10
+ * Possible configuration files are taken from https://prettier.io/docs/configuration
11
+ */
12
+ const configFiles = [
13
+ '.prettierrc',
14
+ '.prettierrc.json',
15
+ '.prettierrc.yml',
16
+ '.prettierrc.yaml',
17
+ '.prettierrc.json5',
18
+ '.prettierrc.js',
19
+ 'prettier.config.js',
20
+ '.prettierrc.ts',
21
+ 'prettier.config.ts',
22
+ '.prettierrc.mjs',
23
+ 'prettier.config.mjs',
24
+ '.prettierrc.mts',
25
+ 'prettier.config.mts',
26
+ '.prettierrc.cjs',
27
+ 'prettier.config.cjs',
28
+ '.prettierrc.cts',
29
+ 'prettier.config.cts',
30
+ '.prettierrc.toml',
31
+ ];
32
+ function isUsingPrettier(root) {
33
+ for (const file of configFiles) {
34
+ if ((0, node_fs_1.existsSync)(file)) {
35
+ return true;
36
+ }
37
+ }
38
+ // Even if no file is present, it is possible the user is configuring prettier via their package.json
39
+ const packageJsonPath = (0, node_path_1.join)(root, 'package.json');
40
+ if ((0, node_fs_1.existsSync)(packageJsonPath)) {
41
+ const packageJson = (0, fileutils_1.readJsonFile)(packageJsonPath);
42
+ if (packageJson.prettier) {
43
+ return true;
44
+ }
45
+ }
46
+ return false;
47
+ }
48
+ function isUsingPrettierInTree(tree) {
49
+ for (const file of configFiles) {
50
+ if (tree.exists(file)) {
51
+ return true;
52
+ }
53
+ }
54
+ // Even if no file is present, it is possible the user is configuring prettier via their package.json
55
+ if (tree.exists('package.json')) {
56
+ const packageJson = (0, json_1.readJson)(tree, 'package.json');
57
+ if (packageJson.prettier) {
58
+ return true;
59
+ }
60
+ }
61
+ return false;
62
+ }
@@ -0,0 +1,7 @@
1
+ import type { NxKey } from '@nx/key';
2
+ export declare function createNxKeyLicenseeInformation(nxKey: NxKey): string;
3
+ export declare function printNxKey(): Promise<void>;
4
+ export declare function getNxKeyInformation(): Promise<NxKey | null>;
5
+ export declare class NxKeyNotInstalledError extends Error {
6
+ constructor(e: Error);
7
+ }