Skip to content
Closed
48 changes: 36 additions & 12 deletions local-cli/runIOS/runIOS.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,16 @@ const findMatchingSimulator = require('./findMatchingSimulator');
const getBuildPath = function(configuration = 'Debug', appName, isDevice) {
return `build/Build/Products/${configuration}-${isDevice ? 'iphoneos' : 'iphonesimulator'}/${appName}.app`;
};
const xcprettyAvailable = function() {
try {
child_process.execSync('xcpretty --version', {
stdio: [ 0, 'pipe', 'ignore', ]
});
} catch (error) {
return false;
}
return true;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no-trailing-spaces: Trailing spaces not allowed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@eslint-bot Idk what you're smoking.

};

function runIOS(argv, config, args) {
if (!fs.existsSync(args.projectPath)) {
Expand Down Expand Up @@ -48,7 +58,7 @@ function runIOS(argv, config, args) {
if (args.device) {
const selectedDevice = matchingDevice(devices, args.device);
if (selectedDevice) {
return runOnDevice(selectedDevice, scheme, xcodeProject, args.configuration, args.packager);
return runOnDevice(selectedDevice, scheme, xcodeProject, args.configuration, args.packager, args.verbose);
} else {
if (devices && devices.length > 0) {
console.log('Could not find device with the name: "' + args.device + '".');
Expand All @@ -68,7 +78,7 @@ 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);
return runOnDevice(selectedDevice, scheme, xcodeProject, args.configuration, args.packager, args.verbose);
} else {
if (devices && devices.length > 0) {
console.log('Could not find device with the udid: "' + args.udid + '".');
Expand Down Expand Up @@ -103,9 +113,9 @@ function runOnSimulator(xcodeProject, args, scheme) {
// instruments always fail with 255 because it expects more arguments,
// but we want it to only launch the simulator
}
resolve(selectedSimulator.udid)
resolve(selectedSimulator.udid);
})
.then((udid) => buildProject(xcodeProject, udid, scheme, args.configuration, args.packager))
.then((udid) => buildProject(xcodeProject, udid, scheme, args.configuration, args.packager, args.verbose))
.then((appName) => {
if (!appName) {
appName = scheme;
Expand All @@ -122,11 +132,11 @@ function runOnSimulator(xcodeProject, args, scheme) {

console.log(`Launching ${bundleID}`);
child_process.spawnSync('xcrun', ['simctl', 'launch', 'booted', bundleID], {stdio: 'inherit'});
})
});
}

function runOnDevice(selectedDevice, scheme, xcodeProject, configuration, launchPackager) {
return buildProject(xcodeProject, selectedDevice.udid, scheme, configuration, launchPackager)
function runOnDevice(selectedDevice, scheme, xcodeProject, configuration, launchPackager, verbose) {
return buildProject(xcodeProject, selectedDevice.udid, scheme, configuration, launchPackager, verbose)
.then((appName) => {
if (!appName) {
appName = scheme;
Expand All @@ -149,7 +159,7 @@ function runOnDevice(selectedDevice, scheme, xcodeProject, configuration, launch
});
}

function buildProject(xcodeProject, udid, scheme, configuration = 'Debug', launchPackager = false) {
function buildProject(xcodeProject, udid, scheme, configuration = 'Debug', launchPackager = false, verbose) {
return new Promise((resolve,reject) =>
{
var xcodebuildArgs = [
Expand All @@ -160,30 +170,41 @@ function buildProject(xcodeProject, udid, scheme, configuration = 'Debug', launc
'-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] });
}
const buildProcess = child_process.spawn('xcodebuild', xcodebuildArgs, getProcessOptions(launchPackager));
let buildOutput = "";
let buildOutput = '';
buildProcess.stdout.on('data', function(data) {
console.log(data.toString());
buildOutput += data.toString();
if (xcpretty) {
xcpretty.stdin.write(data);
} else {
console.log(data.toString());
}
});
buildProcess.stderr.on('data', function(data) {
console.error(data.toString());
});
buildProcess.on('close', function(code) {
if (xcpretty) {
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
}
return buildProcess.error? reject(buildProcess.error) : resolve();
return buildProcess.error ? reject(buildProcess.error) : resolve();
});
});
}

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.`)
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--) {
Expand Down Expand Up @@ -263,5 +284,8 @@ module.exports = {
}, {
command: '--no-packager',
description: 'Do not launch packager while building',
}, {
command: '--verbose',
description: 'Do not use xcpretty even if installed',
}],
};