Make the CLI recognize CRNA projects

Summary:
1. Make running `react-native run-ios` or `react-native run-android`
inside a project created with Create React Native App run the
corresponding react-native-scripts command instead of failing.

    **Before**:
    <img width="762" alt="screen shot 2017-07-21 at 16 55 32" src="https://user-images.githubusercontent.com/497214/28467425-86b309c8-6e38-11e7-8946-139bda927d93.png"><img width="762" alt="screen shot 2017-07-21 at 16 55 52" src="https://user-images.githubusercontent.com/497214/28467436-8df02482-6e38-11e7-8a03-3fa664944cac.png">
    **After**:
    <img width="762" alt="screen shot 2017-07-21 at 16 52 15" src="https://user-images.githubusercontent.com/497214/28467522-e4bb6cae-6e38-11e7-97bb-9cfa9cb4dc67.png">

2. Make running `react-native link` inside a CRNA project display a
helpful error message.

    **Before**:
    <img width="762" alt="screen shot 2017-07-21 at 16 55 10" src="https://user-images.githubusercontent.com/497214/28467608-1d1781fa-6e39-11e7-9620-cc16c8b1b40f.png">
    **After**:
    <img width="762" alt="screen shot 2017-07-21 at 16 53 10" src="https://user-images.githubusercontent.com/497214/28467637-2cd6ed1a-6e39-11e7-8947-6df69b3f321e.png">

Fixes #14828.

* Run `react-native run-ios`, `react-native run-android` and `react-native link` in:
  * A CRNA project (screenshot above)
  * A traditional RN project (existing behaviour)
  * A folder that contains neither (existing behaviour)
Closes https://github.com/facebook/react-native/pull/15139

Differential Revision: D5498914

Pulled By: hramos

fbshipit-source-id: 94b6196e3451857bbaa45335a01643c89bed19a0
This commit is contained in:
Ville Immonen 2017-08-03 11:55:40 -07:00 committed by Facebook Github Bot
parent 6e2e53f49b
commit 6f4025e322
4 changed files with 64 additions and 1 deletions

View File

@ -30,6 +30,7 @@ const getDependencyConfig = require('./getDependencyConfig');
const pollParams = require('./pollParams'); const pollParams = require('./pollParams');
const commandStub = require('./commandStub'); const commandStub = require('./commandStub');
const promisify = require('./promisify'); const promisify = require('./promisify');
const findReactNativeScripts = require('../util/findReactNativeScripts');
import type {RNConfig} from '../core'; import type {RNConfig} from '../core';
@ -147,6 +148,16 @@ function link(args: Array<string>, config: RNConfig) {
return Promise.reject(err); return Promise.reject(err);
} }
if (!project.android && !project.ios && !project.windows && findReactNativeScripts()) {
throw new Error(
'`react-native link` can not be used in Create React Native App projects. ' +
'If you need to include a library that relies on custom native code, ' +
'you might have to eject first. ' +
'See https://github.com/react-community/create-react-native-app/blob/master/EJECTING.md ' +
'for more information.'
);
}
let packageName = args[0]; let packageName = args[0];
// Check if install package by specific version (eg. package@latest) // Check if install package by specific version (eg. package@latest)
if (packageName !== undefined) { if (packageName !== undefined) {

View File

@ -13,6 +13,7 @@ const chalk = require('chalk');
const child_process = require('child_process'); const child_process = require('child_process');
const fs = require('fs'); const fs = require('fs');
const isPackagerRunning = require('../util/isPackagerRunning'); const isPackagerRunning = require('../util/isPackagerRunning');
const findReactNativeScripts = require('../util/findReactNativeScripts');
const isString = require('lodash/isString'); const isString = require('lodash/isString');
const path = require('path'); const path = require('path');
const Promise = require('promise'); const Promise = require('promise');
@ -27,7 +28,16 @@ function checkAndroid(root) {
*/ */
function runAndroid(argv, config, args) { function runAndroid(argv, config, args) {
if (!checkAndroid(args.root)) { if (!checkAndroid(args.root)) {
console.log(chalk.red('Android project not found. Maybe run react-native android first?')); const reactNativeScriptsPath = findReactNativeScripts();
if (reactNativeScriptsPath) {
child_process.spawnSync(
reactNativeScriptsPath,
['android'].concat(process.argv.slice(1)),
{stdio: 'inherit'}
);
} else {
console.log(chalk.red('Android project not found. Maybe run react-native android first?'));
}
return; return;
} }

View File

@ -12,6 +12,7 @@ const child_process = require('child_process');
const fs = require('fs'); const fs = require('fs');
const path = require('path'); const path = require('path');
const findXcodeProject = require('./findXcodeProject'); const findXcodeProject = require('./findXcodeProject');
const findReactNativeScripts = require('../util/findReactNativeScripts');
const parseIOSDevicesList = require('./parseIOSDevicesList'); const parseIOSDevicesList = require('./parseIOSDevicesList');
const findMatchingSimulator = require('./findMatchingSimulator'); const findMatchingSimulator = require('./findMatchingSimulator');
const getBuildPath = function(configuration = 'Debug', appName, isDevice) { const getBuildPath = function(configuration = 'Debug', appName, isDevice) {
@ -19,6 +20,19 @@ const getBuildPath = function(configuration = 'Debug', appName, isDevice) {
}; };
function runIOS(argv, config, args) { function runIOS(argv, config, args) {
if (!fs.existsSync(args.projectPath)) {
const reactNativeScriptsPath = findReactNativeScripts();
if (reactNativeScriptsPath) {
child_process.spawnSync(
reactNativeScriptsPath,
['ios'].concat(process.argv.slice(1)),
{stdio: 'inherit'}
);
return;
} else {
throw new Error('iOS project folder not found. Are you sure this is a React Native project?');
}
}
process.chdir(args.projectPath); process.chdir(args.projectPath);
const xcodeProject = findXcodeProject(fs.readdirSync('.')); const xcodeProject = findXcodeProject(fs.readdirSync('.'));
if (!xcodeProject) { if (!xcodeProject) {

View File

@ -0,0 +1,28 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* @flow
*/
'use strict';
const path = require('path');
const fs = require('fs');
function findReactNativeScripts(): ?string {
const executablePath = path.resolve(
'node_modules',
'.bin',
'react-native-scripts'
);
if (fs.existsSync(executablePath)) {
return executablePath;
}
return null;
}
module.exports = findReactNativeScripts;