summaryrefslogtreecommitdiff
path: root/StoneIsland/platforms/ios/cordova/lib/build.js
diff options
context:
space:
mode:
Diffstat (limited to 'StoneIsland/platforms/ios/cordova/lib/build.js')
-rw-r--r--[-rwxr-xr-x]StoneIsland/platforms/ios/cordova/lib/build.js276
1 files changed, 153 insertions, 123 deletions
diff --git a/StoneIsland/platforms/ios/cordova/lib/build.js b/StoneIsland/platforms/ios/cordova/lib/build.js
index f51b084c..a7203875 100755..100644
--- a/StoneIsland/platforms/ios/cordova/lib/build.js
+++ b/StoneIsland/platforms/ios/cordova/lib/build.js
@@ -17,38 +17,51 @@
* under the License.
*/
-var Q = require('q');
-var path = require('path');
-var shell = require('shelljs');
-var spawn = require('./spawn');
-var fs = require('fs');
-var plist = require('plist');
-var util = require('util');
+const path = require('path');
+const which = require('which');
+const {
+ CordovaError,
+ events,
+ superspawn: { spawn }
+} = require('cordova-common');
+const fs = require('fs-extra');
+const plist = require('plist');
+const util = require('util');
-var check_reqs = require('./check_reqs');
-var projectFile = require('./projectFile');
-
-var events = require('cordova-common').events;
-
-var projectPath = path.join(__dirname, '..', '..');
-var projectName = null;
+const check_reqs = require('./check_reqs');
+const projectFile = require('./projectFile');
// These are regular expressions to detect if the user is changing any of the built-in xcodebuildArgs
/* eslint-disable no-useless-escape */
-var buildFlagMatchers = {
- 'xcconfig': /^\-xcconfig\s*(.*)$/,
- 'workspace': /^\-workspace\s*(.*)/,
- 'scheme': /^\-scheme\s*(.*)/,
- 'configuration': /^\-configuration\s*(.*)/,
- 'sdk': /^\-sdk\s*(.*)/,
- 'destination': /^\-destination\s*(.*)/,
- 'archivePath': /^\-archivePath\s*(.*)/,
- 'configuration_build_dir': /^(CONFIGURATION_BUILD_DIR=.*)/,
- 'shared_precomps_dir': /^(SHARED_PRECOMPS_DIR=.*)/
+const buildFlagMatchers = {
+ workspace: /^\-workspace\s*(.*)/,
+ scheme: /^\-scheme\s*(.*)/,
+ configuration: /^\-configuration\s*(.*)/,
+ sdk: /^\-sdk\s*(.*)/,
+ destination: /^\-destination\s*(.*)/,
+ archivePath: /^\-archivePath\s*(.*)/,
+ configuration_build_dir: /^(CONFIGURATION_BUILD_DIR=.*)/,
+ shared_precomps_dir: /^(SHARED_PRECOMPS_DIR=.*)/
};
/* eslint-enable no-useless-escape */
/**
+ * Creates a project object (see projectFile.js/parseProjectFile) from
+ * a project path and name
+ *
+ * @param {*} projectPath
+ * @param {*} projectName
+ */
+function createProjectObject (projectPath, projectName) {
+ const locations = {
+ root: projectPath,
+ pbxproj: path.join(projectPath, `${projectName}.xcodeproj`, 'project.pbxproj')
+ };
+
+ return projectFile.parse(locations);
+}
+
+/**
* Returns a promise that resolves to the default simulator target; the logic here
* matches what `cordova emulate ios` does.
*
@@ -58,13 +71,13 @@ var buildFlagMatchers = {
* @return {Promise}
*/
function getDefaultSimulatorTarget () {
- return require('./list-emulator-build-targets').run()
- .then(function (emulators) {
- var targetEmulator;
+ return require('./listEmulatorBuildTargets').run()
+ .then(emulators => {
+ let targetEmulator;
if (emulators.length > 0) {
targetEmulator = emulators[0];
}
- emulators.forEach(function (emulator) {
+ emulators.forEach(emulator => {
if (emulator.name.indexOf('iPhone') === 0) {
targetEmulator = emulator;
}
@@ -73,120 +86,137 @@ function getDefaultSimulatorTarget () {
});
}
-module.exports.run = function (buildOpts) {
- var emulatorTarget = '';
+module.exports.run = buildOpts => {
+ let emulatorTarget = '';
+ const projectPath = path.join(__dirname, '..', '..');
+ let projectName = '';
buildOpts = buildOpts || {};
if (buildOpts.debug && buildOpts.release) {
- return Q.reject('Cannot specify "debug" and "release" options together.');
+ return Promise.reject(new CordovaError('Cannot specify "debug" and "release" options together.'));
}
if (buildOpts.device && buildOpts.emulator) {
- return Q.reject('Cannot specify "device" and "emulator" options together.');
+ return Promise.reject(new CordovaError('Cannot specify "device" and "emulator" options together.'));
}
if (buildOpts.buildConfig) {
if (!fs.existsSync(buildOpts.buildConfig)) {
- return Q.reject('Build config file does not exist:' + buildOpts.buildConfig);
+ return Promise.reject(new CordovaError(`Build config file does not exist: ${buildOpts.buildConfig}`));
}
- events.emit('log', 'Reading build config file:', path.resolve(buildOpts.buildConfig));
- var contents = fs.readFileSync(buildOpts.buildConfig, 'utf-8');
- var buildConfig = JSON.parse(contents.replace(/^\ufeff/, '')); // Remove BOM
+ events.emit('log', `Reading build config file: ${path.resolve(buildOpts.buildConfig)}`);
+ const contents = fs.readFileSync(buildOpts.buildConfig, 'utf-8');
+ const buildConfig = JSON.parse(contents.replace(/^\ufeff/, '')); // Remove BOM
if (buildConfig.ios) {
- var buildType = buildOpts.release ? 'release' : 'debug';
- var config = buildConfig.ios[buildType];
+ const buildType = buildOpts.release ? 'release' : 'debug';
+ const config = buildConfig.ios[buildType];
if (config) {
- ['codeSignIdentity', 'codeSignResourceRules', 'provisioningProfile', 'developmentTeam', 'packageType', 'buildFlag', 'iCloudContainerEnvironment'].forEach(
- function (key) {
+ ['codeSignIdentity', 'codeSignResourceRules', 'provisioningProfile', 'developmentTeam', 'packageType', 'buildFlag', 'iCloudContainerEnvironment', 'automaticProvisioning'].forEach(
+ key => {
buildOpts[key] = buildOpts[key] || config[key];
});
}
}
}
- return require('./list-devices').run()
- .then(function (devices) {
+ return require('./listDevices').run()
+ .then(devices => {
if (devices.length > 0 && !(buildOpts.emulator)) {
// we also explicitly set device flag in options as we pass
// those parameters to other api (build as an example)
buildOpts.device = true;
return check_reqs.check_ios_deploy();
}
- }).then(function () {
+ }).then(() => {
// CB-12287: Determine the device we should target when building for a simulator
if (!buildOpts.device) {
- var newTarget = buildOpts.target || '';
+ let newTarget = buildOpts.target || '';
if (newTarget) {
// only grab the device name, not the runtime specifier
newTarget = newTarget.split(',')[0];
}
// a target was given to us, find the matching Xcode destination name
- var promise = require('./list-emulator-build-targets').targetForSimIdentifier(newTarget);
- return promise.then(function (theTarget) {
+ const promise = require('./listEmulatorBuildTargets').targetForSimIdentifier(newTarget);
+ return promise.then(theTarget => {
if (!theTarget) {
- return getDefaultSimulatorTarget().then(function (defaultTarget) {
+ return getDefaultSimulatorTarget().then(defaultTarget => {
emulatorTarget = defaultTarget.name;
- events.emit('log', 'Building for ' + emulatorTarget + ' Simulator');
+ events.emit('warn', `No simulator found for "${newTarget}. Falling back to the default target.`);
+ events.emit('log', `Building for "${emulatorTarget}" Simulator (${defaultTarget.identifier}, ${defaultTarget.simIdentifier}).`);
return emulatorTarget;
});
} else {
emulatorTarget = theTarget.name;
- events.emit('log', 'Building for ' + emulatorTarget + ' Simulator');
+ events.emit('log', `Building for "${emulatorTarget}" Simulator (${theTarget.identifier}, ${theTarget.simIdentifier}).`);
return emulatorTarget;
}
});
}
- }).then(function () {
- return check_reqs.run();
- }).then(function () {
- return findXCodeProjectIn(projectPath);
- }).then(function (name) {
+ })
+ .then(() => check_reqs.run())
+ .then(() => findXCodeProjectIn(projectPath))
+ .then(name => {
projectName = name;
- var extraConfig = '';
+ let extraConfig = '';
if (buildOpts.codeSignIdentity) {
- extraConfig += 'CODE_SIGN_IDENTITY = ' + buildOpts.codeSignIdentity + '\n';
- extraConfig += 'CODE_SIGN_IDENTITY[sdk=iphoneos*] = ' + buildOpts.codeSignIdentity + '\n';
+ extraConfig += `CODE_SIGN_IDENTITY = ${buildOpts.codeSignIdentity}\n`;
+ extraConfig += `CODE_SIGN_IDENTITY[sdk=iphoneos*] = ${buildOpts.codeSignIdentity}\n`;
}
if (buildOpts.codeSignResourceRules) {
- extraConfig += 'CODE_SIGN_RESOURCE_RULES_PATH = ' + buildOpts.codeSignResourceRules + '\n';
+ extraConfig += `CODE_SIGN_RESOURCE_RULES_PATH = ${buildOpts.codeSignResourceRules}\n`;
}
if (buildOpts.provisioningProfile) {
- extraConfig += 'PROVISIONING_PROFILE = ' + buildOpts.provisioningProfile + '\n';
+ extraConfig += `PROVISIONING_PROFILE = ${buildOpts.provisioningProfile}\n`;
}
if (buildOpts.developmentTeam) {
- extraConfig += 'DEVELOPMENT_TEAM = ' + buildOpts.developmentTeam + '\n';
+ extraConfig += `DEVELOPMENT_TEAM = ${buildOpts.developmentTeam}\n`;
}
- return Q.nfcall(fs.writeFile, path.join(__dirname, '..', 'build-extras.xcconfig'), extraConfig, 'utf-8');
- }).then(function () {
- var configuration = buildOpts.release ? 'Release' : 'Debug';
- events.emit('log', 'Building project: ' + path.join(projectPath, projectName + '.xcworkspace'));
- events.emit('log', '\tConfiguration: ' + configuration);
- events.emit('log', '\tPlatform: ' + (buildOpts.device ? 'device' : 'emulator'));
+ function writeCodeSignStyle (value) {
+ const project = createProjectObject(projectPath, projectName);
- var buildOutputDir = path.join(projectPath, 'build', (buildOpts.device ? 'device' : 'emulator'));
+ events.emit('verbose', `Set CODE_SIGN_STYLE Build Property to ${value}.`);
+ project.xcode.updateBuildProperty('CODE_SIGN_STYLE', value);
+ events.emit('verbose', `Set ProvisioningStyle Target Attribute to ${value}.`);
+ project.xcode.addTargetAttribute('ProvisioningStyle', value);
+
+ project.write();
+ }
+
+ if (buildOpts.provisioningProfile) {
+ events.emit('verbose', 'ProvisioningProfile build option set, changing project settings to Manual.');
+ writeCodeSignStyle('Manual');
+ } else if (buildOpts.automaticProvisioning) {
+ events.emit('verbose', 'ProvisioningProfile build option NOT set, changing project settings to Automatic.');
+ writeCodeSignStyle('Automatic');
+ }
+
+ return fs.writeFile(path.join(__dirname, '..', 'build-extras.xcconfig'), extraConfig, 'utf-8');
+ }).then(() => {
+ const configuration = buildOpts.release ? 'Release' : 'Debug';
+
+ events.emit('log', `Building project: ${path.join(projectPath, `${projectName}.xcworkspace`)}`);
+ events.emit('log', `\tConfiguration: ${configuration}`);
+ events.emit('log', `\tPlatform: ${buildOpts.device ? 'device' : 'emulator'}`);
+ events.emit('log', `\tTarget: ${emulatorTarget}`);
+
+ const buildOutputDir = path.join(projectPath, 'build', (buildOpts.device ? 'device' : 'emulator'));
// remove the build/device folder before building
- return spawn('rm', [ '-rf', buildOutputDir ], projectPath)
- .then(function () {
- var xcodebuildArgs = getXcodeBuildArgs(projectName, projectPath, configuration, buildOpts.device, buildOpts.buildFlag, emulatorTarget);
- return spawn('xcodebuild', xcodebuildArgs, projectPath);
- });
+ fs.removeSync(buildOutputDir);
- }).then(function () {
+ const xcodebuildArgs = getXcodeBuildArgs(projectName, projectPath, configuration, buildOpts.device, buildOpts.buildFlag, emulatorTarget, buildOpts.automaticProvisioning);
+ return spawn('xcodebuild', xcodebuildArgs, { cwd: projectPath, printCommand: true, stdio: 'inherit' });
+ }).then(() => {
if (!buildOpts.device || buildOpts.noSign) {
return;
}
- var locations = {
- root: projectPath,
- pbxproj: path.join(projectPath, projectName + '.xcodeproj', 'project.pbxproj')
- };
-
- var bundleIdentifier = projectFile.parse(locations).getPackageName();
- var exportOptions = {'compileBitcode': false, 'method': 'development'};
+ const project = createProjectObject(projectPath, projectName);
+ const bundleIdentifier = project.getPackageName();
+ const exportOptions = { compileBitcode: false, method: 'development' };
if (buildOpts.packageType) {
exportOptions.method = buildOpts.packageType;
@@ -201,7 +231,7 @@ module.exports.run = function (buildOpts) {
}
if (buildOpts.provisioningProfile && bundleIdentifier) {
- exportOptions.provisioningProfiles = { [ bundleIdentifier ]: String(buildOpts.provisioningProfile) };
+ exportOptions.provisioningProfiles = { [bundleIdentifier]: String(buildOpts.provisioningProfile) };
exportOptions.signingStyle = 'manual';
}
@@ -209,13 +239,13 @@ module.exports.run = function (buildOpts) {
exportOptions.signingCertificate = buildOpts.codeSignIdentity;
}
- var exportOptionsPlist = plist.build(exportOptions);
- var exportOptionsPath = path.join(projectPath, 'exportOptions.plist');
+ const exportOptionsPlist = plist.build(exportOptions);
+ const exportOptionsPath = path.join(projectPath, 'exportOptions.plist');
- var buildOutputDir = path.join(projectPath, 'build', 'device');
+ const buildOutputDir = path.join(projectPath, 'build', 'device');
function checkSystemRuby () {
- var ruby_cmd = shell.which('ruby');
+ const ruby_cmd = which.sync('ruby', { nothrow: true });
if (ruby_cmd !== '/usr/bin/ruby') {
events.emit('warn', 'Non-system Ruby in use. This may cause packaging to fail.\n' +
@@ -225,11 +255,11 @@ module.exports.run = function (buildOpts) {
}
function packageArchive () {
- var xcodearchiveArgs = getXcodeArchiveArgs(projectName, projectPath, buildOutputDir, exportOptionsPath);
- return spawn('xcodebuild', xcodearchiveArgs, projectPath);
+ const xcodearchiveArgs = getXcodeArchiveArgs(projectName, projectPath, buildOutputDir, exportOptionsPath, buildOpts.automaticProvisioning);
+ return spawn('xcodebuild', xcodearchiveArgs, { cwd: projectPath, printCommand: true, stdio: 'inherit' });
}
- return Q.nfcall(fs.writeFile, exportOptionsPath, exportOptionsPlist, 'utf-8')
+ return fs.writeFile(exportOptionsPath, exportOptionsPlist, 'utf-8')
.then(checkSystemRuby)
.then(packageArchive);
});
@@ -242,20 +272,17 @@ module.exports.run = function (buildOpts) {
*/
function findXCodeProjectIn (projectPath) {
// 'Searching for Xcode project in ' + projectPath);
- var xcodeProjFiles = shell.ls(projectPath).filter(function (name) {
- return path.extname(name) === '.xcodeproj';
- });
+ const xcodeProjFiles = fs.readdirSync(projectPath).filter(name => path.extname(name) === '.xcodeproj');
if (xcodeProjFiles.length === 0) {
- return Q.reject('No Xcode project found in ' + projectPath);
+ return Promise.reject(new CordovaError(`No Xcode project found in ${projectPath}`));
}
if (xcodeProjFiles.length > 1) {
- events.emit('warn', 'Found multiple .xcodeproj directories in \n' +
- projectPath + '\nUsing first one');
+ events.emit('warn', `Found multiple .xcodeproj directories in \n${projectPath}\nUsing first one`);
}
- var projectName = path.basename(xcodeProjFiles[0], '.xcodeproj');
- return Q.resolve(projectName);
+ const projectName = path.basename(xcodeProjFiles[0], '.xcodeproj');
+ return Promise.resolve(projectName);
}
module.exports.findXCodeProjectIn = findXCodeProjectIn;
@@ -268,21 +295,21 @@ module.exports.findXCodeProjectIn = findXCodeProjectIn;
* @param {Boolean} isDevice Flag that specify target for package (device/emulator)
* @param {Array} buildFlags
* @param {String} emulatorTarget Target for emulator (rather than default)
+ * @param {Boolean} autoProvisioning Whether to allow Xcode to automatically update provisioning
* @return {Array} Array of arguments that could be passed directly to spawn method
*/
-function getXcodeBuildArgs (projectName, projectPath, configuration, isDevice, buildFlags, emulatorTarget) {
- var xcodebuildArgs;
- var options;
- var buildActions;
- var settings;
- var customArgs = {};
+function getXcodeBuildArgs (projectName, projectPath, configuration, isDevice, buildFlags, emulatorTarget, autoProvisioning) {
+ let options;
+ let buildActions;
+ let settings;
+ const customArgs = {};
customArgs.otherFlags = [];
if (buildFlags) {
if (typeof buildFlags === 'string' || buildFlags instanceof String) {
parseBuildFlag(buildFlags, customArgs);
} else { // buildFlags is an Array of strings
- buildFlags.forEach(function (flag) {
+ buildFlags.forEach(flag => {
parseBuildFlag(flag, customArgs);
});
}
@@ -290,36 +317,38 @@ function getXcodeBuildArgs (projectName, projectPath, configuration, isDevice, b
if (isDevice) {
options = [
- '-xcconfig', customArgs.xcconfig || path.join(__dirname, '..', 'build-' + configuration.toLowerCase() + '.xcconfig'),
- '-workspace', customArgs.workspace || projectName + '.xcworkspace',
+ '-workspace', customArgs.workspace || `${projectName}.xcworkspace`,
'-scheme', customArgs.scheme || projectName,
'-configuration', customArgs.configuration || configuration,
'-destination', customArgs.destination || 'generic/platform=iOS',
- '-archivePath', customArgs.archivePath || projectName + '.xcarchive'
+ '-archivePath', customArgs.archivePath || `${projectName}.xcarchive`
];
- buildActions = [ 'archive' ];
+ buildActions = ['archive'];
settings = [
- customArgs.configuration_build_dir || 'CONFIGURATION_BUILD_DIR=' + path.join(projectPath, 'build', 'device'),
- customArgs.shared_precomps_dir || 'SHARED_PRECOMPS_DIR=' + path.join(projectPath, 'build', 'sharedpch')
+ customArgs.configuration_build_dir || `CONFIGURATION_BUILD_DIR=${path.join(projectPath, 'build', 'device')}`,
+ customArgs.shared_precomps_dir || `SHARED_PRECOMPS_DIR=${path.join(projectPath, 'build', 'sharedpch')}`
];
// Add other matched flags to otherFlags to let xcodebuild present an appropriate error.
// This is preferable to just ignoring the flags that the user has passed in.
if (customArgs.sdk) {
customArgs.otherFlags = customArgs.otherFlags.concat(['-sdk', customArgs.sdk]);
}
+
+ if (autoProvisioning) {
+ options = options.concat(['-allowProvisioningUpdates']);
+ }
} else { // emulator
options = [
- '-xcconfig', customArgs.xcconfig || path.join(__dirname, '..', 'build-' + configuration.toLowerCase() + '.xcconfig'),
- '-workspace', customArgs.project || projectName + '.xcworkspace',
+ '-workspace', customArgs.project || `${projectName}.xcworkspace`,
'-scheme', customArgs.scheme || projectName,
'-configuration', customArgs.configuration || configuration,
'-sdk', customArgs.sdk || 'iphonesimulator',
- '-destination', customArgs.destination || 'platform=iOS Simulator,name=' + emulatorTarget
+ '-destination', customArgs.destination || `platform=iOS Simulator,name=${emulatorTarget}`
];
- buildActions = [ 'build' ];
+ buildActions = ['build'];
settings = [
- customArgs.configuration_build_dir || 'CONFIGURATION_BUILD_DIR=' + path.join(projectPath, 'build', 'emulator'),
- customArgs.shared_precomps_dir || 'SHARED_PRECOMPS_DIR=' + path.join(projectPath, 'build', 'sharedpch')
+ customArgs.configuration_build_dir || `CONFIGURATION_BUILD_DIR=${path.join(projectPath, 'build', 'emulator')}`,
+ customArgs.shared_precomps_dir || `SHARED_PRECOMPS_DIR=${path.join(projectPath, 'build', 'sharedpch')}`
];
// Add other matched flags to otherFlags to let xcodebuild present an appropriate error.
// This is preferable to just ignoring the flags that the user has passed in.
@@ -327,8 +356,8 @@ function getXcodeBuildArgs (projectName, projectPath, configuration, isDevice, b
customArgs.otherFlags = customArgs.otherFlags.concat(['-archivePath', customArgs.archivePath]);
}
}
- xcodebuildArgs = options.concat(buildActions).concat(settings).concat(customArgs.otherFlags);
- return xcodebuildArgs;
+
+ return options.concat(buildActions).concat(settings).concat(customArgs.otherFlags);
}
/**
@@ -337,21 +366,22 @@ function getXcodeBuildArgs (projectName, projectPath, configuration, isDevice, b
* @param {String} projectPath Path to project file. Will be used to set CWD for xcodebuild
* @param {String} outputPath Output directory to contain the IPA
* @param {String} exportOptionsPath Path to the exportOptions.plist file
+ * @param {Boolean} autoProvisioning Whether to allow Xcode to automatically update provisioning
* @return {Array} Array of arguments that could be passed directly to spawn method
*/
-function getXcodeArchiveArgs (projectName, projectPath, outputPath, exportOptionsPath) {
+function getXcodeArchiveArgs (projectName, projectPath, outputPath, exportOptionsPath, autoProvisioning) {
return [
'-exportArchive',
- '-archivePath', projectName + '.xcarchive',
+ '-archivePath', `${projectName}.xcarchive`,
'-exportOptionsPlist', exportOptionsPath,
'-exportPath', outputPath
- ];
+ ].concat(autoProvisioning ? ['-allowProvisioningUpdates'] : []);
}
function parseBuildFlag (buildFlag, args) {
- var matched;
- for (var key in buildFlagMatchers) {
- var found = buildFlag.match(buildFlagMatchers[key]);
+ let matched;
+ for (const key in buildFlagMatchers) {
+ const found = buildFlag.match(buildFlagMatchers[key]);
if (found) {
matched = true;
// found[0] is the whole match, found[1] is the first match in parentheses.