diff --git a/docs/commands.md b/docs/commands.md index eab8776ab..cad3114da 100644 --- a/docs/commands.md +++ b/docs/commands.md @@ -101,6 +101,7 @@ Skip dependencies installation Determine if CocoaPods should be installed when initializing a project. If set to `true` it will install pods, if set to `false`, it will skip the step entirely. If not used, prompt will be displayed #### `--npm` + > [!WARNING] > `--npm` is deprecated and will be removed in the future. Please use `--pm npm` instead. @@ -117,6 +118,10 @@ Create project with custom package name for Android and bundle identifier for iO - contain at least two segments separated by dots, e.g. `com.example` - contain only alphanumeric characters and dots +#### `--replace-directory ` + +Replaces the directory if it already exists + ### `upgrade` Usage: diff --git a/packages/cli/src/commands/init/errors/DirectoryAlreadyExistsError.ts b/packages/cli/src/commands/init/errors/DirectoryAlreadyExistsError.ts new file mode 100644 index 000000000..38828df97 --- /dev/null +++ b/packages/cli/src/commands/init/errors/DirectoryAlreadyExistsError.ts @@ -0,0 +1,9 @@ +import {CLIError} from '@react-native-community/cli-tools'; + +export default class DirectoryAlreadyExistsError extends CLIError { + constructor(directory: string) { + super( + `Cannot initialize new project because directory "${directory}" already exists. Please remove or rename the directory and try again.`, + ); + } +} diff --git a/packages/cli/src/commands/init/index.ts b/packages/cli/src/commands/init/index.ts index be2aaee2f..4d7e00d0f 100644 --- a/packages/cli/src/commands/init/index.ts +++ b/packages/cli/src/commands/init/index.ts @@ -47,5 +47,9 @@ export default { description: 'Inits a project with a custom package name (Android) and bundle ID (iOS), e.g. com.example.app', }, + { + name: '--replace-directory [boolean]', + description: 'Replaces the directory if it already exists.', + }, ], }; diff --git a/packages/cli/src/commands/init/init.ts b/packages/cli/src/commands/init/init.ts index 92aeeb461..42bdb7702 100644 --- a/packages/cli/src/commands/init/init.ts +++ b/packages/cli/src/commands/init/init.ts @@ -29,6 +29,7 @@ import {getYarnVersionIfAvailable} from '../../tools/yarn'; import {createHash} from 'crypto'; import createGitRepository from './createGitRepository'; import deepmerge from 'deepmerge'; +import DirectoryAlreadyExistsError from './errors/DirectoryAlreadyExistsError'; const DEFAULT_VERSION = 'latest'; @@ -43,6 +44,7 @@ type Options = { version?: string; packageName?: string; installPods?: string | boolean; + replaceDirectory?: string | boolean; }; interface TemplateOptions { @@ -55,6 +57,7 @@ interface TemplateOptions { skipInstall?: boolean; packageName?: string; installCocoaPods?: string | boolean; + replaceDirectory?: string | boolean; } function doesDirectoryExist(dir: string) { @@ -65,11 +68,21 @@ function getConflictsForDirectory(directory: string) { return readdirSync(directory); } -async function setProjectDirectory(directory: string) { +async function setProjectDirectory( + directory: string, + replaceDirectory: string, +) { const directoryExists = doesDirectoryExist(directory); + + if (replaceDirectory === 'false' && directoryExists) { + throw new DirectoryAlreadyExistsError(directory); + } + let deleteDirectory = false; - if (directoryExists) { + if (replaceDirectory === 'true' && directoryExists) { + deleteDirectory = true; + } else if (directoryExists) { const conflicts = getConflictsForDirectory(directory); if (conflicts.length > 0) { @@ -92,9 +105,7 @@ async function setProjectDirectory(directory: string) { deleteDirectory = replace; if (!replace) { - throw new CLIError( - 'Please remove files manually, or choose other directory.', - ); + throw new DirectoryAlreadyExistsError(directory); } } } @@ -146,6 +157,7 @@ async function createFromTemplate({ skipInstall, packageName, installCocoaPods, + replaceDirectory, }: TemplateOptions) { logger.debug('Initializing new project'); logger.log(banner); @@ -168,7 +180,10 @@ async function createFromTemplate({ packageManager = 'npm'; } - const projectDirectory = await setProjectDirectory(directory); + const projectDirectory = await setProjectDirectory( + directory, + String(replaceDirectory), + ); const loader = getLoader({text: 'Downloading template'}); const templateSourceDir = fs.mkdtempSync( @@ -381,6 +396,7 @@ async function createProject( skipInstall: options.skipInstall, packageName: options.packageName, installCocoaPods: options.installPods, + replaceDirectory: options.replaceDirectory, }); }