11import os from 'os' ;
22import path from 'path' ;
3- import fs from 'fs-extra' ;
3+ import fs , { readdirSync } from 'fs-extra' ;
44import { validateProjectName } from './validate' ;
55import chalk from 'chalk' ;
6- import DirectoryAlreadyExistsError from './errors/DirectoryAlreadyExistsError' ;
76import printRunInstructions from './printRunInstructions' ;
87import {
98 CLIError ,
@@ -35,6 +34,7 @@ import {
3534} from './git' ;
3635import semver from 'semver' ;
3736import { executeCommand } from '../../tools/executeCommand' ;
37+ import DirectoryAlreadyExistsError from './errors/DirectoryAlreadyExistsError' ;
3838
3939const DEFAULT_VERSION = 'latest' ;
4040
@@ -51,6 +51,7 @@ type Options = {
5151 installPods ?: string | boolean ;
5252 platformName ?: string ;
5353 skipGitInit ?: boolean ;
54+ replaceDirectory ?: string | boolean ;
5455} ;
5556
5657interface TemplateOptions {
@@ -65,10 +66,12 @@ interface TemplateOptions {
6566 packageName ?: string ;
6667 installCocoaPods ?: string | boolean ;
6768 version ?: string ;
69+ replaceDirectory ?: string | boolean ;
6870}
6971
7072interface TemplateReturnType {
7173 didInstallPods ?: boolean ;
74+ replaceDirectory ?: string | boolean ;
7275}
7376
7477// Here we are defining explicit version of Yarn to be used in the new project because in some cases providing `3.x` don't work.
@@ -101,8 +104,58 @@ function doesDirectoryExist(dir: string) {
101104 return fs . existsSync ( dir ) ;
102105}
103106
104- async function setProjectDirectory ( directory : string ) {
107+ function getConflictsForDirectory ( directory : string ) {
108+ return readdirSync ( directory ) ;
109+ }
110+
111+ async function setProjectDirectory (
112+ directory : string ,
113+ replaceDirectory : string ,
114+ ) {
115+ const directoryExists = doesDirectoryExist ( directory ) ;
116+
117+ if ( replaceDirectory === 'false' && directoryExists ) {
118+ throw new DirectoryAlreadyExistsError ( directory ) ;
119+ }
120+
121+ let deleteDirectory = false ;
122+
123+ if ( replaceDirectory === 'true' && directoryExists ) {
124+ deleteDirectory = true ;
125+ } else if ( directoryExists ) {
126+ const conflicts = getConflictsForDirectory ( directory ) ;
127+
128+ if ( conflicts . length > 0 ) {
129+ let warnMessage = `The directory ${ chalk . bold (
130+ directory ,
131+ ) } contains files that will be overwritten:\n`;
132+
133+ for ( const conflict of conflicts ) {
134+ warnMessage += ` ${ conflict } \n` ;
135+ }
136+
137+ logger . warn ( warnMessage ) ;
138+
139+ const { replace} = await prompt ( {
140+ type : 'confirm' ,
141+ name : 'replace' ,
142+ message : 'Do you want to replace existing files?' ,
143+ } ) ;
144+
145+ deleteDirectory = replace ;
146+
147+ if ( ! replace ) {
148+ throw new DirectoryAlreadyExistsError ( directory ) ;
149+ }
150+ }
151+ }
152+
105153 try {
154+ if ( deleteDirectory ) {
155+ fs . removeSync ( directory ) ;
156+ }
157+
158+ fs . mkdirSync ( directory , { recursive : true } ) ;
106159 process . chdir ( directory ) ;
107160 } catch ( error ) {
108161 throw new CLIError (
@@ -145,6 +198,7 @@ async function createFromTemplate({
145198 skipInstall,
146199 packageName,
147200 installCocoaPods,
201+ replaceDirectory,
148202} : TemplateOptions ) : Promise < TemplateReturnType > {
149203 logger . debug ( 'Initializing new project' ) ;
150204 // Only print out the banner if we're not in a CI
@@ -173,7 +227,10 @@ async function createFromTemplate({
173227 // if the project with the name already has cache, remove the cache to avoid problems with pods installation
174228 cacheManager . removeProjectCache ( projectName ) ;
175229
176- const projectDirectory = await setProjectDirectory ( directory ) ;
230+ const projectDirectory = await setProjectDirectory (
231+ directory ,
232+ String ( replaceDirectory ) ,
233+ ) ;
177234
178235 const loader = getLoader ( { text : 'Downloading template' } ) ;
179236 const templateSourceDir = fs . mkdtempSync (
@@ -361,6 +418,7 @@ async function createProject(
361418 packageName : options . packageName ,
362419 installCocoaPods : options . installPods ,
363420 version,
421+ replaceDirectory : options . replaceDirectory ,
364422 } ) ;
365423}
366424
@@ -406,12 +464,6 @@ export default (async function initialize(
406464 return ;
407465 }
408466
409- if ( doesDirectoryExist ( projectFolder ) ) {
410- throw new DirectoryAlreadyExistsError ( directoryName ) ;
411- } else {
412- fs . mkdirSync ( projectFolder , { recursive : true } ) ;
413- }
414-
415467 let shouldBumpYarnVersion = true ;
416468 let shouldCreateGitRepository = false ;
417469
0 commit comments