mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-04-22 19:48:56 +08:00
Prettier RN local-cli
Reviewed By: yungsters Differential Revision: D7962462 fbshipit-source-id: 0afe2092af8703895de91a6d1400315c3173aa6d
This commit is contained in:
committed by
Facebook Github Bot
parent
680fb50040
commit
aba4ec0c09
@@ -4,6 +4,7 @@
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
* @flow
|
||||
*/
|
||||
|
||||
@@ -21,7 +22,7 @@ function parseDevicesResult(result: string): Array<string> {
|
||||
const lines = result.trim().split(/\r?\n/);
|
||||
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
let words = lines[i].split(/[ ,\t]+/).filter((w) => w !== '');
|
||||
let words = lines[i].split(/[ ,\t]+/).filter(w => w !== '');
|
||||
|
||||
if (words[1] === 'device') {
|
||||
devices.push(words[0]);
|
||||
@@ -40,11 +41,9 @@ function getDevices(): Array<string> {
|
||||
} catch (e) {
|
||||
return [];
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
parseDevicesResult: parseDevicesResult,
|
||||
getDevices: getDevices
|
||||
getDevices: getDevices,
|
||||
};
|
||||
|
||||
@@ -3,7 +3,10 @@
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const adb = require('./adb');
|
||||
@@ -31,10 +34,14 @@ function runAndroid(argv, config, args) {
|
||||
child_process.spawnSync(
|
||||
reactNativeScriptsPath,
|
||||
['android'].concat(process.argv.slice(1)),
|
||||
{stdio: 'inherit'}
|
||||
{stdio: 'inherit'},
|
||||
);
|
||||
} else {
|
||||
console.log(chalk.red('Android project not found. Maybe run react-native android first?'));
|
||||
console.log(
|
||||
chalk.red(
|
||||
'Android project not found. Maybe run react-native android first?',
|
||||
),
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -47,7 +54,9 @@ function runAndroid(argv, config, args) {
|
||||
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...'));
|
||||
console.warn(
|
||||
chalk.yellow('JS server not recognized, continuing with build...'),
|
||||
);
|
||||
} else {
|
||||
// result == 'not_running'
|
||||
console.log(chalk.bold('Starting JS server...'));
|
||||
@@ -74,9 +83,7 @@ function tryRunAdbReverse(packagerPort, device) {
|
||||
adbArgs.unshift('-s', device);
|
||||
}
|
||||
|
||||
console.log(chalk.bold(
|
||||
`Running ${adbPath} ${adbArgs.join(' ')}`
|
||||
));
|
||||
console.log(chalk.bold(`Running ${adbPath} ${adbArgs.join(' ')}`));
|
||||
|
||||
child_process.execFileSync(adbPath, adbArgs, {
|
||||
stdio: [process.stdin, process.stdout, process.stderr],
|
||||
@@ -99,21 +106,28 @@ function getPackageNameWithSuffix(appId, appIdSuffix, packageName) {
|
||||
// Builds the app and runs it on a connected emulator / device.
|
||||
function buildAndRun(args) {
|
||||
process.chdir(path.join(args.root, 'android'));
|
||||
const cmd = process.platform.startsWith('win')
|
||||
? 'gradlew.bat'
|
||||
: './gradlew';
|
||||
const cmd = process.platform.startsWith('win') ? 'gradlew.bat' : './gradlew';
|
||||
|
||||
const packageName = fs.readFileSync(
|
||||
`${args.appFolder}/src/main/AndroidManifest.xml`,
|
||||
'utf8'
|
||||
).match(/package="(.+?)"/)[1];
|
||||
const packageName = fs
|
||||
.readFileSync(`${args.appFolder}/src/main/AndroidManifest.xml`, 'utf8')
|
||||
.match(/package="(.+?)"/)[1];
|
||||
|
||||
const packageNameWithSuffix = getPackageNameWithSuffix(args.appId, args.appIdSuffix, packageName);
|
||||
const packageNameWithSuffix = getPackageNameWithSuffix(
|
||||
args.appId,
|
||||
args.appIdSuffix,
|
||||
packageName,
|
||||
);
|
||||
|
||||
const adbPath = getAdbPath();
|
||||
if (args.deviceId) {
|
||||
if (isString(args.deviceId)) {
|
||||
runOnSpecificDevice(args, cmd, packageNameWithSuffix, packageName, adbPath);
|
||||
runOnSpecificDevice(
|
||||
args,
|
||||
cmd,
|
||||
packageNameWithSuffix,
|
||||
packageName,
|
||||
adbPath,
|
||||
);
|
||||
} else {
|
||||
console.log(chalk.red('Argument missing for parameter --deviceId'));
|
||||
}
|
||||
@@ -122,14 +136,28 @@ function buildAndRun(args) {
|
||||
}
|
||||
}
|
||||
|
||||
function runOnSpecificDevice(args, gradlew, packageNameWithSuffix, packageName, adbPath) {
|
||||
function runOnSpecificDevice(
|
||||
args,
|
||||
gradlew,
|
||||
packageNameWithSuffix,
|
||||
packageName,
|
||||
adbPath,
|
||||
) {
|
||||
let devices = adb.getDevices();
|
||||
if (devices && devices.length > 0) {
|
||||
if (devices.indexOf(args.deviceId) !== -1) {
|
||||
buildApk(gradlew);
|
||||
installAndLaunchOnDevice(args, args.deviceId, packageNameWithSuffix, packageName, adbPath);
|
||||
installAndLaunchOnDevice(
|
||||
args,
|
||||
args.deviceId,
|
||||
packageNameWithSuffix,
|
||||
packageName,
|
||||
adbPath,
|
||||
);
|
||||
} else {
|
||||
console.log('Could not find device with the id: "' + args.deviceId + '".');
|
||||
console.log(
|
||||
'Could not find device with the id: "' + args.deviceId + '".',
|
||||
);
|
||||
console.log('Choose one of the following:');
|
||||
console.log(devices);
|
||||
}
|
||||
@@ -147,62 +175,104 @@ function buildApk(gradlew) {
|
||||
stdio: [process.stdin, process.stdout, process.stderr],
|
||||
});
|
||||
} catch (e) {
|
||||
console.log(chalk.red('Could not build the app, read the error above for details.\n'));
|
||||
console.log(
|
||||
chalk.red('Could not build the app, read the error above for details.\n'),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function tryInstallAppOnDevice(args, device) {
|
||||
try {
|
||||
const pathToApk = `${args.appFolder}/build/outputs/apk/${args.appFolder}-debug.apk`;
|
||||
const pathToApk = `${args.appFolder}/build/outputs/apk/${
|
||||
args.appFolder
|
||||
}-debug.apk`;
|
||||
const adbPath = getAdbPath();
|
||||
const adbArgs = ['-s', device, 'install', pathToApk];
|
||||
console.log(chalk.bold(
|
||||
`Installing the app on the device (cd android && adb -s ${device} install ${pathToApk}`
|
||||
));
|
||||
console.log(
|
||||
chalk.bold(
|
||||
`Installing the app on the device (cd android && adb -s ${device} install ${pathToApk}`,
|
||||
),
|
||||
);
|
||||
child_process.execFileSync(adbPath, adbArgs, {
|
||||
stdio: [process.stdin, process.stdout, process.stderr],
|
||||
});
|
||||
} catch (e) {
|
||||
console.log(e.message);
|
||||
console.log(chalk.red(
|
||||
'Could not install the app on the device, read the error above for details.\n'
|
||||
));
|
||||
console.log(
|
||||
chalk.red(
|
||||
'Could not install the app on the device, read the error above for details.\n',
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function tryLaunchAppOnDevice(device, packageNameWithSuffix, packageName, adbPath, mainActivity) {
|
||||
function tryLaunchAppOnDevice(
|
||||
device,
|
||||
packageNameWithSuffix,
|
||||
packageName,
|
||||
adbPath,
|
||||
mainActivity,
|
||||
) {
|
||||
try {
|
||||
const adbArgs = ['-s', device, 'shell', 'am', 'start', '-n', packageNameWithSuffix + '/' + packageName + '.' + mainActivity];
|
||||
console.log(chalk.bold(
|
||||
`Starting the app on ${device} (${adbPath} ${adbArgs.join(' ')})...`
|
||||
));
|
||||
const adbArgs = [
|
||||
'-s',
|
||||
device,
|
||||
'shell',
|
||||
'am',
|
||||
'start',
|
||||
'-n',
|
||||
packageNameWithSuffix + '/' + packageName + '.' + mainActivity,
|
||||
];
|
||||
console.log(
|
||||
chalk.bold(
|
||||
`Starting the app on ${device} (${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?'
|
||||
));
|
||||
console.log(
|
||||
chalk.red('adb invocation failed. Do you have adb in your PATH?'),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function installAndLaunchOnDevice(args, selectedDevice, packageNameWithSuffix, packageName, adbPath) {
|
||||
function installAndLaunchOnDevice(
|
||||
args,
|
||||
selectedDevice,
|
||||
packageNameWithSuffix,
|
||||
packageName,
|
||||
adbPath,
|
||||
) {
|
||||
tryRunAdbReverse(args.port, selectedDevice);
|
||||
tryInstallAppOnDevice(args, selectedDevice);
|
||||
tryLaunchAppOnDevice(selectedDevice, packageNameWithSuffix, packageName, adbPath, args.mainActivity);
|
||||
tryLaunchAppOnDevice(
|
||||
selectedDevice,
|
||||
packageNameWithSuffix,
|
||||
packageName,
|
||||
adbPath,
|
||||
args.mainActivity,
|
||||
);
|
||||
}
|
||||
|
||||
function runOnAllDevices(args, cmd, packageNameWithSuffix, packageName, adbPath){
|
||||
function runOnAllDevices(
|
||||
args,
|
||||
cmd,
|
||||
packageNameWithSuffix,
|
||||
packageName,
|
||||
adbPath,
|
||||
) {
|
||||
try {
|
||||
const gradleArgs = [];
|
||||
if (args.variant) {
|
||||
gradleArgs.push('install' +
|
||||
args.variant[0].toUpperCase() + args.variant.slice(1)
|
||||
gradleArgs.push(
|
||||
'install' + args.variant[0].toUpperCase() + args.variant.slice(1),
|
||||
);
|
||||
} else if (args.flavor) {
|
||||
console.warn(chalk.yellow(
|
||||
'--flavor has been deprecated. Use --variant instead'
|
||||
));
|
||||
gradleArgs.push('install' +
|
||||
args.flavor[0].toUpperCase() + args.flavor.slice(1)
|
||||
console.warn(
|
||||
chalk.yellow('--flavor has been deprecated. Use --variant instead'),
|
||||
);
|
||||
gradleArgs.push(
|
||||
'install' + args.flavor[0].toUpperCase() + args.flavor.slice(1),
|
||||
);
|
||||
} else {
|
||||
gradleArgs.push('installDebug');
|
||||
@@ -212,132 +282,186 @@ function runOnAllDevices(args, cmd, packageNameWithSuffix, packageName, adbPath)
|
||||
gradleArgs.push(args.installDebug);
|
||||
}
|
||||
|
||||
console.log(chalk.bold(
|
||||
`Building and installing the app on the device (cd android && ${cmd} ${gradleArgs.join(' ')})...`
|
||||
));
|
||||
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/getting-started.html'
|
||||
));
|
||||
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/getting-started.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)`
|
||||
return Promise.reject();
|
||||
}
|
||||
const devices = adb.getDevices();
|
||||
if (devices && devices.length > 0) {
|
||||
devices.forEach((device) => {
|
||||
tryRunAdbReverse(args.port, device);
|
||||
tryLaunchAppOnDevice(device, packageNameWithSuffix, packageName, adbPath, args.mainActivity);
|
||||
});
|
||||
} else {
|
||||
try {
|
||||
// If we cannot execute based on adb devices output, fall back to
|
||||
// shell am start
|
||||
const fallbackAdbArgs = [
|
||||
'shell', 'am', 'start', '-n', packageNameWithSuffix + '/' + packageName + '.MainActivity'
|
||||
];
|
||||
console.log(chalk.bold(
|
||||
`Starting the app (${adbPath} ${fallbackAdbArgs.join(' ')}...`
|
||||
));
|
||||
child_process.spawnSync(adbPath, fallbackAdbArgs, {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)`
|
||||
return Promise.reject();
|
||||
}
|
||||
const devices = adb.getDevices();
|
||||
if (devices && devices.length > 0) {
|
||||
devices.forEach(device => {
|
||||
tryRunAdbReverse(args.port, device);
|
||||
tryLaunchAppOnDevice(
|
||||
device,
|
||||
packageNameWithSuffix,
|
||||
packageName,
|
||||
adbPath,
|
||||
args.mainActivity,
|
||||
);
|
||||
});
|
||||
} else {
|
||||
try {
|
||||
// If we cannot execute based on adb devices output, fall back to
|
||||
// shell am start
|
||||
const fallbackAdbArgs = [
|
||||
'shell',
|
||||
'am',
|
||||
'start',
|
||||
'-n',
|
||||
packageNameWithSuffix + '/' + packageName + '.MainActivity',
|
||||
];
|
||||
console.log(
|
||||
chalk.bold(
|
||||
`Starting the app (${adbPath} ${fallbackAdbArgs.join(' ')}...`,
|
||||
),
|
||||
);
|
||||
child_process.spawnSync(adbPath, fallbackAdbArgs, {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)`
|
||||
return Promise.reject();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function startServerInNewWindow(port) {
|
||||
const scriptFile = /^win/.test(process.platform) ?
|
||||
'launchPackager.bat' :
|
||||
'launchPackager.command';
|
||||
const scriptFile = /^win/.test(process.platform)
|
||||
? 'launchPackager.bat'
|
||||
: 'launchPackager.command';
|
||||
const scriptsDir = path.resolve(__dirname, '..', '..', 'scripts');
|
||||
const launchPackagerScript = path.resolve(scriptsDir, scriptFile);
|
||||
const procConfig = {cwd: scriptsDir};
|
||||
const terminal = process.env.REACT_TERMINAL;
|
||||
|
||||
// setup the .packager.env file to ensure the packager starts on the right port
|
||||
const packagerEnvFile = path.join(__dirname, '..', '..', 'scripts', '.packager.env');
|
||||
const packagerEnvFile = path.join(
|
||||
__dirname,
|
||||
'..',
|
||||
'..',
|
||||
'scripts',
|
||||
'.packager.env',
|
||||
);
|
||||
const content = `export RCT_METRO_PORT=${port}`;
|
||||
// ensure we overwrite file by passing the 'w' flag
|
||||
fs.writeFileSync(packagerEnvFile, content, {encoding: 'utf8', flag: 'w'});
|
||||
|
||||
if (process.platform === 'darwin') {
|
||||
if (terminal) {
|
||||
return child_process.spawnSync('open', ['-a', terminal, launchPackagerScript], procConfig);
|
||||
return child_process.spawnSync(
|
||||
'open',
|
||||
['-a', terminal, launchPackagerScript],
|
||||
procConfig,
|
||||
);
|
||||
}
|
||||
return child_process.spawnSync('open', [launchPackagerScript], procConfig);
|
||||
|
||||
} else if (process.platform === 'linux') {
|
||||
procConfig.detached = true;
|
||||
if (terminal){
|
||||
return child_process.spawn(terminal, ['-e', 'sh ' + launchPackagerScript], procConfig);
|
||||
if (terminal) {
|
||||
return child_process.spawn(
|
||||
terminal,
|
||||
['-e', 'sh ' + launchPackagerScript],
|
||||
procConfig,
|
||||
);
|
||||
}
|
||||
return child_process.spawn('sh', [launchPackagerScript], procConfig);
|
||||
|
||||
} else if (/^win/.test(process.platform)) {
|
||||
procConfig.detached = true;
|
||||
procConfig.stdio = 'ignore';
|
||||
return child_process.spawn('cmd.exe', ['/C', launchPackagerScript], procConfig);
|
||||
return child_process.spawn(
|
||||
'cmd.exe',
|
||||
['/C', launchPackagerScript],
|
||||
procConfig,
|
||||
);
|
||||
} else {
|
||||
console.log(chalk.red(`Cannot start the packager. Unknown platform ${process.platform}`));
|
||||
console.log(
|
||||
chalk.red(
|
||||
`Cannot start the packager. Unknown platform ${process.platform}`,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
name: 'run-android',
|
||||
description: 'builds your app and starts it on a connected Android emulator or device',
|
||||
description:
|
||||
'builds your app and starts it on a connected Android emulator or device',
|
||||
func: runAndroid,
|
||||
options: [{
|
||||
command: '--install-debug',
|
||||
}, {
|
||||
command: '--root [string]',
|
||||
description: 'Override the root directory for the android build (which contains the android directory)',
|
||||
default: '',
|
||||
}, {
|
||||
command: '--flavor [string]',
|
||||
description: '--flavor has been deprecated. Use --variant instead',
|
||||
}, {
|
||||
command: '--variant [string]',
|
||||
}, {
|
||||
command: '--appFolder [string]',
|
||||
description: 'Specify a different application folder name for the android source.',
|
||||
default: 'app',
|
||||
}, {
|
||||
command: '--appId [string]',
|
||||
description: 'Specify an applicationId to launch after build.',
|
||||
default: '',
|
||||
}, {
|
||||
command: '--appIdSuffix [string]',
|
||||
description: 'Specify an applicationIdSuffix to launch after build.',
|
||||
default: '',
|
||||
}, {
|
||||
command: '--main-activity [string]',
|
||||
description: 'Name of the activity to start',
|
||||
default: 'MainActivity',
|
||||
}, {
|
||||
command: '--deviceId [string]',
|
||||
description: 'builds your app and starts it on a specific device/simulator with the ' +
|
||||
'given device id (listed by running "adb devices" on the command line).',
|
||||
}, {
|
||||
command: '--no-packager',
|
||||
description: 'Do not launch packager while building',
|
||||
}, {
|
||||
command: '--port [number]',
|
||||
default: process.env.RCT_METRO_PORT || 8081,
|
||||
parse: (val: string) => Number(val),
|
||||
}],
|
||||
options: [
|
||||
{
|
||||
command: '--install-debug',
|
||||
},
|
||||
{
|
||||
command: '--root [string]',
|
||||
description:
|
||||
'Override the root directory for the android build (which contains the android directory)',
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
command: '--flavor [string]',
|
||||
description: '--flavor has been deprecated. Use --variant instead',
|
||||
},
|
||||
{
|
||||
command: '--variant [string]',
|
||||
},
|
||||
{
|
||||
command: '--appFolder [string]',
|
||||
description:
|
||||
'Specify a different application folder name for the android source.',
|
||||
default: 'app',
|
||||
},
|
||||
{
|
||||
command: '--appId [string]',
|
||||
description: 'Specify an applicationId to launch after build.',
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
command: '--appIdSuffix [string]',
|
||||
description: 'Specify an applicationIdSuffix to launch after build.',
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
command: '--main-activity [string]',
|
||||
description: 'Name of the activity to start',
|
||||
default: 'MainActivity',
|
||||
},
|
||||
{
|
||||
command: '--deviceId [string]',
|
||||
description:
|
||||
'builds your app and starts it on a specific device/simulator with the ' +
|
||||
'given device id (listed by running "adb devices" on the command line).',
|
||||
},
|
||||
{
|
||||
command: '--no-packager',
|
||||
description: 'Do not launch packager while building',
|
||||
},
|
||||
{
|
||||
command: '--port [number]',
|
||||
default: process.env.RCT_METRO_PORT || 8081,
|
||||
parse: (val: string) => Number(val),
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user