nx 19.8.0-canary.20240912-b6140d4 → 19.8.0-canary.20240913-5bbaffb

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. package/package.json +12 -12
  2. package/src/command-line/add/add.js +2 -2
  3. package/src/command-line/affected/command-object.js +6 -6
  4. package/src/command-line/deprecated/command-objects.js +3 -3
  5. package/src/command-line/generate/generate.js +2 -1
  6. package/src/command-line/generate/generator-utils.d.ts +2 -1
  7. package/src/command-line/import/command-object.js +3 -3
  8. package/src/command-line/login/login.js +2 -2
  9. package/src/command-line/logout/logout.js +2 -2
  10. package/src/command-line/migrate/migrate.js +2 -2
  11. package/src/command-line/new/new.js +2 -1
  12. package/src/command-line/release/changelog.js +2 -2
  13. package/src/command-line/release/plan-check.js +2 -2
  14. package/src/command-line/release/plan.js +2 -2
  15. package/src/command-line/release/publish.js +2 -2
  16. package/src/command-line/release/release.js +2 -2
  17. package/src/command-line/release/version.js +2 -1
  18. package/src/command-line/repair/repair.js +2 -2
  19. package/src/command-line/run/command-object.js +3 -3
  20. package/src/command-line/run/run.js +3 -2
  21. package/src/command-line/run-many/command-object.js +2 -2
  22. package/src/command-line/show/command-object.js +3 -3
  23. package/src/command-line/sync/command-object.js +2 -2
  24. package/src/command-line/sync/sync.js +2 -2
  25. package/src/daemon/client/client.d.ts +2 -1
  26. package/src/daemon/client/client.js +7 -0
  27. package/src/daemon/message-types/task-history.d.ts +9 -3
  28. package/src/daemon/message-types/task-history.js +10 -2
  29. package/src/daemon/server/handle-task-history.d.ts +5 -1
  30. package/src/daemon/server/handle-task-history.js +11 -9
  31. package/src/daemon/server/server.js +5 -2
  32. package/src/native/index.d.ts +1 -0
  33. package/src/native/nx.wasi.cjs +20 -20
  34. package/src/native/nx.wasm32-wasi.wasm +0 -0
  35. package/src/nx-cloud/generators/connect-to-nx-cloud/connect-to-nx-cloud.js +0 -1
  36. package/src/nx-cloud/utilities/get-cloud-options.d.ts +1 -0
  37. package/src/nx-cloud/utilities/get-cloud-options.js +4 -0
  38. package/src/nx-cloud/utilities/is-workspace-claimed.d.ts +1 -1
  39. package/src/nx-cloud/utilities/is-workspace-claimed.js +6 -5
  40. package/src/nx-cloud/utilities/onboarding.js +2 -2
  41. package/src/plugins/js/utils/register.js +7 -0
  42. package/src/project-graph/error-types.d.ts +1 -1
  43. package/src/project-graph/error-types.js +19 -5
  44. package/src/tasks-runner/life-cycles/task-history-life-cycle.js +1 -1
  45. package/src/tasks-runner/run-command.js +2 -2
  46. package/src/tasks-runner/task-orchestrator.js +4 -1
  47. package/src/tasks-runner/tasks-schedule.d.ts +3 -0
  48. package/src/tasks-runner/tasks-schedule.js +22 -4
  49. package/src/utils/handle-errors.d.ts +1 -0
  50. package/src/utils/handle-errors.js +71 -0
  51. package/src/utils/nx-cloud-utils.d.ts +0 -1
  52. package/src/utils/nx-cloud-utils.js +0 -10
  53. package/src/utils/params.d.ts +0 -1
  54. package/src/utils/params.js +0 -50
  55. package/src/utils/plugins/plugin-capabilities.js +4 -1
  56. package/src/utils/task-history.d.ts +12 -1
  57. package/src/utils/task-history.js +23 -0
