Martin Konicek 4411ad49a4 More descriptive error message when Gradle build/install fails
Summary: Inspired by: https://twitter.com/geirmanc/status/660275638637477889

There are many reasons why the Gradle build could fail and the best
thing to do is to read the error message.

We can provide some hints in the most common cases though.

public

Reviewed By: vjeux

Differential Revision: D2604747

fb-gh-sync-id: 1aa83abb9ec823c03814dcc31d630a8f1914cf5c
2015-11-03 03:48:26 -08:00

153 lines
4.6 KiB
JavaScript

/**
* 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.
*/
'use strict';
const chalk = require('chalk');
const child_process = require('child_process');
const fs = require('fs');
const path = require('path');
const parseCommandLine = require('../util/parseCommandLine');
const isPackagerRunning = require('../util/isPackagerRunning');
const Promise = require('promise');
/**
* Starts the app on a connected Android emulator or device.
*/
function runAndroid(argv, config) {
return new Promise((resolve, reject) => {
_runAndroid(argv, config, resolve, reject);
});
}
function _runAndroid(argv, config, resolve, reject) {
const args = parseCommandLine([{
command: 'install-debug',
type: 'string',
required: false,
}], argv);
if (!checkAndroid()) {
console.log(chalk.red('Android project not found. Maybe run react-native android first?'));
return;
}
resolve(isPackagerRunning().then(result => {
if (result === 'running') {
console.log(chalk.bold('JS server already running.'));
} else if (result === 'unrecognized') {
console.warn(chalk.yellow('JS server not recognized, continuing with build...'));
} else {
// result == 'not_running'
console.log(chalk.bold('Starting JS server...'));
startServerInNewWindow();
}
buildAndRun(args, reject);
}));
}
// Verifies this is an Android project
function checkAndroid() {
return fs.existsSync('android/gradlew');
}
// Builds the app and runs it on a connected emulator / device.
function buildAndRun(args, reject) {
process.chdir('android');
try {
const cmd = process.platform.startsWith('win')
? 'gradlew.bat'
: './gradlew';
const gradleArgs = ['installDebug'];
if (args['install-debug']) {
gradleArgs.push(args['install-debug']);
}
console.log(chalk.bold(
'Building and installing the app on the device (cd android && ' + cmd +
' ' + gradleArgs.join(' ') + ')...'
));
child_process.execFileSync(cmd, gradleArgs, {
stdio: [process.stdin, process.stdout, process.stderr],
});
} catch (e) {
console.log(chalk.red(
'Could not install the app on the device, read the error above for details.\n' +
'Make sure you have an Android emulator running or a device connected and have\n' +
'set up your Android development environment:\n' +
'https://facebook.github.io/react-native/docs/android-setup.html'
));
// stderr is automatically piped from the gradle process, so the user
// should see the error already, there is no need to do
// `console.log(e.stderr)`
reject();
return;
}
try {
const packageName = fs.readFileSync(
'app/src/main/AndroidManifest.xml',
'utf8'
).match(/package="(.+?)"/)[1];
const adbPath = process.env.ANDROID_HOME
? process.env.ANDROID_HOME + '/platform-tools/adb'
: 'adb';
const adbArgs = [
'shell', 'am', 'start', '-n', packageName + '/.MainActivity'
];
console.log(chalk.bold(
'Starting the app (' + adbPath + ' ' + adbArgs.join(' ') + ')...'
));
child_process.spawnSync(adbPath, adbArgs, {stdio: 'inherit'});
} catch (e) {
console.log(chalk.red(
'adb invocation failed. Do you have adb in your PATH?'
));
// stderr is automatically piped from the gradle process, so the user
// should see the error already, there is no need to do
// `console.log(e.stderr)`
reject();
return;
}
}
function startServerInNewWindow() {
const launchPackagerScript = path.resolve(
__dirname, '..', '..', '..', 'packager', 'launchPackager.command'
);
if (process.platform === 'darwin') {
child_process.spawnSync('open', [launchPackagerScript]);
} else if (process.platform === 'linux') {
child_process.spawn(
'xterm',
['-e', 'sh', launchPackagerScript],
{detached: true}
);
} else if (/^win/.test(process.platform)) {
console.log(chalk.yellow('Starting the packager in a new window ' +
'is not supported on Windows yet.\nPlease start it manually using ' +
'\'react-native start\'.'));
console.log('We believe the best Windows ' +
'support will come from a community of people\nusing React Native on ' +
'Windows on a daily basis.\n' +
'Would you be up for sending a pull request?');
} else {
console.log(chalk.red('Cannot start the packager. Unknown platform ' +
process.platform));
}
}
module.exports = runAndroid;