nx 21.0.0-beta.0 → 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 (201) 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/migrate/migrate.js +21 -18
  32. package/src/command-line/nx-commands.js +19 -5
  33. package/src/command-line/register/command-object.d.ts +6 -0
  34. package/src/command-line/{activate-powerpack → register}/command-object.js +9 -9
  35. package/src/command-line/register/register.d.ts +2 -0
  36. package/src/command-line/register/register.js +9 -0
  37. package/src/command-line/release/changelog.js +18 -15
  38. package/src/command-line/release/command-object.d.ts +2 -0
  39. package/src/command-line/release/command-object.js +9 -0
  40. package/src/command-line/release/config/config.d.ts +8 -7
  41. package/src/command-line/release/config/config.js +129 -42
  42. package/src/command-line/release/config/use-legacy-versioning.d.ts +2 -0
  43. package/src/command-line/release/config/use-legacy-versioning.js +9 -0
  44. package/src/command-line/release/index.d.ts +4 -0
  45. package/src/command-line/release/index.js +6 -1
  46. package/src/command-line/release/plan-check.js +6 -3
  47. package/src/command-line/release/plan.js +7 -3
  48. package/src/command-line/release/publish.js +7 -3
  49. package/src/command-line/release/release.js +8 -3
  50. package/src/command-line/release/utils/batch-projects-by-generator-config.js +6 -3
  51. package/src/command-line/release/utils/git.d.ts +3 -2
  52. package/src/command-line/release/utils/git.js +65 -9
  53. package/src/command-line/release/utils/github.js +3 -1
  54. package/src/command-line/release/utils/resolve-semver-specifier.d.ts +2 -1
  55. package/src/command-line/release/utils/resolve-semver-specifier.js +2 -1
  56. package/src/command-line/release/utils/semver.d.ts +8 -0
  57. package/src/command-line/release/utils/semver.js +8 -0
  58. package/src/command-line/release/utils/shared-legacy.d.ts +25 -0
  59. package/src/command-line/release/utils/shared-legacy.js +2 -0
  60. package/src/command-line/release/utils/shared.d.ts +11 -17
  61. package/src/command-line/release/version/derive-specifier-from-conventional-commits.d.ts +7 -0
  62. package/src/command-line/release/version/derive-specifier-from-conventional-commits.js +47 -0
  63. package/src/command-line/release/version/deriver-specifier-from-version-plans.d.ts +8 -0
  64. package/src/command-line/release/version/deriver-specifier-from-version-plans.js +59 -0
  65. package/src/command-line/release/version/project-logger.d.ts +8 -0
  66. package/src/command-line/release/version/project-logger.js +45 -0
  67. package/src/command-line/release/version/release-group-processor.d.ts +251 -0
  68. package/src/command-line/release/version/release-group-processor.js +1040 -0
  69. package/src/command-line/release/version/resolve-current-version.d.ts +32 -0
  70. package/src/command-line/release/version/resolve-current-version.js +241 -0
  71. package/src/command-line/release/version/test-utils.d.ts +95 -0
  72. package/src/command-line/release/version/test-utils.js +416 -0
  73. package/src/command-line/release/version/topological-sort.d.ts +9 -0
  74. package/src/command-line/release/version/topological-sort.js +41 -0
  75. package/src/command-line/release/version/version-actions.d.ts +170 -0
  76. package/src/command-line/release/version/version-actions.js +183 -0
  77. package/src/command-line/release/version-legacy.d.ts +46 -0
  78. package/src/command-line/release/version-legacy.js +453 -0
  79. package/src/command-line/release/version.d.ts +0 -40
  80. package/src/command-line/release/version.js +80 -262
  81. package/src/command-line/report/report.d.ts +7 -3
  82. package/src/command-line/report/report.js +52 -18
  83. package/src/command-line/run/command-object.js +2 -2
  84. package/src/command-line/run/run.js +1 -1
  85. package/src/command-line/run-many/command-object.js +2 -2
  86. package/src/command-line/yargs-utils/shared-options.d.ts +4 -0
  87. package/src/command-line/yargs-utils/shared-options.js +20 -0
  88. package/src/config/nx-json.d.ts +153 -15
  89. package/src/config/project-graph.d.ts +4 -2
  90. package/src/config/project-graph.js +8 -0
  91. package/src/config/workspace-json-project-json.d.ts +2 -2
  92. package/src/core/graph/main.js +1 -1
  93. package/src/core/graph/runtime.js +1 -1
  94. package/src/core/graph/styles.css +2 -2
  95. package/src/core/graph/styles.js +1 -1
  96. package/src/daemon/client/client.d.ts +2 -0
  97. package/src/daemon/client/client.js +15 -0
  98. package/src/daemon/message-types/glob.d.ts +7 -0
  99. package/src/daemon/message-types/glob.js +9 -1
  100. package/src/daemon/message-types/hash-glob.d.ts +6 -0
  101. package/src/daemon/message-types/hash-glob.js +9 -1
  102. package/src/daemon/server/handle-glob.d.ts +1 -0
  103. package/src/daemon/server/handle-glob.js +8 -0
  104. package/src/daemon/server/handle-hash-glob.d.ts +1 -0
  105. package/src/daemon/server/handle-hash-glob.js +8 -0
  106. package/src/daemon/server/logger.js +2 -1
  107. package/src/daemon/server/server.js +7 -0
  108. package/src/devkit-internals.d.ts +2 -1
  109. package/src/devkit-internals.js +4 -1
  110. package/src/executors/run-commands/run-commands.impl.d.ts +3 -5
  111. package/src/executors/run-commands/run-commands.impl.js +14 -42
  112. package/src/executors/run-commands/running-tasks.d.ts +7 -5
  113. package/src/executors/run-commands/running-tasks.js +64 -27
  114. package/src/executors/run-script/run-script.impl.js +3 -3
  115. package/src/generators/internal-utils/format-changed-files-with-prettier-if-available.js +8 -0
  116. package/src/generators/testing-utils/create-tree.js +5 -1
  117. package/src/native/index.d.ts +93 -19
  118. package/src/native/native-bindings.js +6 -0
  119. package/src/native/nx.wasi-browser.js +20 -19
  120. package/src/native/nx.wasi.cjs +20 -19
  121. package/src/native/nx.wasm32-wasi.wasm +0 -0
  122. package/src/nx-cloud/nx-cloud-tasks-runner-shell.js +3 -3
  123. package/src/plugins/js/lock-file/lock-file.js +28 -13
  124. package/src/plugins/js/lock-file/utils/package-json.d.ts +1 -1
  125. package/src/plugins/js/lock-file/utils/package-json.js +2 -1
  126. package/src/plugins/js/lock-file/yarn-parser.js +85 -39
  127. package/src/plugins/js/project-graph/affected/lock-file-changes.js +1 -0
  128. package/src/plugins/js/project-graph/build-dependencies/explicit-project-dependencies.js +1 -1
  129. package/src/plugins/js/project-graph/build-dependencies/target-project-locator.d.ts +10 -1
  130. package/src/plugins/js/project-graph/build-dependencies/target-project-locator.js +59 -6
  131. package/src/plugins/js/utils/packages.js +22 -3
  132. package/src/plugins/js/utils/register.js +1 -0
  133. package/src/plugins/js/utils/typescript.js +3 -3
  134. package/src/plugins/package-json/create-nodes.js +3 -1
  135. package/src/project-graph/affected/locators/project-glob-changes.js +2 -2
  136. package/src/project-graph/error-types.js +32 -2
  137. package/src/project-graph/nx-deps-cache.js +7 -2
  138. package/src/project-graph/plugins/get-plugins.js +2 -1
  139. package/src/project-graph/plugins/in-process-loader.js +1 -1
  140. package/src/project-graph/plugins/isolation/plugin-worker.js +12 -6
  141. package/src/project-graph/plugins/loaded-nx-plugin.d.ts +2 -1
  142. package/src/project-graph/plugins/loaded-nx-plugin.js +3 -7
  143. package/src/project-graph/plugins/utils.d.ts +2 -2
  144. package/src/project-graph/plugins/utils.js +2 -2
  145. package/src/project-graph/project-graph.js +5 -2
  146. package/src/project-graph/utils/project-configuration-utils.d.ts +1 -1
  147. package/src/project-graph/utils/project-configuration-utils.js +25 -11
  148. package/src/project-graph/utils/retrieve-workspace-files.d.ts +1 -1
  149. package/src/project-graph/utils/retrieve-workspace-files.js +14 -18
  150. package/src/tasks-runner/batch/batch-messages.d.ts +2 -0
  151. package/src/tasks-runner/batch/run-batch.js +2 -3
  152. package/src/tasks-runner/cache.d.ts +20 -6
  153. package/src/tasks-runner/cache.js +104 -20
  154. package/src/tasks-runner/create-task-graph.d.ts +1 -1
  155. package/src/tasks-runner/create-task-graph.js +12 -11
  156. package/src/tasks-runner/default-tasks-runner.js +4 -13
  157. package/src/tasks-runner/forked-process-task-runner.d.ts +6 -3
  158. package/src/tasks-runner/forked-process-task-runner.js +29 -28
  159. package/src/tasks-runner/init-tasks-runner.d.ts +15 -1
  160. package/src/tasks-runner/init-tasks-runner.js +55 -2
  161. package/src/tasks-runner/is-tui-enabled.d.ts +2 -0
  162. package/src/tasks-runner/is-tui-enabled.js +58 -0
  163. package/src/tasks-runner/life-cycle.d.ts +10 -3
  164. package/src/tasks-runner/life-cycle.js +23 -2
  165. package/src/tasks-runner/life-cycles/task-history-life-cycle-old.js +7 -2
  166. package/src/tasks-runner/life-cycles/task-history-life-cycle.js +6 -1
  167. package/src/tasks-runner/life-cycles/tui-summary-life-cycle.d.ts +17 -0
  168. package/src/tasks-runner/life-cycles/tui-summary-life-cycle.js +221 -0
  169. package/src/tasks-runner/pseudo-terminal.d.ts +10 -7
  170. package/src/tasks-runner/pseudo-terminal.js +37 -35
  171. package/src/tasks-runner/run-command.d.ts +1 -0
  172. package/src/tasks-runner/run-command.js +180 -23
  173. package/src/tasks-runner/task-env.d.ts +1 -4
  174. package/src/tasks-runner/task-env.js +2 -0
  175. package/src/tasks-runner/task-orchestrator.d.ts +21 -9
  176. package/src/tasks-runner/task-orchestrator.js +126 -44
  177. package/src/tasks-runner/utils.d.ts +2 -2
  178. package/src/tasks-runner/utils.js +15 -11
  179. package/src/utils/child-process.d.ts +4 -0
  180. package/src/utils/child-process.js +23 -30
  181. package/src/utils/command-line-utils.d.ts +1 -1
  182. package/src/utils/find-matching-projects.js +2 -2
  183. package/src/utils/handle-errors.js +15 -0
  184. package/src/utils/is-ci.js +4 -1
  185. package/src/utils/is-using-prettier.d.ts +3 -0
  186. package/src/utils/is-using-prettier.js +62 -0
  187. package/src/utils/nx-key.d.ts +7 -0
  188. package/src/utils/nx-key.js +52 -0
  189. package/src/utils/package-manager.js +2 -2
  190. package/src/utils/path.js +1 -1
  191. package/src/utils/require-nx-key.d.ts +1 -0
  192. package/src/utils/require-nx-key.js +22 -0
  193. package/src/utils/workspace-context.d.ts +2 -0
  194. package/src/utils/workspace-context.js +16 -0
  195. package/src/command-line/activate-powerpack/activate-powerpack.d.ts +0 -2
  196. package/src/command-line/activate-powerpack/activate-powerpack.js +0 -34
  197. package/src/command-line/activate-powerpack/command-object.d.ts +0 -6
  198. package/src/command-line/init/implementation/react/write-craco-config.d.ts +0 -1
  199. package/src/command-line/init/implementation/react/write-craco-config.js +0 -61
  200. package/src/utils/powerpack.d.ts +0 -5
  201. package/src/utils/powerpack.js +0 -33
