nx 19.6.0-beta.0 → 19.6.0-beta.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (84) hide show
  1. package/bin/post-install.js +8 -0
  2. package/package.json +12 -12
  3. package/release/changelog-renderer/index.js +16 -1
  4. package/schemas/nx-schema.json +25 -0
  5. package/schemas/project-schema.json +7 -0
  6. package/src/adapter/compat.d.ts +1 -1
  7. package/src/adapter/compat.js +1 -0
  8. package/src/command-line/init/init-v2.js +1 -1
  9. package/src/command-line/nx-commands.js +3 -0
  10. package/src/command-line/release/changelog.js +80 -42
  11. package/src/command-line/release/config/version-plans.d.ts +5 -0
  12. package/src/command-line/release/config/version-plans.js +9 -5
  13. package/src/command-line/release/plan.js +25 -45
  14. package/src/command-line/release/utils/generate-version-plan-content.js +2 -3
  15. package/src/command-line/release/version.d.ts +5 -0
  16. package/src/command-line/sync/command-object.d.ts +6 -0
  17. package/src/command-line/sync/command-object.js +25 -0
  18. package/src/command-line/sync/sync.d.ts +6 -0
  19. package/src/command-line/sync/sync.js +30 -0
  20. package/src/config/nx-json.d.ts +23 -0
  21. package/src/config/workspace-json-project-json.d.ts +5 -0
  22. package/src/core/graph/main.js +1 -1
  23. package/src/core/graph/styles.css +1 -1
  24. package/src/daemon/cache.d.ts +1 -0
  25. package/src/daemon/cache.js +25 -18
  26. package/src/daemon/client/client.d.ts +5 -0
  27. package/src/daemon/client/client.js +42 -1
  28. package/src/daemon/message-types/flush-sync-generator-changes-to-disk.d.ts +6 -0
  29. package/src/daemon/message-types/flush-sync-generator-changes-to-disk.js +11 -0
  30. package/src/daemon/message-types/force-shutdown.d.ts +5 -0
  31. package/src/daemon/message-types/force-shutdown.js +11 -0
  32. package/src/daemon/message-types/get-registered-sync-generators.d.ts +5 -0
  33. package/src/daemon/message-types/get-registered-sync-generators.js +11 -0
  34. package/src/daemon/message-types/get-sync-generator-changes.d.ts +6 -0
  35. package/src/daemon/message-types/get-sync-generator-changes.js +11 -0
  36. package/src/daemon/message-types/update-workspace-context.d.ts +8 -0
  37. package/src/daemon/message-types/update-workspace-context.js +11 -0
  38. package/src/daemon/server/handle-flush-sync-generator-changes-to-disk.d.ts +2 -0
  39. package/src/daemon/server/handle-flush-sync-generator-changes-to-disk.js +11 -0
  40. package/src/daemon/server/handle-force-shutdown.d.ts +5 -0
  41. package/src/daemon/server/handle-force-shutdown.js +18 -0
  42. package/src/daemon/server/handle-get-registered-sync-generators.d.ts +2 -0
  43. package/src/daemon/server/handle-get-registered-sync-generators.js +11 -0
  44. package/src/daemon/server/handle-get-sync-generator-changes.d.ts +2 -0
  45. package/src/daemon/server/handle-get-sync-generator-changes.js +17 -0
  46. package/src/daemon/server/handle-request-shutdown.js +2 -0
  47. package/src/daemon/server/handle-update-workspace-context.d.ts +2 -0
  48. package/src/daemon/server/handle-update-workspace-context.js +11 -0
  49. package/src/daemon/server/project-graph-incremental-recomputation.d.ts +1 -0
  50. package/src/daemon/server/project-graph-incremental-recomputation.js +19 -2
  51. package/src/daemon/server/server.d.ts +1 -0
  52. package/src/daemon/server/server.js +39 -0
  53. package/src/daemon/server/shutdown-utils.d.ts +2 -1
  54. package/src/daemon/server/shutdown-utils.js +11 -4
  55. package/src/daemon/server/sync-generators.d.ts +6 -0
  56. package/src/daemon/server/sync-generators.js +202 -0
  57. package/src/daemon/server/watcher.js +3 -0
  58. package/src/daemon/socket-utils.js +18 -5
  59. package/src/daemon/tmp-dir.js +2 -1
  60. package/src/native/nx.wasm32-wasi.wasm +0 -0
  61. package/src/nx-cloud/generators/connect-to-nx-cloud/connect-to-nx-cloud.js +1 -1
  62. package/src/nx-cloud/models/onboarding-status.d.ts +1 -0
  63. package/src/nx-cloud/models/onboarding-status.js +2 -0
  64. package/src/nx-cloud/utilities/is-workspace-claimed.d.ts +1 -0
  65. package/src/nx-cloud/utilities/is-workspace-claimed.js +24 -0
  66. package/src/nx-cloud/utilities/onboarding.d.ts +5 -0
  67. package/src/nx-cloud/utilities/onboarding.js +28 -0
  68. package/src/plugins/js/project-graph/build-dependencies/target-project-locator.js +7 -2
  69. package/src/project-graph/plugins/internal-api.js +16 -5
  70. package/src/project-graph/plugins/isolation/messaging.d.ts +5 -1
  71. package/src/project-graph/plugins/isolation/messaging.js +1 -0
  72. package/src/project-graph/plugins/isolation/plugin-pool.js +4 -6
  73. package/src/project-graph/plugins/isolation/plugin-worker.js +15 -0
  74. package/src/project-graph/utils/project-configuration-utils.js +5 -2
  75. package/src/tasks-runner/run-command.d.ts +1 -1
  76. package/src/tasks-runner/run-command.js +120 -2
  77. package/src/utils/package-manager.js +12 -3
  78. package/src/utils/plugins/output.js +1 -1
  79. package/src/utils/sync-generators.d.ts +22 -0
  80. package/src/utils/sync-generators.js +161 -0
  81. package/src/utils/workspace-context.d.ts +1 -0
  82. package/src/utils/workspace-context.js +16 -0
  83. package/src/daemon/message-types/update-context-files.d.ts +0 -7
  84. package/src/daemon/message-types/update-context-files.js +0 -11
