nx 20.2.2 → 20.3.0-beta.1

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 (37) hide show
  1. package/package.json +13 -11
  2. package/src/adapter/ngcli-adapter.js +7 -7
  3. package/src/command-line/add/add.js +21 -45
  4. package/src/command-line/generate/generator-utils.js +2 -2
  5. package/src/command-line/import/import.js +60 -34
  6. package/src/command-line/init/configure-plugins.d.ts +35 -0
  7. package/src/command-line/init/configure-plugins.js +189 -0
  8. package/src/command-line/init/init-v2.d.ts +1 -2
  9. package/src/command-line/init/init-v2.js +4 -18
  10. package/src/command-line/run/executor-utils.js +4 -4
  11. package/src/config/schema-utils.d.ts +4 -3
  12. package/src/config/schema-utils.js +71 -4
  13. package/src/config/workspace-json-project-json.d.ts +5 -0
  14. package/src/core/graph/main.js +1 -1
  15. package/src/core/graph/styles.js +1 -1
  16. package/src/daemon/client/client.js +9 -0
  17. package/src/native/nx.wasm32-wasi.wasm +0 -0
  18. package/src/plugins/js/project-graph/build-dependencies/explicit-package-json-dependencies.d.ts +2 -2
  19. package/src/plugins/js/project-graph/build-dependencies/explicit-package-json-dependencies.js +6 -20
  20. package/src/plugins/js/project-graph/build-dependencies/target-project-locator.d.ts +3 -1
  21. package/src/plugins/js/project-graph/build-dependencies/target-project-locator.js +12 -1
  22. package/src/plugins/js/utils/packages.d.ts +3 -0
  23. package/src/plugins/js/utils/packages.js +25 -0
  24. package/src/plugins/package-json/create-nodes.js +6 -0
  25. package/src/project-graph/build-project-graph.js +57 -1
  26. package/src/project-graph/plugins/internal-api.d.ts +4 -3
  27. package/src/project-graph/plugins/internal-api.js +2 -2
  28. package/src/project-graph/plugins/isolation/messaging.d.ts +2 -2
  29. package/src/project-graph/plugins/loader.js +13 -6
  30. package/src/project-graph/utils/project-configuration-utils.js +31 -1
  31. package/src/tasks-runner/forked-process-task-runner.js +30 -8
  32. package/src/utils/delayed-spinner.d.ts +40 -0
  33. package/src/utils/delayed-spinner.js +58 -0
  34. package/src/utils/package-json.d.ts +1 -0
  35. package/src/utils/package-json.js +5 -1
  36. package/src/command-line/import/utils/needs-install.d.ts +0 -3
  37. package/src/command-line/import/utils/needs-install.js +0 -31
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nx",
3
- "version": "20.2.2",
3
+ "version": "20.3.0-beta.1",
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": {
@@ -58,6 +58,7 @@
58
58
  "npm-run-path": "^4.0.1",
59
59
  "open": "^8.4.0",
60
60
  "ora": "5.3.0",
61
+ "resolve.exports": "2.0.3",
61
62
  "semver": "^7.5.3",
62
63
  "string-width": "^4.2.3",
63
64
  "tar-stream": "~2.2.0",
@@ -81,16 +82,16 @@
81
82
  }
82
83
  },
83
84
  "optionalDependencies": {
84
- "@nx/nx-darwin-arm64": "20.2.2",
85
- "@nx/nx-darwin-x64": "20.2.2",
86
- "@nx/nx-freebsd-x64": "20.2.2",
87
- "@nx/nx-linux-arm-gnueabihf": "20.2.2",
88
- "@nx/nx-linux-arm64-gnu": "20.2.2",
89
- "@nx/nx-linux-arm64-musl": "20.2.2",
90
- "@nx/nx-linux-x64-gnu": "20.2.2",
91
- "@nx/nx-linux-x64-musl": "20.2.2",
92
- "@nx/nx-win32-arm64-msvc": "20.2.2",
93
- "@nx/nx-win32-x64-msvc": "20.2.2"
85
+ "@nx/nx-darwin-arm64": "20.3.0-beta.1",
86
+ "@nx/nx-darwin-x64": "20.3.0-beta.1",
87
+ "@nx/nx-freebsd-x64": "20.3.0-beta.1",
88
+ "@nx/nx-linux-arm-gnueabihf": "20.3.0-beta.1",
89
+ "@nx/nx-linux-arm64-gnu": "20.3.0-beta.1",
90
+ "@nx/nx-linux-arm64-musl": "20.3.0-beta.1",
91
+ "@nx/nx-linux-x64-gnu": "20.3.0-beta.1",
92
+ "@nx/nx-linux-x64-musl": "20.3.0-beta.1",
93
+ "@nx/nx-win32-arm64-msvc": "20.3.0-beta.1",
94
+ "@nx/nx-win32-x64-msvc": "20.3.0-beta.1"
94
95
  },
