nx 21.0.0-rc.2 → 21.0.0-rc.4

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.
package/bin/nx.js CHANGED
@@ -18,6 +18,12 @@ const workspace_context_1 = require("../src/utils/workspace-context");
18
18
  const client_1 = require("../src/daemon/client/client");
19
19
  const db_connection_1 = require("../src/utils/db-connection");
20
20
  const exit_codes_1 = require("../src/utils/exit-codes");
21
+ // In case Nx Cloud forcibly exits while the TUI is running, ensure the terminal is restored etc.
22
+ process.on('exit', (...args) => {
23
+ if (typeof globalThis.tuiOnProcessExit === 'function') {
24
+ globalThis.tuiOnProcessExit(...args);
25
+ }
26
+ });
21
27
  function main() {
22
28
  if (process.argv[2] !== 'report' &&
23
29
  process.argv[2] !== '--version' &&
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nx",
3
- "version": "21.0.0-rc.2",
3
+ "version": "21.0.0-rc.4",
4
4
  "private": false,
5
5
  "description": "The core Nx plugin contains the core functionality of Nx like the project graph, nx commands and task orchestration.",
6
6
  "repository": {
@@ -83,16 +83,16 @@
83
83
  }
84
84
  },
85
85
  "optionalDependencies": {
86
- "@nx/nx-darwin-arm64": "21.0.0-rc.2",
87
- "@nx/nx-darwin-x64": "21.0.0-rc.2",
88
- "@nx/nx-freebsd-x64": "21.0.0-rc.2",
89
- "@nx/nx-linux-arm-gnueabihf": "21.0.0-rc.2",
90
- "@nx/nx-linux-arm64-gnu": "21.0.0-rc.2",
91
- "@nx/nx-linux-arm64-musl": "21.0.0-rc.2",
92
- "@nx/nx-linux-x64-gnu": "21.0.0-rc.2",
93
- "@nx/nx-linux-x64-musl": "21.0.0-rc.2",
94
- "@nx/nx-win32-arm64-msvc": "21.0.0-rc.2",
95
- "@nx/nx-win32-x64-msvc": "21.0.0-rc.2"
86
+ "@nx/nx-darwin-arm64": "21.0.0-rc.4",
87
+ "@nx/nx-darwin-x64": "21.0.0-rc.4",
88
+ "@nx/nx-freebsd-x64": "21.0.0-rc.4",
89
+ "@nx/nx-linux-arm-gnueabihf": "21.0.0-rc.4",
90
+ "@nx/nx-linux-arm64-gnu": "21.0.0-rc.4",
91
+ "@nx/nx-linux-arm64-musl": "21.0.0-rc.4",
92
+ "@nx/nx-linux-x64-gnu": "21.0.0-rc.4",
93
+ "@nx/nx-linux-x64-musl": "21.0.0-rc.4",
94
+ "@nx/nx-win32-arm64-msvc": "21.0.0-rc.4",
95
+ "@nx/nx-win32-x64-msvc": "21.0.0-rc.4"
96
96
  },
97
97
  "nx-migrations": {
98
98
  "migrations": "./migrations.json",
@@ -19,6 +19,7 @@ const fs_1 = require("fs");
19
19
  const configuration_1 = require("../../config/configuration");
20
20
  const versions_1 = require("../../utils/versions");
21
21
  const child_process_1 = require("../../utils/child-process");
22
+ const fileutils_1 = require("../../utils/fileutils");
22
23
  function installPluginPackages(repoRoot, pmc = (0, package_manager_1.getPackageManagerCommand)(), plugins) {
23
24
  if (plugins.length === 0) {
24
25
  return;
@@ -33,6 +34,7 @@ function installPluginPackages(repoRoot, pmc = (0, package_manager_1.getPackageM
33
34
  for (const plugin of plugins) {
34
35
  nxJson.installation.plugins[plugin] = versions_1.nxVersion;
35
36
  }
37
+ (0, fileutils_1.writeJsonFile)((0, path_1.join)(repoRoot, 'nx.json'), nxJson);
36
38
  // Invoking nx wrapper to install plugins.
37
39
  (0, child_process_1.runNxSync)('--version', { stdio: 'ignore' });
38
40
  }
@@ -47,21 +49,15 @@ function installPluginPackages(repoRoot, pmc = (0, package_manager_1.getPackageM
47
49
  * @returns void
48
50
  */
49
51
  async function runPluginInitGenerator(plugin, repoRoot = workspace_root_1.workspaceRoot, updatePackageScripts = false, verbose = false, pmc = (0, package_manager_1.getPackageManagerCommand)()) {
52
+ let command = `g ${plugin}:init ${verbose ? '--verbose' : ''}`;
50
53
  try {
51
54
  const { schema } = (0, generator_utils_1.getGeneratorInformation)(plugin, 'init', workspace_root_1.workspaceRoot, {});
52
- let command = `g ${plugin}:init ${verbose ? '--verbose' : ''}`;
53
55
  if (!!schema.properties['keepExistingVersions']) {
54
56
  command += ` --keepExistingVersions`;
55
57
  }
56
58
  if (updatePackageScripts && !!schema.properties['updatePackageScripts']) {
57
59
  command += ` --updatePackageScripts`;
58
60
  }
59
- (0, child_process_1.runNxSync)(command, {
60
- stdio: [0, 1, 2],
61
- cwd: repoRoot,
62
- windowsHide: false,
63
- packageManagerCommand: pmc,
64
- });
65
61
  }
66
62
  catch {
67
63
  // init generator does not exist, so this function should noop
@@ -72,6 +68,12 @@ async function runPluginInitGenerator(plugin, repoRoot = workspace_root_1.worksp
72
68
  }
73
69
  return;
74
70
  }
71
+ (0, child_process_1.runNxSync)(command, {
72
+ stdio: [0, 1, 2],
73
+ cwd: repoRoot,
74
+ windowsHide: false,
75
+ packageManagerCommand: pmc,
76
+ });
75
77
  }
76
78
  /**
77
79
  * Install plugins
@@ -38,7 +38,7 @@ async function initHandler(options) {
38
38
  await (0, react_1.addNxToCraRepo)(options);
39
39
  (0, utils_1.printFinalMessage)({
40
40
  learnMoreLink: options.integrated
41
- ? 'https://nx.dev/getting-started/tutorials/react-monorepo-tutorial'
41
+ ? 'https://nx.dev/tutorials/2-react-monorepo/1r-introduction/1-welcome'
42
42
  : 'https://nx.dev/getting-started/tutorials/react-standalone-tutorial',
43
43
  });
44
44
  return;
@@ -167,7 +167,7 @@ async function runPublishOnProjects(args, projectGraph, nxJson, projectNames, ex
167
167
  * NOTE: Force TUI to be disabled for now.
168
168
  */
169
169
  process.env.NX_TUI = 'false';
170
- const commandResults = await (0, run_command_1.runCommandForTasks)(projectsWithTarget, projectGraph, { nxJson }, {
170
+ const { taskResults } = await (0, run_command_1.runCommandForTasks)(projectsWithTarget, projectGraph, { nxJson }, {
171
171
  targets: [requiredTargetName],
172
172
  outputStyle: 'static',
173
173
  ...args,
@@ -175,13 +175,13 @@ async function runPublishOnProjects(args, projectGraph, nxJson, projectNames, ex
175
175
  nxIgnoreCycles: true,
176
176
  }, overrides, null, {}, extraOptions);
177
177
  const publishProjectsResult = {};
178
- for (const taskData of Object.values(commandResults)) {
178
+ for (const taskData of Object.values(taskResults)) {
179
179
  publishProjectsResult[taskData.task.target.project] = {
180
180
  code: taskData.code,
181
181
  };
182
182
  }
183
183
  await (0, tasks_execution_hooks_1.runPostTasksExecution)({
184
- taskResults: commandResults,
184
+ taskResults,
185
185
  workspaceRoot: workspace_root_1.workspaceRoot,
186
186
  nxJsonConfiguration: nxJson,
187
187
  });
@@ -245,6 +245,7 @@ class ReleaseGroupProcessor {
245
245
  async setupProjectsToProcess() {
246
246
  // Track the projects being directly versioned
247
247
  let projectsToProcess = new Set();
248
+ const resolveVersionActionsForProjectCallbacks = [];
248
249
  // Precompute all projects in nx release config
249
250
  for (const [groupName, group] of Object.entries(this.nxReleaseConfig.groups)) {
250
251
  for (const project of group.projects) {
@@ -276,11 +277,22 @@ class ReleaseGroupProcessor {
276
277
  // Resolve the final configuration for the project
277
278
  const finalConfigForProject = this.resolveFinalConfigForProject(releaseGroup, projectGraphNode);
278
279
  this.finalConfigsByProject.set(project, finalConfigForProject);
279
- const { versionActionsPath, versionActions, afterAllProjectsVersioned, } = await (0, version_actions_1.resolveVersionActionsForProject)(this.tree, releaseGroup, projectGraphNode, finalConfigForProject);
280
- if (!this.uniqueAfterAllProjectsVersioned.has(versionActionsPath)) {
281
- this.uniqueAfterAllProjectsVersioned.set(versionActionsPath, afterAllProjectsVersioned);
282
- }
283
- this.projectsToVersionActions.set(project, versionActions);
280
+ /**
281
+ * For our versionActions validation to accurate, we need to wait until the full allProjectsToProcess
282
+ * set is populated so that all dependencies, including those across release groups, are included.
283
+ *
284
+ * In order to save us fully traversing the graph again to arrive at this project level, schedule a callback
285
+ * to resolve the versionActions for the project only once we have all the projects to process.
286
+ */
287
+ resolveVersionActionsForProjectCallbacks.push(async () => {
288
+ const { versionActionsPath, versionActions, afterAllProjectsVersioned, } = await (0, version_actions_1.resolveVersionActionsForProject)(this.tree, releaseGroup, projectGraphNode, finalConfigForProject,
289
+ // Will be fully populated by the time this callback is executed
290
+ this.allProjectsToProcess.has(project));
291
+ if (!this.uniqueAfterAllProjectsVersioned.has(versionActionsPath)) {
292
+ this.uniqueAfterAllProjectsVersioned.set(versionActionsPath, afterAllProjectsVersioned);
293
+ }
294
+ this.projectsToVersionActions.set(project, versionActions);
295
+ });
284
296
  }
285
297
  }
286
298
  // If no filters are applied, process all projects
@@ -293,6 +305,10 @@ class ReleaseGroupProcessor {
293
305
  throw new Error('No projects are set to be processed, please report this as a bug on https://github.com/nrwl/nx/issues');
294
306
  }
295
307
  this.allProjectsToProcess = new Set(projectsToProcess);
308
+ // Execute all the callbacks to resolve the version actions for the projects
309
+ for (const cb of resolveVersionActionsForProjectCallbacks) {
310
+ await cb();
311
+ }
296
312
  }
297
313
  /**
298
314
  * Find all dependents that should be processed due to dependency updates
@@ -77,7 +77,7 @@ export declare class ExampleNonSemverVersionActions extends VersionActions {
77
77
  export declare function parseGraphDefinition(definition: string): {
78
78
  projects: any;
79
79
  };
80
- export declare function mockResolveVersionActionsForProjectImplementation(tree: Tree, releaseGroup: any, projectGraphNode: any, finalConfigForProject: FinalConfigForProject): Promise<{
80
+ export declare function mockResolveVersionActionsForProjectImplementation(tree: Tree, releaseGroup: any, projectGraphNode: any, finalConfigForProject: FinalConfigForProject, isInProjectsToProcess: boolean): Promise<{
81
81
  versionActionsPath: string;
82
82
  versionActions: ExampleRustVersionActions;
83
83
  afterAllProjectsVersioned?: undefined;
@@ -377,13 +377,13 @@ function setupGraph(tree, graph) {
377
377
  }
378
378
  const exampleRustVersionActions = '__EXAMPLE_RUST_VERSION_ACTIONS__';
379
379
  const exampleNonSemverVersionActions = '__EXAMPLE_NON_SEMVER_VERSION_ACTIONS__';
380
- async function mockResolveVersionActionsForProjectImplementation(tree, releaseGroup, projectGraphNode, finalConfigForProject) {
380
+ async function mockResolveVersionActionsForProjectImplementation(tree, releaseGroup, projectGraphNode, finalConfigForProject, isInProjectsToProcess) {
381
381
  if (projectGraphNode.data.release?.versionActions ===
382
382
  exampleRustVersionActions ||
383
383
  releaseGroup.versionActions === exampleRustVersionActions) {
384
384
  const versionActions = new ExampleRustVersionActions(releaseGroup, projectGraphNode, finalConfigForProject);
385
385
  // Initialize the versionActions with all the required manifest paths etc
386
- await versionActions.init(tree);
386
+ await versionActions.init(tree, isInProjectsToProcess);
387
387
  return {
388
388
  versionActionsPath: exampleRustVersionActions,
389
389
  versionActions,
@@ -394,7 +394,7 @@ async function mockResolveVersionActionsForProjectImplementation(tree, releaseGr
394
394
  releaseGroup.versionActions === exampleNonSemverVersionActions) {
395
395
  const versionActions = new ExampleNonSemverVersionActions(releaseGroup, projectGraphNode, finalConfigForProject);
396
396
  // Initialize the versionActions with all the required manifest paths etc
397
- await versionActions.init(tree);
397
+ await versionActions.init(tree, isInProjectsToProcess);
398
398
  return {
399
399
  versionActionsPath: exampleNonSemverVersionActions,
400
400
  versionActions,
@@ -406,7 +406,7 @@ async function mockResolveVersionActionsForProjectImplementation(tree, releaseGr
406
406
  const JsVersionActions = loaded.default;
407
407
  const versionActions = new JsVersionActions(releaseGroup, projectGraphNode, finalConfigForProject);
408
408
  // Initialize the versionActions with all the required manifest paths etc
409
- await versionActions.init(tree);
409
+ await versionActions.init(tree, isInProjectsToProcess);
410
410
  return {
411
411
  versionActionsPath,
412
412
  versionActions: versionActions,
@@ -27,7 +27,7 @@ export type AfterAllProjectsVersioned = (cwd: string, opts: {
27
27
  changedFiles: string[];
28
28
  deletedFiles: string[];
29
29
  }>;
30
- export declare function resolveVersionActionsForProject(tree: Tree, releaseGroup: ReleaseGroupWithName, projectGraphNode: ProjectGraphProjectNode, finalConfigForProject: FinalConfigForProject): Promise<{
30
+ export declare function resolveVersionActionsForProject(tree: Tree, releaseGroup: ReleaseGroupWithName, projectGraphNode: ProjectGraphProjectNode, finalConfigForProject: FinalConfigForProject, isInProjectsToProcess: boolean): Promise<{
31
31
  versionActionsPath: string;
32
32
  versionActions: VersionActions;
33
33
  afterAllProjectsVersioned: AfterAllProjectsVersioned;
@@ -61,7 +61,7 @@ export declare abstract class VersionActions {
61
61
  /**
62
62
  * Asynchronous initialization of the version actions and validation of certain configuration options.
63
63
  */
64
- init(tree: Tree): Promise<void>;
64
+ init(tree: Tree, isInProjectsToProcess: boolean): Promise<void>;
65
65
  /**
66
66
  * The default implementation will calculate the new version based on semver. If semver is not applicable to a
67
67
  * particular versioning use-case, this method should be overridden with custom logic.
@@ -32,7 +32,7 @@ function resolveVersionActionsPath(path, projectGraphNode) {
32
32
  }
33
33
  }
34
34
  const versionActionsResolutionCache = new Map();
35
- async function resolveVersionActionsForProject(tree, releaseGroup, projectGraphNode, finalConfigForProject) {
35
+ async function resolveVersionActionsForProject(tree, releaseGroup, projectGraphNode, finalConfigForProject, isInProjectsToProcess) {
36
36
  // Project level release version config takes priority, if set
37
37
  const projectVersionConfig = projectGraphNode.data.release?.version;
38
38
  const releaseGroupVersionConfig = releaseGroup.version;
@@ -76,7 +76,7 @@ async function resolveVersionActionsForProject(tree, releaseGroup, projectGraphN
76
76
  }
77
77
  const versionActions = new VersionActionsClass(releaseGroup, projectGraphNode, finalConfigForProject);
78
78
  // Initialize the version actions with all the required manifest paths etc
79
- await versionActions.init(tree);
79
+ await versionActions.init(tree, isInProjectsToProcess);
80
80
  return {
81
81
  versionActionsPath,
82
82
  versionActions,
@@ -101,7 +101,7 @@ class VersionActions {
101
101
  /**
102
102
  * Asynchronous initialization of the version actions and validation of certain configuration options.
103
103
  */
104
- async init(tree) {
104
+ async init(tree, isInProjectsToProcess) {
105
105
  // Default to the first available source manifest root, if applicable, if no custom manifest roots are provided
106
106
  if (this.validManifestFilenames?.length &&
107
107
  this.finalConfigForProject.manifestRootsToUpdate.length === 0) {
@@ -138,11 +138,17 @@ class VersionActions {
138
138
  break;
139
139
  }
140
140
  }
141
- if (!hasValidManifest) {
141
+ /**
142
+ * If projects or groups filters are applied, it is possible that the project is not being actively processed
143
+ * and we should not throw an error in this case.
144
+ */
145
+ if (!hasValidManifest && isInProjectsToProcess) {
142
146
  const validManifestFilenames = this.validManifestFilenames?.join(' or ');
143
147
  throw new Error(`The project "${this.projectGraphNode.name}" does not have a ${validManifestFilenames} file available in ./${interpolatedManifestRoot.path}.
144
-
145
- To fix this you will either need to add a ${validManifestFilenames} file at that location, or configure "release" within your nx.json to exclude "${this.projectGraphNode.name}" from the current release group, or amend the "release.version.manifestRootsToUpdate" configuration to point to where the relevant manifest should be.`);
148
+
149
+ To fix this you will either need to add a ${validManifestFilenames} file at that location, or configure "release" within your nx.json to exclude "${this.projectGraphNode.name}" from the current release group, or amend the "release.version.manifestRootsToUpdate" configuration to point to where the relevant manifest should be.
150
+
151
+ It is also possible that the project is being processed because of a dependency relationship between what you are directly versioning and the project/release group, in which case you will need to amend your filters to include all relevant projects and release groups.`);
146
152
  }
147
153
  }
148
154
  }
@@ -2,12 +2,16 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.resetHandler = resetHandler;
4
4
  const node_fs_1 = require("node:fs");
5
+ const node_path_1 = require("node:path");
5
6
  const client_1 = require("../../daemon/client/client");
6
7
  const cache_directory_1 = require("../../utils/cache-directory");
7
8
  const output_1 = require("../../utils/output");
8
9
  const native_file_cache_location_1 = require("../../native/native-file-cache-location");
9
10
  const client_2 = require("../../nx-cloud/utilities/client");
10
11
  const get_cloud_options_1 = require("../../nx-cloud/utilities/get-cloud-options");
12
+ const nx_cloud_utils_1 = require("../../utils/nx-cloud-utils");
13
+ const configuration_1 = require("../../config/configuration");
14
+ const update_manager_1 = require("../../nx-cloud/update-manager");
11
15
  // Wait at max 5 seconds before giving up on a failing operation.
12
16
  const INCREMENTAL_BACKOFF_MAX_DURATION = 5000;
13
17
  // If an operation fails, wait 100ms before first retry.
@@ -17,6 +21,8 @@ async function resetHandler(args) {
17
21
  const all = args.onlyDaemon === undefined &&
18
22
  args.onlyCache === undefined &&
19
23
  args.onlyWorkspaceData === undefined;
24
+ const nxJson = (0, configuration_1.readNxJson)();
25
+ const cloudEnabled = (0, nx_cloud_utils_1.isNxCloudUsed)(nxJson);
20
26
  const startupMessage = all
21
27
  ? 'Resetting the Nx cache and stopping the daemon.'
22
28
  : 'Resetting:';
@@ -31,6 +37,9 @@ async function resetHandler(args) {
31
37
  if (args.onlyWorkspaceData) {
32
38
  bodyLines.push('- Workspace data directory');
33
39
  }
40
+ if (args.onlyCloud && cloudEnabled) {
41
+ bodyLines.push('- Nx Cloud Client');
42
+ }
34
43
  }
35
44
  output_1.output.note({ title: startupMessage, bodyLines });
36
45
  if (all || args.onlyDaemon) {
@@ -63,9 +72,10 @@ async function resetHandler(args) {
63
72
  errors.push('Failed to clean up the workspace data directory.', e.toString());
64
73
  }
65
74
  }
66
- if (all || args.onlyCloud) {
75
+ if ((cloudEnabled && all) || args.onlyCloud) {
67
76
  try {
68
77
  await resetCloudClient();
78
+ await removeInstalledNxCloudClient();
69
79
  }
70
80
  catch (e) {
71
81
  errors.push('Failed to reset the Nx Cloud client.', e.toString());
@@ -97,6 +107,12 @@ async function resetCloudClient() {
97
107
  }
98
108
  catch { }
99
109
  }
110
+ function removeInstalledNxCloudClient() {
111
+ return incrementalBackoff(INCREMENTAL_BACKOFF_FIRST_DELAY, INCREMENTAL_BACKOFF_MAX_DURATION, () => {
112
+ const cloudClientDir = (0, update_manager_1.getBundleInstallDefaultLocation)();
113
+ (0, node_fs_1.rmSync)((0, node_path_1.join)(cloudClientDir, 'cloud'), { recursive: true, force: true });
114
+ });
115
+ }
100
116
  function cleanupCacheEntries() {
101
117
  return incrementalBackoff(INCREMENTAL_BACKOFF_FIRST_DELAY, INCREMENTAL_BACKOFF_MAX_DURATION, () => {
102
118
  (0, node_fs_1.rmSync)(cache_directory_1.cacheDir, { recursive: true, force: true });
@@ -64,13 +64,15 @@ export declare function withOverrides<T extends {
64
64
  }>(args: T, commandLevel?: number): T & {
65
65
  __overrides_unparsed__: string[];
66
66
  };
67
- declare const allOutputStyles: readonly ["tui", "dynamic", "dynamic-legacy", "static", "stream", "stream-without-prefixes", "compact"];
67
+ declare const allOutputStyles: readonly ["tui", "dynamic", "dynamic-legacy", "static", "stream", "stream-without-prefixes"];
68
68
  export type OutputStyle = (typeof allOutputStyles)[number];
69
- export declare function withOutputStyleOption(yargs: Argv, choices?: ReadonlyArray<OutputStyle>): Argv<{
70
- "output-style": string;
69
+ export declare function withOutputStyleOption<T>(yargs: Argv<T>, choices?: ReadonlyArray<OutputStyle>): Argv<T & {
70
+ outputStyle: OutputStyle;
71
71
  }>;
72
72
  export declare function withRunOneOptions(yargs: Argv): Argv<{
73
- "output-style": string;
73
+ configuration: string;
74
+ } & {
75
+ outputStyle: OutputStyle;
74
76
  } & RunOptions & {
75
77
  project: string;
76
78
  } & {
@@ -237,7 +237,6 @@ const allOutputStyles = [
237
237
  'static',
238
238
  'stream',
239
239
  'stream-without-prefixes',
240
- 'compact',
241
240
  ];
242
241
  function withOutputStyleOption(yargs, choices = [
243
242
  'dynamic-legacy',
@@ -248,7 +247,7 @@ function withOutputStyleOption(yargs, choices = [
248
247
  'stream-without-prefixes',
249
248
  ]) {
250
249
  return yargs
251
- .option('output-style', {
250
+ .option('outputStyle', {
252
251
  describe: `Defines how Nx emits outputs tasks logs. **tui**: enables the Nx Terminal UI, recommended for local development environments. **dynamic-legacy**: use dynamic-legacy output life cycle, previous content is overwritten or modified as new outputs are added, display minimal logs by default, always show errors. This output format is recommended for local development environments where tui is not supported. **static**: uses static output life cycle, no previous content is rewritten or modified as new outputs are added. This output format is recommened for CI environments. **stream**: nx by default logs output to an internal output stream, enable this option to stream logs to stdout / stderr. **stream-without-prefixes**: nx prefixes the project name the target is running on, use this option remove the project name prefix from output.`,
253
252
  type: 'string',
254
253
  choices,