diff --git a/README.md b/README.md index 1992401..71471f6 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,7 @@ STARTER Which template to setup (required) Options: --dir, -d DIR Destination directory (default: ./node-app) --project-name, -n NAME Google Cloud project name (default: directory basename) + --force, -f Overwrite existing destination directory if it's not empty --help, -h Show this help message Starters available: diff --git a/lib/Bootstrap.js b/lib/Bootstrap.js index 8fc846c..954e0cd 100644 --- a/lib/Bootstrap.js +++ b/lib/Bootstrap.js @@ -33,6 +33,13 @@ export class Bootstrap { default: 'node-app', description: 'Google Cloud project name', }) + .option('force', { + type: 'boolean', + alias: 'f', + default: false, + description: + "Overwrite existing destination directory if it's not empty", + }) .version('1.0.0') .help() const parsedArgs = cli.parseSync() @@ -66,7 +73,20 @@ export class Bootstrap { projectName: parsedArgs.projectName, }) starter.setToolbelt(toolbelt) - toolbelt.mkdir(destination, { overwrite: true }) + if (toolbelt.isDirectoryNonEmpty(destination)) { + if (!parsedArgs.force) { + logger.info( + `Directory '${destination}' already exists and is not empty.` + ) + logger.info( + 'Use --force or -f flag to overwrite the existing directory.' + ) + process.exit(1) + } else { + logger.info(`Overwriting existing directory '${destination}'`) + } + } + toolbelt.mkdir(destination, { overwrite: parsedArgs.force }) toolbelt.npm.init() starter.install() } diff --git a/lib/Bootstrap.js.map b/lib/Bootstrap.js.map index 514e438..494c2b4 100644 --- a/lib/Bootstrap.js.map +++ b/lib/Bootstrap.js.map @@ -1 +1 @@ -{"version":3,"file":"Bootstrap.js","sourceRoot":"","sources":["../src/Bootstrap.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"Bootstrap.js","sourceRoot":"","sources":["../src/Bootstrap.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/lib/Toolbelt.js b/lib/Toolbelt.js index c431e30..d808a4e 100644 --- a/lib/Toolbelt.js +++ b/lib/Toolbelt.js @@ -13,14 +13,31 @@ export class Toolbelt { stringToPath(str) { return path.normalize(str) } + isDirectoryNonEmpty(dirpath) { + const path = this.stringToPath(dirpath) + if (!fs.existsSync(path)) { + return false + } + const stat = fs.statSync(path) + if (!stat.isDirectory()) { + return false + } + const contents = fs.readdirSync(path) + return contents.length > 0 + } mkdir(dirpath, option) { dirpath = this.stringToPath(dirpath) const rootPath = ['.', './'] if (!rootPath.includes(dirpath)) { - if (fs.existsSync(dirpath) && option?.overwrite) { - fs.rmSync(dirpath, { recursive: true }) + if (fs.existsSync(dirpath)) { + if (option?.overwrite) { + fs.rmSync(dirpath, { recursive: true }) + fs.mkdirSync(dirpath, { recursive: true }) + } + // If directory exists and we're not overwriting, do nothing + } else { + fs.mkdirSync(dirpath, { recursive: true }) } - fs.mkdirSync(dirpath) } } /** diff --git a/lib/Toolbelt.js.map b/lib/Toolbelt.js.map index 52f0732..10b51d3 100644 --- a/lib/Toolbelt.js.map +++ b/lib/Toolbelt.js.map @@ -1 +1 @@ -{"version":3,"file":"Toolbelt.js","sourceRoot":"","sources":["../src/Toolbelt.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"Toolbelt.js","sourceRoot":"","sources":["../src/Toolbelt.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/src/Bootstrap.ts b/src/Bootstrap.ts index 41122ba..80895de 100644 --- a/src/Bootstrap.ts +++ b/src/Bootstrap.ts @@ -35,6 +35,13 @@ export class Bootstrap { default: 'node-app', description: 'Google Cloud project name', }) + .option('force', { + type: 'boolean', + alias: 'f', + default: false, + description: + "Overwrite existing destination directory if it's not empty", + }) .version('1.0.0') .help() @@ -73,7 +80,19 @@ export class Bootstrap { projectName: parsedArgs.projectName, }) starter.setToolbelt(toolbelt) - toolbelt.mkdir(destination, { overwrite: true }) + + if (!toolbelt.isDirectoryEmpty(destination)) { + if (!parsedArgs.force) { + logger.info( + `Directory '${destination}' already exists and is not empty. Use --force or -f flag to overwrite the existing directory.` + ) + process.exit(1) + } else { + logger.info(`Overwriting existing directory '${destination}'`) + } + } + + toolbelt.mkdir(destination, { overwrite: parsedArgs.force }) toolbelt.npm.init() starter.install() } diff --git a/src/Toolbelt.ts b/src/Toolbelt.ts index 089c0db..afba9ce 100644 --- a/src/Toolbelt.ts +++ b/src/Toolbelt.ts @@ -30,6 +30,23 @@ export class Toolbelt { public stringToPath(str: string) { return path.normalize(str) as Path } + + public isDirectoryEmpty(dirpath: string): boolean { + const path = this.stringToPath(dirpath) + + if (!fs.existsSync(path)) { + return true + } + + const stat = fs.statSync(path) + if (!stat.isDirectory()) { + return true + } + + const contents = fs.readdirSync(path) + return contents.length === 0 + } + public mkdir( dirpath: string, option?: { @@ -43,7 +60,7 @@ export class Toolbelt { if (fs.existsSync(dirpath) && option?.overwrite) { fs.rmSync(dirpath, { recursive: true }) } - fs.mkdirSync(dirpath) + fs.mkdirSync(dirpath, { recursive: true }) } } /**