Prettier RN local-cli

Reviewed By: yungsters

Differential Revision: D7962462

fbshipit-source-id: 0afe2092af8703895de91a6d1400315c3173aa6d
This commit is contained in:
Eli White
2018-05-11 12:43:49 -07:00
committed by Facebook Github Bot
parent 680fb50040
commit aba4ec0c09
209 changed files with 3167 additions and 2071 deletions

View File

@@ -1,9 +1,12 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
* Copyright (c) 2015-present, Facebook, Inc.
*
* 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 child_process = require('child_process');
@@ -13,7 +16,7 @@ const findXcodeProject = require('./findXcodeProject');
const findReactNativeScripts = require('../util/findReactNativeScripts');
const parseIOSDevicesList = require('./parseIOSDevicesList');
const findMatchingSimulator = require('./findMatchingSimulator');
const getBuildPath = function (configuration = 'Debug', appName, isDevice) {
const getBuildPath = function(configuration = 'Debug', appName, isDevice) {
let device;
if (isDevice) {
@@ -29,7 +32,7 @@ const getBuildPath = function (configuration = 'Debug', appName, isDevice) {
const xcprettyAvailable = function() {
try {
child_process.execSync('xcpretty --version', {
stdio: [ 0, 'pipe', 'ignore', ]
stdio: [0, 'pipe', 'ignore'],
});
} catch (error) {
return false;
@@ -44,11 +47,13 @@ function runIOS(argv, config, args) {
child_process.spawnSync(
reactNativeScriptsPath,
['ios'].concat(process.argv.slice(1)),
{stdio: 'inherit'}
{stdio: 'inherit'},
);
return;
} else {
throw new Error('iOS project folder not found. Are you sure this is a React Native project?');
throw new Error(
'iOS project folder not found. Are you sure this is a React Native project?',
);
}
}
process.chdir(args.projectPath);
@@ -57,19 +62,38 @@ function runIOS(argv, config, args) {
throw new Error('Could not find Xcode project files in ios folder');
}
const inferredSchemeName = path.basename(xcodeProject.name, path.extname(xcodeProject.name));
const inferredSchemeName = path.basename(
xcodeProject.name,
path.extname(xcodeProject.name),
);
const scheme = args.scheme || inferredSchemeName;
console.log(`Found Xcode ${xcodeProject.isWorkspace ? 'workspace' : 'project'} ${xcodeProject.name}`);
console.log(
`Found Xcode ${xcodeProject.isWorkspace ? 'workspace' : 'project'} ${
xcodeProject.name
}`,
);
const devices = parseIOSDevicesList(
child_process.execFileSync('xcrun', ['instruments', '-s'], {encoding: 'utf8'})
child_process.execFileSync('xcrun', ['instruments', '-s'], {
encoding: 'utf8',
}),
);
if (args.device) {
const selectedDevice = matchingDevice(devices, args.device);
if (selectedDevice) {
return runOnDevice(selectedDevice, scheme, xcodeProject, args.configuration, args.packager, args.verbose, args.port);
return runOnDevice(
selectedDevice,
scheme,
xcodeProject,
args.configuration,
args.packager,
args.verbose,
args.port,
);
} else {
if (devices && devices.length > 0) {
console.log('Could not find device with the name: "' + args.device + '".');
console.log(
'Could not find device with the name: "' + args.device + '".',
);
console.log('Choose one of the following:');
printFoundDevices(devices);
} else {
@@ -86,7 +110,15 @@ function runIOS(argv, config, args) {
function runOnDeviceByUdid(args, scheme, xcodeProject, devices) {
const selectedDevice = matchingDeviceByUdid(devices, args.udid);
if (selectedDevice) {
return runOnDevice(selectedDevice, scheme, xcodeProject, args.configuration, args.packager, args.verbose, args.port);
return runOnDevice(
selectedDevice,
scheme,
xcodeProject,
args.configuration,
args.packager,
args.verbose,
args.port,
);
} else {
if (devices && devices.length > 0) {
console.log('Could not find device with the udid: "' + args.udid + '".');
@@ -99,10 +131,14 @@ function runOnDeviceByUdid(args, scheme, xcodeProject, devices) {
}
function runOnSimulator(xcodeProject, args, scheme) {
return new Promise((resolve) => {
return new Promise(resolve => {
try {
var simulators = JSON.parse(
child_process.execFileSync('xcrun', ['simctl', 'list', '--json', 'devices'], {encoding: 'utf8'})
child_process.execFileSync(
'xcrun',
['simctl', 'list', '--json', 'devices'],
{encoding: 'utf8'},
),
);
} catch (e) {
throw new Error('Could not parse the simulator list output');
@@ -112,71 +148,110 @@ function runOnSimulator(xcodeProject, args, scheme) {
if (!selectedSimulator) {
throw new Error(`Could not find ${args.simulator} simulator`);
}
/**
* Booting simulator through `xcrun simctl boot` will boot it in the `headless` mode
* (running in the background).
*
* In order for user to see the app and the simulator itself, we have to make sure
* that the Simulator.app is running.
*
* We also pass it `-CurrentDeviceUDID` so that when we launch it for the first time,
* it will not boot the "default" device, but the one we set. If the app is already running,
* this flag has no effect.
*/
child_process.execFileSync('open', [
'/Applications/Xcode.app/Contents/Developer/Applications/Simulator.app',
'--args',
'-CurrentDeviceUDID',
selectedSimulator.udid
]);
* Booting simulator through `xcrun simctl boot` will boot it in the `headless` mode
* (running in the background).
*
* In order for user to see the app and the simulator itself, we have to make sure
* that the Simulator.app is running.
*
* We also pass it `-CurrentDeviceUDID` so that when we launch it for the first time,
* it will not boot the "default" device, but the one we set. If the app is already running,
* this flag has no effect.
*/
child_process.execFileSync('open', [
'/Applications/Xcode.app/Contents/Developer/Applications/Simulator.app',
'--args',
'-CurrentDeviceUDID',
selectedSimulator.udid,
]);
if (!selectedSimulator.booted) {
const simulatorFullName = formattedDeviceName(selectedSimulator);
console.log(`Launching ${simulatorFullName}...`);
try {
child_process.spawnSync('xcrun', ['instruments', '-w', selectedSimulator.udid]);
child_process.spawnSync('xcrun', [
'instruments',
'-w',
selectedSimulator.udid,
]);
} catch (e) {
// instruments always fail with 255 because it expects more arguments,
// but we want it to only launch the simulator
}
}
buildProject(xcodeProject, selectedSimulator.udid, scheme, args.configuration, args.packager, args.verbose, args.port)
.then((appName) => resolve({ udid: selectedSimulator.udid, appName }));
})
.then(({udid, appName}) => {
buildProject(
xcodeProject,
selectedSimulator.udid,
scheme,
args.configuration,
args.packager,
args.verbose,
args.port,
).then(appName => resolve({udid: selectedSimulator.udid, appName}));
}).then(({udid, appName}) => {
if (!appName) {
appName = scheme;
}
let appPath = getBuildPath(args.configuration, appName);
console.log(`Installing ${appPath}`);
child_process.spawnSync('xcrun', ['simctl', 'install', udid, appPath], {stdio: 'inherit'});
child_process.spawnSync('xcrun', ['simctl', 'install', udid, appPath], {
stdio: 'inherit',
});
const bundleID = child_process.execFileSync(
'/usr/libexec/PlistBuddy',
['-c', 'Print:CFBundleIdentifier', path.join(appPath, 'Info.plist')],
{encoding: 'utf8'}
).trim();
const bundleID = child_process
.execFileSync(
'/usr/libexec/PlistBuddy',
['-c', 'Print:CFBundleIdentifier', path.join(appPath, 'Info.plist')],
{encoding: 'utf8'},
)
.trim();
console.log(`Launching ${bundleID}`);
child_process.spawnSync('xcrun', ['simctl', 'launch', udid, bundleID], {stdio: 'inherit'});
child_process.spawnSync('xcrun', ['simctl', 'launch', udid, bundleID], {
stdio: 'inherit',
});
});
}
function runOnDevice(selectedDevice, scheme, xcodeProject, configuration, launchPackager, verbose, port) {
return buildProject(xcodeProject, selectedDevice.udid, scheme, configuration, launchPackager, verbose, port)
.then((appName) => {
function runOnDevice(
selectedDevice,
scheme,
xcodeProject,
configuration,
launchPackager,
verbose,
port,
) {
return buildProject(
xcodeProject,
selectedDevice.udid,
scheme,
configuration,
launchPackager,
verbose,
port,
).then(appName => {
if (!appName) {
appName = scheme;
}
const iosDeployInstallArgs = [
'--bundle', getBuildPath(configuration, appName, true),
'--id' , selectedDevice.udid,
'--justlaunch'
'--bundle',
getBuildPath(configuration, appName, true),
'--id',
selectedDevice.udid,
'--justlaunch',
];
console.log(`installing and launching your app on ${selectedDevice.name}...`);
const iosDeployOutput = child_process.spawnSync('ios-deploy', iosDeployInstallArgs, {encoding: 'utf8'});
console.log(
`installing and launching your app on ${selectedDevice.name}...`,
);
const iosDeployOutput = child_process.spawnSync(
'ios-deploy',
iosDeployInstallArgs,
{encoding: 'utf8'},
);
if (iosDeployOutput.error) {
console.log('');
console.log('** INSTALLATION FAILED **');
@@ -188,22 +263,42 @@ function runOnDevice(selectedDevice, scheme, xcodeProject, configuration, launch
});
}
function buildProject(xcodeProject, udid, scheme, configuration = 'Debug', launchPackager = false, verbose, port) {
return new Promise((resolve,reject) =>
{
var xcodebuildArgs = [
xcodeProject.isWorkspace ? '-workspace' : '-project', xcodeProject.name,
'-configuration', configuration,
'-scheme', scheme,
'-destination', `id=${udid}`,
'-derivedDataPath', 'build',
function buildProject(
xcodeProject,
udid,
scheme,
configuration = 'Debug',
launchPackager = false,
verbose,
port,
) {
return new Promise((resolve, reject) => {
var xcodebuildArgs = [
xcodeProject.isWorkspace ? '-workspace' : '-project',
xcodeProject.name,
'-configuration',
configuration,
'-scheme',
scheme,
'-destination',
`id=${udid}`,
'-derivedDataPath',
'build',
];
console.log(`Building using "xcodebuild ${xcodebuildArgs.join(' ')}"`);
let xcpretty;
if (!verbose) {
xcpretty = xcprettyAvailable() && child_process.spawn('xcpretty', [], { stdio: ['pipe', process.stdout, process.stderr] });
xcpretty =
xcprettyAvailable() &&
child_process.spawn('xcpretty', [], {
stdio: ['pipe', process.stdout, process.stderr],
});
}
const buildProcess = child_process.spawn('xcodebuild', xcodebuildArgs, getProcessOptions(launchPackager, port));
const buildProcess = child_process.spawn(
'xcodebuild',
xcodebuildArgs,
getProcessOptions(launchPackager, port),
);
let buildOutput = '';
buildProcess.stdout.on('data', function(data) {
buildOutput += data.toString();
@@ -221,9 +316,15 @@ function buildProject(xcodeProject, udid, scheme, configuration = 'Debug', launc
xcpretty.stdin.end();
}
//FULL_PRODUCT_NAME is the actual file name of the app, which actually comes from the Product Name in the build config, which does not necessary match a scheme name, example output line: export FULL_PRODUCT_NAME="Super App Dev.app"
let productNameMatch = /export FULL_PRODUCT_NAME="?(.+).app"?$/m.exec(buildOutput);
if (productNameMatch && productNameMatch.length && productNameMatch.length > 1) {
return resolve(productNameMatch[1]);//0 is the full match, 1 is the app name
let productNameMatch = /export FULL_PRODUCT_NAME="?(.+).app"?$/m.exec(
buildOutput,
);
if (
productNameMatch &&
productNameMatch.length &&
productNameMatch.length > 1
) {
return resolve(productNameMatch[1]); //0 is the full match, 1 is the app name
}
return buildProcess.error ? reject(buildProcess.error) : resolve();
});
@@ -231,13 +332,19 @@ function buildProject(xcodeProject, udid, scheme, configuration = 'Debug', launc
}
function matchingDevice(devices, deviceName) {
if (deviceName === true && devices.length === 1)
{
console.log(`Using first available device ${devices[0].name} due to lack of name supplied.`);
if (deviceName === true && devices.length === 1) {
console.log(
`Using first available device ${
devices[0].name
} due to lack of name supplied.`,
);
return devices[0];
}
for (let i = devices.length - 1; i >= 0; i--) {
if (devices[i].name === deviceName || formattedDeviceName(devices[i]) === deviceName) {
if (
devices[i].name === deviceName ||
formattedDeviceName(devices[i]) === deviceName
) {
return devices[i];
}
}
@@ -264,12 +371,12 @@ function printFoundDevices(devices) {
function getProcessOptions(launchPackager, port) {
if (launchPackager) {
return {
env: { ...process.env, RCT_METRO_PORT: port }
env: {...process.env, RCT_METRO_PORT: port},
};
}
return {
env: { ...process.env, RCT_NO_LAUNCH_PACKAGER: true },
env: {...process.env, RCT_NO_LAUNCH_PACKAGER: true},
};
}
@@ -278,53 +385,66 @@ module.exports = {
description: 'builds your app and starts it on iOS simulator',
func: runIOS,
examples: [
{
desc: 'Run on a different simulator, e.g. iPhone 5',
cmd: 'react-native run-ios --simulator "iPhone 5"',
},
{
desc: 'Pass a non-standard location of iOS directory',
cmd: 'react-native run-ios --project-path "./app/ios"',
},
{
desc: "Run on a connected device, e.g. Max's iPhone",
cmd: 'react-native run-ios --device "Max\'s iPhone"',
},
{
desc: 'Run on the AppleTV simulator',
cmd: 'react-native run-ios --simulator "Apple TV" --scheme "helloworld-tvOS"',
}
{
desc: 'Run on a different simulator, e.g. iPhone 5',
cmd: 'react-native run-ios --simulator "iPhone 5"',
},
{
desc: 'Pass a non-standard location of iOS directory',
cmd: 'react-native run-ios --project-path "./app/ios"',
},
{
desc: "Run on a connected device, e.g. Max's iPhone",
cmd: 'react-native run-ios --device "Max\'s iPhone"',
},
{
desc: 'Run on the AppleTV simulator',
cmd:
'react-native run-ios --simulator "Apple TV" --scheme "helloworld-tvOS"',
},
],
options: [
{
command: '--simulator [string]',
description: 'Explicitly set simulator to use',
default: 'iPhone 6',
},
{
command: '--configuration [string]',
description: 'Explicitly set the scheme configuration to use',
},
{
command: '--scheme [string]',
description: 'Explicitly set Xcode scheme to use',
},
{
command: '--project-path [string]',
description:
'Path relative to project root where the Xcode project ' +
"(.xcodeproj) lives. The default is 'ios'.",
default: 'ios',
},
{
command: '--device [string]',
description:
'Explicitly set device to use by name. The value is not required if you have a single device connected.',
},
{
command: '--udid [string]',
description: 'Explicitly set device to use by udid',
},
{
command: '--no-packager',
description: 'Do not launch packager while building',
},
{
command: '--verbose',
description: 'Do not use xcpretty even if installed',
},
{
command: '--port [number]',
default: process.env.RCT_METRO_PORT || 8081,
parse: (val: string) => Number(val),
},
],
options: [{
command: '--simulator [string]',
description: 'Explicitly set simulator to use',
default: 'iPhone 6',
} , {
command: '--configuration [string]',
description: 'Explicitly set the scheme configuration to use',
} , {
command: '--scheme [string]',
description: 'Explicitly set Xcode scheme to use',
}, {
command: '--project-path [string]',
description: 'Path relative to project root where the Xcode project '
+ '(.xcodeproj) lives. The default is \'ios\'.',
default: 'ios',
}, {
command: '--device [string]',
description: 'Explicitly set device to use by name. The value is not required if you have a single device connected.',
}, {
command: '--udid [string]',
description: 'Explicitly set device to use by udid',
}, {
command: '--no-packager',
description: 'Do not launch packager while building',
}, {
command: '--verbose',
description: 'Do not use xcpretty even if installed',
},{
command: '--port [number]',
default: process.env.RCT_METRO_PORT || 8081,
parse: (val: string) => Number(val),
}],
};