From 2e02e36b9ed9c93aed5893e6cfbd900b685242c4 Mon Sep 17 00:00:00 2001
From: Ville Immonen <ville.immonen@iki.fi>
Date: Sat, 10 Dec 2016 03:11:14 +0200
Subject: [PATCH] Clean up Yarn detection and install code (#1223)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* Remove the “‘yarn’ is not recognized as an internal or external
  command, ...” message on Windows
* Simplify the detection code: just run `yarn --version` – if it
  succeeds use `yarn`, if it fails use `npm`.
---
 packages/create-react-app/index.js | 63 ++++++++++++------------------
 1 file changed, 24 insertions(+), 39 deletions(-)

diff --git a/packages/create-react-app/index.js b/packages/create-react-app/index.js
index 403e89edf..e6295ec51 100644
--- a/packages/create-react-app/index.js
+++ b/packages/create-react-app/index.js
@@ -40,6 +40,7 @@
 
 var fs = require('fs');
 var path = require('path');
+var execSync = require('child_process').execSync;
 var spawn = require('cross-spawn');
 var chalk = require('chalk');
 var semver = require('semver');
@@ -107,49 +108,33 @@ function createApp(name, verbose, version) {
   run(root, appName, version, verbose, originalDirectory);
 }
 
+function shouldUseYarn() {
+  try {
+    execSync('yarn --version', {stdio: 'ignore'});
+    return true;
+  } catch (e) {
+    return false;
+  }
+}
+
 function install(packageToInstall, verbose, callback) {
-  function fallbackToNpm() {
-    var npmArgs = [
-      'install',
-      verbose && '--verbose',
-      '--save-dev',
-      '--save-exact',
-      packageToInstall,
-    ].filter(function(e) { return e; });
-    var npmProc = spawn('npm', npmArgs, {stdio: 'inherit'});
-    npmProc.on('close', function (code) {
-      callback(code, 'npm', npmArgs);
-    });
+  var command;
+  var args;
+  if (shouldUseYarn()) {
+    command = 'yarn';
+    args = [ 'add', '--dev', '--exact', packageToInstall];
+  } else {
+    command = 'npm';
+    args = ['install', '--save-dev', '--save-exact', packageToInstall];
   }
 
-  var yarnArgs = [
-    'add',
-    '--dev',
-    '--exact',
-    packageToInstall,
-  ];
-  var yarnProc;
-  var yarnExists = true;
-  try {
-    yarnProc = spawn('yarn', yarnArgs, {stdio: 'inherit'});
-  } catch (err) {
-    // It's not clear why we end up here in some cases but we need this.
-    // https://github.com/facebookincubator/create-react-app/issues/1200
-    yarnExists = false;
-    fallbackToNpm();
-    return;
+  if (verbose) {
+    args.push('--verbose');
   }
-  yarnProc.on('error', function (err) {
-    if (err.code === 'ENOENT') {
-      yarnExists = false;
-    }
-  });
-  yarnProc.on('close', function (code) {
-    if (yarnExists) {
-      callback(code, 'yarn', yarnArgs);
-    } else {
-      fallbackToNpm();
-    }
+
+  var child = spawn(command, args, {stdio: 'inherit'});
+  child.on('close', function(code) {
+    callback(code, command, args);
   });
 }
 
-- 
GitLab