@@ -3,6 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Cache = exports.DbCache = void 0;
4
4
  exports.dbCacheEnabled = dbCacheEnabled;
5
5
  exports.getCache = getCache;
6
+ exports.parseMaxCacheSize = parseMaxCacheSize;
7
+ exports.formatCacheSize = formatCacheSize;
6
8
  const workspace_root_1 = require("../utils/workspace-root");
7
9
  const path_1 = require("path");
8
10
  const perf_hooks_1 = require("perf_hooks");
@@ -68,7 +70,10 @@ function getCache(options) {
68
70
  class DbCache {
69
71
  constructor(options) {
70
72
  this.options = options;
71
- this.cache = new native_1.NxCache(workspace_root_1.workspaceRoot, cache_directory_1.cacheDir, (0, db_connection_1.getDbConnection)());
73
+ this.nxJson = (0, nx_json_1.readNxJson)();
74
+ this.cache = new native_1.NxCache(workspace_root_1.workspaceRoot, cache_directory_1.cacheDir, (0, db_connection_1.getDbConnection)(), undefined, this.nxJson.maxCacheSize !== undefined
75
+ ? parseMaxCacheSize(this.nxJson.maxCacheSize)
76
+ : (0, native_1.getDefaultMaxCacheSize)(cache_directory_1.cacheDir));
72
77
  this.isVerbose = process.env.NX_VERBOSE_LOGGING === 'true';
73
78
  }
74
79
  async init() {
@@ -83,6 +88,7 @@ class DbCache {
83
88
  if (res) {
84
89
  return {
85
90
  ...res,
91
+ terminalOutput: res.terminalOutput ?? '',
86
92
  remote: false,
87
93
  };
88
94
  }
@@ -91,9 +97,10 @@ class DbCache {
91
97
  // attempt remote cache
92
98
  const res = await this.remoteCache.retrieve(task.hash, this.cache.cacheDirectory);
93
99
  if (res) {
94
- this.applyRemoteCacheResults(task.hash, res);
100
+ this.applyRemoteCacheResults(task.hash, res, task.outputs);
95
101
  return {
96
102
  ...res,
103
+ terminalOutput: res.terminalOutput ?? '',
97
104
  remote: true,
98
105
  };
99
106
  }
@@ -105,8 +112,11 @@ class DbCache {
105
112
  return null;
106
113
  }
107
114
  }
108
- applyRemoteCacheResults(hash, res) {
109
- return this.cache.applyRemoteCacheResults(hash, res);
115
+ getUsedCacheSpace() {
116
+ return this.cache.getCacheSize();
117
+ }
118
+ applyRemoteCacheResults(hash, res, outputs) {
119
+ return this.cache.applyRemoteCacheResults(hash, res, outputs);
110
120
  }
111
121
  async put(task, terminalOutput, outputs, code) {
112
122
  return tryAndRetry(async () => {
@@ -155,26 +165,49 @@ class DbCache {
155
165
  }
156
166
  }
157
167
  else {
158
- return ((await this.getPowerpackS3Cache()) ??
159
- (await this.getPowerpackSharedCache()) ??
160
- (await this.getPowerpackGcsCache()) ??
161
- (await this.getPowerpackAzureCache()) ??
168
+ return ((await this.getS3Cache()) ??
169
+ (await this.getSharedCache()) ??
170
+ (await this.getGcsCache()) ??
171
+ (await this.getAzureCache()) ??
172
+ this.getHttpCache() ??
162
173
  null);
163
174
  }
164
175
  }
165
- getPowerpackS3Cache() {
166
- return this.getPowerpackCache('@nx/powerpack-s3-cache');
167
- }
168
- getPowerpackSharedCache() {
169
- return this.getPowerpackCache('@nx/powerpack-shared-fs-cache');
170
- }
171
- getPowerpackGcsCache() {
172
- return this.getPowerpackCache('@nx/powerpack-gcs-cache');
173
- }
174
- getPowerpackAzureCache() {
175
- return this.getPowerpackCache('@nx/powerpack-azure-cache');
176
+ async getS3Cache() {
177
+ const cache = await this.resolveRemoteCache('@nx/s3-cache');
178
+ if (cache)
179
+ return cache;
180
+ return this.resolveRemoteCache('@nx/powerpack-s3-cache');
181
+ }
182
+ async getSharedCache() {
183
+ const cache = await this.resolveRemoteCache('@nx/shared-fs-cache');
184
+ if (cache)
185
+ return cache;
186
+ return this.resolveRemoteCache('@nx/powerpack-shared-fs-cache');
187
+ }
188
+ async getGcsCache() {
189
+ const cache = await this.resolveRemoteCache('@nx/gcs-cache');
190
+ if (cache)
191
+ return cache;
192
+ return this.resolveRemoteCache('@nx/powerpack-gcs-cache');
193
+ }
194
+ async getAzureCache() {
195
+ const cache = await this.resolveRemoteCache('@nx/azure-cache');
196
+ if (cache)
197
+ return cache;
198
+ return this.resolveRemoteCache('@nx/powerpack-azure-cache');
199
+ }
200
+ getHttpCache() {
201
+ if (process.env.NX_SELF_HOSTED_REMOTE_CACHE_SERVER) {
202
+ if (native_1.IS_WASM) {
203
+ logger_1.logger.warn('The HTTP remote cache is not yet supported in the wasm build of Nx.');
204
+ return null;
205
+ }
206
+ return new native_1.HttpRemoteCache();
207
+ }
208
+ return null;
176
209
  }
177
- async getPowerpackCache(pkg) {
210
+ async resolveRemoteCache(pkg) {
178
211
  let getRemoteCache = null;
179
212
  try {
180
213
  getRemoteCache = (await Promise.resolve(`${this.resolvePackage(pkg)}`).then(s => require(s))).getRemoteCache;
@@ -455,3 +488,54 @@ function tryAndRetry(fn) {
455
488
  };
456
489
  return _try();
457
490
  }
491
+ /**
492
+ * Converts a string representation of a max cache size to a number.
493
+ *
494
+ * e.g. '1GB' -> 1024 * 1024 * 1024
495
+ * '1MB' -> 1024 * 1024
496
+ * '1KB' -> 1024
497
+ *
498
+ * @param maxCacheSize Max cache size as specified in nx.json
499
+ */
500
+ function parseMaxCacheSize(maxCacheSize) {
501
+ if (maxCacheSize === null || maxCacheSize === undefined) {
502
+ return undefined;
503
+ }
504
+ let regexResult = maxCacheSize
505
+ // Covers folks who accidentally specify as a number rather than a string
506
+ .toString()
507
+ // Match a number followed by an optional unit (KB, MB, GB), with optional whitespace between the number and unit
508
+ .match(/^(?<size>[\d|.]+)\s?((?<unit>[KMG]?B)?)$/);
509
+ if (!regexResult) {
510
+ throw new Error(`Invalid max cache size specified in nx.json: ${maxCacheSize}. Must be a number followed by an optional unit (KB, MB, GB)`);
511
+ }
512
+ let sizeString = regexResult.groups.size;
513
+ let unit = regexResult.groups.unit;
514
+ if ([...sizeString].filter((c) => c === '.').length > 1) {
515
+ throw new Error(`Invalid max cache size specified in nx.json: ${maxCacheSize} (multiple decimal points in size)`);
516
+ }
517
+ let size = parseFloat(sizeString);
518
+ if (isNaN(size)) {
519
+ throw new Error(`Invalid max cache size specified in nx.json: ${maxCacheSize} (${sizeString} is not a number)`);
520
+ }
521
+ switch (unit) {
522
+ case 'KB':
523
+ return size * 1024;
524
+ case 'MB':
525
+ return size * 1024 * 1024;
526
+ case 'GB':
527
+ return size * 1024 * 1024 * 1024;
528
+ default:
529
+ return size;
530
+ }
531
+ }
532
+ function formatCacheSize(maxCacheSize, decimals = 2) {
533
+ const exponents = ['B', 'KB', 'MB', 'GB'];
534
+ let exponent = 0;
535
+ let size = maxCacheSize;
536
+ while (size >= 1024 && exponent < exponents.length - 1) {
537
+ size /= 1024;
538
+ exponent++;
539
+ }
540
+ return `${size.toFixed(decimals)} ${exponents[exponent]}`;
541
+ }
@@ -24,7 +24,6 @@ export declare class ProcessTasks {
24
24
  private createDummyTask;
25
25
  createTask(id: string, project: ProjectGraphProjectNode, target: string, resolvedConfiguration: string | undefined, overrides: Object): Task;
26
26
  resolveConfiguration(project: ProjectGraphProjectNode, target: string, configuration: string | undefined): string;
27
- getId(project: string, target: string, configuration: string | undefined): string;
28
27
  }
29
28
  export declare function createTaskGraph(projectGraph: ProjectGraph, extraTargetDependencies: TargetDependencies, projectNames: string[], targets: string[], configuration: string | undefined, overrides: Object, excludeTaskDependencies?: boolean): TaskGraph;
30
29
  export declare function mapTargetDefaultsToDependencies(defaults: TargetDefaults | undefined): TargetDependencies;
@@ -41,3 +40,4 @@ export declare function filterDummyTasks(dependencies: {
41
40
  export declare function getNonDummyDeps(currentTask: string, dependencies: {
42
41
  [k: string]: string[];
43
42
  }, cycles?: Set<string>, seen?: Set<string>): string[];
43
+ export declare function createTaskId(project: string, target: string, configuration: string | undefined): string;
@@ -5,6 +5,7 @@ exports.createTaskGraph = createTaskGraph;
5
5
  exports.mapTargetDefaultsToDependencies = mapTargetDefaultsToDependencies;
6
6
  exports.filterDummyTasks = filterDummyTasks;
7
7
  exports.getNonDummyDeps = getNonDummyDeps;
8
+ exports.createTaskId = createTaskId;
8
9
  const utils_1 = require("./utils");
9
10
  const project_graph_utils_1 = require("../utils/project-graph-utils");
10
11
  const output_1 = require("../utils/output");
@@ -33,7 +34,7 @@ class ProcessTasks {
33
34
  const project = this.projectGraph.nodes[projectName];
34
35
  if (targets.length === 1 || project.data.targets[target]) {
35
36
  const resolvedConfiguration = this.resolveConfiguration(project, target, configuration);
36
- const id = this.getId(projectName, target, resolvedConfiguration);
37
+ const id = createTaskId(projectName, target, resolvedConfiguration);
37
38
  const task = this.createTask(id, project, target, resolvedConfiguration, overrides);
38
39
  this.tasks[task.id] = task;
39
40
  this.dependencies[task.id] = [];
@@ -120,7 +121,7 @@ class ProcessTasks {
120
121
  const selfProject = this.projectGraph.nodes[projectName];
121
122
  if ((0, project_graph_utils_1.projectHasTarget)(selfProject, dependencyConfig.target)) {
122
123
  const resolvedConfiguration = this.resolveConfiguration(selfProject, dependencyConfig.target, configuration);
123
- const selfTaskId = this.getId(selfProject.name, dependencyConfig.target, resolvedConfiguration);
124
+ const selfTaskId = createTaskId(selfProject.name, dependencyConfig.target, resolvedConfiguration);
124
125
  if (!this.tasks[selfTaskId]) {
125
126
  const newTask = this.createTask(selfTaskId, selfProject, dependencyConfig.target, resolvedConfiguration, taskOverrides);
126
127
  this.tasks[selfTaskId] = newTask;
@@ -149,7 +150,7 @@ class ProcessTasks {
149
150
  continue;
150
151
  if ((0, project_graph_utils_1.projectHasTarget)(depProject, dependencyConfig.target)) {
151
152
  const resolvedConfiguration = this.resolveConfiguration(depProject, dependencyConfig.target, configuration);
152
- const depTargetId = this.getId(depProject.name, dependencyConfig.target, resolvedConfiguration);
153
+ const depTargetId = createTaskId(depProject.name, dependencyConfig.target, resolvedConfiguration);
153
154
  const depTargetConfiguration = this.projectGraph.nodes[depProject.name].data.targets[dependencyConfig.target];
154
155
  if (task.id !== depTargetId) {
155
156
  if (depTargetConfiguration.continuous) {
@@ -169,7 +170,7 @@ class ProcessTasks {
169
170
  }
170
171
  else {
171
172
  // Create a dummy task for task.target.project... which simulates if depProject had dependencyConfig.target
172
- const dummyId = this.getId(depProject.name, task.target.project +
173
+ const dummyId = createTaskId(depProject.name, task.target.project +
173
174
  '__' +
174
175
  dependencyConfig.target +
175
176
  DUMMY_TASK_TARGET, undefined);
@@ -218,13 +219,6 @@ class ProcessTasks {
218
219
  ? configuration
219
220
  : defaultConfiguration;
220
221
  }
221
- getId(project, target, configuration) {
222
- let id = `${project}:${target}`;
223
- if (configuration) {
224
- id += `:${configuration}`;
225
- }
226
- return id;
227
- }
228
222
  }
229
223
  exports.ProcessTasks = ProcessTasks;
230
224
  function createTaskGraph(projectGraph, extraTargetDependencies, projectNames, targets, configuration, overrides, excludeTaskDependencies = false) {
@@ -299,3 +293,10 @@ function getNonDummyDeps(currentTask, dependencies, cycles, seen = new Set()) {
299
293
  return [currentTask];
300
294
  }
301
295
  }
296
+ function createTaskId(project, target, configuration) {
297
+ let id = `${project}:${target}`;
298
+ if (configuration) {
299
+ id += `:${configuration}`;
300
+ }
301
+ return id;
302
+ }
@@ -54,26 +54,17 @@ class RemoteCacheV2 {
54
54
  }
55
55
  exports.RemoteCacheV2 = RemoteCacheV2;
56
56
  const defaultTasksRunner = async (tasks, options, context) => {
57
- if (options['parallel'] === 'false' ||
58
- options['parallel'] === false) {
59
- options['parallel'] = 1;
60
- }
61
- else if (options['parallel'] === 'true' ||
62
- options['parallel'] === true ||
63
- options['parallel'] === undefined ||
64
- options['parallel'] === '') {
65
- options['parallel'] = Number(options['maxParallel'] || 3);
66
- }
67
- await options.lifeCycle.startCommand();
57
+ const threadCount = (0, task_orchestrator_1.getThreadCount)(options, context.taskGraph);
58
+ await options.lifeCycle.startCommand(threadCount);
68
59
  try {
69
- return await runAllTasks(tasks, options, context);
60
+ return await runAllTasks(options, context);
70
61
  }
71
62
  finally {
72
63
  await options.lifeCycle.endCommand();
73
64
  }
74
65
  };
75
66
  exports.defaultTasksRunner = defaultTasksRunner;
76
- async function runAllTasks(tasks, options, context) {
67
+ async function runAllTasks(options, context) {
77
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);
78
69
  return orchestrator.run();
79
70
  }
@@ -2,17 +2,19 @@ import { DefaultTasksRunnerOptions } from './default-tasks-runner';
2
2
  import { Batch } from './tasks-schedule';
3
3
  import { Task, TaskGraph } from '../config/task-graph';
4
4
  import { PseudoTtyProcess } from './pseudo-terminal';
5
+ import { ProjectGraph } from '../config/project-graph';
5
6
  import { BatchProcess } from './running-tasks/batch-process';
6
7
  import { RunningTask } from './running-tasks/running-task';
7
8
  export declare class ForkedProcessTaskRunner {
8
9
  private readonly options;
10
+ private readonly tuiEnabled;
9
11
  cliPath: string;
10
12
  private readonly verbose;
11
13
  private processes;
12
- private pseudoTerminal;
13
- constructor(options: DefaultTasksRunnerOptions);
14
+ private pseudoTerminals;
15
+ constructor(options: DefaultTasksRunnerOptions, tuiEnabled: boolean);
14
16
  init(): Promise<void>;
15
- forkProcessForBatch({ executorName, taskGraph: batchTaskGraph }: Batch, fullTaskGraph: TaskGraph, env: NodeJS.ProcessEnv): Promise<BatchProcess>;
17
+ forkProcessForBatch({ executorName, taskGraph: batchTaskGraph }: Batch, projectGraph: ProjectGraph, fullTaskGraph: TaskGraph, env: NodeJS.ProcessEnv): Promise<BatchProcess>;
16
18
  forkProcessLegacy(task: Task, { temporaryOutputPath, streamOutput, pipeOutput, taskGraph, env, }: {
17
19
  temporaryOutputPath: string;
18
20
  streamOutput: boolean;
@@ -28,6 +30,7 @@ export declare class ForkedProcessTaskRunner {
28
30
  env: NodeJS.ProcessEnv;
29
31
  disablePseudoTerminal: boolean;
30
32
  }): Promise<RunningTask | PseudoTtyProcess>;
33
+ private createPseudoTerminal;
31
34
  private forkProcessWithPseudoTerminal;
32
35
  private forkProcessWithPrefixAndNotTTY;
33
36
  private forkProcessDirectOutputCapture;
@@ -12,26 +12,23 @@ const pseudo_terminal_1 = require("./pseudo-terminal");
12
12
  const exit_codes_1 = require("../utils/exit-codes");
13
13
  const node_child_process_1 = require("./running-tasks/node-child-process");
14
14
  const batch_process_1 = require("./running-tasks/batch-process");
15
+ const native_1 = require("../native");
15
16
  const forkScript = (0, path_1.join)(__dirname, './fork.js');
16
17
  const workerPath = (0, path_1.join)(__dirname, './batch/run-batch.js');
17
18
  class ForkedProcessTaskRunner {
18
- constructor(options) {
19
+ constructor(options, tuiEnabled) {
19
20
  this.options = options;
21
+ this.tuiEnabled = tuiEnabled;
20
22
  this.cliPath = (0, utils_1.getCliPath)();
21
23
  this.verbose = process.env.NX_VERBOSE_LOGGING === 'true';
22
24
  this.processes = new Set();
23
- this.pseudoTerminal = pseudo_terminal_1.PseudoTerminal.isSupported()
24
- ? (0, pseudo_terminal_1.getPseudoTerminal)()
25
- : null;
25
+ this.pseudoTerminals = new Set();
26
26
  }
27
27
  async init() {
28
- if (this.pseudoTerminal) {
29
- await this.pseudoTerminal.init();
30
- }
31
28
  this.setupProcessEventListeners();
32
29
  }
33
30
  // TODO: vsavkin delegate terminal output printing
34
- async forkProcessForBatch({ executorName, taskGraph: batchTaskGraph }, fullTaskGraph, env) {
31
+ async forkProcessForBatch({ executorName, taskGraph: batchTaskGraph }, projectGraph, fullTaskGraph, env) {
35
32
  const count = Object.keys(batchTaskGraph.tasks).length;
36
33
  if (count > 1) {
37
34
  output_1.output.logSingleLine(`Running ${output_1.output.bold(count)} ${output_1.output.bold('tasks')} with ${output_1.output.bold(executorName)}`);
@@ -53,6 +50,7 @@ class ForkedProcessTaskRunner {
53
50
  cp.send({
54
51
  type: batch_messages_1.BatchMessageType.RunTasks,
55
52
  executorName,
53
+ projectGraph,
56
54
  batchTaskGraph,
57
55
  fullTaskGraph,
58
56
  });
@@ -74,14 +72,15 @@ class ForkedProcessTaskRunner {
74
72
  });
75
73
  }
76
74
  async forkProcess(task, { temporaryOutputPath, streamOutput, taskGraph, env, disablePseudoTerminal, }) {
77
- const shouldPrefix = streamOutput && process.env.NX_PREFIX_OUTPUT === 'true';
75
+ const shouldPrefix = streamOutput &&
76
+ process.env.NX_PREFIX_OUTPUT === 'true' &&
77
+ !this.tuiEnabled;
78
78
  // streamOutput would be false if we are running multiple targets
79
79
  // there's no point in running the commands in a pty if we are not streaming the output
80
- if (!this.pseudoTerminal ||
81
- disablePseudoTerminal ||
82
- !streamOutput ||
83
- shouldPrefix) {
84
- return this.forkProcessWithPrefixAndNotTTY(task, {
80
+ if (pseudo_terminal_1.PseudoTerminal.isSupported() &&
81
+ !disablePseudoTerminal &&
82
+ (this.tuiEnabled || (streamOutput && !shouldPrefix))) {
83
+ return this.forkProcessWithPseudoTerminal(task, {
85
84
  temporaryOutputPath,
86
85
  streamOutput,
87
86
  taskGraph,
@@ -89,7 +88,7 @@ class ForkedProcessTaskRunner {
89
88
  });
90
89
  }
91
90
  else {
92
- return this.forkProcessWithPseudoTerminal(task, {
91
+ return this.forkProcessWithPrefixAndNotTTY(task, {
93
92
  temporaryOutputPath,
94
93
  streamOutput,
95
94
  taskGraph,
@@ -97,13 +96,19 @@ class ForkedProcessTaskRunner {
97
96
  });
98
97
  }
99
98
  }
99
+ async createPseudoTerminal() {
100
+ const terminal = new pseudo_terminal_1.PseudoTerminal(new native_1.RustPseudoTerminal());
101
+ await terminal.init();
102
+ terminal.onMessageFromChildren((message) => {
103
+ process.send(message);
104
+ });
105
+ return terminal;
106
+ }
100
107
  async forkProcessWithPseudoTerminal(task, { temporaryOutputPath, streamOutput, taskGraph, env, }) {
101
- const args = (0, utils_1.getPrintableCommandArgsForTask)(task);
102
- if (streamOutput) {
103
- output_1.output.logCommand(args.join(' '));
104
- }
105
108
  const childId = task.id;
106
- const p = await this.pseudoTerminal.fork(childId, forkScript, {
109
+ const pseudoTerminal = await this.createPseudoTerminal();
110
+ this.pseudoTerminals.add(pseudoTerminal);
111
+ const p = await pseudoTerminal.fork(childId, forkScript, {
107
112
  cwd: process.cwd(),
108
113
  execArgv: process.execArgv,
109
114
  jsEnv: env,
@@ -124,6 +129,7 @@ class ForkedProcessTaskRunner {
124
129
  if (code > 128) {
125
130
  process.exit(code);
126
131
  }
132
+ this.pseudoTerminals.delete(pseudoTerminal);
127
133
  this.processes.delete(p);
128
134
  this.writeTerminalOutput(temporaryOutputPath, terminalOutput);
129
135
  });
@@ -215,16 +221,11 @@ class ForkedProcessTaskRunner {
215
221
  (0, fs_1.writeFileSync)(outputPath, content);
216
222
  }
217
223
  setupProcessEventListeners() {
218
- if (this.pseudoTerminal) {
219
- this.pseudoTerminal.onMessageFromChildren((message) => {
220
- process.send(message);
221
- });
222
- }
223
224
  // When the nx process gets a message, it will be sent into the task's process
224
225
  process.on('message', (message) => {
225
- if (this.pseudoTerminal) {
226
- this.pseudoTerminal.sendMessageToChildren(message);
227
- }
226
+ this.pseudoTerminals.forEach((p) => {
227
+ p.sendMessageToChildren(message);
228
+ });
228
229
  this.processes.forEach((p) => {
229
230
  if ('send' in p) {
230
231
  p.send(message);
@@ -1,6 +1,13 @@
1
1
  import { NxArgs } from '../utils/command-line-utils';
2
2
  import { Task, TaskGraph } from '../config/task-graph';
3
- import { TaskResult } from './life-cycle';
3
+ import { LifeCycle, TaskResult } from './life-cycle';
4
+ import type { ProjectGraph } from '../config/project-graph';
5
+ import type { NxJsonConfiguration } from '../config/nx-json';
6
+ import { RunningTask } from './running-tasks/running-task';
7
+ /**
8
+ * This function is deprecated. Do not use this
9
+ * @deprecated This function is deprecated. Do not use this
10
+ */
4
11
  export declare function initTasksRunner(nxArgs: NxArgs): Promise<{
5
12
  invoke: (opts: {
6
13
  tasks: Task[];
@@ -11,3 +18,10 @@ export declare function initTasksRunner(nxArgs: NxArgs): Promise<{
11
18
  taskResults: Record<string, TaskResult>;
12
19
  }>;
13
20
  }>;
21
+ export declare function runDiscreteTasks(tasks: Task[], projectGraph: ProjectGraph, taskGraphForHashing: TaskGraph, nxJson: NxJsonConfiguration, lifeCycle: LifeCycle): Promise<Promise<{
22
+ task: Task;
23
+ code: number;
24
+ status: import("./tasks-runner").TaskStatus;
25
+ terminalOutput?: string;
26
+ }>[]>;
27
+ export declare function runContinuousTasks(tasks: Task[], projectGraph: ProjectGraph, taskGraphForHashing: TaskGraph, nxJson: NxJsonConfiguration, lifeCycle: LifeCycle): Promise<Record<string, Promise<RunningTask>>>;
@@ -1,17 +1,28 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.initTasksRunner = initTasksRunner;
4
- const configuration_1 = require("../config/configuration");
4
+ exports.runDiscreteTasks = runDiscreteTasks;
5
+ exports.runContinuousTasks = runContinuousTasks;
6
+ const nx_json_1 = require("../config/nx-json");
5
7
  const project_graph_1 = require("../project-graph/project-graph");
6
8
  const run_command_1 = require("./run-command");
7
9
  const invoke_runner_terminal_output_life_cycle_1 = require("./life-cycles/invoke-runner-terminal-output-life-cycle");
8
10
  const perf_hooks_1 = require("perf_hooks");
9
11
  const utils_1 = require("./utils");
10
12
  const dotenv_1 = require("../utils/dotenv");
13
+ const life_cycle_1 = require("./life-cycle");
14
+ const task_orchestrator_1 = require("./task-orchestrator");
15
+ const create_task_hasher_1 = require("../hasher/create-task-hasher");
16
+ const client_1 = require("../daemon/client/client");
17
+ const task_results_life_cycle_1 = require("./life-cycles/task-results-life-cycle");
18
+ /**
19
+ * This function is deprecated. Do not use this
20
+ * @deprecated This function is deprecated. Do not use this
21
+ */
11
22
  async function initTasksRunner(nxArgs) {
12
23
  perf_hooks_1.performance.mark('init-local');
13
24
  (0, dotenv_1.loadRootEnvFiles)();
14
- const nxJson = (0, configuration_1.readNxJson)();
25
+ const nxJson = (0, nx_json_1.readNxJson)();
15
26
  if (nxArgs.verbose) {
16
27
  process.env.NX_VERBOSE_LOGGING = 'true';
17
28
  }
@@ -61,3 +72,45 @@ async function initTasksRunner(nxArgs) {
61
72
  },
62
73
  };
63
74
  }
75
+ async function createOrchestrator(tasks, projectGraph, taskGraphForHashing, nxJson, lifeCycle) {
76
+ (0, dotenv_1.loadRootEnvFiles)();
77
+ const invokeRunnerTerminalLifecycle = new invoke_runner_terminal_output_life_cycle_1.InvokeRunnerTerminalOutputLifeCycle(tasks);
78
+ const taskResultsLifecycle = new task_results_life_cycle_1.TaskResultsLifeCycle();
79
+ const compositedLifeCycle = new life_cycle_1.CompositeLifeCycle([
80
+ ...(0, run_command_1.constructLifeCycles)(invokeRunnerTerminalLifecycle),
81
+ taskResultsLifecycle,
82
+ lifeCycle,
83
+ ]);
84
+ const { runnerOptions: options } = (0, run_command_1.getRunner)({}, nxJson);
85
+ let hasher = (0, create_task_hasher_1.createTaskHasher)(projectGraph, nxJson, options);
86
+ const taskGraph = {
87
+ roots: tasks.map((task) => task.id),
88
+ tasks: tasks.reduce((acc, task) => {
89
+ acc[task.id] = task;
90
+ return acc;
91
+ }, {}),
92
+ dependencies: tasks.reduce((acc, task) => {
93
+ acc[task.id] = [];
94
+ return acc;
95
+ }, {}),
96
+ continuousDependencies: tasks.reduce((acc, task) => {
97
+ acc[task.id] = [];
98
+ return acc;
99
+ }, {}),
100
+ };
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
+ await orchestrator.init();
103
+ await Promise.all(tasks.map((task) => orchestrator.processTask(task.id)));
104
+ return orchestrator;
105
+ }
106
+ async function runDiscreteTasks(tasks, projectGraph, taskGraphForHashing, nxJson, lifeCycle) {
107
+ const orchestrator = await createOrchestrator(tasks, projectGraph, taskGraphForHashing, nxJson, lifeCycle);
108
+ return tasks.map((task, index) => orchestrator.applyFromCacheOrRunTask(true, task, index));
109
+ }
110
+ async function runContinuousTasks(tasks, projectGraph, taskGraphForHashing, nxJson, lifeCycle) {
111
+ const orchestrator = await createOrchestrator(tasks, projectGraph, taskGraphForHashing, nxJson, lifeCycle);
112
+ return tasks.reduce((current, task, index) => {
113
+ current[task.id] = orchestrator.startContinuousTask(task, index);
114
+ return current;
115
+ }, {});
116
+ }
@@ -0,0 +1,2 @@
1
+ import type { NxJsonConfiguration } from '../config/nx-json';
2
+ export declare function isTuiEnabled(nxJson?: NxJsonConfiguration): any;
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isTuiEnabled = isTuiEnabled;
4
+ const devkit_internals_1 = require("../devkit-internals");
5
+ let tuiEnabled = undefined;
6
+ function isTuiEnabled(nxJson) {
7
+ if (tuiEnabled !== undefined) {
8
+ return tuiEnabled;
9
+ }
10
+ // If the current terminal/environment is not capable of displaying the TUI, we don't run it
11
+ const isWindows = process.platform === 'win32';
12
+ const isCapable = process.stderr.isTTY && isUnicodeSupported();
13
+ // Windows is not working well right now, temporarily disable it on Windows even if it has been specified as enabled
14
+ // TODO(@JamesHenry): Remove this check once Windows issues are fixed.
15
+ if (!isCapable || isWindows) {
16
+ tuiEnabled = false;
17
+ process.env.NX_TUI = 'false';
18
+ return tuiEnabled;
19
+ }
20
+ // The environment variable takes precedence over the nx.json config
21
+ if (typeof process.env.NX_TUI === 'string') {
22
+ tuiEnabled = process.env.NX_TUI === 'true' ? true : false;
23
+ return tuiEnabled;
24
+ }
25
+ // Only read from disk if nx.json config is not already provided (and we have not been able to determine tuiEnabled based on the above checks)
26
+ if (!nxJson) {
27
+ nxJson = (0, devkit_internals_1.readNxJsonFromDisk)();
28
+ }
29
+ // Respect user config
30
+ if (typeof nxJson.tui?.enabled === 'boolean') {
31
+ tuiEnabled = Boolean(nxJson.tui?.enabled);
32
+ }
33
+ else {
34
+ // Default to enabling the TUI if the system is capable of displaying it
35
+ tuiEnabled = true;
36
+ }
37
+ // Also set the environment variable for consistency and ease of checking on the rust side, for example
38
+ process.env.NX_TUI = tuiEnabled.toString();
39
+ return tuiEnabled;
40
+ }
41
+ // Credit to https://github.com/sindresorhus/is-unicode-supported/blob/e0373335038856c63034c8eef6ac43ee3827a601/index.js
42
+ function isUnicodeSupported() {
43
+ const { env } = process;
44
+ const { TERM, TERM_PROGRAM } = env;
45
+ if (process.platform !== 'win32') {
46
+ return TERM !== 'linux'; // Linux console (kernel)
47
+ }
48
+ return (Boolean(env.WT_SESSION) || // Windows Terminal
49
+ Boolean(env.TERMINUS_SUBLIME) || // Terminus (<0.2.27)
50
+ env.ConEmuTask === '{cmd::Cmder}' || // ConEmu and cmder
51
+ TERM_PROGRAM === 'Terminus-Sublime' ||
52
+ TERM_PROGRAM === 'vscode' ||
53
+ TERM === 'xterm-256color' ||
54
+ TERM === 'alacritty' ||
55
+ TERM === 'rxvt-unicode' ||
56
+ TERM === 'rxvt-unicode-256color' ||
57
+ env.TERMINAL_EMULATOR === 'JetBrains-JediTerm');
58
+ }
@@ -1,5 +1,6 @@
1
- import { TaskStatus } from './tasks-runner';
2
1
  import { Task } from '../config/task-graph';
2
+ import { ExternalObject, TaskStatus as NativeTaskStatus } from '../native';
3
+ import { TaskStatus } from './tasks-runner';
3
4
  /**
4
5
  * The result of a completed {@link Task}
5
6
  */
@@ -17,7 +18,7 @@ export interface TaskMetadata {
17
18
  groupId: number;
18
19
  }
19
20
  export interface LifeCycle {
20
- startCommand?(): void | Promise<void>;
21
+ startCommand?(parallel?: number): void | Promise<void>;
21
22
  endCommand?(): void | Promise<void>;
22
23
  scheduleTask?(task: Task): void | Promise<void>;
23
24
  /**
@@ -35,11 +36,14 @@ export interface LifeCycle {
35
36
  startTasks?(task: Task[], metadata: TaskMetadata): void | Promise<void>;
36
37
  endTasks?(taskResults: TaskResult[], metadata: TaskMetadata): void | Promise<void>;
37
38
  printTaskTerminalOutput?(task: Task, status: TaskStatus, output: string): void;
39
+ registerRunningTask?(taskId: string, parserAndWriter: ExternalObject<[any, any]>): Promise<void>;
40
+ setTaskStatus?(taskId: string, status: NativeTaskStatus): void;
41
+ registerForcedShutdownCallback?(callback: () => void): void;
38
42
  }
39
43
  export declare class CompositeLifeCycle implements LifeCycle {
40
44
  private readonly lifeCycles;
41
45
  constructor(lifeCycles: LifeCycle[]);
42
- startCommand(): Promise<void>;
46
+ startCommand(parallel?: number): Promise<void>;
43
47
  endCommand(): Promise<void>;
44
48
  scheduleTask(task: Task): Promise<void>;
45
49
  startTask(task: Task): void;
@@ -47,4 +51,7 @@ export declare class CompositeLifeCycle implements LifeCycle {
47
51
  startTasks(tasks: Task[], metadata: TaskMetadata): Promise<void>;
48
52
  endTasks(taskResults: TaskResult[], metadata: TaskMetadata): Promise<void>;
49
53
  printTaskTerminalOutput(task: Task, status: TaskStatus, output: string): void;
54
+ registerRunningTask(taskId: string, parserAndWriter: ExternalObject<[any, any]>): Promise<void>;
55
+ setTaskStatus(taskId: string, status: NativeTaskStatus): void;
56
+ registerForcedShutdownCallback(callback: () => void): void;
50
57
  }