diff --git a/e2e/nx-init/src/nx-init-angular.test.ts b/e2e/nx-init/src/nx-init-angular.test.ts index 98002fdc5c3f9e..3dfaac1f0171fe 100644 --- a/e2e/nx-init/src/nx-init-angular.test.ts +++ b/e2e/nx-init/src/nx-init-angular.test.ts @@ -30,7 +30,9 @@ describe('nx init (Angular CLI)', () => { it('should successfully convert an Angular CLI workspace to an Nx standalone workspace', () => { const output = runCommand( - `${pmc.runUninstalledPackage} nx@${getPublishedVersion()} init -y` + `${ + pmc.runUninstalledPackage + } nx@${getPublishedVersion()} init --no-interactive` ); expect(output).toContain('Nx is now enabled in your workspace!'); @@ -64,7 +66,7 @@ describe('nx init (Angular CLI)', () => { const output = runCommand( `${ pmc.runUninstalledPackage - } nx@${getPublishedVersion()} init -y --integrated` + } nx@${getPublishedVersion()} init --integrated --no-interactive` ); expect(output).toContain('Nx is now enabled in your workspace!'); diff --git a/e2e/nx-init/src/nx-init-monorepo.test.ts b/e2e/nx-init/src/nx-init-monorepo.test.ts index bb631c9616a253..7287f1810cc613 100644 --- a/e2e/nx-init/src/nx-init-monorepo.test.ts +++ b/e2e/nx-init/src/nx-init-monorepo.test.ts @@ -40,7 +40,7 @@ describe('nx init (Monorepo)', () => { const output = runCommand( `${ pmc.runUninstalledPackage - } nx@${getPublishedVersion()} init -y --cacheable=build` + } nx@${getPublishedVersion()} init --cacheable=build --no-interactive` ); expect(output).toContain('🎉 Done!'); diff --git a/e2e/nx-init/src/nx-init-nest.test.ts b/e2e/nx-init/src/nx-init-nest.test.ts index 7aac2737f61736..122e7402e48e39 100644 --- a/e2e/nx-init/src/nx-init-nest.test.ts +++ b/e2e/nx-init/src/nx-init-nest.test.ts @@ -34,7 +34,7 @@ describe('nx init (for NestCLI)', () => { const output = execSync( `${ pmc.runUninstalledPackage - } nx@${getPublishedVersion()} init -y --cacheable=format`, + } nx@${getPublishedVersion()} init --cacheable=format --no-interactive`, { cwd: projectRoot, encoding: 'utf-8', diff --git a/e2e/nx-init/src/nx-init-npm-repo.test.ts b/e2e/nx-init/src/nx-init-npm-repo.test.ts index 4597e244d7ad32..4bf4e470abe6b8 100644 --- a/e2e/nx-init/src/nx-init-npm-repo.test.ts +++ b/e2e/nx-init/src/nx-init-npm-repo.test.ts @@ -32,7 +32,7 @@ describe('nx init (NPM repo)', () => { const output = runCommand( `${ pmc.runUninstalledPackage - } nx@${getPublishedVersion()} init -y --cacheable=echo` + } nx@${getPublishedVersion()} init --cacheable=echo --no-interactive` ); console.log(output); expect(output).toContain('Enabled computation caching'); @@ -61,7 +61,7 @@ describe('nx init (NPM repo)', () => { runCommand( `${ pmc.runUninstalledPackage - } nx@${getPublishedVersion()} init -y --cacheable=compound` + } nx@${getPublishedVersion()} init --cacheable=compound --no-interactive` ); const output = runCommand('npm run compound TEST'); diff --git a/packages/nx/src/command-line/init.ts b/packages/nx/src/command-line/init.ts index 0c3c06527e99fc..592e2c9c6a5f99 100644 --- a/packages/nx/src/command-line/init.ts +++ b/packages/nx/src/command-line/init.ts @@ -14,7 +14,12 @@ import { directoryExists, readJsonFile } from '../utils/fileutils'; import { PackageJson } from '../utils/package-json'; export interface InitArgs { + addE2e: boolean; + force: boolean; integrated: boolean; + interactive: boolean; + vite: boolean; + nxCloud?: boolean; } export async function initHandler(options: InitArgs) { @@ -40,15 +45,15 @@ export async function initHandler(options: InitArgs) { } else if (existsSync('package.json')) { const packageJson: PackageJson = readJsonFile('package.json'); if (existsSync('angular.json')) { - await addNxToAngularCliRepo(options.integrated); + await addNxToAngularCliRepo(options); } else if (isCRA(packageJson)) { - await addNxToCraRepo(options.integrated); + await addNxToCraRepo(options); } else if (isNestCLI(packageJson)) { - await addNxToNest(packageJson); + await addNxToNest(options, packageJson); } else if (isMonorepo(packageJson)) { - await addNxToMonorepo(); + await addNxToMonorepo(options); } else { - await addNxToNpmRepo(); + await addNxToNpmRepo(options); } } else { const useDotNxFolder = await prompt<{ useDotNxFolder: string }>([ diff --git a/packages/nx/src/command-line/nx-commands.ts b/packages/nx/src/command-line/nx-commands.ts index 7cf8508cff6684..d749fdeee5d9b4 100644 --- a/packages/nx/src/command-line/nx-commands.ts +++ b/packages/nx/src/command-line/nx-commands.ts @@ -2,14 +2,12 @@ import * as chalk from 'chalk'; import { execSync } from 'child_process'; import * as path from 'path'; import * as yargs from 'yargs'; -import { nxVersion } from '../utils/versions'; -import { examples } from './examples'; -import { workspaceRoot } from '../utils/workspace-root'; -import { getPackageManagerCommand } from '../utils/package-manager'; +import { runNxSync } from '../utils/child-process'; import { writeJsonFile } from '../utils/fileutils'; +import { getPackageManagerCommand } from '../utils/package-manager'; +import { workspaceRoot } from '../utils/workspace-root'; +import { examples } from './examples'; import { WatchArguments } from './watch'; -import { runNxSync } from '../utils/child-process'; -import { stripIndents } from '../utils/strip-indents'; // Ensure that the output takes up the available width of the terminal. yargs.wrap(yargs.terminalWidth()); @@ -305,7 +303,7 @@ export const commandsObject = yargs command: 'init', describe: 'Adds Nx to any type of workspace. It installs nx, creates an nx.json configuration file and optionally sets up distributed caching. For more info, check https://nx.dev/recipes/adopting-nx.', - builder: (yargs) => withIntegratedOption(yargs), + builder: (yargs) => withInitOptions(yargs), handler: async (args: any) => { await (await import('./init')).initHandler(args); process.exit(0); @@ -1119,14 +1117,47 @@ function withListOptions(yargs) { }); } -function withIntegratedOption(yargs) { - return yargs.option('integrated', { - type: 'boolean', - description: - 'Migrate to an Nx integrated layout workspace. Only for CRA and Angular projects.', - // TODO(leo): keep it hidden until feature is released - hidden: true, - }); +function withInitOptions(yargs: yargs.Argv) { + // TODO(leo): make them visible in docs/help once the feature is released in Nx 16 + return yargs + .options('nxCloud', { + type: 'boolean', + description: 'Set up distributed caching with Nx Cloud.', + hidden: true, + }) + .option('interactive', { + describe: 'When false disables interactive input prompts for options.', + type: 'boolean', + default: true, + hidden: true, + }) + .option('integrated', { + type: 'boolean', + description: + 'Migrate to an Nx integrated layout workspace. Only for Angular CLI workspaces and CRA projects.', + default: false, + hidden: true, + }) + .option('addE2e', { + describe: + 'Set up Cypress E2E tests in integrated workspaces. Only for CRA projects.', + type: 'boolean', + default: false, + hidden: true, + }) + .option('force', { + describe: + 'Force the migration to continue and ignore custom webpack setup or uncommitted changes. Only for CRA projects.', + type: 'boolean', + default: false, + hidden: true, + }) + .options('vite', { + type: 'boolean', + description: 'Use Vite as the bundler. Only for CRA projects.', + default: true, + hidden: true, + }); } function runMigration() { diff --git a/packages/nx/src/nx-init/add-nx-to-monorepo.ts b/packages/nx/src/nx-init/add-nx-to-monorepo.ts index 19ebc293f7f145..ff44d83db5e8af 100644 --- a/packages/nx/src/nx-init/add-nx-to-monorepo.ts +++ b/packages/nx/src/nx-init/add-nx-to-monorepo.ts @@ -1,8 +1,9 @@ import { prompt } from 'enquirer'; -import { existsSync, readFileSync, readdirSync, statSync } from 'fs'; +import { existsSync, readdirSync, readFileSync, statSync } from 'fs'; import ignore from 'ignore'; import { join, relative } from 'path'; import * as yargsParser from 'yargs-parser'; +import { InitArgs } from '../command-line/init'; import { readJsonFile } from '../utils/fileutils'; import { output } from '../utils/output'; import { getPackageManagerCommand } from '../utils/package-manager'; @@ -15,15 +16,13 @@ import { runInstall, } from './utils'; +type Options = Pick; + const parsedArgs = yargsParser(process.argv, { - boolean: ['yes'], string: ['cacheable'], // only used for testing - alias: { - yes: ['y'], - }, }); -export async function addNxToMonorepo() { +export async function addNxToMonorepo(options: Options) { const repoRoot = process.cwd(); if (!existsSync(joinPathFragments(repoRoot, 'package.json'))) { @@ -43,7 +42,7 @@ export async function addNxToMonorepo() { let scriptOutputs = {} as { [script: string]: string }; let useCloud: boolean; - if (parsedArgs.yes !== true && scripts.length > 0) { + if (options.interactive && scripts.length > 0) { output.log({ title: `🧑‍🔧 Please answer the following questions about the scripts found in your workspace in order to generate task runner configuration`, }); @@ -83,13 +82,17 @@ export async function addNxToMonorepo() { )[scriptName]; } - useCloud = await askAboutNxCloud(); + useCloud = + options.nxCloud === undefined ? await askAboutNxCloud() : options.nxCloud; } else { targetDefaults = []; cacheableOperations = parsedArgs.cacheable ? parsedArgs.cacheable.split(',') : []; - useCloud = false; + useCloud = + options.interactive && options.nxCloud === undefined + ? await askAboutNxCloud() + : options.nxCloud ?? false; } createNxJsonFile( diff --git a/packages/nx/src/nx-init/add-nx-to-nest.ts b/packages/nx/src/nx-init/add-nx-to-nest.ts index 7bab293e63eedd..9d14a98ecbf550 100644 --- a/packages/nx/src/nx-init/add-nx-to-nest.ts +++ b/packages/nx/src/nx-init/add-nx-to-nest.ts @@ -1,10 +1,15 @@ -import { unlinkSync, writeFileSync } from 'fs-extra'; -import * as yargsParser from 'yargs-parser'; import * as enquirer from 'enquirer'; +import { unlinkSync, writeFileSync } from 'fs-extra'; import { join } from 'path'; +import * as yargsParser from 'yargs-parser'; +import { InitArgs } from '../command-line/init'; +import { NrwlJsPluginConfig, NxJsonConfiguration } from '../config/nx-json'; +import { ProjectConfiguration } from '../config/workspace-json-project-json'; +import { fileExists, readJsonFile, writeJsonFile } from '../utils/fileutils'; import { output } from '../utils/output'; import { PackageJson } from '../utils/package-json'; -import { fileExists, readJsonFile, writeJsonFile } from '../utils/fileutils'; +import { getPackageManagerCommand } from '../utils/package-manager'; +import { markRootPackageJsonAsNxProject } from './add-nx-to-npm-repo'; import { addDepsToPackageJson, askAboutNxCloud, @@ -12,21 +17,15 @@ import { initCloud, runInstall, } from './utils'; -import { getPackageManagerCommand } from '../utils/package-manager'; -import { markRootPackageJsonAsNxProject } from './add-nx-to-npm-repo'; -import { ProjectConfiguration } from '../config/workspace-json-project-json'; -import { NrwlJsPluginConfig, NxJsonConfiguration } from '../config/nx-json'; +type Options = Pick; type NestCLIConfiguration = any; + const parsedArgs = yargsParser(process.argv, { - boolean: ['yes'], string: ['cacheable'], // only used for testing - alias: { - yes: ['y'], - }, }); -export async function addNxToNest(packageJson: PackageJson) { +export async function addNxToNest(options: Options, packageJson: PackageJson) { const repoRoot = process.cwd(); output.log({ title: `🐳 Nx initialization` }); @@ -68,7 +67,7 @@ export async function addNxToNest(packageJson: PackageJson) { let scriptOutputs = {}; let useCloud: boolean; - if (parsedArgs.yes !== true) { + if (options.interactive) { output.log({ title: `🧑‍🔧 Please answer the following questions about the scripts found in your package.json in order to generate task runner configuration`, }); @@ -96,12 +95,13 @@ export async function addNxToNest(packageJson: PackageJson) { )[scriptName]; } - useCloud = await askAboutNxCloud(); + useCloud = + options.nxCloud === undefined ? await askAboutNxCloud() : options.nxCloud; } else { cacheableOperations = parsedArgs.cacheable ? parsedArgs.cacheable.split(',') : []; - useCloud = false; + useCloud = options.nxCloud ?? false; } createNxJsonFile( diff --git a/packages/nx/src/nx-init/add-nx-to-npm-repo.ts b/packages/nx/src/nx-init/add-nx-to-npm-repo.ts index 52f6e73fbb0b4d..15a468f12d44d6 100644 --- a/packages/nx/src/nx-init/add-nx-to-npm-repo.ts +++ b/packages/nx/src/nx-init/add-nx-to-npm-repo.ts @@ -1,7 +1,14 @@ -import { output } from '../utils/output'; -import * as yargsParser from 'yargs-parser'; import * as enquirer from 'enquirer'; +import * as yargsParser from 'yargs-parser'; +import { InitArgs } from '../command-line/init'; import { readJsonFile, writeJsonFile } from '../utils/fileutils'; +import { output } from '../utils/output'; +import { PackageJson } from '../utils/package-json'; +import { + getPackageManagerCommand, + PackageManagerCommands, +} from '../utils/package-manager'; +import { joinPathFragments } from '../utils/path'; import { addDepsToPackageJson, askAboutNxCloud, @@ -9,22 +16,14 @@ import { initCloud, runInstall, } from './utils'; -import { joinPathFragments } from '../utils/path'; -import { PackageJson } from '../utils/package-json'; -import { - getPackageManagerCommand, - PackageManagerCommands, -} from '../utils/package-manager'; + +type Options = Pick; const parsedArgs = yargsParser(process.argv, { - boolean: ['yes'], string: ['cacheable'], // only used for testing - alias: { - yes: ['y'], - }, }); -export async function addNxToNpmRepo() { +export async function addNxToNpmRepo(options: Options) { const repoRoot = process.cwd(); output.log({ title: `🐳 Nx initialization` }); @@ -38,7 +37,7 @@ export async function addNxToNpmRepo() { (s) => !s.startsWith('pre') && !s.startsWith('post') ); - if (parsedArgs.yes !== true) { + if (options.interactive) { output.log({ title: `🧑‍🔧 Please answer the following questions about the scripts found in your package.json in order to generate task runner configuration`, }); @@ -68,12 +67,13 @@ export async function addNxToNpmRepo() { )[scriptName]; } - useCloud = await askAboutNxCloud(); + useCloud = + options.nxCloud === undefined ? await askAboutNxCloud() : options.nxCloud; } else { cacheableOperations = parsedArgs.cacheable ? parsedArgs.cacheable.split(',') : []; - useCloud = false; + useCloud = options.nxCloud ?? false; } createNxJsonFile(repoRoot, [], cacheableOperations, {}); diff --git a/packages/nx/src/nx-init/angular/index.ts b/packages/nx/src/nx-init/angular/index.ts index 5c0173131883ca..e14bddeb95e4be 100644 --- a/packages/nx/src/nx-init/angular/index.ts +++ b/packages/nx/src/nx-init/angular/index.ts @@ -1,5 +1,6 @@ import { prompt } from 'enquirer'; import { join } from 'path'; +import { InitArgs } from '../../command-line/init'; import { readJsonFile, writeJsonFile } from '../../utils/fileutils'; import { sortObjectByKeys } from '../../utils/object-sort'; import { output } from '../../utils/output'; @@ -13,7 +14,7 @@ import { import { setupIntegratedWorkspace } from './integrated-workspace'; import { getLegacyMigrationFunctionIfApplicable } from './legacy-angular-versions'; import { setupStandaloneWorkspace } from './standalone-workspace'; -import type { AngularJsonConfig } from './types'; +import type { AngularJsonConfig, Options } from './types'; import yargsParser = require('yargs-parser'); const defaultCacheableOperations: string[] = [ @@ -23,24 +24,19 @@ const defaultCacheableOperations: string[] = [ 'lint', ]; const parsedArgs = yargsParser(process.argv, { - boolean: ['yes'], string: ['cacheable'], // only used for testing - alias: { - yes: ['y'], - }, }); let repoRoot: string; let workspaceTargets: string[]; -export async function addNxToAngularCliRepo(integrated: boolean) { +export async function addNxToAngularCliRepo(options: Options) { repoRoot = process.cwd(); output.log({ title: '🧐 Checking versions compatibility' }); const legacyMigrationFn = await getLegacyMigrationFunctionIfApplicable( repoRoot, - integrated, - parsedArgs.yes !== true + options ); if (legacyMigrationFn) { output.log({ title: '💽 Running migration for a legacy Angular version' }); @@ -54,16 +50,19 @@ export async function addNxToAngularCliRepo(integrated: boolean) { }); output.log({ title: '🐳 Nx initialization' }); - const cacheableOperations = !integrated - ? await collectCacheableOperations() + const cacheableOperations = !options.integrated + ? await collectCacheableOperations(options.interactive) : []; - const useNxCloud = parsedArgs.yes !== true ? await askAboutNxCloud() : false; + const useNxCloud = + options.interactive && options.nxCloud === undefined + ? await askAboutNxCloud() + : options.nxCloud ?? false; output.log({ title: '📦 Installing dependencies' }); installDependencies(useNxCloud); output.log({ title: '📝 Setting up workspace' }); - await setupWorkspace(cacheableOperations, integrated); + await setupWorkspace(cacheableOperations, options.integrated); if (useNxCloud) { output.log({ title: '🛠️ Setting up Nx Cloud' }); @@ -79,7 +78,9 @@ export async function addNxToAngularCliRepo(integrated: boolean) { }); } -async function collectCacheableOperations(): Promise { +async function collectCacheableOperations( + interactive: boolean +): Promise { let cacheableOperations: string[]; workspaceTargets = getWorkspaceTargets(); @@ -87,7 +88,7 @@ async function collectCacheableOperations(): Promise { (t) => workspaceTargets.includes(t) ); - if (parsedArgs.yes !== true) { + if (interactive) { output.log({ title: `🧑‍🔧 Please answer the following questions about the targets found in your angular.json in order to generate task runner configuration`, }); diff --git a/packages/nx/src/nx-init/angular/legacy-angular-versions.ts b/packages/nx/src/nx-init/angular/legacy-angular-versions.ts index 7ed4b9e2b756ad..3bddd0fb1a5f2c 100644 --- a/packages/nx/src/nx-init/angular/legacy-angular-versions.ts +++ b/packages/nx/src/nx-init/angular/legacy-angular-versions.ts @@ -6,12 +6,13 @@ import { sortObjectByKeys } from '../../utils/object-sort'; import { output } from '../../utils/output'; import { readModulePackageJson } from '../../utils/package-json'; import { - PackageManagerCommands, getPackageManagerCommand, + PackageManagerCommands, resolvePackageVersionUsingInstallation, resolvePackageVersionUsingRegistry, } from '../../utils/package-manager'; import { askAboutNxCloud, initCloud } from '../utils'; +import type { Options } from './types'; // map of Angular major versions to Nx versions to use for legacy `nx init` migrations, // key is major Angular version and value is Nx version to use @@ -23,8 +24,7 @@ const versionWithConsolidatedPackages = '13.9.0'; export async function getLegacyMigrationFunctionIfApplicable( repoRoot: string, - isIntegratedMigration: boolean, - interactive: boolean + options: Options ): Promise<() => Promise | null> { const angularVersion = readModulePackageJson('@angular/core').packageJson.version; @@ -44,7 +44,7 @@ export async function getLegacyMigrationFunctionIfApplicable( pkgName, `^${majorAngularVersion}.0.0` ); - const preserveAngularCliLayoutFlag = !isIntegratedMigration + const preserveAngularCliLayoutFlag = !options.integrated ? '--preserveAngularCLILayout' : '--preserveAngularCLILayout=false'; legacyMigrationCommand = `ng g ${pkgName}:ng-add ${preserveAngularCliLayoutFlag}`; @@ -52,7 +52,7 @@ export async function getLegacyMigrationFunctionIfApplicable( // for v13, the migration was in @nrwl/angular:ng-add pkgName = '@nrwl/angular'; pkgVersion = await resolvePackageVersion(pkgName, '~14.1.0'); - const preserveAngularCliLayoutFlag = !isIntegratedMigration + const preserveAngularCliLayoutFlag = !options.integrated ? '--preserve-angular-cli-layout' : '--preserve-angular-cli-layout=false'; legacyMigrationCommand = `ng g ${pkgName}:ng-add ${preserveAngularCliLayoutFlag}`; @@ -70,7 +70,10 @@ export async function getLegacyMigrationFunctionIfApplicable( return async () => { output.log({ title: '🐳 Nx initialization' }); - const useNxCloud = interactive ? await askAboutNxCloud() : false; + const useNxCloud = + options.interactive && options.nxCloud === undefined + ? await askAboutNxCloud() + : options.nxCloud ?? false; output.log({ title: '📦 Installing dependencies' }); const pmc = getPackageManagerCommand(); diff --git a/packages/nx/src/nx-init/angular/types.ts b/packages/nx/src/nx-init/angular/types.ts index 6ef86db7852c99..7630d4cc511ead 100644 --- a/packages/nx/src/nx-init/angular/types.ts +++ b/packages/nx/src/nx-init/angular/types.ts @@ -1,5 +1,8 @@ +import { InitArgs } from '../../command-line/init'; import type { TargetConfiguration } from '../../config/workspace-json-project-json'; +export type Options = Pick; + export type AngularJsonConfigTargetConfiguration = Exclude< TargetConfiguration, 'command' | 'executor' | 'outputs' | 'dependsOn' | 'inputs' diff --git a/packages/nx/src/nx-init/react/index.ts b/packages/nx/src/nx-init/react/index.ts index e219dc37282723..f14c04c68a667c 100644 --- a/packages/nx/src/nx-init/react/index.ts +++ b/packages/nx/src/nx-init/react/index.ts @@ -1,14 +1,15 @@ import { execSync } from 'child_process'; import { copySync, moveSync, readdirSync, removeSync } from 'fs-extra'; import { join } from 'path'; -import * as yargsParser from 'yargs-parser'; +import { InitArgs } from '../../command-line/init'; import { fileExists, readJsonFile } from '../../utils/fileutils'; import { output } from '../../utils/output'; import { - PackageManagerCommands, detectPackageManager, getPackageManagerCommand, + PackageManagerCommands, } from '../../utils/package-manager'; +import { askAboutNxCloud } from '../utils'; import { checkForCustomWebpackSetup } from './check-for-custom-webpack-setup'; import { checkForUncommittedChanges } from './check-for-uncommitted-changes'; import { cleanUpFiles } from './clean-up-files'; @@ -20,15 +21,9 @@ import { writeCracoConfig } from './write-craco-config'; import { writeViteConfig } from './write-vite-config'; import { writeViteIndexHtml } from './write-vite-index-html'; -export interface Options { - force: boolean; - e2e: boolean; - nxCloud: boolean; - vite: boolean; - integrated: boolean; -} +type Options = InitArgs; -interface NormalizedOptions extends Options { +type NormalizedOptions = Options & { packageManager: string; pmc: PackageManagerCommands; appIsJs: boolean; @@ -37,31 +32,17 @@ interface NormalizedOptions extends Options { npxYesFlagNeeded: boolean; isVite: boolean; isStandalone: boolean; -} +}; -const parsedArgs = yargsParser(process.argv, { - boolean: ['force', 'e2e', 'nxCloud', 'vite'], - default: { - nxCloud: true, - vite: true, - }, - configuration: { - 'strip-dashed': true, - }, -}); - -export async function addNxToCraRepo(integrated: boolean) { - if (!parsedArgs.force) { +export async function addNxToCraRepo(options: Options) { + if (!options.force) { checkForUncommittedChanges(); checkForCustomWebpackSetup(); } output.log({ title: '✨ Nx initialization' }); - const normalizedOptions = normalizeOptions( - parsedArgs as unknown as Options, - integrated - ); + const normalizedOptions = await normalizeOptions(options); await reorgnizeWorkspaceStructure(normalizedOptions); } @@ -71,10 +52,7 @@ function addDependencies(pmc: PackageManagerCommands, ...deps: string[]) { execSync(`${pmc.addDev} ${depsArg}`, { stdio: [0, 1, 2] }); } -function normalizeOptions( - options: Options, - integrated: boolean -): NormalizedOptions { +async function normalizeOptions(options: Options): Promise { const packageManager = detectPackageManager(); const pmc = getPackageManagerCommand(packageManager); @@ -91,10 +69,16 @@ function normalizeOptions( // Should remove this check 04/2023 once Node 14 & npm 6 reach EOL const npxYesFlagNeeded = !npmVersion.startsWith('6'); // npm 7 added -y flag to npx const isVite = options.vite; - const isStandalone = !integrated; + const isStandalone = !options.integrated; + + const nxCloud = + options.interactive && options.nxCloud === undefined + ? await askAboutNxCloud() + : options.nxCloud ?? false; return { ...options, + nxCloud, packageManager, pmc, appIsJs, @@ -103,7 +87,6 @@ function normalizeOptions( npxYesFlagNeeded, isVite, isStandalone, - integrated, }; } @@ -314,7 +297,7 @@ function cleanUpUnusedFilesAndAddConfigFiles(options: NormalizedOptions) { setupTsConfig(options.reactAppName, options.isStandalone); - if (options.e2e && !options.isStandalone) { + if (options.addE2e && !options.isStandalone) { output.log({ title: '📃 Setup e2e tests' }); setupE2eProject(options.reactAppName); } else {