Mark Rickert 62788a15f9 Allows a user to specify an xcode scheme name.
Summary:When running `react-native run-ios`, this feature allows a user to specify which scheme to run.

My project's scheme name is not the same as the xcode project name. Running `react-native run-ios` would error with the following:

```
± |master ↓95 ✓| → react-native run-ios
Found Xcode workspace Poot.xcworkspace
Launching iPhone 6 (9.2)...
Building using "xcodebuild -workspace Poot.xcworkspace -scheme Poot -destination id=2B3E8AAC-DD61-414C-95BD-F4829A8F7CE6 -derivedDataPath build"
User defaults from command line:
    IDEDerivedDataPathOverride = /Users/mrickert/Documents/project/ios/build

xcodebuild: error: The workspace named "Poot" does not contain a scheme named "Poot". The "-list" option can be used to find the names of the schemes in the workspace.
Installing build/Build/Products/Debug-iphonesimulator/Poot.app
An error was encountered processing the command (domain=NSPOSIXErrorDomain, code=2):
Failed to install the requested application
An application bundle was n
Closes https://github.com/facebook/react-native/pull/6157

Differential Revision: D3020313

Pulled By: frantic

fb-gh-sync-id: 9d99fa382b3f50045759acea18eff418b15d511d
shipit-source-id: 9d99fa382b3f50045759acea18eff418b15d511d
2016-03-07 14:26:25 -08:00

102 lines
3.4 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 child_process = require('child_process');
const fs = require('fs');
const path = require('path');
const parseCommandLine = require('../util/parseCommandLine');
const findXcodeProject = require('./findXcodeProject');
const parseIOSSimulatorsList = require('./parseIOSSimulatorsList');
const Promise = require('promise');
/**
* Starts the app on iOS simulator
*/
function runIOS(argv, config) {
return new Promise((resolve, reject) => {
_runIOS(argv, config, resolve, reject);
resolve();
});
}
function _runIOS(argv, config, resolve, reject) {
const args = parseCommandLine([{
command: 'simulator',
description: 'Explicitly set simulator to use',
type: 'string',
required: false,
default: 'iPhone 6',
}, {
command: 'scheme',
description: 'Explicitly set Xcode scheme to use',
type: 'string',
required: false,
}], argv);
process.chdir('ios');
const xcodeProject = findXcodeProject(fs.readdirSync('.'));
if (!xcodeProject) {
throw new Error(`Could not find Xcode project files in ios folder`);
}
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}`);
const simulators = parseIOSSimulatorsList(
child_process.execFileSync('xcrun', ['simctl', 'list', 'devices'], {encoding: 'utf8'})
);
const selectedSimulator = matchingSimulator(simulators, args.simulator);
if (!selectedSimulator) {
throw new Error(`Cound't find ${args.simulator} simulator`);
}
const simulatorFullName = `${selectedSimulator.name} (${selectedSimulator.version})`;
console.log(`Launching ${simulatorFullName}...`);
try {
child_process.spawnSync('xcrun', ['instruments', '-w', simulatorFullName]);
} catch(e) {
// instruments always fail with 255 because it expects more arguments,
// but we want it to only launch the simulator
}
const xcodebuildArgs = [
xcodeProject.isWorkspace ? '-workspace' : '-project', xcodeProject.name,
'-scheme', scheme,
'-destination', `id=${selectedSimulator.udid}`,
'-derivedDataPath', 'build',
];
console.log(`Building using "xcodebuild ${xcodebuildArgs.join(' ')}"`);
child_process.spawnSync('xcodebuild', xcodebuildArgs, {stdio: 'inherit'});
const appPath = `build/Build/Products/Debug-iphonesimulator/${inferredSchemeName}.app`;
console.log(`Installing ${appPath}`);
child_process.spawnSync('xcrun', ['simctl', 'install', 'booted', appPath], {stdio: 'inherit'});
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', 'booted', bundleID], {stdio: 'inherit'});
}
function matchingSimulator(simulators, simulatorName) {
for (let i = simulators.length - 1; i >= 0; i--) {
if (simulators[i].name === simulatorName) {
return simulators[i];
}
}
}
module.exports = runIOS;