95
96
  "nx-migrations": {
96
97
  "migrations": "./migrations.json",
@@ -121,6 +122,7 @@
121
122
  "@nx/rollup",
122
123
  "@nx/remix",
123
124
  "@nx/rspack",
125
+ "@nx/rsbuild",
124
126
  "@nx/storybook",
125
127
  "@nx/vite",
126
128
  "@nx/vue",
@@ -796,7 +796,7 @@ async function getWrappedWorkspaceNodeModulesArchitectHost(workspace, root, proj
796
796
  builderName,
797
797
  description: executorConfig.description,
798
798
  optionSchema: builderInfo.schema,
799
- import: (0, schema_utils_1.resolveImplementation)(executorConfig.implementation, (0, path_1.dirname)(executorsFilePath)),
799
+ import: (0, schema_utils_1.resolveImplementation)(executorConfig.implementation, (0, path_1.dirname)(executorsFilePath), packageName, this.projects),
800
800
  };
801
801
  }
802
802
  readExecutorsJson(nodeModule, builder, extraRequirePaths = []) {
@@ -825,14 +825,14 @@ async function getWrappedWorkspaceNodeModulesArchitectHost(workspace, root, proj
825
825
  try {
826
826
  const { executorsFilePath, executorConfig, isNgCompat } = this.readExecutorsJson(nodeModule, executor);
827
827
  const executorsDir = (0, path_1.dirname)(executorsFilePath);
828
- const schemaPath = (0, schema_utils_1.resolveSchema)(executorConfig.schema, executorsDir);
828
+ const schemaPath = (0, schema_utils_1.resolveSchema)(executorConfig.schema, executorsDir, nodeModule, this.projects);
829
829
  const schema = (0, executor_utils_1.normalizeExecutorSchema)((0, fileutils_1.readJsonFile)(schemaPath));
830
- const implementationFactory = this.getImplementationFactory(executorConfig.implementation, executorsDir);
830
+ const implementationFactory = this.getImplementationFactory(executorConfig.implementation, executorsDir, nodeModule);
831
831
  const batchImplementationFactory = executorConfig.batchImplementation
832
- ? this.getImplementationFactory(executorConfig.batchImplementation, executorsDir)
832
+ ? this.getImplementationFactory(executorConfig.batchImplementation, executorsDir, nodeModule)
833
833
  : null;
834
834
  const hasherFactory = executorConfig.hasher
835
- ? this.getImplementationFactory(executorConfig.hasher, executorsDir)
835
+ ? this.getImplementationFactory(executorConfig.hasher, executorsDir, nodeModule)
836
836
  : null;
837
837
  return {
838
838
  schema,
@@ -846,8 +846,8 @@ async function getWrappedWorkspaceNodeModulesArchitectHost(workspace, root, proj
846
846
  throw new Error(`Unable to resolve ${nodeModule}:${executor}.\n${e.message}`);
847
847
  }
848
848
  }
849
- getImplementationFactory(implementation, executorsDir) {
850
- return (0, schema_utils_1.getImplementationFactory)(implementation, executorsDir);
849
+ getImplementationFactory(implementation, executorsDir, packageName) {
850
+ return (0, schema_utils_1.getImplementationFactory)(implementation, executorsDir, packageName, this.projects);
851
851
  }
852
852
  }
853
853
  return new WrappedWorkspaceNodeModulesArchitectHost(workspace, root, projects);
@@ -5,7 +5,7 @@ exports.addHandler = addHandler;
5
5
  const child_process_1 = require("child_process");
6
6
  const fs_1 = require("fs");
7
7
  const ora = require("ora");
8
- const angular_json_1 = require("../../adapter/angular-json");
8
+ const yargsParser = require("yargs-parser");
9
9
  const nx_json_1 = require("../../config/nx-json");
10
10
  const child_process_2 = require("../../utils/child-process");
11
11
  const fileutils_1 = require("../../utils/fileutils");
@@ -13,11 +13,11 @@ const logger_1 = require("../../utils/logger");
13
13
  const output_1 = require("../../utils/output");
14
14
  const package_manager_1 = require("../../utils/package-manager");
15
15
  const handle_errors_1 = require("../../utils/handle-errors");
16
- const plugins_1 = require("../../utils/plugins");
17
16
  const versions_1 = require("../../utils/versions");
18
17
  const workspace_root_1 = require("../../utils/workspace-root");
19
18
  const add_nx_scripts_1 = require("../init/implementation/dot-nx/add-nx-scripts");
20
19
  const semver_1 = require("semver");
20
+ const configure_plugins_1 = require("../init/configure-plugins");
21
21
  function addHandler(options) {
22
22
  return (0, handle_errors_1.handleErrors)(options.verbose, async () => {
23
23
  output_1.output.addNewline();
@@ -79,63 +79,39 @@ async function installPackage(pkgName, version, nxJson) {
79
79
  spinner.succeed();
80
80
  }
81
81
  async function initializePlugin(pkgName, options, nxJson) {
82
- const capabilities = await (0, plugins_1.getPluginCapabilities)(workspace_root_1.workspaceRoot, pkgName, {});
83
- const generators = capabilities?.generators;
84
- if (!generators) {
85
- output_1.output.log({
86
- title: `No generators found in ${pkgName}. Skipping initialization.`,
87
- });
88
- return;
89
- }
90
- const initGenerator = findInitGenerator(generators);
91
- if (!initGenerator) {
92
- output_1.output.log({
93
- title: `No "init" generator found in ${pkgName}. Skipping initialization.`,
94
- });
95
- return;
82
+ const parsedCommandArgs = yargsParser(options.__overrides_unparsed__, {
83
+ configuration: {
84
+ 'parse-numbers': false,
85
+ 'parse-positional-numbers': false,
86
+ 'dot-notation': false,
87
+ 'camel-case-expansion': false,
88
+ },
89
+ });
90
+ if (exports.coreNxPluginVersions.has(pkgName)) {
91
+ parsedCommandArgs.keepExistingVersions = true;
92
+ if (options.updatePackageScripts ||
93
+ (options.updatePackageScripts === undefined &&
94
+ nxJson.useInferencePlugins !== false &&
95
+ process.env.NX_ADD_PLUGINS !== 'false')) {
96
+ parsedCommandArgs.updatePackageScripts = true;
97
+ }
96
98
  }
97
99
  const spinner = ora(`Initializing ${pkgName}...`);
98
100
  spinner.start();
99
101
  try {
100
- const args = [];
101
- if (exports.coreNxPluginVersions.has(pkgName)) {
102
- args.push(`--keepExistingVersions`);
103
- if (options.updatePackageScripts ||
104
- (options.updatePackageScripts === undefined &&
105
- nxJson.useInferencePlugins !== false &&
106
- process.env.NX_ADD_PLUGINS !== 'false')) {
107
- args.push(`--updatePackageScripts`);
108
- }
109
- }
110
- if (options.__overrides_unparsed__.length) {
111
- args.push(...options.__overrides_unparsed__);
112
- }
113
- (0, child_process_2.runNxSync)(`g ${pkgName}:${initGenerator} ${args.join(' ')}`, {
114
- stdio: [0, 1, 2],
115
- });
102
+ await (0, configure_plugins_1.installPlugin)(pkgName, workspace_root_1.workspaceRoot, options.verbose, parsedCommandArgs);
116
103
  }
117
104
  catch (e) {
118
105
  spinner.fail();
119
106
  output_1.output.addNewline();
120
- logger_1.logger.error(e);
121
107
  output_1.output.error({
122
- title: `Failed to initialize ${pkgName}. Please check the error above for more details.`,
108
+ title: `Failed to initialize ${pkgName}`,
109
+ bodyLines: (0, configure_plugins_1.getFailedToInstallPluginErrorMessages)(e),
123
110
  });
124
111
  process.exit(1);
125
112
  }
126
113
  spinner.succeed();
127
114
  }
128
- function findInitGenerator(generators) {
129
- if (generators['init']) {
130
- return 'init';
131
- }
132
- const angularPluginInstalled = (0, angular_json_1.isAngularPluginInstalled)();
133
- if (angularPluginInstalled && generators['ng-add']) {
134
- return 'ng-add';
135
- }
136
- return Object.keys(generators).find((name) => generators[name].aliases?.includes('init') ||
137
- (angularPluginInstalled && generators[name].aliases?.includes('ng-add')));
138
- }
139
115
  function parsePackageSpecifier(packageSpecifier) {
140
116
  const i = packageSpecifier.lastIndexOf('@');
141
117
  if (i <= 0) {
@@ -13,14 +13,14 @@ function getGeneratorInformation(collectionName, generatorName, root, projects)
13
13
  const generatorConfig = generatorsJson.generators?.[normalizedGeneratorName] ||
14
14
  generatorsJson.schematics?.[normalizedGeneratorName];
15
15
  const isNgCompat = !generatorsJson.generators?.[normalizedGeneratorName];
16
- const schemaPath = (0, schema_utils_1.resolveSchema)(generatorConfig.schema, generatorsDir);
16
+ const schemaPath = (0, schema_utils_1.resolveSchema)(generatorConfig.schema, generatorsDir, collectionName, projects);
17
17
  const schema = (0, fileutils_1.readJsonFile)(schemaPath);
18
18
  if (!schema.properties || typeof schema.properties !== 'object') {
19
19
  schema.properties = {};
20
20
  }
21
21
  generatorConfig.implementation =
22
22
  generatorConfig.implementation || generatorConfig.factory;
23
- const implementationFactory = (0, schema_utils_1.getImplementationFactory)(generatorConfig.implementation, generatorsDir);
23
+ const implementationFactory = (0, schema_utils_1.getImplementationFactory)(generatorConfig.implementation, generatorsDir, collectionName, projects);
24
24
  const normalizedGeneratorConfiguration = {
25
25
  ...generatorConfig,
26
26
  aliases: generatorConfig.aliases ?? [],
@@ -19,12 +19,12 @@ const utils_1 = require("../init/implementation/utils");
19
19
  const command_line_utils_1 = require("../../utils/command-line-utils");
20
20
  const prepare_source_repo_1 = require("./utils/prepare-source-repo");
21
21
  const merge_remote_source_1 = require("./utils/merge-remote-source");
22
- const needs_install_1 = require("./utils/needs-install");
23
22
  const minimatch_1 = require("minimatch");
23
+ const configure_plugins_1 = require("../init/configure-plugins");
24
24
  const importRemoteName = '__tmp_nx_import__';
25
25
  async function importHandler(options) {
26
26
  process.env.NX_RUNNING_NX_IMPORT = 'true';
27
- let { sourceRepository, ref, source, destination } = options;
27
+ let { sourceRepository, ref, source, destination, verbose } = options;
28
28
  const destinationGitClient = new git_utils_1.GitRepository(process.cwd());
29
29
  if (await destinationGitClient.hasUncommittedChanges()) {
30
30
  throw new Error(`You have uncommitted changes in the destination repository. Commit or revert the changes and try again.`);
@@ -141,7 +141,6 @@ async function importHandler(options) {
141
141
  throw new Error(`The source directory ${source} does not exist in ${sourceRepository}. Please double check to make sure it exists.`);
142
142
  }
143
143
  const packageManager = (0, package_manager_1.detectPackageManager)(workspace_root_1.workspaceRoot);
144
- const originalPackageWorkspaces = await (0, needs_install_1.getPackagesInPackageManagerWorkspace)(packageManager);
145
144
  const sourceIsNxWorkspace = (0, node_fs_1.existsSync)((0, path_1.join)(sourceGitClient.root, 'nx.json'));
146
145
  const relativeDestination = (0, path_1.relative)(destinationGitClient.root, absDestination);
147
146
  await (0, prepare_source_repo_1.prepareSourceRepo)(sourceGitClient, ref, source, relativeDestination, tempImportBranch, sourceRepository);
@@ -165,40 +164,18 @@ async function importHandler(options) {
165
164
  });
166
165
  }
167
166
  await handleMissingWorkspacesEntry(packageManager, pmc, relativeDestination, destinationGitClient);
168
- // If install fails, we should continue since the errors could be resolved later.
169
- let installFailed = false;
170
- if (plugins.length > 0) {
171
- try {
172
- output_1.output.log({ title: 'Installing Plugins' });
173
- (0, init_v2_1.installPlugins)(workspace_root_1.workspaceRoot, plugins, pmc, updatePackageScripts);
174
- await destinationGitClient.amendCommit();
175
- }
176
- catch (e) {
177
- installFailed = true;
178
- output_1.output.error({
179
- title: `Install failed: ${e.message || 'Unknown error'}`,
180
- bodyLines: [e.stack],
181
- });
182
- }
183
- }
184
- else if (await (0, needs_install_1.needsInstall)(packageManager, originalPackageWorkspaces)) {
185
- try {
186
- output_1.output.log({
187
- title: 'Installing dependencies for imported code',
188
- });
189
- (0, utils_1.runInstall)(workspace_root_1.workspaceRoot, (0, package_manager_1.getPackageManagerCommand)(packageManager));
190
- await destinationGitClient.amendCommit();
191
- }
192
- catch (e) {
193
- installFailed = true;
194
- output_1.output.error({
195
- title: `Install failed: ${e.message || 'Unknown error'}`,
196
- bodyLines: [e.stack],
197
- });
167
+ let installed = await runInstallDestinationRepo(packageManager, destinationGitClient);
168
+ if (installed && plugins.length > 0) {
169
+ installed = await runPluginsInstall(plugins, pmc, destinationGitClient);
170
+ if (installed) {
171
+ const { succeededPlugins } = await (0, configure_plugins_1.configurePlugins)(plugins, updatePackageScripts, pmc, workspace_root_1.workspaceRoot, verbose);
172
+ if (succeededPlugins.length > 0) {
173
+ await destinationGitClient.amendCommit();
174
+ }
198
175
  }
199
176
  }
200
177
  console.log(await destinationGitClient.showStat());
201
- if (installFailed) {
178
+ if (installed === false) {
202
179
  const pmc = (0, package_manager_1.getPackageManagerCommand)(packageManager);
203
180
  output_1.output.warn({
204
181
  title: `The import was successful, but the install failed`,
@@ -258,6 +235,55 @@ async function createTemporaryRemote(destinationGitClient, sourceRemoteUrl, remo
258
235
  await destinationGitClient.fetch(remoteName);
259
236
  }
260
237
  /**
238
+ * Run install for the imported code and plugins
239
+ * @returns true if the install failed
240
+ */
241
+ async function runInstallDestinationRepo(packageManager, destinationGitClient) {
242
+ let installed = true;
243
+ try {
244
+ output_1.output.log({
245
+ title: 'Installing dependencies for imported code',
246
+ });
247
+ (0, utils_1.runInstall)(workspace_root_1.workspaceRoot, (0, package_manager_1.getPackageManagerCommand)(packageManager));
248
+ await destinationGitClient.amendCommit();
249
+ }
250
+ catch (e) {
251
+ installed = false;
252
+ output_1.output.error({
253
+ title: `Install failed: ${e.message || 'Unknown error'}`,
254
+ bodyLines: [e.stack],
255
+ });
256
+ }
257
+ return installed;
258
+ }
259
+ async function runPluginsInstall(plugins, pmc, destinationGitClient) {
260
+ let installed = true;
261
+ output_1.output.log({ title: 'Installing Plugins' });
262
+ try {
263
+ (0, configure_plugins_1.runPackageManagerInstallPlugins)(workspace_root_1.workspaceRoot, pmc, plugins);
264
+ await destinationGitClient.amendCommit();
265
+ }
266
+ catch (e) {
267
+ installed = false;
268
+ output_1.output.error({
269
+ title: `Install failed: ${e.message || 'Unknown error'}`,
270
+ bodyLines: [
271
+ 'The following plugins were not installed:',
272
+ ...plugins.map((p) => `- ${chalk.bold(p)}`),
273
+ e.stack,
274
+ ],
275
+ });
276
+ output_1.output.error({
277
+ title: `To install the plugins manually`,
278
+ bodyLines: [
279
+ 'You may need to run commands to install the plugins:',
280
+ ...plugins.map((p) => `- ${chalk.bold(pmc.exec + ' nx add ' + p)}`),
281
+ ],
282
+ });
283
+ }
284
+ return installed;
285
+ }
286
+ /*
261
287
  * If the user imports a project that isn't in the workspaces entry, we should add that path to the workspaces entry.
262
288
  */
263
289
  async function handleMissingWorkspacesEntry(pm, pmc, pkgPath, destinationGitClient) {
@@ -0,0 +1,35 @@
1
+ import { PackageManagerCommands } from '../../utils/package-manager';
2
+ export declare function runPackageManagerInstallPlugins(repoRoot: string, pmc: PackageManagerCommands, plugins: string[]): void;
3
+ /**
4
+ * Installs a plugin by running its init generator. It will change the file system tree passed in.
5
+ * @param plugin The name of the plugin to install
6
+ * @param repoRoot repo root
7
+ * @param verbose verbose
8
+ * @param options options passed to init generator
9
+ * @returns void
10
+ */
11
+ export declare function installPlugin(plugin: string, repoRoot: string, verbose: boolean, options: {
12
+ [k: string]: any;
13
+ }): Promise<void>;
14
+ /**
15
+ * Install plugins
16
+ * Get the implementation of the plugin's init generator and run it
17
+ * @returns a list of succeeded plugins and a map of failed plugins to errors
18
+ */
19
+ export declare function installPlugins(plugins: string[], updatePackageScripts: boolean, repoRoot?: string, verbose?: boolean): Promise<{
20
+ succeededPlugins: string[];
21
+ failedPlugins: {
22
+ [plugin: string]: Error;
23
+ };
24
+ }>;
25
+ /**
26
+ * Configures plugins, installs them, and outputs the results
27
+ * @returns a list of succeeded plugins and a map of failed plugins to errors
28
+ */
29
+ export declare function configurePlugins(plugins: string[], updatePackageScripts: boolean, pmc: PackageManagerCommands, repoRoot?: string, verbose?: boolean): Promise<{
30
+ succeededPlugins: string[];
31
+ failedPlugins: {
32
+ [plugin: string]: Error;
33
+ };
34
+ }>;
35
+ export declare function getFailedToInstallPluginErrorMessages(e: any): string[];
@@ -0,0 +1,189 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.runPackageManagerInstallPlugins = runPackageManagerInstallPlugins;
4
+ exports.installPlugin = installPlugin;
5
+ exports.installPlugins = installPlugins;
6
+ exports.configurePlugins = configurePlugins;
7
+ exports.getFailedToInstallPluginErrorMessages = getFailedToInstallPluginErrorMessages;
8
+ const createSpinner = require("ora");
9
+ const chalk_1 = require("chalk");
10
+ const package_manager_1 = require("../../utils/package-manager");
11
+ const output_1 = require("../../utils/output");
12
+ const tree_1 = require("../../generators/tree");
13
+ const generator_utils_1 = require("../generate/generator-utils");
14
+ const workspace_root_1 = require("../../utils/workspace-root");
15
+ const utils_1 = require("./implementation/utils");
16
+ const plugins_1 = require("../../utils/plugins");
17
+ const angular_json_1 = require("../../adapter/angular-json");
18
+ const error_types_1 = require("../../project-graph/error-types");
19
+ function runPackageManagerInstallPlugins(repoRoot, pmc = (0, package_manager_1.getPackageManagerCommand)(), plugins) {
20
+ if (plugins.length === 0) {
21
+ return;
22
+ }
23
+ (0, utils_1.addDepsToPackageJson)(repoRoot, plugins);
24
+ (0, utils_1.runInstall)(repoRoot, pmc);
25
+ }
26
+ /**
27
+ * Installs a plugin by running its init generator. It will change the file system tree passed in.
28
+ * @param plugin The name of the plugin to install
29
+ * @param repoRoot repo root
30
+ * @param verbose verbose
31
+ * @param options options passed to init generator
32
+ * @returns void
33
+ */
34
+ async function installPlugin(plugin, repoRoot = workspace_root_1.workspaceRoot, verbose = false, options) {
35
+ const host = new tree_1.FsTree(repoRoot, verbose, `install ${plugin}`);
36
+ const capabilities = await (0, plugins_1.getPluginCapabilities)(repoRoot, plugin, {});
37
+ const generators = capabilities?.generators;
38
+ if (!generators) {
39
+ throw new Error(`No generators found in ${plugin}.`);
40
+ }
41
+ const initGenerator = findInitGenerator(generators);
42
+ if (!initGenerator) {
43
+ output_1.output.log({
44
+ title: `No "init" generator found in ${plugin}. Skipping initialization.`,
45
+ });
46
+ return;
47
+ }
48
+ const { implementationFactory } = (0, generator_utils_1.getGeneratorInformation)(plugin, initGenerator, repoRoot, {});
49
+ const implementation = implementationFactory();
50
+ const task = await implementation(host, options);
51
+ (0, tree_1.flushChanges)(repoRoot, host.listChanges());
52
+ if (task) {
53
+ await task();
54
+ }
55
+ }
56
+ /**
57
+ * Install plugins
58
+ * Get the implementation of the plugin's init generator and run it
59
+ * @returns a list of succeeded plugins and a map of failed plugins to errors
60
+ */
61
+ async function installPlugins(plugins, updatePackageScripts, repoRoot = workspace_root_1.workspaceRoot, verbose = false) {
62
+ if (plugins.length === 0) {
63
+ return {
64
+ succeededPlugins: [],
65
+ failedPlugins: {},
66
+ };
67
+ }
68
+ const spinner = createSpinner();
69
+ let succeededPlugins = [];
70
+ const failedPlugins = {};
71
+ for (const plugin of plugins) {
72
+ try {
73
+ spinner.start('Installing plugin ' + plugin);
74
+ await installPlugin(plugin, repoRoot, verbose, {
75
+ keepExistingVersions: true,
76
+ updatePackageScripts,
77
+ addPlugin: true,
78
+ skipFormat: false,
79
+ skipPackageJson: false,
80
+ });
81
+ succeededPlugins.push(plugin);
82
+ spinner.succeed('Installed plugin ' + plugin);
83
+ }
84
+ catch (e) {
85
+ failedPlugins[plugin] = e;
86
+ spinner.fail('Failed to install plugin ' + plugin);
87
+ }
88
+ }
89
+ return {
90
+ succeededPlugins,
91
+ failedPlugins,
92
+ };
93
+ }
94
+ /**
95
+ * Configures plugins, installs them, and outputs the results
96
+ * @returns a list of succeeded plugins and a map of failed plugins to errors
97
+ */
98
+ async function configurePlugins(plugins, updatePackageScripts, pmc, repoRoot = workspace_root_1.workspaceRoot, verbose = false) {
99
+ if (plugins.length === 0) {
100
+ return {
101
+ succeededPlugins: [],
102
+ failedPlugins: {},
103
+ };
104
+ }
105
+ output_1.output.log({ title: '🔨 Configuring plugins' });
106
+ let { succeededPlugins, failedPlugins } = await installPlugins(plugins, updatePackageScripts, repoRoot, verbose);
107
+ if (succeededPlugins.length > 0) {
108
+ output_1.output.success({
109
+ title: 'Installed Plugins',
110
+ bodyLines: succeededPlugins.map((p) => `- ${(0, chalk_1.bold)(p)}`),
111
+ });
112
+ }
113
+ if (Object.keys(failedPlugins).length > 0) {
114
+ output_1.output.error({
115
+ title: `Failed to install plugins`,
116
+ bodyLines: [
117
+ 'The following plugins were not installed:',
118
+ ...Object.keys(failedPlugins).map((p) => `- ${(0, chalk_1.bold)(p)}`),
119
+ ],
120
+ });
121
+ Object.entries(failedPlugins).forEach(([plugin, error]) => {
122
+ output_1.output.error({
123
+ title: `Failed to install ${plugin}`,
124
+ bodyLines: getFailedToInstallPluginErrorMessages(error),
125
+ });
126
+ });
127
+ output_1.output.error({
128
+ title: `To install the plugins manually`,
129
+ bodyLines: [
130
+ 'You may need to run commands to install the plugins:',
131
+ ...Object.keys(failedPlugins).map((p) => `- ${(0, chalk_1.bold)(pmc.exec + ' nx add ' + p)}`),
132
+ ],
133
+ });
134
+ }
135
+ return { succeededPlugins, failedPlugins };
136
+ }
137
+ function findInitGenerator(generators) {
138
+ if (generators['init']) {
139
+ return 'init';
140
+ }
141
+ const angularPluginInstalled = (0, angular_json_1.isAngularPluginInstalled)();
142
+ if (angularPluginInstalled && generators['ng-add']) {
143
+ return 'ng-add';
144
+ }
145
+ return Object.keys(generators).find((name) => generators[name].aliases?.includes('init') ||
146
+ (angularPluginInstalled && generators[name].aliases?.includes('ng-add')));
147
+ }
148
+ function getFailedToInstallPluginErrorMessages(e) {
149
+ const errorBodyLines = [];
150
+ if ((0, error_types_1.isProjectConfigurationsError)(e) && e.errors.length > 0) {
151
+ for (const error of e.errors) {
152
+ if ((0, error_types_1.isAggregateCreateNodesError)(error)) {
153
+ const innerErrors = error.errors;
154
+ for (const [file, e] of innerErrors) {
155
+ if (file) {
156
+ errorBodyLines.push(` - ${(0, chalk_1.bold)(file)}: ${e.message}`);
157
+ }
158
+ else {
159
+ errorBodyLines.push(` - ${e.message}`);
160
+ }
161
+ if (e.stack) {
162
+ const innerStackTrace = ' ' + e.stack.split('\n')?.join('\n ');
163
+ errorBodyLines.push(innerStackTrace);
164
+ }
165
+ }
166
+ }
167
+ else if (!(0, error_types_1.isProjectsWithNoNameError)(error)) {
168
+ // swallow ProjectsWithNameError
169
+ if (error.message) {
170
+ errorBodyLines.push(` - ${error.message}`);
171
+ }
172
+ if (error.stack) {
173
+ const innerStackTrace = ' ' + error.stack.split('\n')?.join('\n ');
174
+ errorBodyLines.push(innerStackTrace);
175
+ }
176
+ }
177
+ }
178
+ }
179
+ else {
180
+ if (e.message) {
181
+ errorBodyLines.push(` - ${e.message}`);
182
+ }
183
+ if (e.stack) {
184
+ const innerStackTrace = ' ' + e.stack.split('\n')?.join('\n ');
185
+ errorBodyLines.push(innerStackTrace);
186
+ }
187
+ }
188
+ return errorBodyLines;
189
+ }
@@ -1,12 +1,11 @@
1
- import { PackageManagerCommands } from '../../utils/package-manager';
2
1
  import { NxJsonConfiguration } from '../../config/nx-json';
3
2
  export interface InitArgs {
4
3
  interactive: boolean;
5
4
  nxCloud?: boolean;
6
5
  useDotNxInstallation?: boolean;
7
6
  integrated?: boolean;
7
+ verbose?: boolean;
8
8
  }
9
- export declare function installPlugins(repoRoot: string, plugins: string[], pmc: PackageManagerCommands, updatePackageScripts: boolean): void;
10
9
  export declare function initHandler(options: InitArgs): Promise<void>;
11
10
  export declare function detectPlugins(nxJson: NxJsonConfiguration, interactive: boolean, includeAngularCli?: boolean): Promise<{
12
11
  plugins: string[];
@@ -1,6 +1,5 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.installPlugins = installPlugins;
4
3
  exports.initHandler = initHandler;
5
4
  exports.detectPlugins = detectPlugins;
6
5
  const fs_1 = require("fs");
@@ -13,7 +12,6 @@ const fileutils_1 = require("../../utils/fileutils");
13
12
  const versions_1 = require("../../utils/versions");
14
13
  const utils_1 = require("./implementation/utils");
15
14
  const enquirer_1 = require("enquirer");
16
- const child_process_2 = require("child_process");
17
15
  const angular_1 = require("./implementation/angular");
18
16
  const workspace_context_1 = require("../../utils/workspace-context");
19
17
  const connect_to_nx_cloud_1 = require("../connect/connect-to-nx-cloud");
@@ -21,21 +19,7 @@ const add_nx_to_npm_repo_1 = require("./implementation/add-nx-to-npm-repo");
21
19
  const add_nx_to_monorepo_1 = require("./implementation/add-nx-to-monorepo");
22
20
  const nx_json_1 = require("../../config/nx-json");
23
21
  const get_package_name_from_import_path_1 = require("../../utils/get-package-name-from-import-path");
24
- function installPlugins(repoRoot, plugins, pmc, updatePackageScripts) {
25
- if (plugins.length === 0) {
26
- return;
27
- }
28
- (0, utils_1.addDepsToPackageJson)(repoRoot, plugins);
29
- (0, utils_1.runInstall)(repoRoot, pmc);
30
- output_1.output.log({ title: '🔨 Configuring plugins' });
31
- for (const plugin of plugins) {
32
- (0, child_process_2.execSync)(`${pmc.exec} nx g ${plugin}:init --keepExistingVersions ${updatePackageScripts ? '--updatePackageScripts' : ''}`, {
33
- stdio: [0, 1, 2],
34
- cwd: repoRoot,
35
- windowsHide: false,
36
- });
37
- }
38
- }
22
+ const configure_plugins_1 = require("./configure-plugins");
39
23
  async function initHandler(options) {
40
24
  process.env.NX_RUNNING_NX_INIT = 'true';
41
25
  const version = process.env.NX_VERSION ?? ((0, semver_1.prerelease)(versions_1.nxVersion) ? 'next' : 'latest');
@@ -98,7 +82,8 @@ async function initHandler(options) {
98
82
  output_1.output.log({ title: '🧐 Checking dependencies' });
99
83
  const { plugins, updatePackageScripts } = await detectPlugins(nxJson, options.interactive);
100
84
  output_1.output.log({ title: '📦 Installing Nx' });
101
- installPlugins(repoRoot, plugins, pmc, updatePackageScripts);
85
+ (0, configure_plugins_1.runPackageManagerInstallPlugins)(repoRoot, pmc, plugins);
86
+ await (0, configure_plugins_1.configurePlugins)(plugins, updatePackageScripts, pmc, repoRoot, options.verbose);
102
87
  if (useNxCloud) {
103
88
  output_1.output.log({ title: '🛠️ Setting up Nx Cloud' });
104
89
  await (0, utils_1.initCloud)('nx-init');
@@ -128,6 +113,7 @@ const npmPackageToPluginMap = {
128
113
  nuxt: '@nx/nuxt',
129
114
  'react-native': '@nx/react-native',
130
115
  '@remix-run/dev': '@nx/remix',
116
+ '@rsbuild/core': '@nx/rsbuild',
131
117
  };
132
118
  async function detectPlugins(nxJson, interactive, includeAngularCli) {
133
119
  let files = ['package.json'].concat((0, workspace_context_1.globWithWorkspaceContextSync)(process.cwd(), ['**/*/package.json']));
@@ -29,14 +29,14 @@ function getExecutorInformation(nodeModule, executor, root, projects) {
29
29
  return cachedExecutorInformation[key];
30
30
  const { executorsFilePath, executorConfig, isNgCompat } = readExecutorJson(nodeModule, executor, root, projects);
31
31
  const executorsDir = (0, path_1.dirname)(executorsFilePath);
32
- const schemaPath = (0, schema_utils_1.resolveSchema)(executorConfig.schema, executorsDir);
32
+ const schemaPath = (0, schema_utils_1.resolveSchema)(executorConfig.schema, executorsDir, nodeModule, projects);
33
33
  const schema = normalizeExecutorSchema((0, fileutils_1.readJsonFile)(schemaPath));
34
- const implementationFactory = (0, schema_utils_1.getImplementationFactory)(executorConfig.implementation, executorsDir);
34
+ const implementationFactory = (0, schema_utils_1.getImplementationFactory)(executorConfig.implementation, executorsDir, nodeModule, projects);
35
35
  const batchImplementationFactory = executorConfig.batchImplementation
36
- ? (0, schema_utils_1.getImplementationFactory)(executorConfig.batchImplementation, executorsDir)
36
+ ? (0, schema_utils_1.getImplementationFactory)(executorConfig.batchImplementation, executorsDir, nodeModule, projects)
37
37
  : null;
38
38
  const hasherFactory = executorConfig.hasher
39
- ? (0, schema_utils_1.getImplementationFactory)(executorConfig.hasher, executorsDir)
39
+ ? (0, schema_utils_1.getImplementationFactory)(executorConfig.hasher, executorsDir, nodeModule, projects)
40
40
  : null;
41
41
  const res = {
42
42
  schema,