From e26b8d9f889ee1692713d9d9446b20940c30b19a Mon Sep 17 00:00:00 2001
From: Rifat Nabi <to.rifat@gmail.com>
Date: Mon, 8 Aug 2016 10:05:58 +0600
Subject: [PATCH] Creating a new app in the current directory (#368)

* Creating a new app in the current directory

* Fixed style mistakes
---
 global-cli/index.js     | 24 ++++++++++++++++++------
 global-cli/package.json |  1 +
 package.json            |  1 +
 scripts/init.js         | 24 +++++++++++++++++++++++-
 4 files changed, 43 insertions(+), 7 deletions(-)

diff --git a/global-cli/index.js b/global-cli/index.js
index d1319aba0..e8dc5a718 100644
--- a/global-cli/index.js
+++ b/global-cli/index.js
@@ -41,6 +41,7 @@ var spawn = require('cross-spawn');
 var chalk = require('chalk');
 var semver = require('semver');
 var argv = require('minimist')(process.argv.slice(2));
+var pathExists = require('path-exists');
 
 /**
  * Arguments:
@@ -67,21 +68,20 @@ if (commands.length === 0) {
 createApp(commands[0], argv.verbose, argv['scripts-version']);
 
 function createApp(name, verbose, version) {
-  if (fs.existsSync(name)) {
-    console.log('The directory `' + name + '` already exists. Aborting.');
+  var root = path.resolve(name);
+  if (!pathExists.sync(name)) {
+    fs.mkdirSync(root);
+  } else if (!isGitHubBoilerplate(root)) {
+    console.log('The directory `' + name + '` contains file(s) that could conflict. Aborting.');
     process.exit(1);
   }
 
-  var root = path.resolve(name);
   var appName = path.basename(root);
-
   console.log(
     'Creating a new React app in ' + root + '.'
   );
   console.log();
 
-  fs.mkdirSync(root);
-
   var packageJson = {
     name: appName,
     version: '0.0.1',
@@ -166,3 +166,15 @@ function checkNodeVersion() {
     process.exit(1);
   }
 }
+
+// Check if GitHub boilerplate compatible
+// https://github.com/facebookincubator/create-react-app/pull/368#issuecomment-237875655
+function isGitHubBoilerplate(root) {
+  var validFiles = [
+    '.DS_Store', 'Thumbs.db', '.git', '.gitignore', 'README.md', 'LICENSE'
+  ];
+  return fs.readdirSync(root)
+    .every(function(file) {
+      return validFiles.indexOf(file) >= 0;
+    });
+}
diff --git a/global-cli/package.json b/global-cli/package.json
index 3e98c4c93..8d038be67 100644
--- a/global-cli/package.json
+++ b/global-cli/package.json
@@ -20,6 +20,7 @@
     "chalk": "^1.1.1",
     "cross-spawn": "^4.0.0",
     "minimist": "^1.2.0",
+    "path-exists": "^3.0.0",
     "semver": "^5.0.3"
   }
 }
diff --git a/package.json b/package.json
index bf3d853af..accba6a05 100644
--- a/package.json
+++ b/package.json
@@ -66,6 +66,7 @@
     "jest": "14.1.0",
     "json-loader": "0.5.4",
     "opn": "4.0.2",
+    "path-exists": "^3.0.0",
     "postcss-loader": "0.9.1",
     "promise": "7.1.1",
     "recursive-readdir": "2.0.0",
diff --git a/scripts/init.js b/scripts/init.js
index 50cc9d25b..074fe428a 100644
--- a/scripts/init.js
+++ b/scripts/init.js
@@ -10,6 +10,8 @@
 var fs = require('fs-extra');
 var path = require('path');
 var spawn = require('cross-spawn');
+var pathExists = require('path-exists');
+var chalk = require('chalk');
 
 module.exports = function(appPath, appName, verbose, originalDirectory) {
   var ownPath = path.join(appPath, 'node_modules', 'react-scripts');
@@ -43,12 +45,28 @@ module.exports = function(appPath, appName, verbose, originalDirectory) {
     JSON.stringify(appPackage, null, 2)
   );
 
+  var readmeExists = pathExists.sync(path.join(appPath, 'README.md'));
+  if (readmeExists) {
+    fs.renameSync(path.join(appPath, 'README.md'), path.join(appPath, 'README.old.md'));
+  }
+
   // Copy the files for the user
   fs.copySync(path.join(ownPath, 'template'), appPath);
 
   // Rename gitignore after the fact to prevent npm from renaming it to .npmignore
   // See: https://github.com/npm/npm/issues/1862
-  fs.move(path.join(appPath, 'gitignore'), path.join(appPath, '.gitignore'), []);
+  fs.move(path.join(appPath, 'gitignore'), path.join(appPath, '.gitignore'), [], function (err) {
+    if (err) {
+      // Append if there's already a `.gitignore` file there
+      if (err.code === 'EEXIST') {
+        var data = fs.readFileSync(path.join(appPath, 'gitignore'));
+        fs.appendFileSync(path.join(appPath, '.gitignore'), data);
+        fs.unlinkSync(path.join(appPath, 'gitignore'));
+      } else {
+        throw err;
+      }
+    }
+  });
 
   // Run another npm install for react and react-dom
   console.log('Installing react and react-dom from npm...');
@@ -88,6 +106,10 @@ module.exports = function(appPath, appName, verbose, originalDirectory) {
     console.log();
     console.log('  cd', cdpath);
     console.log('  npm start');
+    if (readmeExists) {
+      console.log();
+      console.log(chalk.yellow('You had a `README.md` file, we renamed it to `README.old.md`'));
+    }
     console.log();
     console.log('Happy hacking!');
   });
-- 
GitLab