@@ -446,7 +446,7 @@ function normalizeTargets(project, sourceMaps, nxJsonConfiguration) {
446
446
  project.targets[targetName] = normalizeTarget(project.targets[targetName], project);
447
447
  const projectSourceMaps = sourceMaps[project.root];
448
448
  const targetConfig = project.targets[targetName];
449
- const targetDefaults = readTargetDefaultsForTarget(targetName, nxJsonConfiguration.targetDefaults, targetConfig.executor);
449
+ const targetDefaults = deepClone(readTargetDefaultsForTarget(targetName, nxJsonConfiguration.targetDefaults, targetConfig.executor));
450
450
  // We only apply defaults if they exist
451
451
  if (targetDefaults && isCompatibleTarget(targetConfig, targetDefaults)) {
452
452
  project.targets[targetName] = mergeTargetDefaultWithTargetDefinition(targetName, project, normalizeTarget(targetDefaults, project), projectSourceMaps);
@@ -499,9 +499,12 @@ function targetDefaultShouldBeApplied(key, sourceMap) {
499
499
  const [, plugin] = sourceInfo;
500
500
  return !plugin?.startsWith('nx/');
501
501
  }
502
+ function deepClone(obj) {
503
+ return JSON.parse(JSON.stringify(obj));
504
+ }
502
505
  function mergeTargetDefaultWithTargetDefinition(targetName, project, targetDefault, sourceMap) {
503
506
  const targetDefinition = project.targets[targetName] ?? {};
504
- const result = JSON.parse(JSON.stringify(targetDefinition));
507
+ const result = deepClone(targetDefinition);
505
508
  for (const key in targetDefault) {
506
509
  switch (key) {
507
510
  case 'options': {
@@ -5,7 +5,7 @@ import { TargetDependencyConfig } from '../config/workspace-json-project-json';
5
5
  import { NxArgs } from '../utils/command-line-utils';
6
6
  import { LifeCycle } from './life-cycle';
7
7
  import { TasksRunner } from './tasks-runner';
8
- export declare function runCommand(projectsToRun: ProjectGraphProjectNode[], projectGraph: ProjectGraph, { nxJson }: {
8
+ export declare function runCommand(projectsToRun: ProjectGraphProjectNode[], currentProjectGraph: ProjectGraph, { nxJson }: {
9
9
  nxJson: NxJsonConfiguration;
10
10
  }, nxArgs: NxArgs, overrides: any, initiatingProject: string | null, extraTargetDependencies: Record<string, (TargetDependencyConfig | string)[]>, extraOptions: {
11
11
  excludeTaskDependencies: boolean;
@@ -4,16 +4,20 @@ exports.runCommand = runCommand;
4
4
  exports.invokeTasksRunner = invokeTasksRunner;
5
5
  exports.getRunner = getRunner;
6
6
  exports.getRunnerOptions = getRunnerOptions;
7
+ const enquirer_1 = require("enquirer");
8
+ const ora = require("ora");
7
9
  const path_1 = require("path");
8
10
  const nx_json_1 = require("../config/nx-json");
9
11
  const client_1 = require("../daemon/client/client");
10
12
  const create_task_hasher_1 = require("../hasher/create-task-hasher");
11
13
  const hash_task_1 = require("../hasher/hash-task");
14
+ const project_graph_1 = require("../project-graph/project-graph");
12
15
  const fileutils_1 = require("../utils/fileutils");
13
16
  const is_ci_1 = require("../utils/is-ci");
14
17
  const nx_cloud_utils_1 = require("../utils/nx-cloud-utils");
15
18
  const output_1 = require("../utils/output");
16
19
  const params_1 = require("../utils/params");
20
+ const sync_generators_1 = require("../utils/sync-generators");
17
21
  const workspace_root_1 = require("../utils/workspace-root");
18
22
  const create_task_graph_1 = require("./create-task-graph");
19
23
  const life_cycle_1 = require("./life-cycle");
@@ -27,6 +31,7 @@ const task_profiling_life_cycle_1 = require("./life-cycles/task-profiling-life-c
27
31
  const task_timings_life_cycle_1 = require("./life-cycles/task-timings-life-cycle");
28
32
  const task_graph_utils_1 = require("./task-graph-utils");
29
33
  const utils_1 = require("./utils");
34
+ const chalk = require("chalk");
30
35
  async function getTerminalOutputLifeCycle(initiatingProject, projectNames, tasks, nxArgs, nxJson, overrides) {
31
36
  const { runnerOptions } = getRunner(nxArgs, nxJson);
32
37
  const isRunOne = initiatingProject != null;
@@ -90,10 +95,10 @@ function createTaskGraphAndRunValidations(projectGraph, extraTargetDependencies,
90
95
  }
91
96
  return taskGraph;
92
97
  }
93
- async function runCommand(projectsToRun, projectGraph, { nxJson }, nxArgs, overrides, initiatingProject, extraTargetDependencies, extraOptions) {
98
+ async function runCommand(projectsToRun, currentProjectGraph, { nxJson }, nxArgs, overrides, initiatingProject, extraTargetDependencies, extraOptions) {
94
99
  const status = await (0, params_1.handleErrors)(process.env.NX_VERBOSE_LOGGING === 'true', async () => {
95
100
  const projectNames = projectsToRun.map((t) => t.name);
96
- const taskGraph = createTaskGraphAndRunValidations(projectGraph, extraTargetDependencies ?? {}, projectNames, nxArgs, overrides, extraOptions);
101
+ const { projectGraph, taskGraph } = await ensureWorkspaceIsInSyncAndGetGraphs(currentProjectGraph, nxJson, projectNames, nxArgs, overrides, extraTargetDependencies, extraOptions);
97
102
  const tasks = Object.values(taskGraph.tasks);
98
103
  const { lifeCycle, renderIsDone } = await getTerminalOutputLifeCycle(initiatingProject, projectNames, tasks, nxArgs, nxJson, overrides);
99
104
  const status = await invokeTasksRunner({
@@ -111,6 +116,119 @@ async function runCommand(projectsToRun, projectGraph, { nxJson }, nxArgs, overr
111
116
  });
112
117
  return status;
113
118
  }
119
+ async function ensureWorkspaceIsInSyncAndGetGraphs(projectGraph, nxJson, projectNames, nxArgs, overrides, extraTargetDependencies, extraOptions) {
120
+ let taskGraph = createTaskGraphAndRunValidations(projectGraph, extraTargetDependencies ?? {}, projectNames, nxArgs, overrides, extraOptions);
121
+ if (process.env.NX_ENABLE_SYNC_GENERATORS !== 'true') {
122
+ return { projectGraph, taskGraph };
123
+ }
124
+ // collect unique syncGenerators from the tasks
125
+ const uniqueSyncGenerators = new Set();
126
+ for (const { target } of Object.values(taskGraph.tasks)) {
127
+ const { syncGenerators } = projectGraph.nodes[target.project].data.targets[target.target];
128
+ if (!syncGenerators) {
129
+ continue;
130
+ }
131
+ for (const generator of syncGenerators) {
132
+ uniqueSyncGenerators.add(generator);
133
+ }
134
+ }
135
+ if (!uniqueSyncGenerators.size) {
136
+ // There are no sync generators registered in the tasks to run
137
+ return { projectGraph, taskGraph };
138
+ }
139
+ const syncGenerators = Array.from(uniqueSyncGenerators);
140
+ const results = await (0, sync_generators_1.getSyncGeneratorChanges)(syncGenerators);
141
+ if (!results.length) {
142
+ // There are no changes to sync, workspace is up to date
143
+ return { projectGraph, taskGraph };
144
+ }
145
+ const outOfSyncTitle = 'The workspace is out of sync';
146
+ const resultBodyLines = (0, sync_generators_1.syncGeneratorResultsToMessageLines)(results);
147
+ const fixMessage = 'You can manually run `nx sync` to update your workspace or you can set `sync.applyChanges` to `true` in your `nx.json` to apply the changes automatically when running tasks.';
148
+ const willErrorOnCiMessage = 'Please note that this will be an error on CI.';
149
+ if ((0, is_ci_1.isCI)() || !process.stdout.isTTY) {
150
+ // If the user is running in CI or is running in a non-TTY environment we
151
+ // throw an error to stop the execution of the tasks.
152
+ throw new Error(`${outOfSyncTitle}\n${resultBodyLines.join('\n')}\n${fixMessage}`);
153
+ }
154
+ if (nxJson.sync?.applyChanges === false) {
155
+ // If the user has set `sync.applyChanges` to `false` in their `nx.json`
156
+ // we don't prompt the them and just log a warning informing them that
157
+ // the workspace is out of sync and they have it set to not apply changes
158
+ // automatically.
159
+ output_1.output.warn({
160
+ title: outOfSyncTitle,
161
+ bodyLines: [
162
+ ...resultBodyLines,
163
+ 'Your workspace is set to not apply changes automatically (`sync.applyChanges` is set to `false` in your `nx.json`).',
164
+ willErrorOnCiMessage,
165
+ fixMessage,
166
+ ],
167
+ });
168
+ return { projectGraph, taskGraph };
169
+ }
170
+ output_1.output.warn({
171
+ title: outOfSyncTitle,
172
+ bodyLines: [
173
+ ...resultBodyLines,
174
+ nxJson.sync?.applyChanges === true
175
+ ? 'Proceeding to sync the changes automatically (`sync.applyChanges` is set to `true` in your `nx.json`).'
176
+ : willErrorOnCiMessage,
177
+ ],
178
+ });
179
+ const applyChanges = nxJson.sync?.applyChanges === true ||
180
+ (await promptForApplyingSyncGeneratorChanges());
181
+ if (applyChanges) {
182
+ const spinner = ora('Syncing the workspace...');
183
+ spinner.start();
184
+ // Flush sync generator changes to disk
185
+ await (0, sync_generators_1.flushSyncGeneratorChanges)(results);
186
+ // Re-create project graph and task graph
187
+ projectGraph = await (0, project_graph_1.createProjectGraphAsync)();
188
+ taskGraph = createTaskGraphAndRunValidations(projectGraph, extraTargetDependencies ?? {}, projectNames, nxArgs, overrides, extraOptions);
189
+ if (nxJson.sync?.applyChanges === true) {
190
+ spinner.succeed(`The workspace was synced successfully!
191
+
192
+ Please make sure to commit the changes to your repository or this will error on CI.`);
193
+ }
194
+ else {
195
+ // The user was prompted and we already logged a message about erroring on CI
196
+ // so here we just tell them to commit the changes.
197
+ spinner.succeed(`The workspace was synced successfully!
198
+
199
+ Please make sure to commit the changes to your repository.`);
200
+ }
201
+ }
202
+ else {
203
+ output_1.output.warn({
204
+ title: 'Syncing the workspace was skipped',
205
+ bodyLines: [
206
+ 'This could lead to unexpected results or errors when running tasks.',
207
+ fixMessage,
208
+ ],
209
+ });
210
+ }
211
+ return { projectGraph, taskGraph };
212
+ }
213
+ async function promptForApplyingSyncGeneratorChanges() {
214
+ const promptConfig = {
215
+ name: 'applyChanges',
216
+ type: 'select',
217
+ message: 'Would you like to sync the changes to get your worskpace up to date?',
218
+ choices: [
219
+ {
220
+ name: 'yes',
221
+ message: 'Yes, sync the changes and run the tasks',
222
+ },
223
+ {
224
+ name: 'no',
225
+ message: 'No, run the tasks without syncing the changes',
226
+ },
227
+ ],
228
+ footer: () => chalk.dim('\nYou can skip this prompt by setting the `sync.applyChanges` option in your `nx.json`.'),
229
+ };
230
+ return await (0, enquirer_1.prompt)([promptConfig]).then(({ applyChanges }) => applyChanges === 'yes');
231
+ }
114
232
  function setEnvVarsBasedOnArgs(nxArgs, loadDotEnvFiles) {
115
233
  if (nxArgs.outputStyle == 'stream' ||
116
234
  process.env.NX_BATCH_MODE === 'true' ||
@@ -176,6 +176,7 @@ function getPackageManagerVersion(packageManager = detectPackageManager(), cwd =
176
176
  version = (0, child_process_1.execSync)(`${packageManager} --version`, {
177
177
  cwd,
178
178
  encoding: 'utf-8',
179
+ windowsHide: true,
179
180
  }).trim();
180
181
  }
181
182
  catch {
@@ -349,7 +350,10 @@ async function resolvePackageVersionUsingInstallation(packageName, version) {
349
350
  const { dir, cleanup } = createTempNpmDirectory();
350
351
  try {
351
352
  const pmc = getPackageManagerCommand();
352
- await execAsync(`${pmc.add} ${packageName}@${version}`, { cwd: dir });
353
+ await execAsync(`${pmc.add} ${packageName}@${version}`, {
354
+ cwd: dir,
355
+ windowsHide: true,
356
+ });
353
357
  const { packageJson } = (0, package_json_1.readModulePackageJson)(packageName, [dir]);
354
358
  return packageJson.version;
355
359
  }
@@ -372,7 +376,9 @@ async function packageRegistryView(pkg, version, args) {
372
376
  */
373
377
  pm = 'npm';
374
378
  }
375
- const { stdout } = await execAsync(`${pm} view ${pkg}@${version} ${args}`);
379
+ const { stdout } = await execAsync(`${pm} view ${pkg}@${version} ${args}`, {
380
+ windowsHide: true,
381
+ });
376
382
  return stdout.toString().trim();
377
383
  }
378
384
  async function packageRegistryPack(cwd, pkg, version) {
@@ -389,7 +395,10 @@ async function packageRegistryPack(cwd, pkg, version) {
389
395
  */
390
396
  pm = 'npm';
391
397
  }
392
- const { stdout } = await execAsync(`${pm} pack ${pkg}@${version}`, { cwd });
398
+ const { stdout } = await execAsync(`${pm} pack ${pkg}@${version}`, {
399
+ cwd,
400
+ windowsHide: true,
401
+ });
393
402
  const tarballPath = stdout.trim();
394
403
  return { tarballPath };
395
404
  }
@@ -27,7 +27,7 @@ function listPlugins(plugins, title) {
27
27
  if (p.projectInference) {
28
28
  capabilities.push('project-inference');
29
29
  }
30
- bodyLines.push(`${chalk.bold(p.name)} (${capabilities.join()})`);
30
+ bodyLines.push(`${chalk.bold(p.name)} ${capabilities.length >= 1 ? `(${capabilities.join()})` : ''}`);
31
31
  }
32
32
  output_1.output.log({
33
33
  title: title,
@@ -0,0 +1,22 @@
1
+ import type { GeneratorCallback } from '../config/misc-interfaces';
2
+ import type { ProjectGraph } from '../config/project-graph';
3
+ import type { ProjectConfiguration } from '../config/workspace-json-project-json';
4
+ import { FsTree, type FileChange, type Tree } from '../generators/tree';
5
+ export type SyncGeneratorResult = void | {
6
+ callback?: GeneratorCallback;
7
+ outOfSyncMessage?: string;
8
+ };
9
+ export type SyncGenerator = (tree: Tree) => SyncGeneratorResult | Promise<SyncGeneratorResult>;
10
+ export type SyncGeneratorChangesResult = {
11
+ changes: FileChange[];
12
+ generatorName: string;
13
+ callback?: GeneratorCallback;
14
+ outOfSyncMessage?: string;
15
+ };
16
+ export declare function getSyncGeneratorChanges(generators: string[]): Promise<SyncGeneratorChangesResult[]>;
17
+ export declare function flushSyncGeneratorChanges(results: SyncGeneratorChangesResult[]): Promise<void>;
18
+ export declare function collectAllRegisteredSyncGenerators(projectGraph: ProjectGraph): Promise<string[]>;
19
+ export declare function runSyncGenerator(tree: FsTree, generatorSpecifier: string, projects: Record<string, ProjectConfiguration>): Promise<SyncGeneratorChangesResult>;
20
+ export declare function collectRegisteredTaskSyncGenerators(projectGraph: ProjectGraph): Set<string>;
21
+ export declare function collectRegisteredGlobalSyncGenerators(nxJson?: import("../config/nx-json").NxJsonConfiguration<string[] | "*">): Set<string>;
22
+ export declare function syncGeneratorResultsToMessageLines(results: SyncGeneratorChangesResult[]): string[];
@@ -0,0 +1,161 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getSyncGeneratorChanges = getSyncGeneratorChanges;
4
+ exports.flushSyncGeneratorChanges = flushSyncGeneratorChanges;
5
+ exports.collectAllRegisteredSyncGenerators = collectAllRegisteredSyncGenerators;
6
+ exports.runSyncGenerator = runSyncGenerator;
7
+ exports.collectRegisteredTaskSyncGenerators = collectRegisteredTaskSyncGenerators;
8
+ exports.collectRegisteredGlobalSyncGenerators = collectRegisteredGlobalSyncGenerators;
9
+ exports.syncGeneratorResultsToMessageLines = syncGeneratorResultsToMessageLines;
10
+ const perf_hooks_1 = require("perf_hooks");
11
+ const generate_1 = require("../command-line/generate/generate");
12
+ const generator_utils_1 = require("../command-line/generate/generator-utils");
13
+ const nx_json_1 = require("../config/nx-json");
14
+ const client_1 = require("../daemon/client/client");
15
+ const is_on_daemon_1 = require("../daemon/is-on-daemon");
16
+ const tree_1 = require("../generators/tree");
17
+ const project_graph_1 = require("../project-graph/project-graph");
18
+ const workspace_context_1 = require("./workspace-context");
19
+ const workspace_root_1 = require("./workspace-root");
20
+ const chalk = require("chalk");
21
+ async function getSyncGeneratorChanges(generators) {
22
+ perf_hooks_1.performance.mark('get-sync-generators-changes:start');
23
+ let results;
24
+ if (!client_1.daemonClient.enabled()) {
25
+ results = await runSyncGenerators(generators);
26
+ }
27
+ else {
28
+ results = await client_1.daemonClient.getSyncGeneratorChanges(generators);
29
+ }
30
+ perf_hooks_1.performance.mark('get-sync-generators-changes:end');
31
+ perf_hooks_1.performance.measure('get-sync-generators-changes', 'get-sync-generators-changes:start', 'get-sync-generators-changes:end');
32
+ return results.filter((r) => r.changes.length > 0);
33
+ }
34
+ async function flushSyncGeneratorChanges(results) {
35
+ if ((0, is_on_daemon_1.isOnDaemon)() || !client_1.daemonClient.enabled()) {
36
+ await flushSyncGeneratorChangesToDisk(results);
37
+ }
38
+ else {
39
+ await client_1.daemonClient.flushSyncGeneratorChangesToDisk(results.map((r) => r.generatorName));
40
+ }
41
+ }
42
+ async function collectAllRegisteredSyncGenerators(projectGraph) {
43
+ if (!client_1.daemonClient.enabled()) {
44
+ return [
45
+ ...collectRegisteredTaskSyncGenerators(projectGraph),
46
+ ...collectRegisteredGlobalSyncGenerators(),
47
+ ];
48
+ }
49
+ return await client_1.daemonClient.getRegisteredSyncGenerators();
50
+ }
51
+ async function runSyncGenerator(tree, generatorSpecifier, projects) {
52
+ perf_hooks_1.performance.mark(`run-sync-generator:${generatorSpecifier}:start`);
53
+ const { collection, generator } = (0, generate_1.parseGeneratorString)(generatorSpecifier);
54
+ const { implementationFactory } = (0, generator_utils_1.getGeneratorInformation)(collection, generator, workspace_root_1.workspaceRoot, projects);
55
+ const implementation = implementationFactory();
56
+ const result = await implementation(tree);
57
+ let callback;
58
+ let outOfSyncMessage;
59
+ if (result && typeof result === 'object') {
60
+ callback = result.callback;
61
+ outOfSyncMessage = result.outOfSyncMessage;
62
+ }
63
+ perf_hooks_1.performance.mark(`run-sync-generator:${generatorSpecifier}:end`);
64
+ perf_hooks_1.performance.measure(`run-sync-generator:${generatorSpecifier}`, `run-sync-generator:${generatorSpecifier}:start`, `run-sync-generator:${generatorSpecifier}:end`);
65
+ return {
66
+ changes: tree.listChanges(),
67
+ generatorName: generatorSpecifier,
68
+ callback,
69
+ outOfSyncMessage,
70
+ };
71
+ }
72
+ function collectRegisteredTaskSyncGenerators(projectGraph) {
73
+ const taskSyncGenerators = new Set();
74
+ for (const { data: { targets }, } of Object.values(projectGraph.nodes)) {
75
+ if (!targets) {
76
+ continue;
77
+ }
78
+ for (const target of Object.values(targets)) {
79
+ if (!target.syncGenerators) {
80
+ continue;
81
+ }
82
+ for (const generator of target.syncGenerators) {
83
+ taskSyncGenerators.add(generator);
84
+ }
85
+ }
86
+ }
87
+ return taskSyncGenerators;
88
+ }
89
+ function collectRegisteredGlobalSyncGenerators(nxJson = (0, nx_json_1.readNxJson)()) {
90
+ const globalSyncGenerators = new Set();
91
+ if (!nxJson.sync?.globalGenerators?.length) {
92
+ return globalSyncGenerators;
93
+ }
94
+ for (const generator of nxJson.sync.globalGenerators) {
95
+ globalSyncGenerators.add(generator);
96
+ }
97
+ return globalSyncGenerators;
98
+ }
99
+ function syncGeneratorResultsToMessageLines(results) {
100
+ const messageLines = [];
101
+ for (const result of results) {
102
+ messageLines.push(`The ${chalk.bold(result.generatorName)} sync generator identified ${chalk.bold(result.changes.length)} file${result.changes.length === 1 ? '' : 's'} in the workspace that ${result.changes.length === 1 ? 'is' : 'are'} out of sync${result.outOfSyncMessage ? ':' : '.'}`);
103
+ if (result.outOfSyncMessage) {
104
+ messageLines.push(result.outOfSyncMessage);
105
+ }
106
+ messageLines.push('');
107
+ }
108
+ return messageLines;
109
+ }
110
+ async function runSyncGenerators(generators) {
111
+ const tree = new tree_1.FsTree(workspace_root_1.workspaceRoot, false, 'running sync generators');
112
+ const projectGraph = await (0, project_graph_1.createProjectGraphAsync)();
113
+ const { projects } = (0, project_graph_1.readProjectsConfigurationFromProjectGraph)(projectGraph);
114
+ const results = [];
115
+ for (const generator of generators) {
116
+ const result = await runSyncGenerator(tree, generator, projects);
117
+ results.push(result);
118
+ }
119
+ return results;
120
+ }
121
+ async function flushSyncGeneratorChangesToDisk(results) {
122
+ perf_hooks_1.performance.mark('flush-sync-generator-changes-to-disk:start');
123
+ const { changes, createdFiles, updatedFiles, deletedFiles, callbacks } = processSyncGeneratorResults(results);
124
+ // Write changes to disk
125
+ (0, tree_1.flushChanges)(workspace_root_1.workspaceRoot, changes);
126
+ // Run the callbacks
127
+ if (callbacks.length) {
128
+ for (const callback of callbacks) {
129
+ await callback();
130
+ }
131
+ }
132
+ // Update the context files
133
+ await (0, workspace_context_1.updateContextWithChangedFiles)(createdFiles, updatedFiles, deletedFiles);
134
+ perf_hooks_1.performance.mark('flush-sync-generator-changes-to-disk:end');
135
+ perf_hooks_1.performance.measure('flush sync generator changes to disk', 'flush-sync-generator-changes-to-disk:start', 'flush-sync-generator-changes-to-disk:end');
136
+ }
137
+ function processSyncGeneratorResults(results) {
138
+ const changes = [];
139
+ const createdFiles = [];
140
+ const updatedFiles = [];
141
+ const deletedFiles = [];
142
+ const callbacks = [];
143
+ for (const result of results) {
144
+ if (result.callback) {
145
+ callbacks.push(result.callback);
146
+ }
147
+ for (const change of result.changes) {
148
+ changes.push(change);
149
+ if (change.type === 'CREATE') {
150
+ createdFiles.push(change.path);
151
+ }
152
+ else if (change.type === 'UPDATE') {
153
+ updatedFiles.push(change.path);
154
+ }
155
+ else if (change.type === 'DELETE') {
156
+ deletedFiles.push(change.path);
157
+ }
158
+ }
159
+ }
160
+ return { changes, createdFiles, updatedFiles, deletedFiles, callbacks };
161
+ }
@@ -11,6 +11,7 @@ export declare function getNxWorkspaceFilesFromContext(workspaceRoot: string, pr
11
11
  export declare function globWithWorkspaceContextSync(workspaceRoot: string, globs: string[], exclude?: string[]): string[];
12
12
  export declare function globWithWorkspaceContext(workspaceRoot: string, globs: string[], exclude?: string[]): Promise<string[]>;
13
13
  export declare function hashWithWorkspaceContext(workspaceRoot: string, globs: string[], exclude?: string[]): Promise<string>;
14
+ export declare function updateContextWithChangedFiles(createdFiles: string[], updatedFiles: string[], deletedFiles: string[]): Promise<void>;
14
15
  export declare function updateFilesInContext(updatedFiles: string[], deletedFiles: string[]): Record<string, string>;
15
16
  export declare function getAllFileDataInContext(workspaceRoot: string): Promise<import("../native").FileData[]>;
16
17
  export declare function getFilesInDirectoryUsingContext(workspaceRoot: string, dir: string): Promise<string[]>;
@@ -5,6 +5,7 @@ exports.getNxWorkspaceFilesFromContext = getNxWorkspaceFilesFromContext;
5
5
  exports.globWithWorkspaceContextSync = globWithWorkspaceContextSync;
6
6
  exports.globWithWorkspaceContext = globWithWorkspaceContext;
7
7
  exports.hashWithWorkspaceContext = hashWithWorkspaceContext;
8
+ exports.updateContextWithChangedFiles = updateContextWithChangedFiles;
8
9
  exports.updateFilesInContext = updateFilesInContext;
9
10
  exports.getAllFileDataInContext = getAllFileDataInContext;
10
11
  exports.getFilesInDirectoryUsingContext = getFilesInDirectoryUsingContext;
@@ -56,6 +57,21 @@ async function hashWithWorkspaceContext(workspaceRoot, globs, exclude) {
56
57
  }
57
58
  return client_1.daemonClient.hashGlob(globs, exclude);
58
59
  }
60
+ async function updateContextWithChangedFiles(createdFiles, updatedFiles, deletedFiles) {
61
+ if (!client_1.daemonClient.enabled()) {
62
+ updateFilesInContext([...createdFiles, ...updatedFiles], deletedFiles);
63
+ }
64
+ else if ((0, is_on_daemon_1.isOnDaemon)()) {
65
+ // make sure to only import this when running on the daemon
66
+ const { addUpdatedAndDeletedFiles } = await Promise.resolve().then(() => require('../daemon/server/project-graph-incremental-recomputation'));
67
+ // update files for the incremental graph recomputation on the daemon
68
+ addUpdatedAndDeletedFiles(createdFiles, updatedFiles, deletedFiles);
69
+ }
70
+ else {
71
+ // daemon is enabled but we are not running on it, ask the daemon to update the context
72
+ await client_1.daemonClient.updateWorkspaceContext(createdFiles, updatedFiles, deletedFiles);
73
+ }
74
+ }
59
75
  function updateFilesInContext(updatedFiles, deletedFiles) {
60
76
  return workspaceContext?.incrementalUpdate(updatedFiles, deletedFiles);
61
77
  }
@@ -1,7 +0,0 @@
1
- export declare const GLOB: "GLOB";
2
- export type HandleUpdateContextMessage = {
3
- type: typeof GLOB;
4
- updatedFiles: string[];
5
- deletedFiles: string[];
6
- };
7
- export declare function isHandleUpdateContextMessage(message: unknown): message is HandleUpdateContextMessage;
@@ -1,11 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.GLOB = void 0;
4
- exports.isHandleUpdateContextMessage = isHandleUpdateContextMessage;
5
- exports.GLOB = 'GLOB';
6
- function isHandleUpdateContextMessage(message) {
7
- return (typeof message === 'object' &&
8
- message !== null &&
9
- 'type' in message &&
10
- message['type'] === exports.GLOB);
11
- }