@@ -1,4 +1,4 @@
1
- import { TaskRun } from '../../native';
1
+ import type { TaskRun, TaskTarget } from '../../native';
2
2
  export declare function handleRecordTaskRuns(taskRuns: TaskRun[]): Promise<{
3
3
  response: string;
4
4
  description: string;
@@ -7,3 +7,7 @@ export declare function handleGetFlakyTasks(hashes: string[]): Promise<{
7
7
  response: string;
8
8
  description: string;
9
9
  }>;
10
+ export declare function handleGetEstimatedTaskTimings(targets: TaskTarget[]): Promise<{
11
+ response: string;
12
+ description: string;
13
+ }>;
@@ -2,16 +2,10 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.handleRecordTaskRuns = handleRecordTaskRuns;
4
4
  exports.handleGetFlakyTasks = handleGetFlakyTasks;
5
+ exports.handleGetEstimatedTaskTimings = handleGetEstimatedTaskTimings;
5
6
  const task_history_1 = require("../../utils/task-history");
6
- let taskHistory;
7
- function getTaskHistory() {
8
- if (!taskHistory) {
9
- taskHistory = new task_history_1.TaskHistory();
10
- }
11
- return taskHistory;
12
- }
13
7
  async function handleRecordTaskRuns(taskRuns) {
14
- const taskHistory = getTaskHistory();
8
+ const taskHistory = (0, task_history_1.getTaskHistory)();
15
9
  await taskHistory.recordTaskRuns(taskRuns);
16
10
  return {
17
11
  response: 'true',
@@ -19,10 +13,18 @@ async function handleRecordTaskRuns(taskRuns) {
19
13
  };
20
14
  }
21
15
  async function handleGetFlakyTasks(hashes) {
22
- const taskHistory = getTaskHistory();
16
+ const taskHistory = (0, task_history_1.getTaskHistory)();
23
17
  const history = await taskHistory.getFlakyTasks(hashes);
24
18
  return {
25
19
  response: JSON.stringify(history),
26
20
  description: 'handleGetFlakyTasks',
27
21
  };
28
22
  }
23
+ async function handleGetEstimatedTaskTimings(targets) {
24
+ const taskHistory = (0, task_history_1.getTaskHistory)();
25
+ const history = await taskHistory.getEstimatedTaskTimings(targets);
26
+ return {
27
+ response: JSON.stringify(history),
28
+ description: 'handleGetEstimatedTaskTimings',
29
+ };
30
+ }
@@ -140,10 +140,13 @@ async function handleMessage(socket, data) {
140
140
  await handleResult(socket, hash_glob_1.HASH_GLOB, () => (0, handle_hash_glob_1.handleHashGlob)(payload.globs, payload.exclude));
141
141
  }
142
142
  else if ((0, task_history_1.isHandleGetFlakyTasksMessage)(payload)) {
143
- await handleResult(socket, 'GET_TASK_HISTORY_FOR_HASHES', () => (0, handle_task_history_1.handleGetFlakyTasks)(payload.hashes));
143
+ await handleResult(socket, task_history_1.GET_FLAKY_TASKS, () => (0, handle_task_history_1.handleGetFlakyTasks)(payload.hashes));
144
+ }
145
+ else if ((0, task_history_1.isHandleGetEstimatedTaskTimings)(payload)) {
146
+ await handleResult(socket, task_history_1.GET_ESTIMATED_TASK_TIMINGS, () => (0, handle_task_history_1.handleGetEstimatedTaskTimings)(payload.targets));
144
147
  }
145
148
  else if ((0, task_history_1.isHandleWriteTaskRunsToHistoryMessage)(payload)) {
146
- await handleResult(socket, 'WRITE_TASK_RUNS_TO_HISTORY', () => (0, handle_task_history_1.handleRecordTaskRuns)(payload.taskRuns));
149
+ await handleResult(socket, task_history_1.RECORD_TASK_RUNS, () => (0, handle_task_history_1.handleRecordTaskRuns)(payload.taskRuns));
147
150
  }
148
151
  else if ((0, force_shutdown_1.isHandleForceShutdownMessage)(payload)) {
149
152
  await handleResult(socket, 'FORCE_SHUTDOWN', () => (0, handle_force_shutdown_1.handleForceShutdown)(server));
@@ -41,6 +41,7 @@ export declare class NxTaskHistory {
41
41
  constructor(db: ExternalObject<Connection>)
42
42
  recordTaskRuns(taskRuns: Array<TaskRun>): void
43
43
  getFlakyTasks(hashes: Array<string>): Array<string>
44
+ getEstimatedTaskTimings(targets: Array<TaskTarget>): Record<string, number>
44
45
  }
45
46
 
46
47
  export declare class RustPseudoTerminal {
@@ -113,26 +113,26 @@ function __napi_rs_initialize_modules(__napiInstance) {
113
113
  __napiInstance.exports['__napi_register__TaskHasher_impl_42']?.()
114
114
  __napiInstance.exports['__napi_register__TaskRun_struct_43']?.()
115
115
  __napiInstance.exports['__napi_register__NxTaskHistory_struct_44']?.()
116
- __napiInstance.exports['__napi_register__NxTaskHistory_impl_48']?.()
117
- __napiInstance.exports['__napi_register__Task_struct_49']?.()
118
- __napiInstance.exports['__napi_register__TaskTarget_struct_50']?.()
119
- __napiInstance.exports['__napi_register__TaskGraph_struct_51']?.()
120
- __napiInstance.exports['__napi_register__FileData_struct_52']?.()
121
- __napiInstance.exports['__napi_register__InputsInput_struct_53']?.()
122
- __napiInstance.exports['__napi_register__FileSetInput_struct_54']?.()
123
- __napiInstance.exports['__napi_register__RuntimeInput_struct_55']?.()
124
- __napiInstance.exports['__napi_register__EnvironmentInput_struct_56']?.()
125
- __napiInstance.exports['__napi_register__ExternalDependenciesInput_struct_57']?.()
126
- __napiInstance.exports['__napi_register__DepsOutputsInput_struct_58']?.()
127
- __napiInstance.exports['__napi_register__NxJson_struct_59']?.()
128
- __napiInstance.exports['__napi_register__WorkspaceContext_struct_60']?.()
129
- __napiInstance.exports['__napi_register__WorkspaceContext_impl_69']?.()
130
- __napiInstance.exports['__napi_register__WorkspaceErrors_70']?.()
131
- __napiInstance.exports['__napi_register__NxWorkspaceFiles_struct_71']?.()
132
- __napiInstance.exports['__napi_register__NxWorkspaceFilesExternals_struct_72']?.()
133
- __napiInstance.exports['__napi_register__UpdatedWorkspaceFiles_struct_73']?.()
134
- __napiInstance.exports['__napi_register__FileMap_struct_74']?.()
135
- __napiInstance.exports['__napi_register____test_only_transfer_file_map_75']?.()
116
+ __napiInstance.exports['__napi_register__NxTaskHistory_impl_49']?.()
117
+ __napiInstance.exports['__napi_register__Task_struct_50']?.()
118
+ __napiInstance.exports['__napi_register__TaskTarget_struct_51']?.()
119
+ __napiInstance.exports['__napi_register__TaskGraph_struct_52']?.()
120
+ __napiInstance.exports['__napi_register__FileData_struct_53']?.()
121
+ __napiInstance.exports['__napi_register__InputsInput_struct_54']?.()
122
+ __napiInstance.exports['__napi_register__FileSetInput_struct_55']?.()
123
+ __napiInstance.exports['__napi_register__RuntimeInput_struct_56']?.()
124
+ __napiInstance.exports['__napi_register__EnvironmentInput_struct_57']?.()
125
+ __napiInstance.exports['__napi_register__ExternalDependenciesInput_struct_58']?.()
126
+ __napiInstance.exports['__napi_register__DepsOutputsInput_struct_59']?.()
127
+ __napiInstance.exports['__napi_register__NxJson_struct_60']?.()
128
+ __napiInstance.exports['__napi_register__WorkspaceContext_struct_61']?.()
129
+ __napiInstance.exports['__napi_register__WorkspaceContext_impl_70']?.()
130
+ __napiInstance.exports['__napi_register__WorkspaceErrors_71']?.()
131
+ __napiInstance.exports['__napi_register__NxWorkspaceFiles_struct_72']?.()
132
+ __napiInstance.exports['__napi_register__NxWorkspaceFilesExternals_struct_73']?.()
133
+ __napiInstance.exports['__napi_register__UpdatedWorkspaceFiles_struct_74']?.()
134
+ __napiInstance.exports['__napi_register__FileMap_struct_75']?.()
135
+ __napiInstance.exports['__napi_register____test_only_transfer_file_map_76']?.()
136
136
  }
137
137
  module.exports.HashPlanner = __napiModule.exports.HashPlanner
138
138
  module.exports.ImportResult = __napiModule.exports.ImportResult
Binary file
@@ -89,7 +89,6 @@ async function connectToNxCloud(tree, schema, nxJson = (0, nx_json_1.readNxJson)
89
89
  return null;
90
90
  }
91
91
  const isGitHubDetected = schema.github ?? (await (0, url_shorten_1.repoUsesGithub)(schema.github));
92
- let responseFromCreateNxCloudWorkspaceV1;
93
92
  let responseFromCreateNxCloudWorkspaceV2;
94
93
  /**
95
94
  * Do not create an Nx Cloud token if the user is using GitHub and
@@ -2,3 +2,4 @@ import { CloudTaskRunnerOptions } from '../nx-cloud-tasks-runner-shell';
2
2
  export declare function getCloudOptions(directory?: string): CloudTaskRunnerOptions;
3
3
  export declare function getCloudUrl(): string;
4
4
  export declare function removeTrailingSlash(apiUrl: string): string;
5
+ export declare function isNxCloudId(token: string): boolean;
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getCloudOptions = getCloudOptions;
4
4
  exports.getCloudUrl = getCloudUrl;
5
5
  exports.removeTrailingSlash = removeTrailingSlash;
6
+ exports.isNxCloudId = isNxCloudId;
6
7
  const nx_json_1 = require("../../config/nx-json");
7
8
  const run_command_1 = require("../../tasks-runner/run-command");
8
9
  const workspace_root_1 = require("../../utils/workspace-root");
@@ -17,3 +18,6 @@ function getCloudUrl() {
17
18
  function removeTrailingSlash(apiUrl) {
18
19
  return apiUrl[apiUrl.length - 1] === '/' ? apiUrl.slice(0, -1) : apiUrl;
19
20
  }
21
+ function isNxCloudId(token) {
22
+ return token.length === 24;
23
+ }
@@ -1 +1 @@
1
- export declare function isWorkspaceClaimed(nxCloudAccessToken: any): Promise<any>;
1
+ export declare function isWorkspaceClaimed(accessToken: string): Promise<any>;
@@ -2,14 +2,15 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.isWorkspaceClaimed = isWorkspaceClaimed;
4
4
  const get_cloud_options_1 = require("./get-cloud-options");
5
- async function isWorkspaceClaimed(nxCloudAccessToken) {
6
- if (!nxCloudAccessToken)
5
+ async function isWorkspaceClaimed(accessToken) {
6
+ if (!accessToken)
7
7
  return false;
8
8
  const apiUrl = (0, get_cloud_options_1.getCloudUrl)();
9
9
  try {
10
- const response = await require('axios').post(`${apiUrl}/nx-cloud/is-workspace-claimed`, {
11
- nxCloudAccessToken,
12
- });
10
+ const requestData = (0, get_cloud_options_1.isNxCloudId)(accessToken)
11
+ ? { nxCloudId: accessToken }
12
+ : { nxCloudAccessToken: accessToken };
13
+ const response = await require('axios').post(`${apiUrl}/nx-cloud/is-workspace-claimed`, requestData);
13
14
  if (response.data.message) {
14
15
  return false;
15
16
  }
@@ -23,6 +23,6 @@ async function getNxCloudAppOnBoardingUrl(token) {
23
23
  }
24
24
  function readNxCloudToken(tree) {
25
25
  const nxJson = (0, devkit_exports_1.readNxJson)(tree);
26
- const { accessToken } = (0, run_command_1.getRunnerOptions)('default', nxJson, {}, true);
27
- return accessToken;
26
+ const { accessToken, nxCloudId } = (0, run_command_1.getRunnerOptions)('default', nxJson, {}, true);
27
+ return accessToken || nxCloudId;
28
28
  }
@@ -63,6 +63,13 @@ function registerTsProject(path, configFilename) {
63
63
  // Based on limited testing, it doesn't seem to matter if we register it multiple times, but just in
64
64
  // case let's keep a flag to prevent it.
65
65
  if (!isTsEsmLoaderRegistered) {
66
+ // We need a way to ensure that `.ts` files are treated as ESM not CJS.
67
+ // Since there is no way to pass compilerOptions like we do with the programmatic API, we should default
68
+ // the environment variable that ts-node checks.
69
+ process.env.TS_NODE_COMPILER_OPTIONS ??= JSON.stringify({
70
+ moduleResolution: 'nodenext',
71
+ module: 'nodenext',
72
+ });
66
73
  const module = require('node:module');
67
74
  if (module.register && packageIsInstalled('ts-node/esm')) {
68
75
  const url = require('node:url');
@@ -18,7 +18,7 @@ export declare class ProjectGraphError extends Error {
18
18
  */
19
19
  getPartialProjectGraph(): ProjectGraph;
20
20
  getPartialSourcemaps(): ConfigurationSourceMaps;
21
- getErrors(): (AggregateCreateNodesError | MergeNodesError | CreateMetadataError | ProjectsWithNoNameError | MultipleProjectsWithSameNameError | ProcessDependenciesError | ProcessProjectGraphError | WorkspaceValidityError)[];
21
+ getErrors(): (AggregateCreateNodesError | MergeNodesError | ProjectsWithNoNameError | MultipleProjectsWithSameNameError | CreateMetadataError | ProcessDependenciesError | ProcessProjectGraphError | WorkspaceValidityError)[];
22
22
  }
23
23
  export declare class MultipleProjectsWithSameNameError extends Error {
24
24
  conflicts: Map<string, string[]>;
@@ -24,7 +24,7 @@ class ProjectGraphError extends Error {
24
24
  tslib_1.__classPrivateFieldSet(this, _ProjectGraphError_partialProjectGraph, partialProjectGraph, "f");
25
25
  tslib_1.__classPrivateFieldSet(this, _ProjectGraphError_partialSourceMaps, partialSourceMaps, "f");
26
26
  this.stack = `${this.message}\n ${errors
27
- .map((error) => error.stack.split('\n').join('\n '))
27
+ .map((error) => indentString(formatErrorStackAndCause(error), 2))
28
28
  .join('\n')}`;
29
29
  }
30
30
  /**
@@ -186,13 +186,13 @@ class MergeNodesError extends Error {
186
186
  this.name = this.constructor.name;
187
187
  this.file = file;
188
188
  this.pluginName = pluginName;
189
- this.stack = `${this.message}\n ${error.stack.split('\n').join('\n ')}`;
189
+ this.stack = `${this.message}\n${indentString(formatErrorStackAndCause(error), 2)}`;
190
190
  }
191
191
  }
192
192
  exports.MergeNodesError = MergeNodesError;
193
193
  class CreateMetadataError extends Error {
194
194
  constructor(error, plugin) {
195
- super(`The "${plugin}" plugin threw an error while creating metadata:`, {
195
+ super(`The "${plugin}" plugin threw an error while creating metadata: ${error.message}`, {
196
196
  cause: error,
197
197
  });
198
198
  this.error = error;
@@ -203,7 +203,7 @@ class CreateMetadataError extends Error {
203
203
  exports.CreateMetadataError = CreateMetadataError;
204
204
  class ProcessDependenciesError extends Error {
205
205
  constructor(pluginName, { cause }) {
206
- super(`The "${pluginName}" plugin threw an error while creating dependencies:`, {
206
+ super(`The "${pluginName}" plugin threw an error while creating dependencies: ${cause.message}`, {
207
207
  cause,
208
208
  });
209
209
  this.pluginName = pluginName;
@@ -234,7 +234,7 @@ class ProcessProjectGraphError extends Error {
234
234
  });
235
235
  this.pluginName = pluginName;
236
236
  this.name = this.constructor.name;
237
- this.stack = `${this.message}\n ${cause.stack.split('\n').join('\n ')}`;
237
+ this.stack = `${this.message}\n${indentString(cause, 2)}`;
238
238
  }
239
239
  }
240
240
  exports.ProcessProjectGraphError = ProcessProjectGraphError;
@@ -289,3 +289,17 @@ class LoadPluginError extends Error {
289
289
  }
290
290
  }
291
291
  exports.LoadPluginError = LoadPluginError;
292
+ function indentString(str, indent) {
293
+ return (' '.repeat(indent) +
294
+ str
295
+ .split('\n')
296
+ .map((line) => ' '.repeat(indent) + line)
297
+ .join('\n'));
298
+ }
299
+ function formatErrorStackAndCause(error) {
300
+ const cause = error.cause && error.cause instanceof Error ? error.cause : null;
301
+ return (error.stack +
302
+ (cause
303
+ ? `\nCaused by: \n${indentString(cause.stack ?? cause.message, 2)}`
304
+ : ''));
305
+ }
@@ -8,7 +8,7 @@ class TaskHistoryLifeCycle {
8
8
  constructor() {
9
9
  this.startTimings = {};
10
10
  this.taskRuns = new Map();
11
- this.taskHistory = new task_history_1.TaskHistory();
11
+ this.taskHistory = (0, task_history_1.getTaskHistory)();
12
12
  }
13
13
  startTasks(tasks) {
14
14
  for (let task of tasks) {
@@ -17,7 +17,7 @@ const fileutils_1 = require("../utils/fileutils");
17
17
  const is_ci_1 = require("../utils/is-ci");
18
18
  const nx_cloud_utils_1 = require("../utils/nx-cloud-utils");
19
19
  const output_1 = require("../utils/output");
20
- const params_1 = require("../utils/params");
20
+ const handle_errors_1 = require("../utils/handle-errors");
21
21
  const sync_generators_1 = require("../utils/sync-generators");
22
22
  const workspace_root_1 = require("../utils/workspace-root");
23
23
  const create_task_graph_1 = require("./create-task-graph");
@@ -98,7 +98,7 @@ function createTaskGraphAndRunValidations(projectGraph, extraTargetDependencies,
98
98
  return taskGraph;
99
99
  }
100
100
  async function runCommand(projectsToRun, currentProjectGraph, { nxJson }, nxArgs, overrides, initiatingProject, extraTargetDependencies, extraOptions) {
101
- const status = await (0, params_1.handleErrors)(process.env.NX_VERBOSE_LOGGING === 'true', async () => {
101
+ const status = await (0, handle_errors_1.handleErrors)(process.env.NX_VERBOSE_LOGGING === 'true', async () => {
102
102
  const projectNames = projectsToRun.map((t) => t.name);
103
103
  const { projectGraph, taskGraph } = await ensureWorkspaceIsInSyncAndGetGraphs(currentProjectGraph, nxJson, projectNames, nxArgs, overrides, extraTargetDependencies, extraOptions);
104
104
  const tasks = Object.values(taskGraph.tasks);
@@ -41,7 +41,10 @@ class TaskOrchestrator {
41
41
  }
42
42
  async run() {
43
43
  // Init the ForkedProcessTaskRunner
44
- await this.forkedProcessTaskRunner.init();
44
+ await Promise.all([
45
+ this.forkedProcessTaskRunner.init(),
46
+ this.tasksSchedule.init(),
47
+ ]);
45
48
  // initial scheduling
46
49
  await this.scheduleNextTasks();
47
50
  perf_hooks_1.performance.mark('task-execution:start');
@@ -12,12 +12,15 @@ export declare class TasksSchedule {
12
12
  private notScheduledTaskGraph;
13
13
  private reverseTaskDeps;
14
14
  private reverseProjectGraph;
15
+ private taskHistory;
15
16
  private scheduledBatches;
16
17
  private scheduledTasks;
17
18
  private runningTasks;
18
19
  private completedTasks;
19
20
  private scheduleRequestsExecutionChain;
21
+ private estimatedTaskTimings;
20
22
  constructor(projectGraph: ProjectGraph, taskGraph: TaskGraph, options: DefaultTasksRunnerOptions);
23
+ init(): Promise<void>;
21
24
  scheduleNextTasks(): Promise<void>;
22
25
  hasTasks(): boolean;
23
26
  complete(taskIds: string[]): void;
@@ -4,6 +4,7 @@ exports.TasksSchedule = void 0;
4
4
  const utils_1 = require("./utils");
5
5
  const project_graph_utils_1 = require("../utils/project-graph-utils");
6
6
  const operators_1 = require("../project-graph/operators");
7
+ const task_history_1 = require("../utils/task-history");
7
8
  class TasksSchedule {
8
9
  constructor(projectGraph, taskGraph, options) {
9
10
  this.projectGraph = projectGraph;
@@ -12,12 +13,16 @@ class TasksSchedule {
12
13
  this.notScheduledTaskGraph = this.taskGraph;
13
14
  this.reverseTaskDeps = (0, utils_1.calculateReverseDeps)(this.taskGraph);
14
15
  this.reverseProjectGraph = (0, operators_1.reverse)(this.projectGraph);
16
+ this.taskHistory = (0, task_history_1.getTaskHistory)();
15
17
  this.scheduledBatches = [];
16
18
  this.scheduledTasks = [];
17
19
  this.runningTasks = new Set();
18
20
  this.completedTasks = new Set();
19
21
  this.scheduleRequestsExecutionChain = Promise.resolve();
20
22
  }
23
+ async init() {
24
+ this.estimatedTaskTimings = await this.taskHistory.getEstimatedTaskTimings(Object.values(this.taskGraph.tasks).map((t) => t.target));
25
+ }
21
26
  async scheduleNextTasks() {
22
27
  this.scheduleRequestsExecutionChain =
23
28
  this.scheduleRequestsExecutionChain.then(() => this.scheduleTasks());
@@ -81,10 +86,23 @@ class TasksSchedule {
81
86
  // Most likely tasks with no dependencies such as test
82
87
  const project1 = this.taskGraph.tasks[taskId1].target.project;
83
88
  const project2 = this.taskGraph.tasks[taskId2].target.project;
84
- return ((0, project_graph_utils_1.findAllProjectNodeDependencies)(project2, this.reverseProjectGraph)
85
- .length -
86
- (0, project_graph_utils_1.findAllProjectNodeDependencies)(project1, this.reverseProjectGraph)
87
- .length);
89
+ const project1NodeDependencies = (0, project_graph_utils_1.findAllProjectNodeDependencies)(project1, this.reverseProjectGraph).length;
90
+ const project2NodeDependencies = (0, project_graph_utils_1.findAllProjectNodeDependencies)(project2, this.reverseProjectGraph).length;
91
+ const dependenciesDiff = project2NodeDependencies - project1NodeDependencies;
92
+ if (dependenciesDiff !== 0) {
93
+ return dependenciesDiff;
94
+ }
95
+ const task1Timing = this.estimatedTaskTimings[taskId1];
96
+ if (!task1Timing) {
97
+ // if no timing or 0, put task1 at beginning
98
+ return -1;
99
+ }
100
+ const task2Timing = this.estimatedTaskTimings[taskId2];
101
+ if (!task2Timing) {
102
+ // if no timing or 0, put task2 at beginning
103
+ return 1;
104
+ }
105
+ return task2Timing - task1Timing;
88
106
  });
89
107
  this.runningTasks.add(taskId);
90
108
  }
@@ -0,0 +1 @@
1
+ export declare function handleErrors(isVerbose: boolean, fn: Function): Promise<number>;
@@ -0,0 +1,71 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.handleErrors = handleErrors;
4
+ const client_1 = require("../daemon/client/client");
5
+ const logger_1 = require("./logger");
6
+ const output_1 = require("./output");
7
+ async function handleErrors(isVerbose, fn) {
8
+ try {
9
+ const result = await fn();
10
+ if (typeof result === 'number') {
11
+ return result;
12
+ }
13
+ return 0;
14
+ }
15
+ catch (err) {
16
+ err ||= new Error('Unknown error caught');
17
+ if (err.constructor.name === 'UnsuccessfulWorkflowExecution') {
18
+ logger_1.logger.error('The generator workflow failed. See above.');
19
+ }
20
+ else if (err.name === 'ProjectGraphError') {
21
+ const projectGraphError = err;
22
+ let title = projectGraphError.message;
23
+ if (projectGraphError.cause &&
24
+ typeof projectGraphError.cause === 'object' &&
25
+ 'message' in projectGraphError.cause) {
26
+ title += ' ' + projectGraphError.cause.message + '.';
27
+ }
28
+ if (isVerbose) {
29
+ title += ' See errors below.';
30
+ }
31
+ const bodyLines = isVerbose
32
+ ? formatErrorStackAndCause(projectGraphError)
33
+ : ['Pass --verbose to see the stacktraces.'];
34
+ output_1.output.error({
35
+ title,
36
+ bodyLines: bodyLines,
37
+ });
38
+ }
39
+ else {
40
+ const lines = (err.message ? err.message : err.toString()).split('\n');
41
+ const bodyLines = lines.slice(1);
42
+ if (isVerbose) {
43
+ bodyLines.push(...formatErrorStackAndCause(err));
44
+ }
45
+ else if (err.stack) {
46
+ bodyLines.push('Pass --verbose to see the stacktrace.');
47
+ }
48
+ output_1.output.error({
49
+ title: lines[0],
50
+ bodyLines,
51
+ });
52
+ }
53
+ if (client_1.daemonClient.enabled()) {
54
+ client_1.daemonClient.reset();
55
+ }
56
+ return 1;
57
+ }
58
+ }
59
+ function formatErrorStackAndCause(error) {
60
+ return [
61
+ error.stack || error.message,
62
+ ...(error.cause && typeof error.cause === 'object'
63
+ ? [
64
+ 'Caused by:',
65
+ 'stack' in error.cause
66
+ ? error.cause.stack.toString()
67
+ : error.cause.toString(),
68
+ ]
69
+ : []),
70
+ ];
71
+ }
@@ -1,4 +1,3 @@
1
1
  import { NxJsonConfiguration } from '../config/nx-json';
2
2
  export declare function isNxCloudUsed(nxJson: NxJsonConfiguration): boolean;
3
3
  export declare function getNxCloudUrl(nxJson: NxJsonConfiguration): string;
4
- export declare function getNxCloudToken(nxJson: NxJsonConfiguration): string;
@@ -2,7 +2,6 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.isNxCloudUsed = isNxCloudUsed;
4
4
  exports.getNxCloudUrl = getNxCloudUrl;
5
- exports.getNxCloudToken = getNxCloudToken;
6
5
  function isNxCloudUsed(nxJson) {
7
6
  return (!!process.env.NX_CLOUD_ACCESS_TOKEN ||
8
7
  !!nxJson.nxCloudAccessToken ||
@@ -17,12 +16,3 @@ function getNxCloudUrl(nxJson) {
17
16
  throw new Error('nx-cloud runner not found in nx.json');
18
17
  return cloudRunner?.options?.url ?? nxJson.nxCloudUrl ?? 'https://nx.app';
19
18
  }
20
- function getNxCloudToken(nxJson) {
21
- const cloudRunner = Object.values(nxJson.tasksRunnerOptions ?? {}).find((r) => r.runner == '@nrwl/nx-cloud' || r.runner == 'nx-cloud');
22
- if (!cloudRunner &&
23
- !(nxJson.nxCloudAccessToken || process.env.NX_CLOUD_ACCESS_TOKEN))
24
- throw new Error('nx-cloud runner not found in nx.json');
25
- return (process.env.NX_CLOUD_ACCESS_TOKEN ??
26
- cloudRunner?.options.accessToken ??
27
- nxJson.nxCloudAccessToken);
28
- }
@@ -79,7 +79,6 @@ export type Options = {
79
79
  '--'?: Unmatched[];
80
80
  [k: string]: string | number | boolean | string[] | Unmatched[] | undefined;
81
81
  };
82
- export declare function handleErrors(isVerbose: boolean, fn: Function): Promise<number>;
83
82
  export declare function convertToCamelCase(parsed: {
84
83
  [k: string]: any;
85
84
  }, schema: Schema): Options;
@@ -1,7 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SchemaError = void 0;
4
- exports.handleErrors = handleErrors;
5
4
  exports.convertToCamelCase = convertToCamelCase;
6
5
  exports.coerceTypesInOptions = coerceTypesInOptions;
7
6
  exports.convertAliases = convertAliases;
@@ -15,55 +14,6 @@ exports.warnDeprecations = warnDeprecations;
15
14
  exports.convertSmartDefaultsIntoNamedParams = convertSmartDefaultsIntoNamedParams;
16
15
  exports.getPromptsForSchema = getPromptsForSchema;
17
16
  const logger_1 = require("./logger");
18
- const output_1 = require("./output");
19
- const client_1 = require("../daemon/client/client");
20
- async function handleErrors(isVerbose, fn) {
21
- try {
22
- const result = await fn();
23
- if (typeof result === 'number') {
24
- return result;
25
- }
26
- return 0;
27
- }
28
- catch (err) {
29
- err ||= new Error('Unknown error caught');
30
- if (err.constructor.name === 'UnsuccessfulWorkflowExecution') {
31
- logger_1.logger.error('The generator workflow failed. See above.');
32
- }
33
- else if (err.name === 'ProjectGraphError') {
34
- const projectGraphError = err;
35
- let title = projectGraphError.message;
36
- if (isVerbose) {
37
- title += ' See errors below.';
38
- }
39
- const bodyLines = isVerbose
40
- ? [projectGraphError.stack]
41
- : ['Pass --verbose to see the stacktraces.'];
42
- output_1.output.error({
43
- title,
44
- bodyLines: bodyLines,
45
- });
46
- }
47
- else {
48
- const lines = (err.message ? err.message : err.toString()).split('\n');
49
- const bodyLines = lines.slice(1);
50
- if (err.stack && !isVerbose) {
51
- bodyLines.push('Pass --verbose to see the stacktrace.');
52
- }
53
- output_1.output.error({
54
- title: lines[0],
55
- bodyLines,
56
- });
57
- if (err.stack && isVerbose) {
58
- logger_1.logger.info(err.stack);
59
- }
60
- }
61
- if (client_1.daemonClient.enabled()) {
62
- client_1.daemonClient.reset();
63
- }
64
- return 1;
65
- }
66
- }
67
17
  function camelCase(input) {
68
18
  if (input.indexOf('-') > 1) {
69
19
  return input
@@ -41,10 +41,13 @@ async function getPluginCapabilities(workspaceRoot, pluginName, projects, includ
41
41
  projectGraphExtension: pluginModule &&
42
42
  ('processProjectGraph' in pluginModule ||
43
43
  'createNodes' in pluginModule ||
44
+ 'createNodesV2' in pluginModule ||
45
+ 'createMetadata' in pluginModule ||
44
46
  'createDependencies' in pluginModule),
45
47
  projectInference: pluginModule &&
46
48
  ('projectFilePatterns' in pluginModule ||
47
- 'createNodes' in pluginModule),
49
+ 'createNodes' in pluginModule ||
50
+ 'createNodesV2' in pluginModule),
48
51
  };
49
52
  }
50
53
  catch {
@@ -1,6 +1,17 @@
1
- import { NxTaskHistory, TaskRun } from '../native';
1
+ import { NxTaskHistory, TaskRun, TaskTarget } from '../native';
2
2
  export declare class TaskHistory {
3
3
  taskHistory: NxTaskHistory;
4
+ /**
5
+ * This function returns estimated timings per task
6
+ * @param targets
7
+ * @returns a map where key is task id (project:target:configuration), value is average time of historical runs
8
+ */
9
+ getEstimatedTaskTimings(targets: TaskTarget[]): Promise<Record<string, number>>;
4
10
  getFlakyTasks(hashes: string[]): Promise<string[]>;
5
11
  recordTaskRuns(taskRuns: TaskRun[]): Promise<void>;
6
12
  }
13
+ /**
14
+ * This function returns the singleton instance of TaskHistory
15
+ * @returns singleton instance of TaskHistory
16
+ */
17
+ export declare function getTaskHistory(): TaskHistory;