summaryrefslogtreecommitdiff
path: root/StoneIsland/platforms/ios/cordova
diff options
context:
space:
mode:
authorJules Laplace <julescarbon@gmail.com>2020-08-31 23:07:20 +0200
committerJules Laplace <julescarbon@gmail.com>2020-08-31 23:07:20 +0200
commit22721a013bdd10d5eb395ba18453585f5f3f1f7f (patch)
tree5a920e31d6026ed5dc55265e5fd057febccc50e3 /StoneIsland/platforms/ios/cordova
parentd22d51a1ae49680015326857360eb699f31efced (diff)
rebuild the ios platform and the plugins
Diffstat (limited to 'StoneIsland/platforms/ios/cordova')
-rw-r--r--[-rwxr-xr-x]StoneIsland/platforms/ios/cordova/Api.js551
-rwxr-xr-xStoneIsland/platforms/ios/cordova/apple_ios_version2
-rwxr-xr-xStoneIsland/platforms/ios/cordova/apple_osx_version2
-rwxr-xr-xStoneIsland/platforms/ios/cordova/apple_xcode_version15
-rwxr-xr-xStoneIsland/platforms/ios/cordova/build47
-rw-r--r--[-rwxr-xr-x]StoneIsland/platforms/ios/cordova/build-debug.xcconfig2
-rw-r--r--[-rwxr-xr-x]StoneIsland/platforms/ios/cordova/build-extras.xcconfig0
-rw-r--r--[-rwxr-xr-x]StoneIsland/platforms/ios/cordova/build-release.xcconfig0
-rw-r--r--[-rwxr-xr-x]StoneIsland/platforms/ios/cordova/build.xcconfig4
-rwxr-xr-xStoneIsland/platforms/ios/cordova/check_reqs8
-rwxr-xr-xStoneIsland/platforms/ios/cordova/clean24
-rw-r--r--[-rwxr-xr-x]StoneIsland/platforms/ios/cordova/defaults.xml8
-rw-r--r--StoneIsland/platforms/ios/cordova/lib/BridgingHeader.js123
-rw-r--r--[-rwxr-xr-x]StoneIsland/platforms/ios/cordova/lib/Podfile.js289
-rw-r--r--[-rwxr-xr-x]StoneIsland/platforms/ios/cordova/lib/PodsJson.js154
-rw-r--r--[-rwxr-xr-x]StoneIsland/platforms/ios/cordova/lib/build.js276
-rw-r--r--[-rwxr-xr-x]StoneIsland/platforms/ios/cordova/lib/check_reqs.js139
-rw-r--r--[-rwxr-xr-x]StoneIsland/platforms/ios/cordova/lib/clean.js37
-rwxr-xr-xStoneIsland/platforms/ios/cordova/lib/copy-www-build-step.js73
-rwxr-xr-xStoneIsland/platforms/ios/cordova/lib/list-devices49
-rwxr-xr-xStoneIsland/platforms/ios/cordova/lib/list-emulator-build-targets99
-rwxr-xr-xStoneIsland/platforms/ios/cordova/lib/list-emulator-images29
-rwxr-xr-xStoneIsland/platforms/ios/cordova/lib/list-started-emulators32
-rw-r--r--StoneIsland/platforms/ios/cordova/lib/listDevices.js42
-rw-r--r--StoneIsland/platforms/ios/cordova/lib/listEmulatorBuildTargets.js95
-rw-r--r--StoneIsland/platforms/ios/cordova/lib/listEmulatorImages.js30
-rw-r--r--StoneIsland/platforms/ios/cordova/lib/listStartedEmulators.js50
-rw-r--r--[-rwxr-xr-x]StoneIsland/platforms/ios/cordova/lib/plugman/pluginHandlers.js205
-rw-r--r--[-rwxr-xr-x]StoneIsland/platforms/ios/cordova/lib/prepare.js863
-rw-r--r--[-rwxr-xr-x]StoneIsland/platforms/ios/cordova/lib/projectFile.js69
-rw-r--r--[-rwxr-xr-x]StoneIsland/platforms/ios/cordova/lib/run.js168
-rwxr-xr-xStoneIsland/platforms/ios/cordova/lib/spawn.js47
-rw-r--r--[-rwxr-xr-x]StoneIsland/platforms/ios/cordova/lib/versions.js173
-rw-r--r--[-rwxr-xr-x]StoneIsland/platforms/ios/cordova/loggingHelper.js2
-rwxr-xr-xStoneIsland/platforms/ios/cordova/node_modules/nopt/LICENSE15
-rwxr-xr-xStoneIsland/platforms/ios/cordova/node_modules/nopt/lib/nopt.js415
-rwxr-xr-xStoneIsland/platforms/ios/cordova/node_modules/nopt/package.json57
-rwxr-xr-xStoneIsland/platforms/ios/cordova/node_modules/q/LICENSE18
-rwxr-xr-xStoneIsland/platforms/ios/cordova/node_modules/q/package.json117
-rwxr-xr-xStoneIsland/platforms/ios/cordova/node_modules/q/q.js2073
-rwxr-xr-xStoneIsland/platforms/ios/cordova/node_modules/q/queue.js35
-rwxr-xr-xStoneIsland/platforms/ios/cordova/node_modules/shelljs/LICENSE26
-rwxr-xr-xStoneIsland/platforms/ios/cordova/node_modules/shelljs/package.json67
-rwxr-xr-xStoneIsland/platforms/ios/cordova/node_modules/shelljs/shell.js159
-rwxr-xr-xStoneIsland/platforms/ios/cordova/run45
-rwxr-xr-xStoneIsland/platforms/ios/cordova/version8
46 files changed, 2112 insertions, 4630 deletions
diff --git a/StoneIsland/platforms/ios/cordova/Api.js b/StoneIsland/platforms/ios/cordova/Api.js
index dd50d11f..a7b62b68 100755..100644
--- a/StoneIsland/platforms/ios/cordova/Api.js
+++ b/StoneIsland/platforms/ios/cordova/Api.js
@@ -19,17 +19,27 @@
/* jslint node: true */
-var fs = require('fs');
-var path = require('path');
-var unorm = require('unorm');
-var projectFile = require('./lib/projectFile');
-var check_reqs = require('./lib/check_reqs');
-var CordovaError = require('cordova-common').CordovaError;
-var CordovaLogger = require('cordova-common').CordovaLogger;
-var events = require('cordova-common').events;
-var PluginManager = require('cordova-common').PluginManager;
-var Q = require('q');
-var util = require('util');
+/**
+ * @todo update coho to update this line.
+ * @todo use `package.json` instead but first
+ * figure out how this fit in with the platform-centered workflow structure.
+ * This workflow would not have the `package.json` file.
+ */
+// Coho updates this line
+const VERSION = '6.1.1';
+
+const fs = require('fs-extra');
+const path = require('path');
+const unorm = require('unorm');
+const projectFile = require('./lib/projectFile');
+const check_reqs = require('./lib/check_reqs');
+const CordovaError = require('cordova-common').CordovaError;
+const CordovaLogger = require('cordova-common').CordovaLogger;
+const events = require('cordova-common').events;
+const PluginManager = require('cordova-common').PluginManager;
+const util = require('util');
+const xcode = require('xcode');
+const ConfigParser = require('cordova-common').ConfigParser;
function setupEvents (externalEventEmitter) {
if (externalEventEmitter) {
@@ -42,6 +52,10 @@ function setupEvents (externalEventEmitter) {
}
}
+function getVariableSpec (spec, options) {
+ return spec.includes('$') ? options.cli_variables[spec.replace('$', '')] : spec;
+}
+
/**
* Creates a new PlatformApi instance.
*
@@ -60,19 +74,28 @@ function Api (platform, platformRootDir, events) {
setupEvents(events);
- var xcodeProjDir;
- var xcodeCordovaProj;
+ let xcodeProjDir;
+ let xcodeCordovaProj;
try {
- xcodeProjDir = fs.readdirSync(this.root).filter(function (e) { return e.match(/\.xcodeproj$/i); })[0];
+ const xcodeProjDir_array = fs.readdirSync(this.root).filter(e => e.match(/\.xcodeproj$/i));
+ if (xcodeProjDir_array.length > 1) {
+ for (let x = 0; x < xcodeProjDir_array.length; x++) {
+ if (xcodeProjDir_array[x].substring(0, 2) === '._') {
+ xcodeProjDir_array.splice(x, 1);
+ }
+ }
+ }
+ xcodeProjDir = xcodeProjDir_array[0];
+
if (!xcodeProjDir) {
- throw new CordovaError('The provided path "' + this.root + '" is not a Cordova iOS project.');
+ throw new CordovaError(`The provided path "${this.root}" is not a Cordova iOS project.`);
}
- var cordovaProjName = xcodeProjDir.substring(xcodeProjDir.lastIndexOf(path.sep) + 1, xcodeProjDir.indexOf('.xcodeproj'));
+ const cordovaProjName = xcodeProjDir.substring(xcodeProjDir.lastIndexOf(path.sep) + 1, xcodeProjDir.indexOf('.xcodeproj'));
xcodeCordovaProj = path.join(this.root, cordovaProjName);
} catch (e) {
- throw new CordovaError('The provided path "' + this.root + '" is not a Cordova iOS project.');
+ throw new CordovaError(`The provided path "${this.root}" is not a Cordova iOS project.`);
}
this.locations = {
@@ -83,11 +106,7 @@ function Api (platform, platformRootDir, events) {
defaultConfigXml: path.join(this.root, 'cordova/defaults.xml'),
pbxproj: path.join(this.root, xcodeProjDir, 'project.pbxproj'),
xcodeProjDir: path.join(this.root, xcodeProjDir),
- xcodeCordovaProj: xcodeCordovaProj,
- // NOTE: this is required by browserify logic.
- // As per platformApi spec we return relative to template root paths here
- cordovaJs: 'bin/CordovaLib/cordova.js',
- cordovaJsSrc: 'bin/cordova-js-src'
+ xcodeCordovaProj
};
}
@@ -95,7 +114,7 @@ function Api (platform, platformRootDir, events) {
* Creates platform in a specified directory.
*
* @param {String} destination Destination directory, where install platform to
- * @param {ConfigParser} [config] ConfgiParser instance, used to retrieve
+ * @param {ConfigParser} [config] ConfigParser instance, used to retrieve
* project creation options, such as package id and project name.
* @param {Object} [options] An options object. The most common options are:
* @param {String} [options.customTemplate] A path to custom template, that
@@ -109,26 +128,26 @@ function Api (platform, platformRootDir, events) {
* @return {Promise<PlatformApi>} Promise either fulfilled with PlatformApi
* instance or rejected with CordovaError.
*/
-Api.createPlatform = function (destination, config, options, events) {
+Api.createPlatform = (destination, config, options, events) => {
setupEvents(events);
// CB-6992 it is necessary to normalize characters
// because node and shell scripts handles unicode symbols differently
// We need to normalize the name to NFD form since iOS uses NFD unicode form
- var name = unorm.nfd(config.name());
- var result;
+ const name = unorm.nfd(config.name());
+ let result;
try {
result = require('../../../lib/create')
- .createProject(destination, config.packageName(), name, options)
- .then(function () {
+ .createProject(destination, config.getAttribute('ios-CFBundleIdentifier') || config.packageName(), name, options, config)
+ .then(() => {
// after platform is created we return Api instance based on new Api.js location
// This is required to correctly resolve paths in the future api calls
- var PlatformApi = require(path.resolve(destination, 'cordova/Api'));
+ const PlatformApi = require(path.resolve(destination, 'cordova/Api'));
return new PlatformApi('ios', destination, events);
});
} catch (e) {
events.emit('error', 'createPlatform is not callable from the iOS project API.');
- throw (e);
+ throw e;
}
return result;
};
@@ -149,20 +168,20 @@ Api.createPlatform = function (destination, config, options, events) {
* @return {Promise<PlatformApi>} Promise either fulfilled with PlatformApi
* instance or rejected with CordovaError.
*/
-Api.updatePlatform = function (destination, options, events) {
+Api.updatePlatform = (destination, options, events) => {
setupEvents(events);
- var result;
+ let result;
try {
result = require('../../../lib/create')
.updateProject(destination, options)
- .then(function () {
- var PlatformApi = require(path.resolve(destination, 'cordova/Api'));
+ .then(() => {
+ const PlatformApi = require(path.resolve(destination, 'cordova/Api'));
return new PlatformApi('ios', destination, events);
});
} catch (e) {
events.emit('error', 'updatePlatform is not callable from the iOS project API, you will need to do this manually.');
- throw (e);
+ throw e;
}
return result;
};
@@ -174,12 +193,12 @@ Api.updatePlatform = function (destination, options, events) {
* platform's file structure and other properties of platform.
*/
Api.prototype.getPlatformInfo = function () {
- var result = {};
+ const result = {};
result.locations = this.locations;
result.root = this.root;
result.name = this.platform;
- result.version = require('./version');
- result.projectConfig = this._config;
+ result.version = Api.version();
+ result.projectConfig = new ConfigParser(this.locations.configXml);
return result;
};
@@ -199,6 +218,8 @@ Api.prototype.getPlatformInfo = function () {
* CordovaError instance.
*/
Api.prototype.prepare = function (cordovaProject) {
+ cordovaProject.projectConfig = new ConfigParser(cordovaProject.locations.rootConfigXml || cordovaProject.projectConfig.path);
+
return require('./lib/prepare').prepare.call(this, cordovaProject);
};
@@ -220,8 +241,7 @@ Api.prototype.prepare = function (cordovaProject) {
* CordovaError instance.
*/
Api.prototype.addPlugin = function (plugin, installOptions) {
- var xcodeproj = projectFile.parse(this.locations);
- var self = this;
+ const xcodeproj = projectFile.parse(this.locations);
installOptions = installOptions || {};
installOptions.variables = installOptions.variables || {};
@@ -230,70 +250,36 @@ Api.prototype.addPlugin = function (plugin, installOptions) {
installOptions.variables.PACKAGE_NAME = xcodeproj.getPackageName();
}
- return PluginManager.get(self.platform, self.locations, xcodeproj)
+ return PluginManager.get(this.platform, this.locations, xcodeproj)
.addPlugin(plugin, installOptions)
- .then(function () {
- var frameworkTags = plugin.getFrameworks(self.platform);
- var frameworkPods = frameworkTags.filter(function (obj) {
- return (obj.type === 'podspec');
- });
-
- return Q.resolve(frameworkPods);
- })
- .then(function (frameworkPods) {
- if (!(frameworkPods.length)) {
- return Q.resolve();
- }
-
- var project_dir = self.locations.root;
- var project_name = self.locations.xcodeCordovaProj.split('/').pop();
-
- var Podfile = require('./lib/Podfile').Podfile;
- var PodsJson = require('./lib/PodsJson').PodsJson;
-
- events.emit('verbose', 'Adding pods since the plugin contained <framework>(s) with type="podspec"');
-
- var podsjsonFile = new PodsJson(path.join(project_dir, PodsJson.FILENAME));
- var podfileFile = new Podfile(path.join(project_dir, Podfile.FILENAME), project_name);
-
- frameworkPods.forEach(function (obj) {
- var podJson = {
- name: obj.src,
- type: obj.type,
- spec: obj.spec
- };
-
- var val = podsjsonFile.get(podJson.name);
- if (val) { // found
- if (podJson.spec !== val.spec) { // exists, different spec, print warning
- events.emit('warn', plugin.id + ' depends on ' + podJson.name + '@' + podJson.spec + ', which conflicts with another plugin. ' + podJson.name + '@' + val.spec + ' is already installed and was not overwritten.');
- }
- // increment count, but don't add in Podfile because it already exists
- podsjsonFile.increment(podJson.name);
- } else { // not found, write new
- podJson.count = 1;
- podsjsonFile.setJson(podJson.name, podJson);
- // add to Podfile
- podfileFile.addSpec(podJson.name, podJson.spec);
+ .then(() => {
+ if (plugin != null) {
+ const headerTags = plugin.getHeaderFiles(this.platform);
+ const bridgingHeaders = headerTags.filter(obj => obj.type === 'BridgingHeader');
+ if (bridgingHeaders.length > 0) {
+ const project_dir = this.locations.root;
+ const project_name = this.locations.xcodeCordovaProj.split('/').pop();
+ const BridgingHeader = require('./lib/BridgingHeader').BridgingHeader;
+ const bridgingHeaderFile = new BridgingHeader(path.join(project_dir, project_name, 'Bridging-Header.h'));
+ events.emit('verbose', 'Adding Bridging-Headers since the plugin contained <header-file> with type="BridgingHeader"');
+ bridgingHeaders.forEach(obj => {
+ const bridgingHeaderPath = path.basename(obj.src);
+ bridgingHeaderFile.addHeader(plugin.id, bridgingHeaderPath);
+ });
+ bridgingHeaderFile.write();
}
- });
-
- // now that all the pods have been processed, write to pods.json
- podsjsonFile.write();
-
- // only write and pod install if the Podfile changed
- if (podfileFile.isDirty()) {
- podfileFile.write();
- events.emit('verbose', 'Running `pod install` (to install plugins)');
-
- return podfileFile.install(check_reqs.check_cocoapods);
- } else {
- events.emit('verbose', 'Podfile unchanged, skipping `pod install`');
}
})
- // CB-11022 return non-falsy value to indicate
- // that there is no need to run prepare after
- .thenResolve(true);
+ .then(() => {
+ if (plugin != null) {
+ const podSpecs = plugin.getPodSpecs ? plugin.getPodSpecs(this.platform) : [];
+ const frameworkTags = plugin.getFrameworks(this.platform);
+ const frameworkPods = frameworkTags.filter(obj => obj.type === 'podspec');
+ return this.addPodSpecs(plugin, podSpecs, frameworkPods, installOptions);
+ }
+ })
+ // CB-11022 Return truthy value to prevent running prepare after
+ .then(() => true);
};
/**
@@ -310,69 +296,321 @@ Api.prototype.addPlugin = function (plugin, installOptions) {
* CordovaError instance.
*/
Api.prototype.removePlugin = function (plugin, uninstallOptions) {
- var xcodeproj = projectFile.parse(this.locations);
- var self = this;
+ const xcodeproj = projectFile.parse(this.locations);
- return PluginManager.get(self.platform, self.locations, xcodeproj)
+ return PluginManager.get(this.platform, this.locations, xcodeproj)
.removePlugin(plugin, uninstallOptions)
- .then(function () {
- var frameworkTags = plugin.getFrameworks(self.platform);
- var frameworkPods = frameworkTags.filter(function (obj) {
- return (obj.type === 'podspec');
+ .then(() => {
+ if (plugin != null) {
+ const headerTags = plugin.getHeaderFiles(this.platform);
+ const bridgingHeaders = headerTags.filter(obj => obj.type === 'BridgingHeader');
+ if (bridgingHeaders.length > 0) {
+ const project_dir = this.locations.root;
+ const project_name = this.locations.xcodeCordovaProj.split('/').pop();
+ const BridgingHeader = require('./lib/BridgingHeader').BridgingHeader;
+ const bridgingHeaderFile = new BridgingHeader(path.join(project_dir, project_name, 'Bridging-Header.h'));
+ events.emit('verbose', 'Removing Bridging-Headers since the plugin contained <header-file> with type="BridgingHeader"');
+ bridgingHeaders.forEach(obj => {
+ const bridgingHeaderPath = path.basename(obj.src);
+ bridgingHeaderFile.removeHeader(plugin.id, bridgingHeaderPath);
+ });
+ bridgingHeaderFile.write();
+ }
+ }
+ })
+ .then(() => {
+ if (plugin != null) {
+ const podSpecs = plugin.getPodSpecs ? plugin.getPodSpecs(this.platform) : [];
+ const frameworkTags = plugin.getFrameworks(this.platform);
+ const frameworkPods = frameworkTags.filter(obj => obj.type === 'podspec');
+ return this.removePodSpecs(plugin, podSpecs, frameworkPods, uninstallOptions);
+ }
+ })
+ // CB-11022 Return truthy value to prevent running prepare after
+ .then(() => true);
+};
+
+/**
+ * adding CocoaPods libraries
+ *
+ * @param {PluginInfo} plugin A PluginInfo instance that represents plugin
+ * that will be installed.
+ * @param {Object} podSpecs: the return value of plugin.getPodSpecs(this.platform)
+ * @param {Object} frameworkPods: framework tags object with type === 'podspec'
+ * @return {Promise} Return a promise
+ */
+
+Api.prototype.addPodSpecs = function (plugin, podSpecs, frameworkPods, installOptions) {
+ const project_dir = this.locations.root;
+ const project_name = this.locations.xcodeCordovaProj.split('/').pop();
+ const minDeploymentTarget = this.getPlatformInfo().projectConfig.getPreference('deployment-target', 'ios');
+
+ const Podfile = require('./lib/Podfile').Podfile;
+ const PodsJson = require('./lib/PodsJson').PodsJson;
+ const podsjsonFile = new PodsJson(path.join(project_dir, PodsJson.FILENAME));
+ const podfileFile = new Podfile(path.join(project_dir, Podfile.FILENAME), project_name, minDeploymentTarget);
+
+ if (podSpecs.length) {
+ events.emit('verbose', 'Adding pods since the plugin contained <podspecs>');
+ podSpecs.forEach(obj => {
+ // declarations
+ Object.keys(obj.declarations).forEach(key => {
+ if (obj.declarations[key] === 'true') {
+ const declaration = Podfile.proofDeclaration(key);
+ const podJson = {
+ declaration
+ };
+ const val = podsjsonFile.getDeclaration(declaration);
+ if (val) {
+ podsjsonFile.incrementDeclaration(declaration);
+ } else {
+ podJson.count = 1;
+ podsjsonFile.setJsonDeclaration(declaration, podJson);
+ podfileFile.addDeclaration(podJson.declaration);
+ }
+ }
});
+ // sources
+ Object.keys(obj.sources).forEach(key => {
+ const podJson = {
+ source: obj.sources[key].source
+ };
+ const val = podsjsonFile.getSource(key);
+ if (val) {
+ podsjsonFile.incrementSource(key);
+ } else {
+ podJson.count = 1;
+ podsjsonFile.setJsonSource(key, podJson);
+ podfileFile.addSource(podJson.source);
+ }
+ });
+ // libraries
+ Object.keys(obj.libraries).forEach(key => {
+ const podJson = Object.assign({}, obj.libraries[key]);
+ if (podJson.spec) {
+ podJson.spec = getVariableSpec(podJson.spec, installOptions);
+ }
+ const val = podsjsonFile.getLibrary(key);
+ if (val) {
+ events.emit('warn', `${plugin.id} depends on ${podJson.name}, which may conflict with another plugin. ${podJson.name}@${val.spec} is already installed and was not overwritten.`);
+ podsjsonFile.incrementLibrary(key);
+ } else {
+ podJson.count = 1;
+ podsjsonFile.setJsonLibrary(key, podJson);
+ podfileFile.addSpec(podJson.name, podJson);
+ }
+ });
+ });
+ }
- return Q.resolve(frameworkPods);
- })
- .then(function (frameworkPods) {
- if (!(frameworkPods.length)) {
- return Q.resolve();
+ if (frameworkPods.length) {
+ events.emit('warn', '"framework" tag with type "podspec" is deprecated and will be removed. Please use the "podspec" tag.');
+ events.emit('verbose', 'Adding pods since the plugin contained <framework>(s) with type="podspec"');
+ frameworkPods.forEach(obj => {
+ const spec = getVariableSpec(obj.spec, installOptions);
+ const podJson = {
+ name: obj.src,
+ type: obj.type,
+ spec
+ };
+
+ const val = podsjsonFile.getLibrary(podJson.name);
+ if (val) { // found
+ if (podJson.spec !== val.spec) { // exists, different spec, print warning
+ events.emit('warn', `${plugin.id} depends on ${podJson.name}@${podJson.spec}, which conflicts with another plugin. ${podJson.name}@${val.spec} is already installed and was not overwritten.`);
+ }
+ // increment count, but don't add in Podfile because it already exists
+ podsjsonFile.incrementLibrary(podJson.name);
+ } else { // not found, write new
+ podJson.count = 1;
+ podsjsonFile.setJsonLibrary(podJson.name, podJson);
+ // add to Podfile
+ podfileFile.addSpec(podJson.name, podJson.spec);
}
+ });
+ }
+
+ if (podSpecs.length > 0 || frameworkPods.length > 0) {
+ // now that all the pods have been processed, write to pods.json
+ podsjsonFile.write();
- var project_dir = self.locations.root;
- var project_name = self.locations.xcodeCordovaProj.split('/').pop();
+ // only write and pod install if the Podfile changed
+ if (podfileFile.isDirty()) {
+ podfileFile.write();
+ events.emit('verbose', 'Running `pod install` (to install plugins)');
+ projectFile.purgeProjectFileCache(this.locations.root);
- var Podfile = require('./lib/Podfile').Podfile;
- var PodsJson = require('./lib/PodsJson').PodsJson;
+ return podfileFile.install(check_reqs.check_cocoapods)
+ .then(() => this.setSwiftVersionForCocoaPodsLibraries(podsjsonFile));
+ } else {
+ events.emit('verbose', 'Podfile unchanged, skipping `pod install`');
+ }
+ }
+ return Promise.resolve();
+};
+
+/**
+ * removing CocoaPods libraries
+ *
+ * @param {PluginInfo} plugin A PluginInfo instance that represents plugin
+ * that will be installed.
+ * @param {Object} podSpecs: the return value of plugin.getPodSpecs(this.platform)
+ * @param {Object} frameworkPods: framework tags object with type === 'podspec'
+ * @return {Promise} Return a promise
+ */
- events.emit('verbose', 'Adding pods since the plugin contained <framework>(s) with type=\"podspec\"'); /* eslint no-useless-escape : 0 */
+Api.prototype.removePodSpecs = function (plugin, podSpecs, frameworkPods, uninstallOptions) {
+ const project_dir = this.locations.root;
+ const project_name = this.locations.xcodeCordovaProj.split('/').pop();
- var podsjsonFile = new PodsJson(path.join(project_dir, PodsJson.FILENAME));
- var podfileFile = new Podfile(path.join(project_dir, Podfile.FILENAME), project_name);
+ const Podfile = require('./lib/Podfile').Podfile;
+ const PodsJson = require('./lib/PodsJson').PodsJson;
+ const podsjsonFile = new PodsJson(path.join(project_dir, PodsJson.FILENAME));
+ const podfileFile = new Podfile(path.join(project_dir, Podfile.FILENAME), project_name);
- frameworkPods.forEach(function (obj) {
- var podJson = {
- name: obj.src,
- type: obj.type,
- spec: obj.spec
+ if (podSpecs.length) {
+ events.emit('verbose', 'Adding pods since the plugin contained <podspecs>');
+ podSpecs.forEach(obj => {
+ // declarations
+ Object.keys(obj.declarations).forEach(key => {
+ if (obj.declarations[key] === 'true') {
+ const declaration = Podfile.proofDeclaration(key);
+ const podJson = {
+ declaration
+ };
+ const val = podsjsonFile.getDeclaration(declaration);
+ if (val) {
+ podsjsonFile.decrementDeclaration(declaration);
+ } else {
+ const message = util.format('plugin \"%s\" declaration \"%s\" does not seem to be in pods.json, nothing to remove. Will attempt to remove from Podfile.', plugin.id, podJson.declaration); /* eslint no-useless-escape : 0 */
+ events.emit('verbose', message);
+ }
+ if (!val || val.count === 0) {
+ podfileFile.removeDeclaration(podJson.declaration);
+ }
+ }
+ });
+ // sources
+ Object.keys(obj.sources).forEach(key => {
+ const podJson = {
+ source: obj.sources[key].source
};
-
- var val = podsjsonFile.get(podJson.name);
- if (val) { // found, decrement count
- podsjsonFile.decrement(podJson.name);
- } else { // not found (perhaps a sync error)
- var message = util.format('plugin \"%s\" podspec \"%s\" does not seem to be in pods.json, nothing to remove. Will attempt to remove from Podfile.', plugin.id, podJson.name); /* eslint no-useless-escape : 0 */
+ const val = podsjsonFile.getSource(key);
+ if (val) {
+ podsjsonFile.decrementSource(key);
+ } else {
+ const message = util.format('plugin \"%s\" source \"%s\" does not seem to be in pods.json, nothing to remove. Will attempt to remove from Podfile.', plugin.id, podJson.source); /* eslint no-useless-escape : 0 */
events.emit('verbose', message);
}
-
- // always remove from the Podfile
- podfileFile.removeSpec(podJson.name);
+ if (!val || val.count === 0) {
+ podfileFile.removeSource(podJson.source);
+ }
+ });
+ // libraries
+ Object.keys(obj.libraries).forEach(key => {
+ const podJson = Object.assign({}, obj.libraries[key]);
+ if (podJson.spec) {
+ podJson.spec = getVariableSpec(podJson.spec, uninstallOptions);
+ }
+ const val = podsjsonFile.getLibrary(key);
+ if (val) {
+ podsjsonFile.decrementLibrary(key);
+ } else {
+ const message = util.format('plugin \"%s\" podspec \"%s\" does not seem to be in pods.json, nothing to remove. Will attempt to remove from Podfile.', plugin.id, podJson.name); /* eslint no-useless-escape : 0 */
+ events.emit('verbose', message);
+ }
+ if (!val || val.count === 0) {
+ podfileFile.removeSpec(podJson.name);
+ }
});
+ });
+ }
+
+ if (frameworkPods.length) {
+ events.emit('warn', '"framework" tag with type "podspec" is deprecated and will be removed. Please use the "podspec" tag.');
+ events.emit('verbose', 'Adding pods since the plugin contained <framework>(s) with type=\"podspec\"'); /* eslint no-useless-escape : 0 */
+ frameworkPods.forEach(obj => {
+ const spec = getVariableSpec(obj.spec, uninstallOptions);
+ const podJson = {
+ name: obj.src,
+ type: obj.type,
+ spec
+ };
+
+ const val = podsjsonFile.getLibrary(podJson.name);
+ if (val) { // found, decrement count
+ podsjsonFile.decrementLibrary(podJson.name);
+ } else { // not found (perhaps a sync error)
+ const message = util.format('plugin \"%s\" podspec \"%s\" does not seem to be in pods.json, nothing to remove. Will attempt to remove from Podfile.', plugin.id, podJson.name); /* eslint no-useless-escape : 0 */
+ events.emit('verbose', message);
+ }
+
+ // always remove from the Podfile
+ podfileFile.removeSpec(podJson.name);
+ });
+ }
- // now that all the pods have been processed, write to pods.json
- podsjsonFile.write();
+ if (podSpecs.length > 0 || frameworkPods.length > 0) {
+ // now that all the pods have been processed, write to pods.json
+ podsjsonFile.write();
- if (podfileFile.isDirty()) {
- podfileFile.write();
- events.emit('verbose', 'Running `pod install` (to uninstall pods)');
+ if (podfileFile.isDirty()) {
+ podfileFile.write();
+ events.emit('verbose', 'Running `pod install` (to uninstall pods)');
- return podfileFile.install(check_reqs.check_cocoapods);
- } else {
- events.emit('verbose', 'Podfile unchanged, skipping `pod install`');
+ return podfileFile.install(check_reqs.check_cocoapods)
+ .then(() => this.setSwiftVersionForCocoaPodsLibraries(podsjsonFile));
+ } else {
+ events.emit('verbose', 'Podfile unchanged, skipping `pod install`');
+ }
+ }
+ return Promise.resolve();
+};
+
+/**
+ * set Swift Version for all CocoaPods libraries
+ *
+ * @param {PodsJson} podsjsonFile A PodsJson instance that represents pods.json
+ */
+
+Api.prototype.setSwiftVersionForCocoaPodsLibraries = function (podsjsonFile) {
+ let __dirty = false;
+ return check_reqs.check_cocoapods().then(toolOptions => {
+ if (toolOptions.ignore) {
+ events.emit('verbose', '=== skip Swift Version Settings For Cocoapods Libraries');
+ } else {
+ const podPbxPath = path.join(this.root, 'Pods', 'Pods.xcodeproj', 'project.pbxproj');
+ const podXcodeproj = xcode.project(podPbxPath);
+ podXcodeproj.parseSync();
+ const podTargets = podXcodeproj.pbxNativeTargetSection();
+ const podConfigurationList = podXcodeproj.pbxXCConfigurationList();
+ const podConfigs = podXcodeproj.pbxXCBuildConfigurationSection();
+
+ const libraries = podsjsonFile.getLibraries();
+ Object.keys(libraries).forEach(key => {
+ const podJson = libraries[key];
+ const name = podJson.name;
+ const swiftVersion = podJson['swift-version'];
+ if (swiftVersion) {
+ __dirty = true;
+ Object.keys(podTargets)
+ .filter(targetKey => podTargets[targetKey].productName === name)
+ .map(targetKey => podTargets[targetKey].buildConfigurationList)
+ .map(buildConfigurationListId => podConfigurationList[buildConfigurationListId])
+ .map(buildConfigurationList => buildConfigurationList.buildConfigurations)
+ .reduce((acc, buildConfigurations) => acc.concat(buildConfigurations), [])
+ .map(buildConfiguration => buildConfiguration.value)
+ .forEach(buildId => {
+ __dirty = true;
+ podConfigs[buildId].buildSettings.SWIFT_VERSION = swiftVersion;
+ });
+ }
+ });
+ if (__dirty) {
+ fs.writeFileSync(podPbxPath, podXcodeproj.writeSync(), 'utf-8');
}
- })
- // CB-11022 return non-falsy value to indicate
- // that there is no need to run prepare after
- .thenResolve(true);
+ }
+ });
};
/**
@@ -408,11 +646,8 @@ Api.prototype.removePlugin = function (plugin, uninstallOptions) {
* CordovaError instance.
*/
Api.prototype.build = function (buildOptions) {
- var self = this;
return check_reqs.run()
- .then(function () {
- return require('./lib/build').run.call(self, buildOptions);
- });
+ .then(() => require('./lib/build').run.call(this, buildOptions));
};
/**
@@ -428,11 +663,8 @@ Api.prototype.build = function (buildOptions) {
* successfully, or rejected with CordovaError.
*/
Api.prototype.run = function (runOptions) {
- var self = this;
return check_reqs.run()
- .then(function () {
- return require('./lib/run').run.call(self, runOptions);
- });
+ .then(() => require('./lib/run').run.call(this, runOptions));
};
/**
@@ -442,14 +674,9 @@ Api.prototype.run = function (runOptions) {
* CordovaError.
*/
Api.prototype.clean = function (cleanOptions) {
- var self = this;
return check_reqs.run()
- .then(function () {
- return require('./lib/clean').run.call(self, cleanOptions);
- })
- .then(function () {
- return require('./lib/prepare').clean.call(self, cleanOptions);
- });
+ .then(() => require('./lib/clean').run.call(this, cleanOptions))
+ .then(() => require('./lib/prepare').clean.call(this, cleanOptions));
};
/**
@@ -464,4 +691,8 @@ Api.prototype.requirements = function () {
return check_reqs.check_all();
};
+Api.version = function () {
+ return VERSION;
+};
+
module.exports = Api;
diff --git a/StoneIsland/platforms/ios/cordova/apple_ios_version b/StoneIsland/platforms/ios/cordova/apple_ios_version
index d397bb6b..5fee9e85 100755
--- a/StoneIsland/platforms/ios/cordova/apple_ios_version
+++ b/StoneIsland/platforms/ios/cordova/apple_ios_version
@@ -21,7 +21,7 @@
var versions = require('./lib/versions.js');
-versions.get_apple_ios_version().done(null, function(err) {
+versions.get_apple_ios_version().catch(err => {
console.log(err);
process.exit(2);
});
diff --git a/StoneIsland/platforms/ios/cordova/apple_osx_version b/StoneIsland/platforms/ios/cordova/apple_osx_version
index 6e697add..062d8b7f 100755
--- a/StoneIsland/platforms/ios/cordova/apple_osx_version
+++ b/StoneIsland/platforms/ios/cordova/apple_osx_version
@@ -21,7 +21,7 @@
var versions = require('./lib/versions.js');
-versions.get_apple_osx_version().done(null, function(err) {
+versions.get_apple_osx_version().catch(err => {
console.log(err);
process.exit(2);
});
diff --git a/StoneIsland/platforms/ios/cordova/apple_xcode_version b/StoneIsland/platforms/ios/cordova/apple_xcode_version
index 112eba32..4656e385 100755
--- a/StoneIsland/platforms/ios/cordova/apple_xcode_version
+++ b/StoneIsland/platforms/ios/cordova/apple_xcode_version
@@ -21,9 +21,12 @@
var versions = require('./lib/versions.js');
-versions.get_apple_xcode_version().done(function (version) {
- console.log(version);
-}, function(err) {
- console.error(err);
- process.exit(2);
-});
+versions.get_apple_xcode_version().then(
+ version => {
+ console.log(version);
+ },
+ err => {
+ console.error(err);
+ process.exit(2);
+ }
+);
diff --git a/StoneIsland/platforms/ios/cordova/build b/StoneIsland/platforms/ios/cordova/build
index 61d26cca..f4b0d9a0 100755
--- a/StoneIsland/platforms/ios/cordova/build
+++ b/StoneIsland/platforms/ios/cordova/build
@@ -19,45 +19,48 @@
under the License.
*/
-var args = process.argv;
+var args = process.argv;
var Api = require('./Api');
var nopt = require('nopt');
-var path = require('path');
// Support basic help commands
-if(['--help', '/?', '-h', 'help', '-help', '/help'].indexOf(process.argv[2]) >= 0) {
+if (['--help', '/?', '-h', 'help', '-help', '/help'].indexOf(process.argv[2]) >= 0) {
require('./lib/build').help();
process.exit(0);
}
// Parse arguments
var buildOpts = nopt({
- 'verbose' : Boolean,
- 'silent' : Boolean,
- 'archs': String,
- 'debug': Boolean,
- 'release': Boolean,
- 'device': Boolean,
- 'emulator': Boolean,
- 'codeSignIdentity': String,
- 'codeSignResourceRules': String,
- 'provisioningProfile': String,
- 'developmentTeam': String,
- 'packageType': String,
- 'buildConfig' : String,
- 'buildFlag' : [String, Array],
- 'noSign' : Boolean
-}, { '-r': '--release', 'd' : '--verbose' }, args);
+ verbose: Boolean,
+ silent: Boolean,
+ archs: String,
+ debug: Boolean,
+ release: Boolean,
+ device: Boolean,
+ emulator: Boolean,
+ codeSignIdentity: String,
+ codeSignResourceRules: String,
+ provisioningProfile: String,
+ automaticProvisioning: Boolean,
+ developmentTeam: String,
+ packageType: String,
+ buildConfig: String,
+ buildFlag: [String, Array],
+ noSign: Boolean
+}, { '-r': '--release', d: '--verbose' }, args);
// Make buildOptions compatible with PlatformApi build method spec
buildOpts.argv = buildOpts.argv.remain;
require('./loggingHelper').adjustLoggerLevel(buildOpts);
-new Api().build(buildOpts).done(function() {
+new Api().build(buildOpts).then(
+ () => {
console.log('** BUILD SUCCEEDED **');
- }, function(err) {
+ },
+ err => {
var errorMessage = (err && err.stack) ? err.stack : err;
console.error(errorMessage);
process.exit(2);
- });
+ }
+);
diff --git a/StoneIsland/platforms/ios/cordova/build-debug.xcconfig b/StoneIsland/platforms/ios/cordova/build-debug.xcconfig
index 3f4767d2..7e7985bb 100755..100644
--- a/StoneIsland/platforms/ios/cordova/build-debug.xcconfig
+++ b/StoneIsland/platforms/ios/cordova/build-debug.xcconfig
@@ -23,7 +23,7 @@
#include "build.xcconfig"
-GCC_PREPROCESSOR_DEFINITIONS = DEBUG=1
+GCC_PREPROCESSOR_DEFINITIONS = $(inherited) DEBUG=1
#include "build-extras.xcconfig"
diff --git a/StoneIsland/platforms/ios/cordova/build-extras.xcconfig b/StoneIsland/platforms/ios/cordova/build-extras.xcconfig
index e69de29b..e69de29b 100755..100644
--- a/StoneIsland/platforms/ios/cordova/build-extras.xcconfig
+++ b/StoneIsland/platforms/ios/cordova/build-extras.xcconfig
diff --git a/StoneIsland/platforms/ios/cordova/build-release.xcconfig b/StoneIsland/platforms/ios/cordova/build-release.xcconfig
index 70b0f073..70b0f073 100755..100644
--- a/StoneIsland/platforms/ios/cordova/build-release.xcconfig
+++ b/StoneIsland/platforms/ios/cordova/build-release.xcconfig
diff --git a/StoneIsland/platforms/ios/cordova/build.xcconfig b/StoneIsland/platforms/ios/cordova/build.xcconfig
index cc78c73e..3c8b9307 100755..100644
--- a/StoneIsland/platforms/ios/cordova/build.xcconfig
+++ b/StoneIsland/platforms/ios/cordova/build.xcconfig
@@ -36,8 +36,10 @@ ENABLE_BITCODE = NO
// (CB-9719) Set CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES to YES in build.xcconfig
CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES
-// (CB-10072)
+// (CB-10072)
SWIFT_OBJC_BRIDGING_HEADER = $(PROJECT_DIR)/$(PROJECT_NAME)/Bridging-Header.h
// (CB-11854)
CODE_SIGN_ENTITLEMENTS = $(PROJECT_DIR)/$(PROJECT_NAME)/Entitlements-$(CONFIGURATION).plist
+
+GCC_PREPROCESSOR_DEFINITIONS = $(inherited) WK_WEB_VIEW_ONLY=$(WK_WEB_VIEW_ONLY)
diff --git a/StoneIsland/platforms/ios/cordova/check_reqs b/StoneIsland/platforms/ios/cordova/check_reqs
index d101ccd1..e46db6c8 100755
--- a/StoneIsland/platforms/ios/cordova/check_reqs
+++ b/StoneIsland/platforms/ios/cordova/check_reqs
@@ -25,8 +25,8 @@ var check_reqs = require('./lib/check_reqs');
if (['--help', '/?', '-h', 'help', '-help', '/help'].indexOf(process.argv[2]) > -1) {
console.log('Usage: check_reqs or node check_reqs');
} else {
- check_reqs.run().done(null, function (err) {
- console.error('Failed to check requirements due to ' + err);
- process.exit(2);
- });
+ check_reqs.run().catch(err => {
+ console.error('Failed to check requirements due to ' + err);
+ process.exit(2);
+ });
}
diff --git a/StoneIsland/platforms/ios/cordova/clean b/StoneIsland/platforms/ios/cordova/clean
index 56665c48..f36a648e 100755
--- a/StoneIsland/platforms/ios/cordova/clean
+++ b/StoneIsland/platforms/ios/cordova/clean
@@ -20,19 +20,18 @@
*/
var Api = require('./Api');
-var path = require('path');
var nopt = require('nopt');
-if(['--help', '/?', '-h', 'help', '-help', '/help'].indexOf(process.argv[2]) >= 0) {
+if (['--help', '/?', '-h', 'help', '-help', '/help'].indexOf(process.argv[2]) >= 0) {
console.log('Cleans the project directory.');
process.exit(0);
}
// Do some basic argument parsing
var opts = nopt({
- 'verbose' : Boolean,
- 'silent' : Boolean
-}, { 'd' : '--verbose' });
+ verbose: Boolean,
+ silent: Boolean
+}, { d: '--verbose' });
// Make buildOptions compatible with PlatformApi clean method spec
opts.argv = opts.argv.original;
@@ -42,9 +41,12 @@ opts.noPrepare = true;
require('./loggingHelper').adjustLoggerLevel(opts);
-new Api().clean(opts).done(function() {
- console.log('** CLEAN SUCCEEDED **');
-}, function(err) {
- console.error(err);
- process.exit(2);
-});
+new Api().clean(opts).then(
+ () => {
+ console.log('** CLEAN SUCCEEDED **');
+ },
+ err => {
+ console.error(err);
+ process.exit(2);
+ }
+);
diff --git a/StoneIsland/platforms/ios/cordova/defaults.xml b/StoneIsland/platforms/ios/cordova/defaults.xml
index 77a0a0b3..8733ce39 100755..100644
--- a/StoneIsland/platforms/ios/cordova/defaults.xml
+++ b/StoneIsland/platforms/ios/cordova/defaults.xml
@@ -27,7 +27,7 @@
<preference name="DisallowOverscroll" value="false" />
<preference name="EnableViewportScale" value="false" />
<preference name="KeyboardDisplayRequiresUserAction" value="true" />
- <preference name="MediaPlaybackRequiresUserAction" value="false" />
+ <preference name="MediaTypesRequiringUserActionForPlayback" value="none" />
<preference name="SuppressesIncrementalRendering" value="false" />
<preference name="SuppressesLongPressGesture" value="false" />
<preference name="Suppresses3DTouchGesture" value="false" />
@@ -36,6 +36,12 @@
<preference name="PaginationBreakingMode" value="page" /> <!-- page, column -->
<preference name="PaginationMode" value="unpaginated" /> <!-- unpaginated, leftToRight, topToBottom, bottomToTop, rightToLeft -->
+ <feature name="CDVWebViewEngine">
+ <param name="ios-package" value="CDVWebViewEngine" />
+ </feature>
+ <feature name="LaunchScreen">
+ <param name="ios-package" value="CDVLaunchScreen"/>
+ </feature>
<feature name="LocalStorage">
<param name="ios-package" value="CDVLocalStorage"/>
</feature>
diff --git a/StoneIsland/platforms/ios/cordova/lib/BridgingHeader.js b/StoneIsland/platforms/ios/cordova/lib/BridgingHeader.js
new file mode 100644
index 00000000..9e200b50
--- /dev/null
+++ b/StoneIsland/platforms/ios/cordova/lib/BridgingHeader.js
@@ -0,0 +1,123 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+*/
+'use strict';
+
+const fs = require('fs-extra');
+const CordovaError = require('cordova-common').CordovaError;
+
+function BridgingHeader (bridgingHeaderPath) {
+ this.path = bridgingHeaderPath;
+ this.bridgingHeaders = null;
+ if (!fs.existsSync(this.path)) {
+ throw new CordovaError('BridgingHeader.h is not found.');
+ }
+ this.bridgingHeaders = this.__parseForBridgingHeader(fs.readFileSync(this.path, 'utf8'));
+}
+
+BridgingHeader.prototype.addHeader = function (plugin_id, header_path) {
+ this.bridgingHeaders.push({ type: 'code', code: `#import "${header_path}"\n` });
+};
+
+BridgingHeader.prototype.removeHeader = function (plugin_id, header_path) {
+ this.bridgingHeaders = this.bridgingHeaders.filter(function (line) {
+ if (this.found) {
+ return true;
+ }
+ if (line.type === 'code') {
+ const re = new RegExp(`#import\\s+"${preg_quote(header_path)}"(\\s*|\\s.+)(\\n|$)`);
+ if (re.test(line.code)) {
+ this.found = true;
+ return false;
+ }
+ }
+ return true;
+ }, { found: false });
+};
+
+BridgingHeader.prototype.write = function () {
+ const text = this.__stringifyForBridgingHeader(this.bridgingHeaders);
+ fs.writeFileSync(this.path, text, 'utf8');
+};
+
+BridgingHeader.prototype.__stringifyForBridgingHeader = function (bridgingHeaders) {
+ return bridgingHeaders.map(obj => obj.code).join('');
+};
+
+BridgingHeader.prototype.__parseForBridgingHeader = function (text) {
+ let i = 0;
+ const list = [];
+ let type = 'code';
+ let start = 0;
+ while (i < text.length) {
+ switch (type) {
+ case 'comment':
+ if (i + 1 < text.length && text[i] === '*' && text[i + 1] === '/') {
+ i += 2;
+ list.push({ type, code: text.slice(start, i) });
+ type = 'code';
+ start = i;
+ } else {
+ i += 1;
+ }
+ break;
+ case 'line-comment':
+ if (i < text.length && text[i] === '\n') {
+ i += 1;
+ list.push({ type, code: text.slice(start, i) });
+ type = 'code';
+ start = i;
+ } else {
+ i += 1;
+ }
+ break;
+ case 'code':
+ default:
+ if (i + 1 < text.length && text[i] === '/' && text[i + 1] === '*') { // comment
+ if (start < i) {
+ list.push({ type, code: text.slice(start, i) });
+ }
+ type = 'comment';
+ start = i;
+ } else if (i + 1 < text.length && text[i] === '/' && text[i + 1] === '/') { // line comment
+ if (start < i) {
+ list.push({ type, code: text.slice(start, i) });
+ }
+ type = 'line-comment';
+ start = i;
+ } else if (i < text.length && text[i] === '\n') {
+ i += 1;
+ list.push({ type, code: text.slice(start, i) });
+ start = i;
+ } else {
+ i += 1;
+ }
+ break;
+ }
+ }
+ if (start < i) {
+ list.push({ type, code: text.slice(start, i) });
+ }
+ return list;
+};
+
+function preg_quote (str, delimiter) {
+ return (`${str}`).replace(new RegExp(`[.\\\\+*?\\[\\^\\]$(){}=!<>|:\\${delimiter || ''}-]`, 'g'), '\\$&');
+}
+
+module.exports.BridgingHeader = BridgingHeader;
diff --git a/StoneIsland/platforms/ios/cordova/lib/Podfile.js b/StoneIsland/platforms/ios/cordova/lib/Podfile.js
index 49173c4c..f1672974 100755..100644
--- a/StoneIsland/platforms/ios/cordova/lib/Podfile.js
+++ b/StoneIsland/platforms/ios/cordova/lib/Podfile.js
@@ -18,27 +18,37 @@
*/
'use strict';
-var fs = require('fs');
-var path = require('path');
-var util = require('util');
-var events = require('cordova-common').events;
-var Q = require('q');
-var superspawn = require('cordova-common').superspawn;
-var CordovaError = require('cordova-common').CordovaError;
+const fs = require('fs-extra');
+const path = require('path');
+const util = require('util');
+const {
+ CordovaError,
+ events,
+ superspawn: { spawn }
+} = require('cordova-common');
Podfile.FILENAME = 'Podfile';
+Podfile.declarationRegexpMap = {
+ 'use_frameworks!': 'use[-_]frameworks!?',
+ 'inhibit_all_warnings!': 'inhibit[-_]all[-_]warnings!?'
+};
-function Podfile (podFilePath, projectName) {
+function Podfile (podFilePath, projectName, minDeploymentTarget) {
+ this.declarationToken = '##INSERT_DECLARATION##';
+ this.sourceToken = '##INSERT_SOURCE##';
this.podToken = '##INSERT_POD##';
this.path = podFilePath;
this.projectName = projectName;
+ this.minDeploymentTarget = minDeploymentTarget || '11.0';
this.contents = null;
+ this.sources = null;
+ this.declarations = null;
this.pods = null;
this.__dirty = false;
// check whether it is named Podfile
- var filename = this.path.split(path.sep).pop();
+ const filename = this.path.split(path.sep).pop();
if (filename !== Podfile.FILENAME) {
throw new CordovaError(util.format('Podfile: The file at %s is not `%s`.', this.path, Podfile.FILENAME));
}
@@ -55,33 +65,101 @@ function Podfile (podFilePath, projectName) {
} else {
events.emit('verbose', 'Podfile found in platforms/ios');
// parse for pods
- this.pods = this.__parseForPods(fs.readFileSync(this.path, 'utf8'));
+ const fileText = fs.readFileSync(this.path, 'utf8');
+ this.declarations = this.__parseForDeclarations(fileText);
+ this.sources = this.__parseForSources(fileText);
+ this.pods = this.__parseForPods(fileText);
}
}
+Podfile.prototype.__parseForDeclarations = function (text) {
+ // split by \n
+ const arr = text.split('\n');
+
+ // getting lines between "platform :ios, '11.0'"" and "target 'HelloCordova'" do
+ const declarationsPreRE = new RegExp('platform :ios,\\s+\'[^\']+\'');
+ const declarationsPostRE = new RegExp('target\\s+\'[^\']+\'\\s+do');
+ const declarationRE = new RegExp('^\\s*[^#]');
+
+ return arr.reduce((acc, line) => {
+ switch (acc.state) {
+ case 0:
+ if (declarationsPreRE.exec(line)) {
+ acc.state = 1; // Start to read
+ }
+ break;
+ case 1:
+ if (declarationsPostRE.exec(line)) {
+ acc.state = 2; // Finish to read
+ } else {
+ acc.lines.push(line);
+ }
+ break;
+ case 2:
+ default:
+ // do nothing;
+ }
+ return acc;
+ }, { state: 0, lines: [] })
+ .lines
+ .filter(line => declarationRE.exec(line))
+ .reduce((obj, line) => {
+ obj[line] = line;
+ return obj;
+ }, {});
+};
+
+Podfile.prototype.__parseForSources = function (text) {
+ // split by \n
+ const arr = text.split('\n');
+
+ const sourceRE = new RegExp('source \'(.*)\'');
+ return arr.filter(line => {
+ const m = sourceRE.exec(line);
+
+ return (m !== null);
+ })
+ .reduce((obj, line) => {
+ const m = sourceRE.exec(line);
+ if (m !== null) {
+ const source = m[1];
+ obj[source] = source;
+ }
+ return obj;
+ }, {});
+};
+
Podfile.prototype.__parseForPods = function (text) {
// split by \n
- var arr = text.split('\n');
+ const arr = text.split('\n');
// aim is to match (space insignificant around the comma, comma optional):
// pod 'Foobar', '1.2'
// pod 'Foobar', 'abc 123 1.2'
// pod 'PonyDebugger', :configurations => ['Debug', 'Beta']
- var podRE = new RegExp('pod \'([^\']*)\'\\s*,?\\s*(.*)');
+ // var podRE = new RegExp('pod \'([^\']*)\'\\s*,?\\s*(.*)');
+ const podRE = new RegExp('pod \'([^\']*)\'\\s*(?:,\\s*\'([^\']*)\'\\s*)?,?\\s*(.*)');
// only grab lines that don't have the pod spec'
- return arr.filter(function (line) {
- var m = podRE.exec(line);
+ return arr.filter(line => {
+ const m = podRE.exec(line);
return (m !== null);
})
- .reduce(function (obj, line) {
- var m = podRE.exec(line);
+ .reduce((obj, line) => {
+ const m = podRE.exec(line);
if (m !== null) {
- // strip out any single quotes around the value m[2]
- var podSpec = m[2].replace(/^\'|\'$/g, ''); /* eslint no-useless-escape : 0 */
- obj[m[1]] = podSpec; // i.e pod 'Foo', '1.2' ==> { 'Foo' : '1.2'}
+ const podspec = {
+ name: m[1]
+ };
+ if (m[2]) {
+ podspec.spec = m[2];
+ }
+ if (m[3]) {
+ podspec.options = m[3];
+ }
+ obj[m[1]] = podspec; // i.e pod 'Foo', '1.2' ==> { 'Foo' : '1.2'}
}
return obj;
@@ -89,20 +167,22 @@ Podfile.prototype.__parseForPods = function (text) {
};
Podfile.prototype.escapeSingleQuotes = function (string) {
- return string.replace('\'', '\\\'');
+ return string.replace(/'/g, '\\\'');
};
Podfile.prototype.getTemplate = function () {
// Escaping possible ' in the project name
- var projectName = this.escapeSingleQuotes(this.projectName);
+ const projectName = this.escapeSingleQuotes(this.projectName);
return util.format(
'# DO NOT MODIFY -- auto-generated by Apache Cordova\n' +
- 'platform :ios, \'8.0\'\n' +
+ '%s\n' +
+ 'platform :ios, \'%s\'\n' +
+ '%s\n' +
'target \'%s\' do\n' +
'\tproject \'%s.xcodeproj\'\n' +
'%s\n' +
'end\n',
- projectName, projectName, this.podToken);
+ this.sourceToken, this.minDeploymentTarget, this.declarationToken, projectName, projectName, this.podToken);
};
Podfile.prototype.addSpec = function (name, spec) {
@@ -114,6 +194,14 @@ Podfile.prototype.addSpec = function (name, spec) {
throw new CordovaError('Podfile addSpec: name is not specified.');
}
+ if (typeof spec === 'string') {
+ if (spec.startsWith(':')) {
+ spec = { name, options: spec };
+ } else {
+ spec = { name, spec };
+ }
+ }
+
this.pods[name] = spec;
this.__dirty = true;
@@ -137,7 +225,60 @@ Podfile.prototype.existsSpec = function (name) {
return (name in this.pods);
};
+Podfile.prototype.addSource = function (src) {
+ this.sources[src] = src;
+ this.__dirty = true;
+
+ events.emit('verbose', util.format('Added source line for `%s`', src));
+};
+
+Podfile.prototype.removeSource = function (src) {
+ if (this.existsSource(src)) {
+ delete this.sources[src];
+ this.__dirty = true;
+ }
+
+ events.emit('verbose', util.format('Removed source line for `%s`', src));
+};
+
+Podfile.prototype.existsSource = function (src) {
+ return (src in this.sources);
+};
+
+Podfile.prototype.addDeclaration = function (declaration) {
+ this.declarations[declaration] = declaration;
+ this.__dirty = true;
+
+ events.emit('verbose', util.format('Added declaration line for `%s`', declaration));
+};
+
+Podfile.prototype.removeDeclaration = function (declaration) {
+ if (this.existsDeclaration(declaration)) {
+ delete this.declarations[declaration];
+ this.__dirty = true;
+ }
+
+ events.emit('verbose', util.format('Removed source line for `%s`', declaration));
+};
+
+Podfile.proofDeclaration = declaration => {
+ const list = Object.keys(Podfile.declarationRegexpMap).filter(key => {
+ const regexp = new RegExp(Podfile.declarationRegexpMap[key]);
+ return regexp.test(declaration);
+ });
+ if (list.length > 0) {
+ return list[0];
+ }
+ return declaration;
+};
+
+Podfile.prototype.existsDeclaration = function (declaration) {
+ return (declaration in this.declarations);
+};
+
Podfile.prototype.clear = function () {
+ this.sources = {};
+ this.declarations = {};
this.pods = {};
this.__dirty = true;
};
@@ -148,28 +289,65 @@ Podfile.prototype.destroy = function () {
};
Podfile.prototype.write = function () {
- var text = this.getTemplate();
- var self = this;
+ let text = this.getTemplate();
- var podsString =
- Object.keys(this.pods).map(function (key) {
- var name = key;
- var spec = self.pods[key];
+ const podsString =
+ Object.keys(this.pods).map(key => {
+ const name = key;
+ const json = this.pods[key];
- if (spec.length) {
- if (spec.indexOf(':') === 0) {
- // don't quote it, it's a specification (starts with ':')
- return util.format('\tpod \'%s\', %s', name, spec);
+ if (typeof json === 'string') { // compatibility for using framework tag.
+ const spec = json;
+ if (spec.length) {
+ if (spec.indexOf(':') === 0) {
+ // don't quote it, it's a specification (starts with ':')
+ return util.format('\tpod \'%s\', %s', name, spec);
+ } else {
+ // quote it, it's a version
+ return util.format('\tpod \'%s\', \'%s\'', name, spec);
+ }
} else {
- // quote it, it's a version
- return util.format('\tpod \'%s\', \'%s\'', name, spec);
+ return util.format('\tpod \'%s\'', name);
}
} else {
- return util.format('\tpod \'%s\'', name);
+ const list = [`'${name}'`];
+ if ('spec' in json && json.spec.length) {
+ list.push(`'${json.spec}'`);
+ }
+
+ let options = ['tag', 'branch', 'commit', 'git', 'podspec']
+ .filter(tag => tag in json)
+ .map(tag => `:${tag} => '${json[tag]}'`);
+
+ if ('configurations' in json) {
+ options.push(`:configurations => [${json.configurations.split(',').map(conf => `'${conf.trim()}'`).join(',')}]`);
+ }
+ if ('options' in json) {
+ options = [json.options];
+ }
+ if (options.length > 0) {
+ list.push(options.join(', '));
+ }
+ return util.format('\tpod %s', list.join(', '));
}
}).join('\n');
- text = text.replace(this.podToken, podsString);
+ const sourcesString =
+ Object.keys(this.sources).map(key => {
+ const source = this.sources[key];
+ return util.format('source \'%s\'', source);
+ }).join('\n');
+
+ const declarationString =
+ Object.keys(this.declarations).map(key => {
+ const declaration = this.declarations[key];
+ return declaration;
+ }).join('\n');
+
+ text = text.replace(this.podToken, podsString)
+ .replace(this.sourceToken, sourcesString)
+ .replace(this.declarationToken, declarationString);
+
fs.writeFileSync(this.path, text, 'utf8');
this.__dirty = false;
@@ -184,45 +362,43 @@ Podfile.prototype.before_install = function (toolOptions) {
toolOptions = toolOptions || {};
// Template tokens in order: project name, project name, debug | release
- var template =
+ const template =
'// DO NOT MODIFY -- auto-generated by Apache Cordova\n' +
'#include "Pods/Target Support Files/Pods-%s/Pods-%s.%s.xcconfig"';
- var debugContents = util.format(template, this.projectName, this.projectName, 'debug');
- var releaseContents = util.format(template, this.projectName, this.projectName, 'release');
+ const debugContents = util.format(template, this.projectName, this.projectName, 'debug');
+ const releaseContents = util.format(template, this.projectName, this.projectName, 'release');
- var debugConfigPath = path.join(this.path, '..', 'pods-debug.xcconfig');
- var releaseConfigPath = path.join(this.path, '..', 'pods-release.xcconfig');
+ const debugConfigPath = path.join(this.path, '..', 'pods-debug.xcconfig');
+ const releaseConfigPath = path.join(this.path, '..', 'pods-release.xcconfig');
fs.writeFileSync(debugConfigPath, debugContents, 'utf8');
fs.writeFileSync(releaseConfigPath, releaseContents, 'utf8');
- return Q.resolve(toolOptions);
+ return Promise.resolve(toolOptions);
};
Podfile.prototype.install = function (requirementsCheckerFunction) {
- var opts = {};
+ const opts = {};
opts.cwd = path.join(this.path, '..'); // parent path of this Podfile
opts.stdio = 'pipe';
- var first = true;
- var self = this;
+ opts.printCommand = true;
+ let first = true;
if (!requirementsCheckerFunction) {
- requirementsCheckerFunction = Q();
+ requirementsCheckerFunction = Promise.resolve();
}
return requirementsCheckerFunction()
- .then(function (toolOptions) {
- return self.before_install(toolOptions);
- })
- .then(function (toolOptions) {
+ .then(toolOptions => this.before_install(toolOptions))
+ .then(toolOptions => {
if (toolOptions.ignore) {
events.emit('verbose', '==== pod install start ====\n');
events.emit('verbose', toolOptions.ignoreMessage);
- return Q.resolve();
+ return Promise.resolve();
} else {
- return superspawn.spawn('pod', ['install', '--verbose'], opts)
- .progress(function (stdio) {
+ return spawn('pod', ['install', '--verbose'], opts)
+ .progress(stdio => {
if (stdio.stderr) { console.error(stdio.stderr); }
if (stdio.stdout) {
if (first) {
@@ -234,11 +410,8 @@ Podfile.prototype.install = function (requirementsCheckerFunction) {
});
}
})
- .then(function () { // done
+ .then(() => { // done
events.emit('verbose', '==== pod install end ====\n');
- })
- .fail(function (error) {
- throw error;
});
};
diff --git a/StoneIsland/platforms/ios/cordova/lib/PodsJson.js b/StoneIsland/platforms/ios/cordova/lib/PodsJson.js
index 04705273..598d9607 100755..100644
--- a/StoneIsland/platforms/ios/cordova/lib/PodsJson.js
+++ b/StoneIsland/platforms/ios/cordova/lib/PodsJson.js
@@ -17,20 +17,23 @@
under the License.
*/
-var fs = require('fs');
-var path = require('path');
-var util = require('util');
-var events = require('cordova-common').events;
-var CordovaError = require('cordova-common').CordovaError;
+const fs = require('fs-extra');
+const path = require('path');
+const util = require('util');
+const events = require('cordova-common').events;
+const CordovaError = require('cordova-common').CordovaError;
PodsJson.FILENAME = 'pods.json';
+PodsJson.LIBRARY = 'libraries';
+PodsJson.SOURCE = 'sources';
+PodsJson.DECLARATION = 'declarations';
function PodsJson (podsJsonPath) {
this.path = podsJsonPath;
this.contents = null;
this.__dirty = false;
- var filename = this.path.split(path.sep).pop();
+ const filename = this.path.split(path.sep).pop();
if (filename !== PodsJson.FILENAME) {
throw new CordovaError(util.format('PodsJson: The file at %s is not `%s`.', this.path, PodsJson.FILENAME));
}
@@ -43,25 +46,81 @@ function PodsJson (podsJsonPath) {
} else {
events.emit('verbose', 'pods.json found in platforms/ios');
// load contents
- this.contents = fs.readFileSync(this.path, 'utf8');
- this.contents = JSON.parse(this.contents);
+ const contents = fs.readFileSync(this.path, 'utf8');
+ this.contents = JSON.parse(contents);
}
+ this.__updateFormatIfNecessary();
}
-PodsJson.prototype.get = function (name) {
- return this.contents[name];
+PodsJson.prototype.__isOldFormat = function () {
+ if (this.contents !== null) {
+ if (this.contents.declarations === undefined ||
+ this.contents.sources === undefined ||
+ this.contents.libraries === undefined) {
+ return true;
+ }
+ }
+ return false;
};
-PodsJson.prototype.remove = function (name) {
- if (this.contents[name]) {
- delete this.contents[name];
+PodsJson.prototype.__updateFormatIfNecessary = function () {
+ if (this.__isOldFormat()) {
+ this.contents = {
+ declarations: {},
+ sources: {},
+ libraries: this.contents
+ };
this.__dirty = true;
- events.emit('verbose', util.format('Remove from pods.json for `%s`', name));
+ events.emit('verbose', 'Update format of pods.json');
}
};
+PodsJson.prototype.getLibraries = function () {
+ return this.contents[PodsJson.LIBRARY];
+};
+
+PodsJson.prototype.__get = function (kind, name) {
+ return this.contents[kind][name];
+};
+
+PodsJson.prototype.getLibrary = function (name) {
+ return this.__get(PodsJson.LIBRARY, name);
+};
+
+PodsJson.prototype.getSource = function (name) {
+ return this.__get(PodsJson.SOURCE, name);
+};
+
+PodsJson.prototype.getDeclaration = function (name) {
+ return this.__get(PodsJson.DECLARATION, name);
+};
+
+PodsJson.prototype.__remove = function (kind, name) {
+ if (this.contents[kind][name]) {
+ delete this.contents[kind][name];
+ this.__dirty = true;
+ events.emit('verbose', util.format('Remove from pods.json for `%s` - `%s`', name));
+ }
+};
+
+PodsJson.prototype.removeLibrary = function (name) {
+ this.__remove(PodsJson.LIBRARY, name);
+};
+
+PodsJson.prototype.removeSource = function (name) {
+ this.__remove(PodsJson.SOURCE, name);
+};
+
+PodsJson.prototype.removeDeclaration = function (name) {
+ this.__remove(PodsJson.DECLARATION, name);
+};
+
PodsJson.prototype.clear = function () {
- this.contents = {};
+ this.contents = {
+ declarations: {},
+ sources: {},
+ libraries: {}
+ };
this.__dirty = true;
};
@@ -78,34 +137,69 @@ PodsJson.prototype.write = function () {
}
};
-PodsJson.prototype.set = function (name, type, spec, count) {
- this.setJson(name, { name: name, type: type, spec: spec, count: count });
-};
-
-PodsJson.prototype.increment = function (name) {
- var val = this.get(name);
+PodsJson.prototype.__increment = function (kind, name) {
+ const val = this.__get(kind, name);
if (val) {
val.count++;
- this.setJson(val);
}
};
-PodsJson.prototype.decrement = function (name) {
- var val = this.get(name);
+PodsJson.prototype.incrementLibrary = function (name) {
+ this.__increment(PodsJson.LIBRARY, name);
+};
+
+PodsJson.prototype.incrementSource = function (name) {
+ this.__increment(PodsJson.SOURCE, name);
+};
+
+PodsJson.prototype.incrementDeclaration = function (name) {
+ this.__increment(PodsJson.DECLARATION, name);
+};
+
+PodsJson.prototype.__decrement = function (kind, name) {
+ const val = this.__get(kind, name);
if (val) {
val.count--;
if (val.count <= 0) {
- this.remove(name);
- } else {
- this.setJson(val);
+ this.__remove(kind, name);
}
}
};
-PodsJson.prototype.setJson = function (name, json) {
- this.contents[name] = json;
+PodsJson.prototype.decrementLibrary = function (name) {
+ this.__decrement(PodsJson.LIBRARY, name);
+};
+
+PodsJson.prototype.decrementSource = function (name) {
+ this.__decrement(PodsJson.SOURCE, name);
+};
+
+PodsJson.prototype.decrementDeclaration = function (name) {
+ this.__decrement(PodsJson.DECLARATION, name);
+};
+
+PodsJson.prototype.__setJson = function (kind, name, json) {
+ this.contents[kind][name] = Object.assign({}, json);
this.__dirty = true;
- events.emit('verbose', util.format('Set pods.json for `%s`', name));
+ events.emit('verbose', util.format('Set pods.json for `%s` - `%s`', kind, name));
+};
+
+// sample json for library
+// { name: "Eureka", spec: "4.2.0", "swift-version": "4.1", count: 1 }
+PodsJson.prototype.setJsonLibrary = function (name, json) {
+ this.__setJson(PodsJson.LIBRARY, name, json);
+};
+
+// sample json for source
+// { source: "https://github.com/brightcove/BrightcoveSpecs.git", count: 1 }
+PodsJson.prototype.setJsonSource = function (name, json) {
+ this.__setJson(PodsJson.SOURCE, name, json);
+};
+
+// sample json for declaration
+// { declaration: ""}
+PodsJson.prototype.setJsonDeclaration = function (name, json) {
+ this.__setJson(PodsJson.DECLARATION, name, json);
};
PodsJson.prototype.isDirty = function () {
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.
diff --git a/StoneIsland/platforms/ios/cordova/lib/check_reqs.js b/StoneIsland/platforms/ios/cordova/lib/check_reqs.js
index 21a22081..33dc684f 100755..100644
--- a/StoneIsland/platforms/ios/cordova/lib/check_reqs.js
+++ b/StoneIsland/platforms/ios/cordova/lib/check_reqs.js
@@ -19,37 +19,28 @@
'use strict';
-const Q = require('q');
-const shell = require('shelljs');
-const util = require('util');
+const which = require('which');
const versions = require('./versions');
+const { CordovaError } = require('cordova-common');
-const SUPPORTED_OS_PLATFORMS = [ 'darwin' ];
+const SUPPORTED_OS_PLATFORMS = ['darwin'];
-const XCODEBUILD_MIN_VERSION = '7.0.0';
+const XCODEBUILD_MIN_VERSION = '9.0.0';
const XCODEBUILD_NOT_FOUND_MESSAGE =
- 'Please install version ' + XCODEBUILD_MIN_VERSION + ' or greater from App Store';
+ `Please install version ${XCODEBUILD_MIN_VERSION} or greater from App Store`;
const IOS_DEPLOY_MIN_VERSION = '1.9.2';
const IOS_DEPLOY_NOT_FOUND_MESSAGE =
- 'Please download, build and install version ' + IOS_DEPLOY_MIN_VERSION + ' or greater' +
- ' from https://github.com/phonegap/ios-deploy into your path, or do \'npm install -g ios-deploy\'';
+ `Please download, build and install version ${IOS_DEPLOY_MIN_VERSION} or greater from https://github.com/ios-control/ios-deploy into your path, or do 'npm install -g ios-deploy'`;
-const COCOAPODS_MIN_VERSION = '1.0.1';
-const COCOAPODS_NOT_FOUND_MESSAGE =
- 'Please install version ' + COCOAPODS_MIN_VERSION + ' or greater from https://cocoapods.org/';
-const COCOAPODS_NOT_SYNCED_MESSAGE =
- 'The CocoaPods repo has not been synced yet, this will take a long time (approximately 500MB as of Sept 2016). Please run `pod setup` first to sync the repo.';
-const COCOAPODS_SYNCED_MIN_SIZE = 475; // in megabytes
-const COCOAPODS_SYNC_ERROR_MESSAGE =
- 'The CocoaPods repo has been created, but there appears to be a sync error. The repo size should be at least ' + COCOAPODS_SYNCED_MIN_SIZE + '. Please run `pod setup --verbose` to sync the repo.';
-const COCOAPODS_REPO_NOT_FOUND_MESSAGE = 'The CocoaPods repo at ~/.cocoapods was not found.';
+const COCOAPODS_MIN_VERSION = '1.8.0';
+const COCOAPODS_NOT_FOUND_MESSAGE = `Please install version ${COCOAPODS_MIN_VERSION} or greater from https://cocoapods.org/`;
/**
* Checks if xcode util is available
* @return {Promise} Returns a promise either resolved with xcode version or rejected
*/
-module.exports.run = module.exports.check_xcodebuild = function () {
+module.exports.run = module.exports.check_xcodebuild = () => {
return checkTool('xcodebuild', XCODEBUILD_MIN_VERSION, XCODEBUILD_NOT_FOUND_MESSAGE);
};
@@ -57,81 +48,27 @@ module.exports.run = module.exports.check_xcodebuild = function () {
* Checks if ios-deploy util is available
* @return {Promise} Returns a promise either resolved with ios-deploy version or rejected
*/
-module.exports.check_ios_deploy = function () {
+module.exports.check_ios_deploy = () => {
return checkTool('ios-deploy', IOS_DEPLOY_MIN_VERSION, IOS_DEPLOY_NOT_FOUND_MESSAGE);
};
-module.exports.check_os = function () {
+module.exports.check_os = () => {
// Build iOS apps available for OSX platform only, so we reject on others platforms
- return os_platform_is_supported() ?
- Q.resolve(process.platform) :
- Q.reject('Cordova tooling for iOS requires Apple macOS');
+ return os_platform_is_supported()
+ ? Promise.resolve(process.platform)
+ : Promise.reject(new CordovaError('Cordova tooling for iOS requires Apple macOS'));
};
function os_platform_is_supported () {
return (SUPPORTED_OS_PLATFORMS.indexOf(process.platform) !== -1);
}
-function check_cocoapod_tool (toolChecker) {
- toolChecker = toolChecker || checkTool;
- if (os_platform_is_supported()) { // CB-12856
- return toolChecker('pod', COCOAPODS_MIN_VERSION, COCOAPODS_NOT_FOUND_MESSAGE, 'CocoaPods');
- } else {
- return Q.resolve({
- 'ignore': true,
- 'ignoreMessage': `CocoaPods check and installation ignored on ${process.platform}`
- });
- }
-}
-
/**
- * Checks if cocoapods repo size is what is expected
+ * Checks if cocoapods is available.
* @return {Promise} Returns a promise either resolved or rejected
*/
-module.exports.check_cocoapods_repo_size = function () {
- return check_cocoapod_tool()
- .then(function (toolOptions) {
- // check size of ~/.cocoapods repo
- let commandString = util.format('du -sh %s/.cocoapods', process.env.HOME);
- let command = shell.exec(commandString, { silent: true });
- // command.output is e.g "750M path/to/.cocoapods", we just scan the number
- let size = toolOptions.ignore ? 0 : parseFloat(command.output);
-
- if (toolOptions.ignore || command.code === 0) { // success, parse output
- return Q.resolve(size, toolOptions);
- } else { // error, perhaps not found
- return Q.reject(util.format('%s (%s)', COCOAPODS_REPO_NOT_FOUND_MESSAGE, command.output));
- }
- })
- .then(function (repoSize, toolOptions) {
- if (toolOptions.ignore || COCOAPODS_SYNCED_MIN_SIZE <= repoSize) { // success, expected size
- return Q.resolve(toolOptions);
- } else {
- return Q.reject(COCOAPODS_SYNC_ERROR_MESSAGE);
- }
- });
-};
-
-/**
- * Checks if cocoapods is available, and whether the repo is synced (because it takes a long time to download)
- * @return {Promise} Returns a promise either resolved or rejected
- */
-module.exports.check_cocoapods = function (toolChecker) {
- return check_cocoapod_tool(toolChecker)
- // check whether the cocoapods repo has been synced through `pod repo` command
- // a value of '0 repos' means it hasn't been synced
- .then(function (toolOptions) {
- let code = shell.exec('pod repo | grep -e "^0 repos"', { silent: true }).code;
- let repoIsSynced = (code !== 0);
-
- if (toolOptions.ignore || repoIsSynced) {
- // return check_cocoapods_repo_size();
- // we could check the repo size above, but it takes too long.
- return Q.resolve(toolOptions);
- } else {
- return Q.reject(COCOAPODS_NOT_SYNCED_MESSAGE);
- }
- });
+module.exports.check_cocoapods = toolChecker => {
+ return checkTool('pod', COCOAPODS_MIN_VERSION, COCOAPODS_NOT_FOUND_MESSAGE, 'CocoaPods');
};
/**
@@ -146,18 +83,17 @@ function checkTool (tool, minVersion, message, toolFriendlyName) {
toolFriendlyName = toolFriendlyName || tool;
// Check whether tool command is available at all
- let tool_command = shell.which(tool);
+ const tool_command = which.sync(tool, { nothrow: true });
if (!tool_command) {
- return Q.reject(toolFriendlyName + ' was not found. ' + (message || ''));
+ return Promise.reject(new CordovaError(`${toolFriendlyName} was not found. ${message || ''}`));
}
// check if tool version is greater than specified one
- return versions.get_tool_version(tool).then(function (version) {
+ return versions.get_tool_version(tool).then(version => {
version = version.trim();
- return versions.compareVersions(version, minVersion) >= 0 ?
- Q.resolve({ 'version': version }) :
- Q.reject('Cordova needs ' + toolFriendlyName + ' version ' + minVersion +
- ' or greater, you have version ' + version + '. ' + (message || ''));
+ return versions.compareVersions(version, minVersion) >= 0
+ ? Promise.resolve({ version })
+ : Promise.reject(new CordovaError(`Cordova needs ${toolFriendlyName} version ${minVersion} or greater, you have version ${version}. ${message || ''}`));
});
}
@@ -168,7 +104,7 @@ function checkTool (tool, minVersion, message, toolFriendlyName) {
* @param {Boolean} isFatal Marks the requirement as fatal. If such requirement will fail
* next requirements' checks will be skipped.
*/
-let Requirement = function (id, name, isFatal) {
+const Requirement = function (id, name, isFatal) {
this.id = id;
this.name = name;
this.installed = false;
@@ -182,8 +118,7 @@ let Requirement = function (id, name, isFatal) {
*
* @return Promise<Requirement[]> Array of requirements. Due to implementation, promise is always fulfilled.
*/
-module.exports.check_all = function () {
-
+module.exports.check_all = () => {
const requirements = [
new Requirement('os', 'Apple macOS', true),
new Requirement('xcode', 'Xcode'),
@@ -191,10 +126,10 @@ module.exports.check_all = function () {
new Requirement('CocoaPods', 'CocoaPods')
];
- let result = [];
+ const result = [];
let fatalIsHit = false;
- let checkFns = [
+ const checkFns = [
module.exports.check_os,
module.exports.check_xcodebuild,
module.exports.check_ios_deploy,
@@ -202,27 +137,25 @@ module.exports.check_all = function () {
];
// Then execute requirement checks one-by-one
- return checkFns.reduce(function (promise, checkFn, idx) {
- return promise.then(function () {
+ return checkFns.reduce((promise, checkFn, idx) => {
+ return promise.then(() => {
// If fatal requirement is failed,
// we don't need to check others
- if (fatalIsHit) return Q();
+ if (fatalIsHit) return Promise.resolve();
- let requirement = requirements[idx];
+ const requirement = requirements[idx];
return checkFn()
- .then(function (version) {
+ .then(version => {
requirement.installed = true;
requirement.metadata.version = version;
result.push(requirement);
- }, function (err) {
+ }, err => {
if (requirement.isFatal) fatalIsHit = true;
requirement.metadata.reason = err;
result.push(requirement);
});
});
- }, Q())
- .then(function () {
- // When chain is completed, return requirements array to upstream API
- return result;
- });
+ }, Promise.resolve())
+ // When chain is completed, return requirements array to upstream API
+ .then(() => result);
};
diff --git a/StoneIsland/platforms/ios/cordova/lib/clean.js b/StoneIsland/platforms/ios/cordova/lib/clean.js
index 20e8ac66..72aac0ba 100755..100644
--- a/StoneIsland/platforms/ios/cordova/lib/clean.js
+++ b/StoneIsland/platforms/ios/cordova/lib/clean.js
@@ -17,26 +17,31 @@
* under the License.
*/
-var Q = require('q');
-var path = require('path');
-var shell = require('shelljs');
-var spawn = require('./spawn');
+const path = require('path');
+const fs = require('fs-extra');
+const {
+ CordovaError,
+ superspawn: { spawn }
+} = require('cordova-common');
-var projectPath = path.join(__dirname, '..', '..');
+const projectPath = path.join(__dirname, '..', '..');
-module.exports.run = function () {
- var projectName = shell.ls(projectPath).filter(function (name) {
- return path.extname(name) === '.xcodeproj';
- })[0];
+module.exports.run = () => {
+ const projectName = fs.readdirSync(projectPath).filter(name => path.extname(name) === '.xcodeproj');
if (!projectName) {
- return Q.reject('No Xcode project found in ' + projectPath);
+ return Promise.reject(new CordovaError(`No Xcode project found in ${projectPath}`));
}
- return spawn('xcodebuild', ['-project', projectName, '-configuration', 'Debug', '-alltargets', 'clean'], projectPath)
- .then(function () {
- return spawn('xcodebuild', ['-project', projectName, '-configuration', 'Release', '-alltargets', 'clean'], projectPath);
- }).then(function () {
- return shell.rm('-rf', path.join(projectPath, 'build'));
- });
+ const xcodebuildClean = configName => {
+ return spawn(
+ 'xcodebuild',
+ ['-project', projectName, '-configuration', configName, '-alltargets', 'clean'],
+ { cwd: projectPath, printCommand: true, stdio: 'inherit' }
+ );
+ };
+
+ return xcodebuildClean('Debug')
+ .then(() => xcodebuildClean('Release'))
+ .then(() => fs.removeSync(path.join(projectPath, 'build')));
};
diff --git a/StoneIsland/platforms/ios/cordova/lib/copy-www-build-step.js b/StoneIsland/platforms/ios/cordova/lib/copy-www-build-step.js
deleted file mode 100755
index e05aacf2..00000000
--- a/StoneIsland/platforms/ios/cordova/lib/copy-www-build-step.js
+++ /dev/null
@@ -1,73 +0,0 @@
-#!/usr/bin/env node
-
-/*
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied. See the License for the
- specific language governing permissions and limitations
- under the License.
-*/
-
-// This script copies the www directory into the Xcode project.
-
-// This script should not be called directly.
-// It is called as a build step from Xcode.
-
-var BUILT_PRODUCTS_DIR = process.env.BUILT_PRODUCTS_DIR;
-var FULL_PRODUCT_NAME = process.env.FULL_PRODUCT_NAME;
-var COPY_HIDDEN = process.env.COPY_HIDDEN;
-var PROJECT_FILE_PATH = process.env.PROJECT_FILE_PATH;
-
-var path = require('path');
-var fs = require('fs');
-var shell = require('shelljs');
-var srcDir = 'www';
-var dstDir = path.join(BUILT_PRODUCTS_DIR, FULL_PRODUCT_NAME);
-var dstWwwDir = path.join(dstDir, 'www');
-
-if (!BUILT_PRODUCTS_DIR) {
- console.error('The script is meant to be run as an Xcode build step and relies on env variables set by Xcode.');
- process.exit(1);
-}
-
-try {
- fs.statSync(srcDir);
-} catch (e) {
- console.error('Path does not exist: ' + srcDir);
- process.exit(2);
-}
-
-// Code signing files must be removed or else there are
-// resource signing errors.
-shell.rm('-rf', dstWwwDir);
-shell.rm('-rf', path.join(dstDir, '_CodeSignature'));
-shell.rm('-rf', path.join(dstDir, 'PkgInfo'));
-shell.rm('-rf', path.join(dstDir, 'embedded.mobileprovision'));
-
-// Copy www dir recursively
-var code;
-if (COPY_HIDDEN) {
- code = shell.exec('rsync -Lra "' + srcDir + '" "' + dstDir + '"').code;
-} else {
- code = shell.exec('rsync -Lra --exclude="- .*" "' + srcDir + '" "' + dstDir + '"').code;
-}
-
-if (code !== 0) {
- console.error('Error occured on copying www. Code: ' + code);
- process.exit(3);
-}
-
-// Copy the config.xml file.
-shell.cp('-f', path.join(path.dirname(PROJECT_FILE_PATH), path.basename(PROJECT_FILE_PATH, '.xcodeproj'), 'config.xml'),
- dstDir);
diff --git a/StoneIsland/platforms/ios/cordova/lib/list-devices b/StoneIsland/platforms/ios/cordova/lib/list-devices
index 047d5950..5f89e21b 100755
--- a/StoneIsland/platforms/ios/cordova/lib/list-devices
+++ b/StoneIsland/platforms/ios/cordova/lib/list-devices
@@ -19,49 +19,10 @@
under the License.
*/
+const { run } = require('./listDevices');
-var Q = require('q'),
- exec = require('child_process').exec;
-
-/**
- * Gets list of connected iOS devices
- * @return {Promise} Promise fulfilled with list of available iOS devices
- */
-function listDevices() {
- var commands = [
- Q.nfcall(exec, 'system_profiler SPUSBDataType | sed -n -e \'/iPad/,/Serial/p\' | grep "Serial Number:" | awk -F ": " \'{print $2 " iPad"}\''),
- Q.nfcall(exec, 'system_profiler SPUSBDataType | sed -n -e \'/iPhone/,/Serial/p\' | grep "Serial Number:" | awk -F ": " \'{print $2 " iPhone"}\''),
- Q.nfcall(exec, 'system_profiler SPUSBDataType | sed -n -e \'/iPod/,/Serial/p\' | grep "Serial Number:" | awk -F ": " \'{print $2 " iPod"}\'')
- ];
-
- // wrap al lexec calls into promises and wait until they're fullfilled
- return Q.all(commands).then(function (results) {
- var accumulator = [];
- results.forEach(function (result) {
- var devicefound;
- // Each command promise resolves with array [stout, stderr], and we need stdout only
- // Append stdout lines to accumulator
- devicefound = result[0].trim().split('\n');
- if(devicefound && devicefound.length) {
- devicefound.forEach(function(device) {
- if (device) {
- accumulator.push(device);
- }
- });
- }
- });
- return accumulator;
- });
-}
-
-exports.run = listDevices;
-
-// Check if module is started as separate script.
-// If so, then invoke main method and print out results.
-if (!module.parent) {
- listDevices().then(function (devices) {
- devices.forEach(function (device) {
- console.log(device);
- });
+run().then(devices => {
+ devices.forEach(device => {
+ console.log(device);
});
-} \ No newline at end of file
+});
diff --git a/StoneIsland/platforms/ios/cordova/lib/list-emulator-build-targets b/StoneIsland/platforms/ios/cordova/lib/list-emulator-build-targets
index ccf61f98..304c4c17 100755
--- a/StoneIsland/platforms/ios/cordova/lib/list-emulator-build-targets
+++ b/StoneIsland/platforms/ios/cordova/lib/list-emulator-build-targets
@@ -19,99 +19,8 @@
under the License.
*/
+const { run } = require('./listEmulatorBuildTargets');
-var Q = require('q'),
- exec = require('child_process').exec;
-
-/**
- * Returns a list of available simulator build targets of the form
- *
- * [
- * { name: <xcode-destination-name>,
- * identifier: <simctl-identifier>,
- * simIdentifier: <cordova emulate target>
- * }
- * ]
- *
- */
-function listEmulatorBuildTargets () {
- return Q.nfcall(exec, 'xcrun simctl list --json')
- .then(function(stdio) {
- return JSON.parse(stdio[0]);
- })
- .then(function(simInfo) {
- var devices = simInfo.devices;
- var deviceTypes = simInfo.devicetypes;
- return deviceTypes.reduce(function (typeAcc, deviceType) {
- if (!deviceType.name.match(/^[iPad|iPhone]/)) {
- // ignore targets we don't support (like Apple Watch or Apple TV)
- return typeAcc;
- }
- var availableDevices = Object.keys(devices).reduce(function (availAcc, deviceCategory) {
- var availableDevicesInCategory = devices[deviceCategory];
- availableDevicesInCategory.forEach(function (device) {
- if (device && device.name === deviceType.name.replace(/\-inch/g, ' inch') && device.isAvailable == true) {
- availAcc.push(device);
- }
- });
- return availAcc;
- }, []);
-
- // var availableDevices = Object.keys(devices).reduce(function (availAcc, deviceCategory) {
- // var availableDevicesInCategory = devices[deviceCategory];
- // availableDevicesInCategory.forEach(function (device) {
- // if (device.name === deviceType.name.replace(/\-inch/g, ' inch') &&
- // device.availability.toLowerCase().indexOf('unavailable') < 0) {
- // availAcc.push(device);
- // }
- // });
- // return availAcc;
- //}, []);
- // we only want device types that have at least one available device
- // (regardless of OS); this filters things out like iPhone 4s, which
- // is present in deviceTypes, but probably not available on the user's
- // system.
- if (availableDevices.length > 0) {
- typeAcc.push(deviceType);
- }
- return typeAcc;
- }, []);
- })
- .then(function(filteredTargets) {
- // the simIdentifier, or cordova emulate target name, is the very last part
- // of identifier.
- return filteredTargets.map(function (target) {
- var identifierPieces = target.identifier.split(".");
- target.simIdentifier = identifierPieces[identifierPieces.length-1];
- return target;
- });
- });
-}
-
-exports.run = listEmulatorBuildTargets;
-
-/**
- * Given a simIdentifier, return the matching target.
- *
- * @param {string} simIdentifier a target, like "iPhone-SE"
- * @return {Object} the matching target, or undefined if no match
- */
-exports.targetForSimIdentifier = function(simIdentifier) {
- return listEmulatorBuildTargets()
- .then(function(targets) {
- return targets.reduce(function(acc, target) {
- if (!acc && target.simIdentifier.toLowerCase() === simIdentifier.toLowerCase()) {
- acc = target;
- }
- return acc;
- }, undefined);
- });
-}
-
-// Check if module is started as separate script.
-// If so, then invoke main method and print out results.
-if (!module.parent) {
- listEmulatorBuildTargets().then(function (targets) {
- console.log(JSON.stringify(targets, null, 2));
- });
-}
+run().then(targets => {
+ console.log(JSON.stringify(targets, null, 2));
+});
diff --git a/StoneIsland/platforms/ios/cordova/lib/list-emulator-images b/StoneIsland/platforms/ios/cordova/lib/list-emulator-images
index d8be5766..db9b72af 100755
--- a/StoneIsland/platforms/ios/cordova/lib/list-emulator-images
+++ b/StoneIsland/platforms/ios/cordova/lib/list-emulator-images
@@ -19,29 +19,10 @@
under the License.
*/
+const { run } = require('./listEmulatorImages');
-var Q = require('q'),
- iossim = require('ios-sim'),
- exec = require('child_process').exec,
- check_reqs = require('./check_reqs');
-
-/**
- * Gets list of iOS devices available for simulation
- * @return {Promise} Promise fulfilled with list of devices available for simulation
- */
-function listEmulatorImages () {
- return Q.resolve(iossim.getdevicetypes());
-}
-
-
-exports.run = listEmulatorImages;
-
-// Check if module is started as separate script.
-// If so, then invoke main method and print out results.
-if (!module.parent) {
- listEmulatorImages().then(function (names) {
- names.forEach(function (name) {
- console.log(name);
- });
+run().then(names => {
+ names.forEach(name => {
+ console.log(name);
});
-}
+});
diff --git a/StoneIsland/platforms/ios/cordova/lib/list-started-emulators b/StoneIsland/platforms/ios/cordova/lib/list-started-emulators
index 710fa2f7..7f06cf2e 100755
--- a/StoneIsland/platforms/ios/cordova/lib/list-started-emulators
+++ b/StoneIsland/platforms/ios/cordova/lib/list-started-emulators
@@ -19,32 +19,10 @@
under the License.
*/
+const { run } = require('./listStartedEmulators');
-var Q = require('q'),
- exec = require('child_process').exec;
-
-/**
- * Gets list of running iOS simulators
- * @return {Promise} Promise fulfilled with list of running iOS simulators
- */
-function listStartedEmulators () {
- // wrap exec call into promise
- return Q.nfcall(exec, 'ps aux | grep -i "[i]OS Simulator"')
- .then(function () {
- return Q.nfcall(exec, 'defaults read com.apple.iphonesimulator "SimulateDevice"');
- }).then(function (stdio) {
- return stdio[0].trim().split('\n');
- });
-}
-
-exports.run = listStartedEmulators;
-
-// Check if module is started as separate script.
-// If so, then invoke main method and print out results.
-if (!module.parent) {
- listStartedEmulators().then(function (emulators) {
- emulators.forEach(function (emulator) {
- console.log(emulator);
- });
+run().then(emulators => {
+ emulators.forEach(emulator => {
+ console.log(emulator);
});
-}
+});
diff --git a/StoneIsland/platforms/ios/cordova/lib/listDevices.js b/StoneIsland/platforms/ios/cordova/lib/listDevices.js
new file mode 100644
index 00000000..86a67ffb
--- /dev/null
+++ b/StoneIsland/platforms/ios/cordova/lib/listDevices.js
@@ -0,0 +1,42 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+*/
+
+const { superspawn: { spawn } } = require('cordova-common');
+
+const DEVICE_REGEX = /-o (iPhone|iPad|iPod)@.*?"USB Serial Number" = "([^"]*)"/gs;
+
+/**
+ * Gets list of connected iOS devices
+ * @return {Promise} Promise fulfilled with list of available iOS devices
+ */
+function listDevices () {
+ return spawn('ioreg', ['-p', 'IOUSB', '-l'])
+ .then(output => {
+ return [...matchAll(output, DEVICE_REGEX)]
+ .map(m => m.slice(1).reverse().join(' '));
+ });
+}
+
+// TODO: Should be replaced with String#matchAll once available
+function * matchAll (s, r) {
+ let match;
+ while ((match = r.exec(s))) yield match;
+}
+
+exports.run = listDevices;
diff --git a/StoneIsland/platforms/ios/cordova/lib/listEmulatorBuildTargets.js b/StoneIsland/platforms/ios/cordova/lib/listEmulatorBuildTargets.js
new file mode 100644
index 00000000..73e35c05
--- /dev/null
+++ b/StoneIsland/platforms/ios/cordova/lib/listEmulatorBuildTargets.js
@@ -0,0 +1,95 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+*/
+
+const { superspawn: { spawn } } = require('cordova-common');
+
+/**
+ * Returns a list of available simulator build targets of the form
+ *
+ * [
+ * { name: <xcode-destination-name>,
+ * identifier: <simctl-identifier>,
+ * simIdentifier: <cordova emulate target>
+ * }
+ * ]
+ *
+ */
+function listEmulatorBuildTargets () {
+ return spawn('xcrun', ['simctl', 'list', '--json'])
+ .then(output => JSON.parse(output))
+ .then(function (simInfo) {
+ var devices = simInfo.devices;
+ var deviceTypes = simInfo.devicetypes;
+ return deviceTypes.reduce(function (typeAcc, deviceType) {
+ if (!deviceType.name.match(/^[iPad|iPhone]/)) {
+ // ignore targets we don't support (like Apple Watch or Apple TV)
+ return typeAcc;
+ }
+ var availableDevices = Object.keys(devices).reduce(function (availAcc, deviceCategory) {
+ var availableDevicesInCategory = devices[deviceCategory];
+ availableDevicesInCategory.forEach(function (device) {
+ if (device.name === deviceType.name || device.name === deviceType.name.replace(/-inch/g, ' inch')) {
+ // Check new flag isAvailable (XCode 10.1+) or legacy string availability (XCode 10 and lower)
+ if (device.isAvailable || (device.availability && device.availability.toLowerCase().indexOf('unavailable') < 0)) {
+ availAcc.push(device);
+ }
+ }
+ });
+ return availAcc;
+ }, []);
+ // we only want device types that have at least one available device
+ // (regardless of OS); this filters things out like iPhone 4s, which
+ // is present in deviceTypes, but probably not available on the user's
+ // system.
+ if (availableDevices.length > 0) {
+ typeAcc.push(deviceType);
+ }
+ return typeAcc;
+ }, []);
+ })
+ .then(function (filteredTargets) {
+ // the simIdentifier, or cordova emulate target name, is the very last part
+ // of identifier.
+ return filteredTargets.map(function (target) {
+ var identifierPieces = target.identifier.split('.');
+ target.simIdentifier = identifierPieces[identifierPieces.length - 1];
+ return target;
+ });
+ });
+}
+
+exports.run = listEmulatorBuildTargets;
+
+/**
+ * Given a simIdentifier, return the matching target.
+ *
+ * @param {string} simIdentifier a target, like "iPhone-SE"
+ * @return {Object} the matching target, or undefined if no match
+ */
+exports.targetForSimIdentifier = function (simIdentifier) {
+ return listEmulatorBuildTargets()
+ .then(function (targets) {
+ return targets.reduce(function (acc, target) {
+ if (!acc && target.simIdentifier.toLowerCase() === simIdentifier.toLowerCase()) {
+ acc = target;
+ }
+ return acc;
+ }, undefined);
+ });
+};
diff --git a/StoneIsland/platforms/ios/cordova/lib/listEmulatorImages.js b/StoneIsland/platforms/ios/cordova/lib/listEmulatorImages.js
new file mode 100644
index 00000000..09e14340
--- /dev/null
+++ b/StoneIsland/platforms/ios/cordova/lib/listEmulatorImages.js
@@ -0,0 +1,30 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+*/
+
+var iossim = require('ios-sim');
+
+/**
+ * Gets list of iOS devices available for simulation
+ * @return {Promise} Promise fulfilled with list of devices available for simulation
+ */
+function listEmulatorImages () {
+ return Promise.resolve(iossim.getdevicetypes());
+}
+
+exports.run = listEmulatorImages;
diff --git a/StoneIsland/platforms/ios/cordova/lib/listStartedEmulators.js b/StoneIsland/platforms/ios/cordova/lib/listStartedEmulators.js
new file mode 100644
index 00000000..ec1cb7f2
--- /dev/null
+++ b/StoneIsland/platforms/ios/cordova/lib/listStartedEmulators.js
@@ -0,0 +1,50 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+*/
+
+const { superspawn: { spawn } } = require('cordova-common');
+
+/**
+ * Gets list of running iOS simulators
+ * @return {Promise} Promise fulfilled with list of running iOS simulators
+ *
+ * @todo In the next PR, I will refactor this entire method.
+ *
+ * The process no longer contains the pattern "[i]OS Simulator".
+ * The process is now called "Simulator.app"
+ *
+ * Additionaly, `defaults read com.apple.iphonesimulator "SimulateDevice"` is also not valid aymore.
+ *
+ * I will replace this entire method to locate the active simulators though `simctl`
+ *
+ * Alternativly, remove this file. It is not documented in Cordova and not used anywhere in our code base.
+ */
+function listStartedEmulators () {
+ // wrap exec call into promise
+ return spawn('ps', ['aux'])
+ .then(output => {
+ if (output.match(/[i]OS Simulator/)) {
+ return spawn('defaults', ['read', 'com.apple.iphonesimulator', '"SimulateDevice"']);
+ }
+
+ return '';
+ })
+ .then(output => output.split('\n'));
+}
+
+exports.run = listStartedEmulators;
diff --git a/StoneIsland/platforms/ios/cordova/lib/plugman/pluginHandlers.js b/StoneIsland/platforms/ios/cordova/lib/plugman/pluginHandlers.js
index 1f6920fa..09d5ae51 100755..100644
--- a/StoneIsland/platforms/ios/cordova/lib/plugman/pluginHandlers.js
+++ b/StoneIsland/platforms/ios/cordova/lib/plugman/pluginHandlers.js
@@ -15,21 +15,20 @@
under the License.
*/
'use strict';
-var fs = require('fs');
-var path = require('path');
-var shell = require('shelljs');
-var util = require('util');
-var events = require('cordova-common').events;
-var CordovaError = require('cordova-common').CordovaError;
+const fs = require('fs-extra');
+const path = require('path');
+const util = require('util');
+const events = require('cordova-common').events;
+const CordovaError = require('cordova-common').CordovaError;
// These frameworks are required by cordova-ios by default. We should never add/remove them.
-var keep_these_frameworks = [
+const keep_these_frameworks = [
'MobileCoreServices.framework',
'CoreGraphics.framework',
'AssetsLibrary.framework'
];
-var handlers = {
+const handlers = {
'source-file': {
install: function (obj, plugin, project, options) {
installHelper('source-file', obj, plugin.dir, project.projectDir, plugin.id, options, project);
@@ -48,47 +47,47 @@ var handlers = {
},
'resource-file': {
install: function (obj, plugin, project, options) {
- var src = obj.src;
- var target = obj.target;
- var srcFile = path.resolve(plugin.dir, src);
+ const src = obj.src;
+ let target = obj.target;
+ const srcFile = path.resolve(plugin.dir, src);
if (!target) {
target = path.basename(src);
}
- var destFile = path.resolve(project.resources_dir, target);
+ const destFile = path.resolve(project.resources_dir, target);
if (!fs.existsSync(srcFile)) {
- throw new CordovaError('Cannot find resource file "' + srcFile + '" for plugin ' + plugin.id + ' in iOS platform');
+ throw new CordovaError(`Cannot find resource file "${srcFile}" for plugin ${plugin.id} in iOS platform`);
}
if (fs.existsSync(destFile)) {
- throw new CordovaError('File already exists at destination "' + destFile + '" for resource file specified by plugin ' + plugin.id + ' in iOS platform');
+ throw new CordovaError(`File already exists at destination "${destFile}" for resource file specified by plugin ${plugin.id} in iOS platform`);
}
project.xcode.addResourceFile(path.join('Resources', target));
- var link = !!(options && options.link);
+ const link = !!(options && options.link);
copyFile(plugin.dir, src, project.projectDir, destFile, link);
},
uninstall: function (obj, plugin, project, options) {
- var src = obj.src;
- var target = obj.target;
+ const src = obj.src;
+ let target = obj.target;
if (!target) {
target = path.basename(src);
}
- var destFile = path.resolve(project.resources_dir, target);
+ const destFile = path.resolve(project.resources_dir, target);
project.xcode.removeResourceFile(path.join('Resources', target));
- shell.rm('-rf', destFile);
+ fs.removeSync(destFile);
}
},
- 'framework': { // CB-5238 custom frameworks only
+ framework: { // CB-5238 custom frameworks only
install: function (obj, plugin, project, options) {
- var src = obj.src;
- var custom = !!(obj.custom); // convert to boolean (if truthy/falsy)
- var embed = !!(obj.embed); // convert to boolean (if truthy/falsy)
- var link = !embed; // either link or embed can be true, but not both. the other has to be false
+ const src = obj.src;
+ const custom = !!(obj.custom); // convert to boolean (if truthy/falsy)
+ const embed = !!(obj.embed); // convert to boolean (if truthy/falsy)
+ const link = !embed; // either link or embed can be true, but not both. the other has to be false
if (!custom) {
- var keepFrameworks = keep_these_frameworks;
+ const keepFrameworks = keep_these_frameworks;
if (keepFrameworks.indexOf(src) < 0) {
if (obj.type === 'podspec') {
@@ -96,7 +95,7 @@ var handlers = {
} else {
project.frameworks[src] = project.frameworks[src] || 0;
project.frameworks[src]++;
- let opt = { customFramework: false, embed: false, link: true, weak: obj.weak };
+ const opt = { customFramework: false, embed: false, link: true, weak: obj.weak };
events.emit('verbose', util.format('Adding non-custom framework to project... %s -> %s', src, JSON.stringify(opt)));
project.xcode.addFramework(src, opt);
events.emit('verbose', util.format('Non-custom framework added to project. %s -> %s', src, JSON.stringify(opt)));
@@ -104,41 +103,32 @@ var handlers = {
}
return;
}
- var srcFile = path.resolve(plugin.dir, src);
- var targetDir = path.resolve(project.plugins_dir, plugin.id, path.basename(src));
- if (!fs.existsSync(srcFile)) throw new CordovaError('Cannot find framework "' + srcFile + '" for plugin ' + plugin.id + ' in iOS platform');
- if (fs.existsSync(targetDir)) throw new CordovaError('Framework "' + targetDir + '" for plugin ' + plugin.id + ' already exists in iOS platform');
- var symlink = !!(options && options.link);
+ const srcFile = path.resolve(plugin.dir, src);
+ const targetDir = path.resolve(project.plugins_dir, plugin.id, path.basename(src));
+ if (!fs.existsSync(srcFile)) throw new CordovaError(`Cannot find framework "${srcFile}" for plugin ${plugin.id} in iOS platform`);
+ if (fs.existsSync(targetDir)) throw new CordovaError(`Framework "${targetDir}" for plugin ${plugin.id} already exists in iOS platform`);
+ const symlink = !!(options && options.link);
copyFile(plugin.dir, src, project.projectDir, targetDir, symlink); // frameworks are directories
// CB-10773 translate back slashes to forward on win32
- var project_relative = fixPathSep(path.relative(project.projectDir, targetDir));
+ const project_relative = fixPathSep(path.relative(project.projectDir, targetDir));
// CB-11233 create Embed Frameworks Build Phase if does not exist
- var existsEmbedFrameworks = project.xcode.buildPhaseObject('PBXCopyFilesBuildPhase', 'Embed Frameworks');
+ const existsEmbedFrameworks = project.xcode.buildPhaseObject('PBXCopyFilesBuildPhase', 'Embed Frameworks');
if (!existsEmbedFrameworks && embed) {
events.emit('verbose', '"Embed Frameworks" Build Phase (Embedded Binaries) does not exist, creating it.');
project.xcode.addBuildPhase([], 'PBXCopyFilesBuildPhase', 'Embed Frameworks', null, 'frameworks');
}
- let opt = { customFramework: true, embed: embed, link: link, sign: true };
+ const opt = { customFramework: true, embed, link, sign: true };
events.emit('verbose', util.format('Adding custom framework to project... %s -> %s', src, JSON.stringify(opt)));
project.xcode.addFramework(project_relative, opt);
events.emit('verbose', util.format('Custom framework added to project. %s -> %s', src, JSON.stringify(opt)));
},
uninstall: function (obj, plugin, project, options) {
- var src = obj.src;
+ const src = obj.src;
if (!obj.custom) { // CB-9825 cocoapod integration for plugins
- var keepFrameworks = keep_these_frameworks;
+ const keepFrameworks = keep_these_frameworks;
if (keepFrameworks.indexOf(src) < 0) {
- if (obj.type === 'podspec') {
- var podsJSON = require(path.join(project.projectDir, 'pods.json'));
- if (podsJSON[src]) {
- if (podsJSON[src].count > 1) {
- podsJSON[src].count = podsJSON[src].count - 1;
- } else {
- delete podsJSON[src];
- }
- }
- } else {
+ if (obj.type !== 'podspec') {
// this should be refactored
project.frameworks[src] = project.frameworks[src] || 1;
project.frameworks[src]--;
@@ -153,12 +143,12 @@ var handlers = {
return;
}
- var targetDir = fixPathSep(path.resolve(project.plugins_dir, plugin.id, path.basename(src)));
- var pbxFile = project.xcode.removeFramework(targetDir, {customFramework: true});
+ const targetDir = fixPathSep(path.resolve(project.plugins_dir, plugin.id, path.basename(src)));
+ const pbxFile = project.xcode.removeFramework(targetDir, { customFramework: true });
if (pbxFile) {
project.xcode.removeFromPbxEmbedFrameworksBuildPhase(pbxFile);
}
- shell.rm('-rf', targetDir);
+ fs.removeSync(targetDir);
}
},
'lib-file': {
@@ -169,7 +159,7 @@ var handlers = {
events.emit('verbose', '<lib-file> uninstall is not supported for iOS plugins');
}
},
- 'asset': {
+ asset: {
install: function (obj, plugin, project, options) {
if (!obj.src) {
throw new CordovaError(generateAttributeError('src', 'asset', plugin.id));
@@ -182,7 +172,7 @@ var handlers = {
if (options && options.usePlatformWww) copyFile(plugin.dir, obj.src, project.platformWww, obj.target);
},
uninstall: function (obj, plugin, project, options) {
- var target = obj.target;
+ const target = obj.target;
if (!target) {
throw new CordovaError(generateAttributeError('target', 'asset', plugin.id));
@@ -199,58 +189,58 @@ var handlers = {
'js-module': {
install: function (obj, plugin, project, options) {
// Copy the plugin's files into the www directory.
- var moduleSource = path.resolve(plugin.dir, obj.src);
- var moduleName = plugin.id + '.' + (obj.name || path.basename(obj.src, path.extname(obj.src)));
+ const moduleSource = path.resolve(plugin.dir, obj.src);
+ const moduleName = `${plugin.id}.${obj.name || path.basename(obj.src, path.extname(obj.src))}`;
// Read in the file, prepend the cordova.define, and write it back out.
- var scriptContent = fs.readFileSync(moduleSource, 'utf-8').replace(/^\ufeff/, ''); // Window BOM
+ let scriptContent = fs.readFileSync(moduleSource, 'utf-8').replace(/^\ufeff/, ''); // Window BOM
if (moduleSource.match(/.*\.json$/)) {
- scriptContent = 'module.exports = ' + scriptContent;
+ scriptContent = `module.exports = ${scriptContent}`;
}
- scriptContent = 'cordova.define("' + moduleName + '", function(require, exports, module) {\n' + scriptContent + '\n});\n';
+ scriptContent = `cordova.define("${moduleName}", function(require, exports, module) {\n${scriptContent}\n});\n`;
- var moduleDestination = path.resolve(project.www, 'plugins', plugin.id, obj.src);
- shell.mkdir('-p', path.dirname(moduleDestination));
+ const moduleDestination = path.resolve(project.www, 'plugins', plugin.id, obj.src);
+ fs.ensureDirSync(path.dirname(moduleDestination));
fs.writeFileSync(moduleDestination, scriptContent, 'utf-8');
if (options && options.usePlatformWww) {
- var platformWwwDestination = path.resolve(project.platformWww, 'plugins', plugin.id, obj.src);
- shell.mkdir('-p', path.dirname(platformWwwDestination));
+ const platformWwwDestination = path.resolve(project.platformWww, 'plugins', plugin.id, obj.src);
+ fs.ensureDirSync(path.dirname(platformWwwDestination));
fs.writeFileSync(platformWwwDestination, scriptContent, 'utf-8');
}
},
uninstall: function (obj, plugin, project, options) {
- var pluginRelativePath = path.join('plugins', plugin.id, obj.src);
+ const pluginRelativePath = path.join('plugins', plugin.id, obj.src);
removeFileAndParents(project.www, pluginRelativePath);
if (options && options.usePlatformWww) removeFileAndParents(project.platformWww, pluginRelativePath);
}
}
};
-module.exports.getInstaller = function (type) {
+module.exports.getInstaller = type => {
if (handlers[type] && handlers[type].install) {
return handlers[type].install;
}
- events.emit('warn', '<' + type + '> is not supported for iOS plugins');
+ events.emit('warn', `<${type}> is not supported for iOS plugins`);
};
-module.exports.getUninstaller = function (type) {
+module.exports.getUninstaller = type => {
if (handlers[type] && handlers[type].uninstall) {
return handlers[type].uninstall;
}
- events.emit('warn', '<' + type + '> is not supported for iOS plugins');
+ events.emit('warn', `<${type}> is not supported for iOS plugins`);
};
function installHelper (type, obj, plugin_dir, project_dir, plugin_id, options, project) {
- var srcFile = path.resolve(plugin_dir, obj.src);
- var targetDir = path.resolve(project.plugins_dir, plugin_id, obj.targetDir || '');
- var destFile = path.join(targetDir, path.basename(obj.src));
+ const srcFile = path.resolve(plugin_dir, obj.src);
+ const targetDir = path.resolve(project.plugins_dir, plugin_id, obj.targetDir || '');
+ const destFile = path.join(targetDir, path.basename(obj.src));
- var project_ref;
- var link = !!(options && options.link);
+ let project_ref;
+ const link = !!(options && options.link);
if (link) {
- var trueSrc = fs.realpathSync(srcFile);
+ const trueSrc = fs.realpathSync(srcFile);
// Create a symlink in the expected place, so that uninstall can use it.
if (options && options.force) {
copyFile(plugin_dir, trueSrc, project_dir, destFile, link);
@@ -261,101 +251,98 @@ function installHelper (type, obj, plugin_dir, project_dir, plugin_id, options,
// Make the Xcode reference the file directly.
// Note: Can't use path.join() here since it collapses 'Plugins/..', and xcode
// library special-cases Plugins/ prefix.
- project_ref = 'Plugins/' + fixPathSep(path.relative(fs.realpathSync(project.plugins_dir), trueSrc));
+ project_ref = `Plugins/${fixPathSep(path.relative(fs.realpathSync(project.plugins_dir), trueSrc))}`;
} else {
if (options && options.force) {
copyFile(plugin_dir, srcFile, project_dir, destFile, link);
} else {
copyNewFile(plugin_dir, srcFile, project_dir, destFile, link);
}
- project_ref = 'Plugins/' + fixPathSep(path.relative(project.plugins_dir, destFile));
+ project_ref = `Plugins/${fixPathSep(path.relative(project.plugins_dir, destFile))}`;
}
if (type === 'header-file') {
project.xcode.addHeaderFile(project_ref);
} else if (obj.framework) {
- var opt = { weak: obj.weak };
- var project_relative = path.join(path.basename(project.xcode_path), project_ref);
+ const opt = { weak: obj.weak };
+ const project_relative = path.join(path.basename(project.xcode_path), project_ref);
project.xcode.addFramework(project_relative, opt);
- project.xcode.addToLibrarySearchPaths({path: project_ref});
+ project.xcode.addToLibrarySearchPaths({ path: project_ref });
} else {
- project.xcode.addSourceFile(project_ref, obj.compilerFlags ? {compilerFlags: obj.compilerFlags} : {});
+ project.xcode.addSourceFile(project_ref, obj.compilerFlags ? { compilerFlags: obj.compilerFlags } : {});
}
}
function uninstallHelper (type, obj, project_dir, plugin_id, options, project) {
- var targetDir = path.resolve(project.plugins_dir, plugin_id, obj.targetDir || '');
- var destFile = path.join(targetDir, path.basename(obj.src));
+ const targetDir = path.resolve(project.plugins_dir, plugin_id, obj.targetDir || '');
+ const destFile = path.join(targetDir, path.basename(obj.src));
- var project_ref;
- var link = !!(options && options.link);
+ let project_ref;
+ const link = !!(options && options.link);
if (link) {
- var trueSrc = fs.readlinkSync(destFile);
- project_ref = 'Plugins/' + fixPathSep(path.relative(fs.realpathSync(project.plugins_dir), trueSrc));
+ const trueSrc = fs.readlinkSync(destFile);
+ project_ref = `Plugins/${fixPathSep(path.relative(fs.realpathSync(project.plugins_dir), trueSrc))}`;
} else {
- project_ref = 'Plugins/' + fixPathSep(path.relative(project.plugins_dir, destFile));
+ project_ref = `Plugins/${fixPathSep(path.relative(project.plugins_dir, destFile))}`;
}
- shell.rm('-rf', targetDir);
+ fs.removeSync(targetDir);
if (type === 'header-file') {
project.xcode.removeHeaderFile(project_ref);
} else if (obj.framework) {
- var project_relative = path.join(path.basename(project.xcode_path), project_ref);
+ const project_relative = path.join(path.basename(project.xcode_path), project_ref);
project.xcode.removeFramework(project_relative);
- project.xcode.removeFromLibrarySearchPaths({path: project_ref});
+ project.xcode.removeFromLibrarySearchPaths({ path: project_ref });
} else {
project.xcode.removeSourceFile(project_ref);
}
}
-var pathSepFix = new RegExp(path.sep.replace(/\\/, '\\\\'), 'g');
+const pathSepFix = new RegExp(path.sep.replace(/\\/, '\\\\'), 'g');
function fixPathSep (file) {
return file.replace(pathSepFix, '/');
}
function copyFile (plugin_dir, src, project_dir, dest, link) {
src = path.resolve(plugin_dir, src);
- if (!fs.existsSync(src)) throw new CordovaError('"' + src + '" not found!');
+ if (!fs.existsSync(src)) throw new CordovaError(`"${src}" not found!`);
// check that src path is inside plugin directory
- var real_path = fs.realpathSync(src);
- var real_plugin_path = fs.realpathSync(plugin_dir);
- if (real_path.indexOf(real_plugin_path) !== 0) { throw new CordovaError('File "' + src + '" is located outside the plugin directory "' + plugin_dir + '"'); }
+ const real_path = fs.realpathSync(src);
+ const real_plugin_path = fs.realpathSync(plugin_dir);
+ if (real_path.indexOf(real_plugin_path) !== 0) { throw new CordovaError(`File "${src}" is located outside the plugin directory "${plugin_dir}"`); }
dest = path.resolve(project_dir, dest);
// check that dest path is located in project directory
- if (dest.indexOf(project_dir) !== 0) { throw new CordovaError('Destination "' + dest + '" for source file "' + src + '" is located outside the project'); }
+ if (dest.indexOf(project_dir) !== 0) { throw new CordovaError(`Destination "${dest}" for source file "${src}" is located outside the project`); }
- shell.mkdir('-p', path.dirname(dest));
+ fs.ensureDirSync(path.dirname(dest));
if (link) {
linkFileOrDirTree(src, dest);
- } else if (fs.statSync(src).isDirectory()) {
- // XXX shelljs decides to create a directory when -R|-r is used which sucks. http://goo.gl/nbsjq
- shell.cp('-Rf', path.join(src, '/*'), dest);
} else {
- shell.cp('-f', src, dest);
+ fs.copySync(src, dest);
}
}
// Same as copy file but throws error if target exists
function copyNewFile (plugin_dir, src, project_dir, dest, link) {
- var target_path = path.resolve(project_dir, dest);
- if (fs.existsSync(target_path)) { throw new CordovaError('"' + target_path + '" already exists!'); }
+ const target_path = path.resolve(project_dir, dest);
+ if (fs.existsSync(target_path)) { throw new CordovaError(`"${target_path}" already exists!`); }
copyFile(plugin_dir, src, project_dir, dest, !!link);
}
function linkFileOrDirTree (src, dest) {
if (fs.existsSync(dest)) {
- shell.rm('-Rf', dest);
+ fs.removeSync(dest);
}
if (fs.statSync(src).isDirectory()) {
- shell.mkdir('-p', dest);
- fs.readdirSync(src).forEach(function (entry) {
+ fs.ensureDirSync(dest);
+ fs.readdirSync(src).forEach(entry => {
linkFileOrDirTree(path.join(src, entry), path.join(dest, entry));
});
} else {
@@ -365,24 +352,24 @@ function linkFileOrDirTree (src, dest) {
// checks if file exists and then deletes. Error if doesn't exist
function removeFile (project_dir, src) {
- var file = path.resolve(project_dir, src);
- shell.rm('-Rf', file);
+ const file = path.resolve(project_dir, src);
+ fs.removeSync(file);
}
// deletes file/directory without checking
function removeFileF (file) {
- shell.rm('-Rf', file);
+ fs.removeSync(file);
}
function removeFileAndParents (baseDir, destFile, stopper) {
stopper = stopper || '.';
- var file = path.resolve(baseDir, destFile);
+ const file = path.resolve(baseDir, destFile);
if (!fs.existsSync(file)) return;
removeFileF(file);
// check if directory is empty
- var curDir = path.dirname(file);
+ let curDir = path.dirname(file);
while (curDir !== path.resolve(baseDir, stopper)) {
if (fs.existsSync(curDir) && fs.readdirSync(curDir).length === 0) {
@@ -396,5 +383,5 @@ function removeFileAndParents (baseDir, destFile, stopper) {
}
function generateAttributeError (attribute, element, id) {
- return 'Required attribute "' + attribute + '" not specified in <' + element + '> element from plugin: ' + id;
+ return `Required attribute "${attribute}" not specified in <${element}> element from plugin: ${id}`;
}
diff --git a/StoneIsland/platforms/ios/cordova/lib/prepare.js b/StoneIsland/platforms/ios/cordova/lib/prepare.js
index 17bbfeb7..c98cb8f4 100755..100644
--- a/StoneIsland/platforms/ios/cordova/lib/prepare.js
+++ b/StoneIsland/platforms/ios/cordova/lib/prepare.js
@@ -18,53 +18,46 @@
*/
'use strict';
-var Q = require('q');
-var fs = require('fs');
-var path = require('path');
-var shell = require('shelljs');
-var xcode = require('xcode');
-var unorm = require('unorm');
-var plist = require('plist');
-var URL = require('url');
-var events = require('cordova-common').events;
-var xmlHelpers = require('cordova-common').xmlHelpers;
-var ConfigParser = require('cordova-common').ConfigParser;
-var CordovaError = require('cordova-common').CordovaError;
-var PlatformJson = require('cordova-common').PlatformJson;
-var PlatformMunger = require('cordova-common').ConfigChanges.PlatformMunger;
-var PluginInfoProvider = require('cordova-common').PluginInfoProvider;
-var FileUpdater = require('cordova-common').FileUpdater;
-var projectFile = require('./projectFile');
+
+const fs = require('fs-extra');
+const path = require('path');
+const unorm = require('unorm');
+const plist = require('plist');
+const URL = require('url');
+const events = require('cordova-common').events;
+const xmlHelpers = require('cordova-common').xmlHelpers;
+const ConfigParser = require('cordova-common').ConfigParser;
+const CordovaError = require('cordova-common').CordovaError;
+const PlatformJson = require('cordova-common').PlatformJson;
+const PlatformMunger = require('cordova-common').ConfigChanges.PlatformMunger;
+const PluginInfoProvider = require('cordova-common').PluginInfoProvider;
+const FileUpdater = require('cordova-common').FileUpdater;
+const projectFile = require('./projectFile');
// launch storyboard and related constants
-var LAUNCHIMAGE_BUILD_SETTING = 'ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME';
-var LAUNCHIMAGE_BUILD_SETTING_VALUE = 'LaunchImage';
-var UI_LAUNCH_STORYBOARD_NAME = 'UILaunchStoryboardName';
-var CDV_LAUNCH_STORYBOARD_NAME = 'CDVLaunchScreen';
-var IMAGESET_COMPACT_SIZE_CLASS = 'compact';
-var CDV_ANY_SIZE_CLASS = 'any';
+const IMAGESET_COMPACT_SIZE_CLASS = 'compact';
+const CDV_ANY_SIZE_CLASS = 'any';
module.exports.prepare = function (cordovaProject, options) {
- var self = this;
-
- var platformJson = PlatformJson.load(this.locations.root, 'ios');
- var munger = new PlatformMunger('ios', this.locations.root, platformJson, new PluginInfoProvider());
+ const platformJson = PlatformJson.load(this.locations.root, 'ios');
+ const munger = new PlatformMunger('ios', this.locations.root, platformJson, new PluginInfoProvider());
this._config = updateConfigFile(cordovaProject.projectConfig, munger, this.locations);
// Update own www dir with project's www assets and plugins' assets and js-files
- return Q.when(updateWww(cordovaProject, this.locations))
- .then(function () {
- // update project according to config.xml changes.
- return updateProject(self._config, self.locations);
+ return updateWww(cordovaProject, this.locations)
+ // update project according to config.xml changes.
+ .then(() => updateProject(this._config, this.locations))
+ .then(() => {
+ updateIcons(cordovaProject, this.locations);
+ updateLaunchStoryboardImages(cordovaProject, this.locations);
+ updateBackgroundColor(cordovaProject, this.locations);
+ updateFileResources(cordovaProject, this.locations);
})
- .then(function () {
- updateIcons(cordovaProject, self.locations);
- updateSplashScreens(cordovaProject, self.locations);
- updateLaunchStoryboardImages(cordovaProject, self.locations);
- updateFileResources(cordovaProject, self.locations);
+ .then(() => {
+ alertDeprecatedPreference(this._config);
})
- .then(function () {
+ .then(() => {
events.emit('verbose', 'Prepared iOS project successfully');
});
};
@@ -74,22 +67,21 @@ module.exports.clean = function (options) {
// been called from the platform shell script rather than the CLI. Check for the
// noPrepare option passed in by the non-CLI clean script. If that's present, or if
// there's no config.xml found at the project root, then don't clean prepared files.
- var projectRoot = path.resolve(this.root, '../..');
- var projectConfigFile = path.join(projectRoot, 'config.xml');
+ const projectRoot = path.resolve(this.root, '../..');
+ const projectConfigFile = path.join(projectRoot, 'config.xml');
if ((options && options.noPrepare) || !fs.existsSync(projectConfigFile) ||
!fs.existsSync(this.locations.configXml)) {
- return Q();
+ return Promise.resolve();
}
- var projectConfig = new ConfigParser(this.locations.configXml);
+ const projectConfig = new ConfigParser(this.locations.configXml);
- var self = this;
- return Q().then(function () {
- cleanWww(projectRoot, self.locations);
- cleanIcons(projectRoot, projectConfig, self.locations);
- cleanSplashScreens(projectRoot, projectConfig, self.locations);
- cleanLaunchStoryboardImages(projectRoot, projectConfig, self.locations);
- cleanFileResources(projectRoot, projectConfig, self.locations);
+ return Promise.resolve().then(() => {
+ cleanWww(projectRoot, this.locations);
+ cleanIcons(projectRoot, projectConfig, this.locations);
+ cleanLaunchStoryboardImages(projectRoot, projectConfig, this.locations);
+ cleanBackgroundColor(projectRoot, projectConfig, this.locations);
+ cleanFileResources(projectRoot, projectConfig, this.locations);
});
};
@@ -108,11 +100,11 @@ module.exports.clean = function (options) {
* configuration is already dumped to appropriate config.xml file.
*/
function updateConfigFile (sourceConfig, configMunger, locations) {
- events.emit('verbose', 'Generating platform-specific config.xml from defaults for iOS at ' + locations.configXml);
+ events.emit('verbose', `Generating platform-specific config.xml from defaults for iOS at ${locations.configXml}`);
// First cleanup current config and merge project's one into own
// Overwrite platform config.xml with defaults.xml.
- shell.cp('-f', locations.defaultConfigXml, locations.configXml);
+ fs.copySync(locations.defaultConfigXml, locations.configXml);
// Then apply config changes from global munge to all config files
// in project (including project's config)
@@ -120,7 +112,7 @@ function updateConfigFile (sourceConfig, configMunger, locations) {
events.emit('verbose', 'Merging project\'s config.xml into platform-specific iOS config.xml');
// Merge changes from app's config.xml into platform's one
- var config = new ConfigParser(locations.configXml);
+ const config = new ConfigParser(locations.configXml);
xmlHelpers.mergeXml(sourceConfig.doc.getroot(),
config.doc.getroot(), 'ios', /* clobber= */true);
@@ -132,7 +124,7 @@ function updateConfigFile (sourceConfig, configMunger, locations) {
* Logs all file operations via the verbose event stream, indented.
*/
function logFileOp (message) {
- events.emit('verbose', ' ' + message);
+ events.emit('verbose', ` ${message}`);
}
/**
@@ -145,31 +137,33 @@ function logFileOp (message) {
* paths for www files.
*/
function updateWww (cordovaProject, destinations) {
- var sourceDirs = [
+ const sourceDirs = [
path.relative(cordovaProject.root, cordovaProject.locations.www),
path.relative(cordovaProject.root, destinations.platformWww)
];
// If project contains 'merges' for our platform, use them as another overrides
- var merges_path = path.join(cordovaProject.root, 'merges', 'ios');
+ const merges_path = path.join(cordovaProject.root, 'merges', 'ios');
if (fs.existsSync(merges_path)) {
events.emit('verbose', 'Found "merges/ios" folder. Copying its contents into the iOS project.');
sourceDirs.push(path.join('merges', 'ios'));
}
- var targetDir = path.relative(cordovaProject.root, destinations.www);
+ const targetDir = path.relative(cordovaProject.root, destinations.www);
events.emit(
- 'verbose', 'Merging and updating files from [' + sourceDirs.join(', ') + '] to ' + targetDir);
+ 'verbose', `Merging and updating files from [${sourceDirs.join(', ')}] to ${targetDir}`);
FileUpdater.mergeAndUpdateDir(
sourceDirs, targetDir, { rootDir: cordovaProject.root }, logFileOp);
+
+ return Promise.resolve();
}
/**
* Cleans all files from the platform 'www' directory.
*/
function cleanWww (projectRoot, locations) {
- var targetDir = path.relative(projectRoot, locations.www);
- events.emit('verbose', 'Cleaning ' + targetDir);
+ const targetDir = path.relative(projectRoot, locations.www);
+ events.emit('verbose', `Cleaning ${targetDir}`);
// No source paths are specified, so mergeAndUpdateDir() will clear the target directory.
FileUpdater.mergeAndUpdateDir(
@@ -184,169 +178,176 @@ function cleanWww (projectRoot, locations) {
* @param {Object} locations A map of locations for this platform (In/Out)
*/
function updateProject (platformConfig, locations) {
-
// CB-6992 it is necessary to normalize characters
// because node and shell scripts handles unicode symbols differently
// We need to normalize the name to NFD form since iOS uses NFD unicode form
- var name = unorm.nfd(platformConfig.name());
- var pkg = platformConfig.getAttribute('ios-CFBundleIdentifier') || platformConfig.packageName();
- var version = platformConfig.version();
- var displayName = platformConfig.shortName && platformConfig.shortName();
+ const name = unorm.nfd(platformConfig.name());
+ const version = platformConfig.version();
+ const displayName = platformConfig.shortName && platformConfig.shortName();
- var originalName = path.basename(locations.xcodeCordovaProj);
+ const originalName = path.basename(locations.xcodeCordovaProj);
// Update package id (bundle id)
- var plistFile = path.join(locations.xcodeCordovaProj, originalName + '-Info.plist');
- var infoPlist = plist.parse(fs.readFileSync(plistFile, 'utf8'));
- infoPlist['CFBundleIdentifier'] = pkg;
+ const plistFile = path.join(locations.xcodeCordovaProj, `${originalName}-Info.plist`);
+ const infoPlist = plist.parse(fs.readFileSync(plistFile, 'utf8'));
// Update version (bundle version)
- infoPlist['CFBundleShortVersionString'] = version;
- var CFBundleVersion = platformConfig.getAttribute('ios-CFBundleVersion') || default_CFBundleVersion(version);
- infoPlist['CFBundleVersion'] = CFBundleVersion;
+ infoPlist.CFBundleShortVersionString = version;
+ const CFBundleVersion = platformConfig.getAttribute('ios-CFBundleVersion') || default_CFBundleVersion(version);
+ infoPlist.CFBundleVersion = CFBundleVersion;
if (platformConfig.getAttribute('defaultlocale')) {
- infoPlist['CFBundleDevelopmentRegion'] = platformConfig.getAttribute('defaultlocale');
+ infoPlist.CFBundleDevelopmentRegion = platformConfig.getAttribute('defaultlocale');
}
if (displayName) {
- infoPlist['CFBundleDisplayName'] = displayName;
+ infoPlist.CFBundleDisplayName = displayName;
}
// replace Info.plist ATS entries according to <access> and <allow-navigation> config.xml entries
- var ats = writeATSEntries(platformConfig);
+ const ats = writeATSEntries(platformConfig);
if (Object.keys(ats).length > 0) {
- infoPlist['NSAppTransportSecurity'] = ats;
+ infoPlist.NSAppTransportSecurity = ats;
} else {
- delete infoPlist['NSAppTransportSecurity'];
+ delete infoPlist.NSAppTransportSecurity;
}
handleOrientationSettings(platformConfig, infoPlist);
- updateProjectPlistForLaunchStoryboard(platformConfig, infoPlist);
- var info_contents = plist.build(infoPlist);
+ /* eslint-disable no-tabs */
+ // Write out the plist file with the same formatting as Xcode does
+ let info_contents = plist.build(infoPlist, { indent: '\t', offset: -1 });
+ /* eslint-enable no-tabs */
+
info_contents = info_contents.replace(/<string>[\s\r\n]*<\/string>/g, '<string></string>');
fs.writeFileSync(plistFile, info_contents, 'utf-8');
- events.emit('verbose', 'Wrote out iOS Bundle Identifier "' + pkg + '" and iOS Bundle Version "' + version + '" to ' + plistFile);
+ events.emit('verbose', `Wrote out iOS Bundle Version "${version}" to ${plistFile}`);
- return handleBuildSettings(platformConfig, locations, infoPlist).then(function () {
+ return handleBuildSettings(platformConfig, locations, infoPlist).then(() => {
if (name === originalName) {
- events.emit('verbose', 'iOS Product Name has not changed (still "' + originalName + '")');
- return Q();
+ events.emit('verbose', `iOS Product Name has not changed (still "${originalName}")`);
+ return Promise.resolve();
} else { // CB-11712 <name> was changed, we don't support it'
- var errorString =
+ const errorString =
'The product name change (<name> tag) in config.xml is not supported dynamically.\n' +
'To change your product name, you have to remove, then add your ios platform again.\n' +
'Make sure you save your plugins beforehand using `cordova plugin save`.\n' +
'\tcordova plugin save\n' +
'\tcordova platform rm ios\n' +
- '\tcordova platform add ios\n'
- ;
+ '\tcordova platform add ios\n';
- return Q.reject(new CordovaError(errorString));
+ return Promise.reject(new CordovaError(errorString));
}
});
}
function handleOrientationSettings (platformConfig, infoPlist) {
-
switch (getOrientationValue(platformConfig)) {
case 'portrait':
- infoPlist['UIInterfaceOrientation'] = [ 'UIInterfaceOrientationPortrait' ];
- infoPlist['UISupportedInterfaceOrientations'] = [ 'UIInterfaceOrientationPortrait', 'UIInterfaceOrientationPortraitUpsideDown' ];
- infoPlist['UISupportedInterfaceOrientations~ipad'] = [ 'UIInterfaceOrientationPortrait', 'UIInterfaceOrientationPortraitUpsideDown' ];
+ infoPlist.UIInterfaceOrientation = ['UIInterfaceOrientationPortrait'];
+ infoPlist.UISupportedInterfaceOrientations = ['UIInterfaceOrientationPortrait', 'UIInterfaceOrientationPortraitUpsideDown'];
+ infoPlist['UISupportedInterfaceOrientations~ipad'] = ['UIInterfaceOrientationPortrait', 'UIInterfaceOrientationPortraitUpsideDown'];
break;
case 'landscape':
- infoPlist['UIInterfaceOrientation'] = [ 'UIInterfaceOrientationLandscapeLeft' ];
- infoPlist['UISupportedInterfaceOrientations'] = [ 'UIInterfaceOrientationLandscapeLeft', 'UIInterfaceOrientationLandscapeRight' ];
- infoPlist['UISupportedInterfaceOrientations~ipad'] = [ 'UIInterfaceOrientationLandscapeLeft', 'UIInterfaceOrientationLandscapeRight' ];
+ infoPlist.UIInterfaceOrientation = ['UIInterfaceOrientationLandscapeLeft'];
+ infoPlist.UISupportedInterfaceOrientations = ['UIInterfaceOrientationLandscapeLeft', 'UIInterfaceOrientationLandscapeRight'];
+ infoPlist['UISupportedInterfaceOrientations~ipad'] = ['UIInterfaceOrientationLandscapeLeft', 'UIInterfaceOrientationLandscapeRight'];
break;
case 'all':
- infoPlist['UIInterfaceOrientation'] = [ 'UIInterfaceOrientationPortrait' ];
- infoPlist['UISupportedInterfaceOrientations'] = [ 'UIInterfaceOrientationPortrait', 'UIInterfaceOrientationPortraitUpsideDown', 'UIInterfaceOrientationLandscapeLeft', 'UIInterfaceOrientationLandscapeRight' ];
- infoPlist['UISupportedInterfaceOrientations~ipad'] = [ 'UIInterfaceOrientationPortrait', 'UIInterfaceOrientationPortraitUpsideDown', 'UIInterfaceOrientationLandscapeLeft', 'UIInterfaceOrientationLandscapeRight' ];
+ infoPlist.UIInterfaceOrientation = ['UIInterfaceOrientationPortrait'];
+ infoPlist.UISupportedInterfaceOrientations = ['UIInterfaceOrientationPortrait', 'UIInterfaceOrientationPortraitUpsideDown', 'UIInterfaceOrientationLandscapeLeft', 'UIInterfaceOrientationLandscapeRight'];
+ infoPlist['UISupportedInterfaceOrientations~ipad'] = ['UIInterfaceOrientationPortrait', 'UIInterfaceOrientationPortraitUpsideDown', 'UIInterfaceOrientationLandscapeLeft', 'UIInterfaceOrientationLandscapeRight'];
break;
case 'default':
- infoPlist['UISupportedInterfaceOrientations'] = [ 'UIInterfaceOrientationPortrait', 'UIInterfaceOrientationLandscapeLeft', 'UIInterfaceOrientationLandscapeRight' ];
- infoPlist['UISupportedInterfaceOrientations~ipad'] = [ 'UIInterfaceOrientationPortrait', 'UIInterfaceOrientationPortraitUpsideDown', 'UIInterfaceOrientationLandscapeLeft', 'UIInterfaceOrientationLandscapeRight' ];
- delete infoPlist['UIInterfaceOrientation'];
+ infoPlist.UISupportedInterfaceOrientations = ['UIInterfaceOrientationPortrait', 'UIInterfaceOrientationLandscapeLeft', 'UIInterfaceOrientationLandscapeRight'];
+ infoPlist['UISupportedInterfaceOrientations~ipad'] = ['UIInterfaceOrientationPortrait', 'UIInterfaceOrientationPortraitUpsideDown', 'UIInterfaceOrientationLandscapeLeft', 'UIInterfaceOrientationLandscapeRight'];
+ delete infoPlist.UIInterfaceOrientation;
}
}
function handleBuildSettings (platformConfig, locations, infoPlist) {
- var targetDevice = parseTargetDevicePreference(platformConfig.getPreference('target-device', 'ios'));
- var deploymentTarget = platformConfig.getPreference('deployment-target', 'ios');
- var needUpdatedBuildSettingsForLaunchStoryboard = checkIfBuildSettingsNeedUpdatedForLaunchStoryboard(platformConfig, infoPlist);
+ const pkg = platformConfig.getAttribute('ios-CFBundleIdentifier') || platformConfig.packageName();
+ const targetDevice = parseTargetDevicePreference(platformConfig.getPreference('target-device', 'ios'));
+ const deploymentTarget = platformConfig.getPreference('deployment-target', 'ios');
+ const swiftVersion = platformConfig.getPreference('SwiftVersion', 'ios');
+
+ let project;
+
+ try {
+ project = projectFile.parse(locations);
+ } catch (err) {
+ return Promise.reject(new CordovaError(`Could not parse ${locations.pbxproj}: ${err}`));
+ }
+
+ const origPkg = project.xcode.getBuildProperty('PRODUCT_BUNDLE_IDENTIFIER', undefined, platformConfig.name());
// no build settings provided and we don't need to update build settings for launch storyboards,
// then we don't need to parse and update .pbxproj file
- if (!targetDevice && !deploymentTarget && !needUpdatedBuildSettingsForLaunchStoryboard) {
- return Q();
+ if (origPkg === pkg && !targetDevice && !deploymentTarget && !swiftVersion) {
+ return Promise.resolve();
}
- var proj = new xcode.project(locations.pbxproj); /* eslint new-cap : 0 */
-
- try {
- proj.parseSync();
- } catch (err) {
- return Q.reject(new CordovaError('Could not parse project.pbxproj: ' + err));
+ if (origPkg !== pkg) {
+ events.emit('verbose', `Set PRODUCT_BUNDLE_IDENTIFIER to ${pkg}.`);
+ project.xcode.updateBuildProperty('PRODUCT_BUNDLE_IDENTIFIER', pkg, null, platformConfig.name());
}
if (targetDevice) {
- events.emit('verbose', 'Set TARGETED_DEVICE_FAMILY to ' + targetDevice + '.');
- proj.updateBuildProperty('TARGETED_DEVICE_FAMILY', targetDevice);
+ events.emit('verbose', `Set TARGETED_DEVICE_FAMILY to ${targetDevice}.`);
+ project.xcode.updateBuildProperty('TARGETED_DEVICE_FAMILY', targetDevice);
}
if (deploymentTarget) {
- events.emit('verbose', 'Set IPHONEOS_DEPLOYMENT_TARGET to "' + deploymentTarget + '".');
- proj.updateBuildProperty('IPHONEOS_DEPLOYMENT_TARGET', deploymentTarget);
+ events.emit('verbose', `Set IPHONEOS_DEPLOYMENT_TARGET to "${deploymentTarget}".`);
+ project.xcode.updateBuildProperty('IPHONEOS_DEPLOYMENT_TARGET', deploymentTarget);
}
- updateBuildSettingsForLaunchStoryboard(proj, platformConfig, infoPlist);
+ if (swiftVersion) {
+ events.emit('verbose', `Set SwiftVersion to "${swiftVersion}".`);
+ project.xcode.updateBuildProperty('SWIFT_VERSION', swiftVersion);
+ }
- fs.writeFileSync(locations.pbxproj, proj.writeSync(), 'utf-8');
+ project.write();
- return Q();
+ return Promise.resolve();
}
function mapIconResources (icons, iconsDir) {
// See https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/MobileHIG/IconMatrix.html
// for launch images sizes reference.
- var platformIcons = [
- {dest: 'icon-20.png', width: 20, height: 20},
- {dest: 'icon-20@2x.png', width: 40, height: 40},
- {dest: 'icon-20@3x.png', width: 60, height: 60},
- {dest: 'icon-40.png', width: 40, height: 40},
- {dest: 'icon-50.png', width: 50, height: 50},
- {dest: 'icon-50@2x.png', width: 100, height: 100},
- {dest: 'icon-60@2x.png', width: 120, height: 120},
- {dest: 'icon-60@3x.png', width: 180, height: 180},
- {dest: 'icon-72.png', width: 72, height: 72},
- {dest: 'icon-72@2x.png', width: 144, height: 144},
- {dest: 'icon-76.png', width: 76, height: 76},
- {dest: 'icon-76@2x.png', width: 152, height: 152},
- {dest: 'icon-83.5@2x.png', width: 167, height: 167},
- {dest: 'icon-1024.png', width: 1024, height: 1024},
- {dest: 'icon-small.png', width: 29, height: 29},
- {dest: 'icon-small@2x.png', width: 58, height: 58},
- {dest: 'icon-small@3x.png', width: 87, height: 87},
- {dest: 'icon.png', width: 57, height: 57},
- {dest: 'icon@2x.png', width: 114, height: 114},
- {dest: 'AppIcon24x24@2x.png', width: 48, height: 48},
- {dest: 'AppIcon27.5x27.5@2x.png', width: 55, height: 55},
- {dest: 'AppIcon29x29@2x.png', width: 58, height: 58},
- {dest: 'AppIcon29x29@3x.png', width: 87, height: 87},
- {dest: 'AppIcon40x40@2x.png', width: 80, height: 80},
- {dest: 'AppIcon44x44@2x.png', width: 88, height: 88},
- {dest: 'AppIcon86x86@2x.png', width: 172, height: 172},
- {dest: 'AppIcon98x98@2x.png', width: 196, height: 196}
+ const platformIcons = [
+ { dest: 'icon-20.png', width: 20, height: 20 },
+ { dest: 'icon-20@2x.png', width: 40, height: 40 },
+ { dest: 'icon-20@3x.png', width: 60, height: 60 },
+ { dest: 'icon-40.png', width: 40, height: 40 },
+ { dest: 'icon-40@2x.png', width: 80, height: 80 },
+ { dest: 'icon-50.png', width: 50, height: 50 },
+ { dest: 'icon-50@2x.png', width: 100, height: 100 },
+ { dest: 'icon-60@2x.png', width: 120, height: 120 },
+ { dest: 'icon-60@3x.png', width: 180, height: 180 },
+ { dest: 'icon-72.png', width: 72, height: 72 },
+ { dest: 'icon-72@2x.png', width: 144, height: 144 },
+ { dest: 'icon-76.png', width: 76, height: 76 },
+ { dest: 'icon-76@2x.png', width: 152, height: 152 },
+ { dest: 'icon-83.5@2x.png', width: 167, height: 167 },
+ { dest: 'icon-1024.png', width: 1024, height: 1024 },
+ { dest: 'icon-29.png', width: 29, height: 29 },
+ { dest: 'icon-29@2x.png', width: 58, height: 58 },
+ { dest: 'icon-29@3x.png', width: 87, height: 87 },
+ { dest: 'icon.png', width: 57, height: 57 },
+ { dest: 'icon@2x.png', width: 114, height: 114 },
+ { dest: 'icon-24@2x.png', width: 48, height: 48 },
+ { dest: 'icon-27.5@2x.png', width: 55, height: 55 },
+ { dest: 'icon-44@2x.png', width: 88, height: 88 },
+ { dest: 'icon-86@2x.png', width: 172, height: 172 },
+ { dest: 'icon-98@2x.png', width: 196, height: 196 }
];
- var pathMap = {};
- platformIcons.forEach(function (item) {
- var icon = icons.getBySize(item.width, item.height) || icons.getDefault();
+ const pathMap = {};
+ platformIcons.forEach(item => {
+ const icon = icons.getBySize(item.width, item.height) || icons.getDefault();
if (icon) {
- var target = path.join(iconsDir, item.dest);
+ const target = path.join(iconsDir, item.dest);
pathMap[target] = icon.src;
}
});
@@ -354,8 +355,8 @@ function mapIconResources (icons, iconsDir) {
}
function getIconsDir (projectRoot, platformProjDir) {
- var iconsDir;
- var xcassetsExists = folderExists(path.join(projectRoot, platformProjDir, 'Images.xcassets/'));
+ let iconsDir;
+ const xcassetsExists = folderExists(path.join(projectRoot, platformProjDir, 'Images.xcassets/'));
if (xcassetsExists) {
iconsDir = path.join(platformProjDir, 'Images.xcassets/AppIcon.appiconset/');
@@ -367,31 +368,31 @@ function getIconsDir (projectRoot, platformProjDir) {
}
function updateIcons (cordovaProject, locations) {
- var icons = cordovaProject.projectConfig.getIcons('ios');
+ const icons = cordovaProject.projectConfig.getIcons('ios');
if (icons.length === 0) {
events.emit('verbose', 'This app does not have icons defined');
return;
}
- var platformProjDir = path.relative(cordovaProject.root, locations.xcodeCordovaProj);
- var iconsDir = getIconsDir(cordovaProject.root, platformProjDir);
- var resourceMap = mapIconResources(icons, iconsDir);
- events.emit('verbose', 'Updating icons at ' + iconsDir);
+ const platformProjDir = path.relative(cordovaProject.root, locations.xcodeCordovaProj);
+ const iconsDir = getIconsDir(cordovaProject.root, platformProjDir);
+ const resourceMap = mapIconResources(icons, iconsDir);
+ events.emit('verbose', `Updating icons at ${iconsDir}`);
FileUpdater.updatePaths(
resourceMap, { rootDir: cordovaProject.root }, logFileOp);
}
function cleanIcons (projectRoot, projectConfig, locations) {
- var icons = projectConfig.getIcons('ios');
+ const icons = projectConfig.getIcons('ios');
if (icons.length > 0) {
- var platformProjDir = path.relative(projectRoot, locations.xcodeCordovaProj);
- var iconsDir = getIconsDir(projectRoot, platformProjDir);
- var resourceMap = mapIconResources(icons, iconsDir);
- Object.keys(resourceMap).forEach(function (targetIconPath) {
+ const platformProjDir = path.relative(projectRoot, locations.xcodeCordovaProj);
+ const iconsDir = getIconsDir(projectRoot, platformProjDir);
+ const resourceMap = mapIconResources(icons, iconsDir);
+ Object.keys(resourceMap).forEach(targetIconPath => {
resourceMap[targetIconPath] = null;
});
- events.emit('verbose', 'Cleaning icons at ' + iconsDir);
+ events.emit('verbose', `Cleaning icons at ${iconsDir}`);
// Source paths are removed from the map, so updatePaths() will delete the target files.
FileUpdater.updatePaths(
@@ -399,74 +400,120 @@ function cleanIcons (projectRoot, projectConfig, locations) {
}
}
-function mapSplashScreenResources (splashScreens, splashScreensDir) {
- var platformSplashScreens = [
- {dest: 'Default~iphone.png', width: 320, height: 480},
- {dest: 'Default@2x~iphone.png', width: 640, height: 960},
- {dest: 'Default-Portrait~ipad.png', width: 768, height: 1024},
- {dest: 'Default-Portrait@2x~ipad.png', width: 1536, height: 2048},
- {dest: 'Default-Landscape~ipad.png', width: 1024, height: 768},
- {dest: 'Default-Landscape@2x~ipad.png', width: 2048, height: 1536},
- {dest: 'Default-568h@2x~iphone.png', width: 640, height: 1136},
- {dest: 'Default-667h.png', width: 750, height: 1334},
- {dest: 'Default-736h.png', width: 1242, height: 2208},
- {dest: 'Default-Landscape-736h.png', width: 2208, height: 1242}
- ];
-
- var pathMap = {};
- platformSplashScreens.forEach(function (item) {
- var splash = splashScreens.getBySize(item.width, item.height);
- if (splash) {
- var target = path.join(splashScreensDir, item.dest);
- pathMap[target] = splash.src;
- }
- });
- return pathMap;
+/**
+ * Returns the directory for the BackgroundColor.colorset asset, or null if no
+ * xcassets exist.
+ *
+ * @param {string} projectRoot The project's root directory
+ * @param {string} platformProjDir The platform's project directory
+ */
+function getBackgroundColorDir (projectRoot, platformProjDir) {
+ if (folderExists(path.join(projectRoot, platformProjDir, 'Images.xcassets/'))) {
+ return path.join(platformProjDir, 'Images.xcassets', 'BackgroundColor.colorset');
+ } else {
+ return null;
+ }
}
-function getSplashScreensDir (projectRoot, platformProjDir) {
- var splashScreensDir;
- var xcassetsExists = folderExists(path.join(projectRoot, platformProjDir, 'Images.xcassets/'));
+function colorPreferenceToComponents (pref) {
+ if (!pref || !pref.match(/^(#[0-9A-F]{3}|(0x|#)([0-9A-F]{2})?[0-9A-F]{6})$/)) {
+ return {
+ platform: 'ios',
+ reference: 'systemBackgroundColor'
+ };
+ }
- if (xcassetsExists) {
- splashScreensDir = path.join(platformProjDir, 'Images.xcassets/LaunchImage.launchimage/');
- } else {
- splashScreensDir = path.join(platformProjDir, 'Resources/splash/');
+ let red = 'FF';
+ let green = 'FF';
+ let blue = 'FF';
+ let alpha = 1.0;
+
+ if (pref[0] === '#' && pref.length === 4) {
+ red = pref[1] + pref[1];
+ green = pref[2] + pref[2];
+ blue = pref[3] + pref[3];
}
- return splashScreensDir;
-}
+ if (pref.length >= 7 && (pref[0] === '#' || pref.substring(0, 2) === '0x')) {
+ let offset = pref[0] === '#' ? 1 : 2;
-function updateSplashScreens (cordovaProject, locations) {
- var splashScreens = cordovaProject.projectConfig.getSplashScreens('ios');
+ if (pref.substring(offset).length === 8) {
+ alpha = parseInt(pref.substring(offset, offset + 2), 16) / 255.0;
+ offset += 2;
+ }
- if (splashScreens.length === 0) {
- events.emit('verbose', 'This app does not have splash screens defined');
- return;
+ red = pref.substring(offset, offset + 2);
+ green = pref.substring(offset + 2, offset + 4);
+ blue = pref.substring(offset + 4, offset + 6);
}
- var platformProjDir = path.relative(cordovaProject.root, locations.xcodeCordovaProj);
- var splashScreensDir = getSplashScreensDir(cordovaProject.root, platformProjDir);
- var resourceMap = mapSplashScreenResources(splashScreens, splashScreensDir);
- events.emit('verbose', 'Updating splash screens at ' + splashScreensDir);
- FileUpdater.updatePaths(
- resourceMap, { rootDir: cordovaProject.root }, logFileOp);
+ return {
+ 'color-space': 'srgb',
+ components: {
+ red: '0x' + red,
+ green: '0x' + green,
+ blue: '0x' + blue,
+ alpha: alpha.toFixed(3)
+ }
+ };
}
-function cleanSplashScreens (projectRoot, projectConfig, locations) {
- var splashScreens = projectConfig.getSplashScreens('ios');
- if (splashScreens.length > 0) {
- var platformProjDir = path.relative(projectRoot, locations.xcodeCordovaProj);
- var splashScreensDir = getSplashScreensDir(projectRoot, platformProjDir);
- var resourceMap = mapIconResources(splashScreens, splashScreensDir);
- Object.keys(resourceMap).forEach(function (targetSplashPath) {
- resourceMap[targetSplashPath] = null;
- });
- events.emit('verbose', 'Cleaning splash screens at ' + splashScreensDir);
+/**
+ * Update the background color Contents.json in xcassets.
+ *
+ * @param {Object} cordovaProject The cordova project
+ * @param {Object} locations A dictionary containing useful location paths
+ */
+function updateBackgroundColor (cordovaProject, locations) {
+ const pref = cordovaProject.projectConfig.getPreference('BackgroundColor', 'ios') || '';
- // Source paths are removed from the map, so updatePaths() will delete the target files.
- FileUpdater.updatePaths(
- resourceMap, { rootDir: projectRoot, all: true }, logFileOp);
+ const platformProjDir = path.relative(cordovaProject.root, locations.xcodeCordovaProj);
+ const backgroundColorDir = getBackgroundColorDir(cordovaProject.root, platformProjDir);
+
+ if (backgroundColorDir) {
+ const contentsJSON = {
+ colors: [{
+ idiom: 'universal',
+ color: colorPreferenceToComponents(pref)
+ }],
+ info: {
+ author: 'Xcode',
+ version: 1
+ }
+ };
+
+ events.emit('verbose', 'Updating Background Color color set Contents.json');
+ fs.writeFileSync(path.join(cordovaProject.root, backgroundColorDir, 'Contents.json'),
+ JSON.stringify(contentsJSON, null, 2));
+ }
+}
+
+/**
+ * Resets the background color Contents.json in xcassets to default.
+ *
+ * @param {string} projectRoot Path to the project root
+ * @param {Object} projectConfig The project's config.xml
+ * @param {Object} locations A dictionary containing useful location paths
+ */
+function cleanBackgroundColor (projectRoot, projectConfig, locations) {
+ const platformProjDir = path.relative(projectRoot, locations.xcodeCordovaProj);
+ const backgroundColorDir = getBackgroundColorDir(projectRoot, platformProjDir);
+
+ if (backgroundColorDir) {
+ const contentsJSON = {
+ colors: [{
+ idiom: 'universal',
+ color: colorPreferenceToComponents(null)
+ }],
+ info: {
+ author: 'Xcode',
+ version: 1
+ }
+ };
+
+ events.emit('verbose', 'Cleaning Background Color color set Contents.json');
+ fs.writeFileSync(path.join(projectRoot, backgroundColorDir, 'Contents.json'),
+ JSON.stringify(contentsJSON, null, 2));
}
}
@@ -482,9 +529,9 @@ function updateFileResources (cordovaProject, locations) {
return;
}
- let resourceMap = {};
- files.forEach(function (res) {
- let src = res.src;
+ const resourceMap = {};
+ files.forEach(res => {
+ const src = res.src;
let target = res.target;
if (!target) {
@@ -494,29 +541,75 @@ function updateFileResources (cordovaProject, locations) {
let targetPath = path.join(project.resources_dir, target);
targetPath = path.relative(cordovaProject.root, targetPath);
- project.xcode.addResourceFile(target);
+ if (!fs.existsSync(targetPath)) {
+ project.xcode.addResourceFile(target);
+ } else {
+ events.emit('warn', `Overwriting existing resource file at ${targetPath}`);
+ }
resourceMap[targetPath] = src;
});
- events.emit('verbose', 'Updating resource files at ' + platformDir);
+ events.emit('verbose', `Updating resource files at ${platformDir}`);
FileUpdater.updatePaths(
resourceMap, { rootDir: cordovaProject.root }, logFileOp);
project.write();
}
+function alertDeprecatedPreference (configParser) {
+ const deprecatedToNewPreferences = {
+ MediaPlaybackRequiresUserAction: {
+ newPreference: 'MediaTypesRequiringUserActionForPlayback',
+ isDeprecated: true
+ },
+ MediaPlaybackAllowsAirPlay: {
+ newPreference: 'AllowsAirPlayForMediaPlayback',
+ isDeprecated: false
+ }
+ };
+
+ Object.keys(deprecatedToNewPreferences).forEach(oldKey => {
+ if (configParser.getPreference(oldKey)) {
+ const isDeprecated = deprecatedToNewPreferences[oldKey].isDeprecated;
+ const verb = isDeprecated ? 'has been' : 'is being';
+ const newPreferenceKey = deprecatedToNewPreferences[oldKey].newPreference;
+
+ // Create the Log Message
+ const log = [`The preference name "${oldKey}" ${verb} deprecated.`];
+ if (newPreferenceKey) {
+ log.push(`It is recommended to replace this preference with "${newPreferenceKey}."`);
+ } else {
+ log.push('There is no replacement for this preference.');
+ }
+
+ /**
+ * If the preference has been deprecated, the usage of the old preference is no longer used.
+ * Therefore, the following line is not appended. It is added only if the old preference is still used.
+ * We are only keeping the top lines for deprecated items only for an additional major release when
+ * the pre-warning was not provided in a past major release due to a necessary quick deprecation.
+ * Typically caused by implementation nature or third-party requirement changes.
+ */
+ if (!isDeprecated) {
+ log.push('Please note that this preference will be removed in the near future.');
+ }
+
+ events.emit('warn', log.join(' '));
+ }
+ });
+}
+
function cleanFileResources (projectRoot, projectConfig, locations) {
const platformDir = path.relative(projectRoot, locations.root);
const files = projectConfig.getFileResources('ios', true);
if (files.length > 0) {
- events.emit('verbose', 'Cleaning resource files at ' + platformDir);
+ events.emit('verbose', `Cleaning resource files at ${platformDir}`);
const project = projectFile.parse(locations);
- var resourceMap = {};
- files.forEach(function (res) {
- let src = res.src;
+ const resourceMap = {};
+ files.forEach(res => {
+ const src = res.src;
let target = res.target;
if (!target) {
@@ -532,7 +625,7 @@ function cleanFileResources (projectRoot, projectConfig, locations) {
});
FileUpdater.updatePaths(
- resourceMap, {rootDir: projectRoot, all: true}, logFileOp);
+ resourceMap, { rootDir: projectRoot, all: true }, logFileOp);
project.write();
}
@@ -555,7 +648,8 @@ function cleanFileResources (projectRoot, projectConfig, locations) {
* height: 'any|com',
* filename: undefined|'Default@scale~idiom~widthheight.png',
* src: undefined|'path/to/original/matched/image/from/splash/screens.png',
- * target: undefined|'path/to/asset/library/Default@scale~idiom~widthheight.png'
+ * target: undefined|'path/to/asset/library/Default@scale~idiom~widthheight.png',
+ * appearence: undefined|'dark'|'light'
* }, ...
* ]
*
@@ -564,51 +658,54 @@ function cleanFileResources (projectRoot, projectConfig, locations) {
* @return {Array<Object>}
*/
function mapLaunchStoryboardContents (splashScreens, launchStoryboardImagesDir) {
- var platformLaunchStoryboardImages = [];
- var idioms = ['universal', 'ipad', 'iphone'];
- var scalesForIdiom = {
+ const platformLaunchStoryboardImages = [];
+ const idioms = ['universal', 'ipad', 'iphone'];
+ const scalesForIdiom = {
universal: ['1x', '2x', '3x'],
ipad: ['1x', '2x'],
iphone: ['1x', '2x', '3x']
};
- var sizes = ['com', 'any'];
+ const sizes = ['com', 'any'];
+ const appearences = ['', 'dark', 'light'];
- idioms.forEach(function (idiom) {
- scalesForIdiom[idiom].forEach(function (scale) {
- sizes.forEach(function (width) {
- sizes.forEach(function (height) {
- var item = {
- idiom: idiom,
- scale: scale,
- width: width,
- height: height
- };
+ idioms.forEach(idiom => {
+ scalesForIdiom[idiom].forEach(scale => {
+ sizes.forEach(width => {
+ sizes.forEach(height => {
+ appearences.forEach(appearence => {
+ const item = { idiom, scale, width, height };
- /* examples of the search pattern:
- * scale ~ idiom ~ width height
- * @2x ~ universal ~ any any
- * @3x ~ iphone ~ com any
- * @2x ~ ipad ~ com any
- */
- var searchPattern = '@' + scale + '~' + idiom + '~' + width + height;
+ if (appearence !== '') {
+ item.appearence = appearence;
+ }
- /* because old node versions don't have Array.find, the below is
- * functionally equivalent to this:
- * var launchStoryboardImage = splashScreens.find(function(item) {
- * return item.src.indexOf(searchPattern) >= 0;
- * });
- */
- var launchStoryboardImage = splashScreens.reduce(function (p, c) {
- return (c.src.indexOf(searchPattern) >= 0) ? c : p;
- }, undefined);
+ /* examples of the search pattern:
+ * scale ~ idiom ~ width height ~ appearence
+ * @2x ~ universal ~ any any
+ * @3x ~ iphone ~ com any ~ dark
+ * @2x ~ ipad ~ com any ~ light
+ */
+ const searchPattern = '@' + scale + '~' + idiom + '~' + width + height + (appearence ? '~' + appearence : '');
- if (launchStoryboardImage) {
- item.filename = 'Default' + searchPattern + '.png';
- item.src = launchStoryboardImage.src;
- item.target = path.join(launchStoryboardImagesDir, item.filename);
- }
+ /* because old node versions don't have Array.find, the below is
+ * functionally equivalent to this:
+ * var launchStoryboardImage = splashScreens.find(function(item) {
+ * return (item.src.indexOf(searchPattern) >= 0) ? (appearence !== '' ? true : ((item.src.indexOf(searchPattern + '~light') >= 0 || (item.src.indexOf(searchPattern + '~dark') >= 0)) ? false : true)) : false;
+ * });
+ */
+ const launchStoryboardImage = splashScreens.reduce(
+ (p, c) => (c.src.indexOf(searchPattern) >= 0) ? (appearence !== '' ? c : ((c.src.indexOf(searchPattern + '~light') >= 0 || (c.src.indexOf(searchPattern + '~dark') >= 0)) ? p : c)) : p,
+ undefined
+ );
- platformLaunchStoryboardImages.push(item);
+ if (launchStoryboardImage) {
+ item.filename = `Default${searchPattern}.png`;
+ item.src = launchStoryboardImage.src;
+ item.target = path.join(launchStoryboardImagesDir, item.filename);
+ }
+
+ platformLaunchStoryboardImages.push(item);
+ });
});
});
});
@@ -632,9 +729,9 @@ function mapLaunchStoryboardContents (splashScreens, launchStoryboardImagesDir)
* @return {Object}
*/
function mapLaunchStoryboardResources (splashScreens, launchStoryboardImagesDir) {
- var platformLaunchStoryboardImages = mapLaunchStoryboardContents(splashScreens, launchStoryboardImagesDir);
- var pathMap = {};
- platformLaunchStoryboardImages.forEach(function (item) {
+ const platformLaunchStoryboardImages = mapLaunchStoryboardContents(splashScreens, launchStoryboardImagesDir);
+ const pathMap = {};
+ platformLaunchStoryboardImages.forEach(item => {
if (item.target) {
pathMap[item.target] = item.src;
}
@@ -654,6 +751,7 @@ function mapLaunchStoryboardResources (splashScreens, launchStoryboardImagesDir)
* scale: '1x|2x|3x',
* width-class: undefined|'compact',
* height-class: undefined|'compact'
+ * ...
* }, ...
* ],
* info: {
@@ -670,17 +768,16 @@ function mapLaunchStoryboardResources (splashScreens, launchStoryboardImagesDir)
* @return {Object}
*/
function getLaunchStoryboardContentsJSON (splashScreens, launchStoryboardImagesDir) {
-
- var platformLaunchStoryboardImages = mapLaunchStoryboardContents(splashScreens, launchStoryboardImagesDir);
- var contentsJSON = {
+ const platformLaunchStoryboardImages = mapLaunchStoryboardContents(splashScreens, launchStoryboardImagesDir);
+ const contentsJSON = {
images: [],
info: {
author: 'Xcode',
version: 1
}
};
- contentsJSON.images = platformLaunchStoryboardImages.map(function (item) {
- var newItem = {
+ contentsJSON.images = platformLaunchStoryboardImages.map(item => {
+ const newItem = {
idiom: item.idiom,
scale: item.scale
};
@@ -694,6 +791,10 @@ function getLaunchStoryboardContentsJSON (splashScreens, launchStoryboardImagesD
newItem['height-class'] = IMAGESET_COMPACT_SIZE_CLASS;
}
+ if (item.appearence) {
+ newItem.appearances = [{ appearance: 'luminosity', value: item.appearence }];
+ }
+
// Xcode doesn't want a filename property if there's no image for these traits
if (item.filename) {
newItem.filename = item.filename;
@@ -704,107 +805,6 @@ function getLaunchStoryboardContentsJSON (splashScreens, launchStoryboardImagesD
}
/**
- * Determines if the project's build settings may need to be updated for launch storyboard support
- *
- */
-function checkIfBuildSettingsNeedUpdatedForLaunchStoryboard (platformConfig, infoPlist) {
- var hasLaunchStoryboardImages = platformHasLaunchStoryboardImages(platformConfig);
- var hasLegacyLaunchImages = platformHasLegacyLaunchImages(platformConfig);
- var currentLaunchStoryboard = infoPlist[UI_LAUNCH_STORYBOARD_NAME];
-
- if (hasLaunchStoryboardImages && currentLaunchStoryboard === CDV_LAUNCH_STORYBOARD_NAME && !hasLegacyLaunchImages) {
- // don't need legacy launch images if we are using our launch storyboard
- // so we do need to update the project file
- events.emit('verbose', 'Need to update build settings because project is using our launch storyboard.');
- return true;
- } else if (hasLegacyLaunchImages && !currentLaunchStoryboard) {
- // we do need to ensure legacy launch images are used if there's no launch storyboard present
- // so we do need to update the project file
- events.emit('verbose', 'Need to update build settings because project is using legacy launch images and no storyboard.');
- return true;
- }
- events.emit('verbose', 'No need to update build settings for launch storyboard support.');
- return false;
-}
-
-function updateBuildSettingsForLaunchStoryboard (proj, platformConfig, infoPlist) {
- var hasLaunchStoryboardImages = platformHasLaunchStoryboardImages(platformConfig);
- var hasLegacyLaunchImages = platformHasLegacyLaunchImages(platformConfig);
- var currentLaunchStoryboard = infoPlist[UI_LAUNCH_STORYBOARD_NAME];
-
- if (hasLaunchStoryboardImages && currentLaunchStoryboard === CDV_LAUNCH_STORYBOARD_NAME && !hasLegacyLaunchImages) {
- // don't need legacy launch images if we are using our launch storyboard
- events.emit('verbose', 'Removed ' + LAUNCHIMAGE_BUILD_SETTING + ' because project is using our launch storyboard.');
- proj.removeBuildProperty(LAUNCHIMAGE_BUILD_SETTING);
- } else if (hasLegacyLaunchImages && !currentLaunchStoryboard) {
- // we do need to ensure legacy launch images are used if there's no launch storyboard present
- events.emit('verbose', 'Set ' + LAUNCHIMAGE_BUILD_SETTING + ' to ' + LAUNCHIMAGE_BUILD_SETTING_VALUE + ' because project is using legacy launch images and no storyboard.');
- proj.updateBuildProperty(LAUNCHIMAGE_BUILD_SETTING, LAUNCHIMAGE_BUILD_SETTING_VALUE);
- } else {
- events.emit('verbose', 'Did not update build settings for launch storyboard support.');
- }
-}
-
-function splashScreensHaveLaunchStoryboardImages (contentsJSON) {
- /* do we have any launch images do we have for our launch storyboard?
- * Again, for old Node versions, the below code is equivalent to this:
- * return !!contentsJSON.images.find(function (item) {
- * return item.filename !== undefined;
- * });
- */
- return !!contentsJSON.images.reduce(function (p, c) {
- return (c.filename !== undefined) ? c : p;
- }, undefined);
-}
-
-function platformHasLaunchStoryboardImages (platformConfig) {
- var splashScreens = platformConfig.getSplashScreens('ios');
- var contentsJSON = getLaunchStoryboardContentsJSON(splashScreens, ''); // note: we don't need a file path here; we're just counting
- return splashScreensHaveLaunchStoryboardImages(contentsJSON);
-}
-
-function platformHasLegacyLaunchImages (platformConfig) {
- var splashScreens = platformConfig.getSplashScreens('ios');
- return !!splashScreens.reduce(function (p, c) {
- return (c.width !== undefined || c.height !== undefined) ? c : p;
- }, undefined);
-}
-
-/**
- * Updates the project's plist based upon our launch storyboard images. If there are no images, then we should
- * fall back to the regular launch images that might be supplied (that is, our app will be scaled on an iPad Pro),
- * and if there are some images, we need to alter the UILaunchStoryboardName property to point to
- * CDVLaunchScreen.
- *
- * There's some logic here to avoid overwriting changes the user might have made to their plist if they are using
- * their own launch storyboard.
- */
-function updateProjectPlistForLaunchStoryboard (platformConfig, infoPlist) {
- var currentLaunchStoryboard = infoPlist[UI_LAUNCH_STORYBOARD_NAME];
- events.emit('verbose', 'Current launch storyboard ' + currentLaunchStoryboard);
-
- var hasLaunchStoryboardImages = platformHasLaunchStoryboardImages(platformConfig);
-
- if (hasLaunchStoryboardImages && !currentLaunchStoryboard) {
- // only change the launch storyboard if we have images to use AND the current value is blank
- // if it's not blank, we've either done this before, or the user has their own launch storyboard
- events.emit('verbose', 'Changing info plist to use our launch storyboard');
- infoPlist[UI_LAUNCH_STORYBOARD_NAME] = CDV_LAUNCH_STORYBOARD_NAME;
- return;
- }
-
- if (!hasLaunchStoryboardImages && currentLaunchStoryboard === CDV_LAUNCH_STORYBOARD_NAME) {
- // only revert to using the launch images if we have don't have any images for the launch storyboard
- // but only clear it if current launch storyboard is our storyboard; the user might be using their
- // own storyboard instead.
- events.emit('verbose', 'Changing info plist to use legacy launch images');
- delete infoPlist[UI_LAUNCH_STORYBOARD_NAME];
- return;
- }
- events.emit('verbose', 'Not changing launch storyboard setting in info plist.');
-}
-
-/**
* Returns the directory for the Launch Storyboard image set, if image sets are being used. If they aren't
* being used, returns null.
*
@@ -812,8 +812,8 @@ function updateProjectPlistForLaunchStoryboard (platformConfig, infoPlist) {
* @param {string} platformProjDir The platform's project directory
*/
function getLaunchStoryboardImagesDir (projectRoot, platformProjDir) {
- var launchStoryboardImagesDir;
- var xcassetsExists = folderExists(path.join(projectRoot, platformProjDir, 'Images.xcassets/'));
+ let launchStoryboardImagesDir;
+ const xcassetsExists = folderExists(path.join(projectRoot, platformProjDir, 'Images.xcassets/'));
if (xcassetsExists) {
launchStoryboardImagesDir = path.join(platformProjDir, 'Images.xcassets/LaunchStoryboard.imageset/');
@@ -832,15 +832,15 @@ function getLaunchStoryboardImagesDir (projectRoot, platformProjDir) {
* @param {Object} locations A dictionary containing useful location paths
*/
function updateLaunchStoryboardImages (cordovaProject, locations) {
- var splashScreens = cordovaProject.projectConfig.getSplashScreens('ios');
- var platformProjDir = path.relative(cordovaProject.root, locations.xcodeCordovaProj);
- var launchStoryboardImagesDir = getLaunchStoryboardImagesDir(cordovaProject.root, platformProjDir);
+ const splashScreens = cordovaProject.projectConfig.getSplashScreens('ios');
+ const platformProjDir = path.relative(cordovaProject.root, locations.xcodeCordovaProj);
+ const launchStoryboardImagesDir = getLaunchStoryboardImagesDir(cordovaProject.root, platformProjDir);
if (launchStoryboardImagesDir) {
- var resourceMap = mapLaunchStoryboardResources(splashScreens, launchStoryboardImagesDir);
- var contentsJSON = getLaunchStoryboardContentsJSON(splashScreens, launchStoryboardImagesDir);
+ const resourceMap = mapLaunchStoryboardResources(splashScreens, launchStoryboardImagesDir);
+ const contentsJSON = getLaunchStoryboardContentsJSON(splashScreens, launchStoryboardImagesDir);
- events.emit('verbose', 'Updating launch storyboard images at ' + launchStoryboardImagesDir);
+ events.emit('verbose', `Updating launch storyboard images at ${launchStoryboardImagesDir}`);
FileUpdater.updatePaths(
resourceMap, { rootDir: cordovaProject.root }, logFileOp);
@@ -859,24 +859,24 @@ function updateLaunchStoryboardImages (cordovaProject, locations) {
* @param {Object} locations A dictionary containing useful location paths
*/
function cleanLaunchStoryboardImages (projectRoot, projectConfig, locations) {
- var splashScreens = projectConfig.getSplashScreens('ios');
- var platformProjDir = path.relative(projectRoot, locations.xcodeCordovaProj);
- var launchStoryboardImagesDir = getLaunchStoryboardImagesDir(projectRoot, platformProjDir);
+ const splashScreens = projectConfig.getSplashScreens('ios');
+ const platformProjDir = path.relative(projectRoot, locations.xcodeCordovaProj);
+ const launchStoryboardImagesDir = getLaunchStoryboardImagesDir(projectRoot, platformProjDir);
if (launchStoryboardImagesDir) {
- var resourceMap = mapLaunchStoryboardResources(splashScreens, launchStoryboardImagesDir);
- var contentsJSON = getLaunchStoryboardContentsJSON(splashScreens, launchStoryboardImagesDir);
+ const resourceMap = mapLaunchStoryboardResources(splashScreens, launchStoryboardImagesDir);
+ const contentsJSON = getLaunchStoryboardContentsJSON(splashScreens, launchStoryboardImagesDir);
- Object.keys(resourceMap).forEach(function (targetPath) {
+ Object.keys(resourceMap).forEach(targetPath => {
resourceMap[targetPath] = null;
});
- events.emit('verbose', 'Cleaning storyboard image set at ' + launchStoryboardImagesDir);
+ events.emit('verbose', `Cleaning storyboard image set at ${launchStoryboardImagesDir}`);
// Source paths are removed from the map, so updatePaths() will delete the target files.
FileUpdater.updatePaths(
resourceMap, { rootDir: projectRoot, all: true }, logFileOp);
// delete filename from contents.json
- contentsJSON.images.forEach(function (image) {
+ contentsJSON.images.forEach(image => {
image.filename = undefined;
});
@@ -896,10 +896,9 @@ function cleanLaunchStoryboardImages (projectRoot, projectConfig, locations) {
* (or empty string if both are undefined).
*/
function getOrientationValue (platformConfig) {
+ const ORIENTATION_DEFAULT = 'default';
- var ORIENTATION_DEFAULT = 'default';
-
- var orientation = platformConfig.getPreference('orientation');
+ let orientation = platformConfig.getPreference('orientation');
if (!orientation) {
return '';
}
@@ -911,8 +910,7 @@ function getOrientationValue (platformConfig) {
return orientation;
}
- events.emit('warn', 'Unrecognized value for Orientation preference: ' + orientation +
- '. Defaulting to value: ' + ORIENTATION_DEFAULT + '.');
+ events.emit('warn', `Unrecognized value for Orientation preference: ${orientation}. Defaulting to value: ${ORIENTATION_DEFAULT}.`);
return ORIENTATION_DEFAULT;
}
@@ -938,20 +936,20 @@ function getOrientationValue (platformConfig) {
}
*/
function processAccessAndAllowNavigationEntries (config) {
- var accesses = config.getAccesses();
- var allow_navigations = config.getAllowNavigations();
+ const accesses = config.getAccesses();
+ const allow_navigations = config.getAllowNavigations();
return allow_navigations
- // we concat allow_navigations and accesses, after processing accesses
- .concat(accesses.map(function (obj) {
+ // we concat allow_navigations and accesses, after processing accesses
+ .concat(accesses.map(obj => {
// map accesses to a common key interface using 'href', not origin
obj.href = obj.origin;
delete obj.origin;
return obj;
}))
// we reduce the array to an object with all the entries processed (key is Hostname)
- .reduce(function (previousReturn, currentElement) {
- var options = {
+ .reduce((previousReturn, currentElement) => {
+ const options = {
minimum_tls_version: currentElement.minimum_tls_version,
requires_forward_secrecy: currentElement.requires_forward_secrecy,
requires_certificate_transparency: currentElement.requires_certificate_transparency,
@@ -959,16 +957,16 @@ function processAccessAndAllowNavigationEntries (config) {
allows_arbitrary_loads_in_web_content: currentElement.allows_arbitrary_loads_in_web_content,
allows_local_networking: currentElement.allows_local_networking
};
- var obj = parseWhitelistUrlForATS(currentElement.href, options);
+ const obj = parseWhitelistUrlForATS(currentElement.href, options);
if (obj) {
// we 'union' duplicate entries
- var item = previousReturn[obj.Hostname];
+ let item = previousReturn[obj.Hostname];
if (!item) {
item = {};
}
- for (var o in obj) {
- if (obj.hasOwnProperty(o)) {
+ for (const o in obj) {
+ if (Object.prototype.hasOwnProperty.call(obj, o)) {
item[o] = obj[o];
}
}
@@ -999,15 +997,16 @@ function processAccessAndAllowNavigationEntries (config) {
null is returned if the URL cannot be parsed, or is to be skipped for ATS.
*/
function parseWhitelistUrlForATS (url, options) {
- var href = URL.parse(url);
- var retObj = {};
+ // @todo 'url.parse' was deprecated since v11.0.0. Use 'url.URL' constructor instead.
+ const href = URL.parse(url); // eslint-disable-line
+ const retObj = {};
retObj.Hostname = href.hostname;
// Guiding principle: we only set values in retObj if they are NOT the default
if (url === '*') {
retObj.Hostname = '*';
- var val;
+ let val;
val = (options.allows_arbitrary_loads_in_web_content === 'true');
if (options.allows_arbitrary_loads_in_web_content && val) { // default is false
@@ -1029,10 +1028,12 @@ function parseWhitelistUrlForATS (url, options) {
if (!retObj.Hostname) {
// check origin, if it allows subdomains (wildcard in hostname), we set NSIncludesSubdomains to YES. Default is NO
- var subdomain1 = '/*.'; // wildcard in hostname
- var subdomain2 = '*://*.'; // wildcard in hostname and protocol
- var subdomain3 = '*://'; // wildcard in protocol only
- if (href.pathname.indexOf(subdomain1) === 0) {
+ const subdomain1 = '/*.'; // wildcard in hostname
+ const subdomain2 = '*://*.'; // wildcard in hostname and protocol
+ const subdomain3 = '*://'; // wildcard in protocol only
+ if (!href.pathname) {
+ return null;
+ } else if (href.pathname.indexOf(subdomain1) === 0) {
retObj.NSIncludesSubdomains = true;
retObj.Hostname = href.pathname.substring(subdomain1.length);
} else if (href.pathname.indexOf(subdomain2) === 0) {
@@ -1050,12 +1051,12 @@ function parseWhitelistUrlForATS (url, options) {
retObj.NSExceptionMinimumTLSVersion = options.minimum_tls_version;
}
- var rfs = (options.requires_forward_secrecy === 'true');
+ const rfs = (options.requires_forward_secrecy === 'true');
if (options.requires_forward_secrecy && !rfs) { // default is true
retObj.NSExceptionRequiresForwardSecrecy = false;
}
- var rct = (options.requires_certificate_transparency === 'true');
+ const rct = (options.requires_certificate_transparency === 'true');
if (options.requires_certificate_transparency && rct) { // default is false
retObj.NSRequiresCertificateTransparency = true;
}
@@ -1075,48 +1076,48 @@ function parseWhitelistUrlForATS (url, options) {
in config.xml
*/
function writeATSEntries (config) {
- var pObj = processAccessAndAllowNavigationEntries(config);
+ const pObj = processAccessAndAllowNavigationEntries(config);
- var ats = {};
+ const ats = {};
- for (var hostname in pObj) {
- if (pObj.hasOwnProperty(hostname)) {
- var entry = pObj[hostname];
+ for (const hostname in pObj) {
+ if (Object.prototype.hasOwnProperty.call(pObj, hostname)) {
+ const entry = pObj[hostname];
// Guiding principle: we only set values if they are available
if (hostname === '*') {
// always write this, for iOS 9, since in iOS 10 it will be overriden if
// any of the other three keys are written
- ats['NSAllowsArbitraryLoads'] = true;
+ ats.NSAllowsArbitraryLoads = true;
// at least one of the overriding keys is present
if (entry.NSAllowsArbitraryLoadsInWebContent) {
- ats['NSAllowsArbitraryLoadsInWebContent'] = true;
+ ats.NSAllowsArbitraryLoadsInWebContent = true;
}
if (entry.NSAllowsArbitraryLoadsForMedia) {
- ats['NSAllowsArbitraryLoadsForMedia'] = true;
+ ats.NSAllowsArbitraryLoadsForMedia = true;
}
if (entry.NSAllowsLocalNetworking) {
- ats['NSAllowsLocalNetworking'] = true;
+ ats.NSAllowsLocalNetworking = true;
}
continue;
}
- var exceptionDomain = {};
+ const exceptionDomain = {};
- for (var key in entry) {
- if (entry.hasOwnProperty(key) && key !== 'Hostname') {
+ for (const key in entry) {
+ if (Object.prototype.hasOwnProperty.call(entry, key) && key !== 'Hostname') {
exceptionDomain[key] = entry[key];
}
}
- if (!ats['NSExceptionDomains']) {
- ats['NSExceptionDomains'] = {};
+ if (!ats.NSExceptionDomains) {
+ ats.NSExceptionDomains = {};
}
- ats['NSExceptionDomains'][hostname] = exceptionDomain;
+ ats.NSExceptionDomains[hostname] = exceptionDomain;
}
}
@@ -1125,7 +1126,7 @@ function writeATSEntries (config) {
function folderExists (folderPath) {
try {
- var stat = fs.statSync(folderPath);
+ const stat = fs.statSync(folderPath);
return stat && stat.isDirectory();
} catch (e) {
return false;
@@ -1141,10 +1142,10 @@ function default_CFBundleVersion (version) {
// Converts cordova specific representation of target device to XCode value
function parseTargetDevicePreference (value) {
if (!value) return null;
- var map = {'universal': '"1,2"', 'handset': '"1"', 'tablet': '"2"'};
+ const map = { universal: '"1,2"', handset: '"1"', tablet: '"2"' };
if (map[value.toLowerCase()]) {
return map[value.toLowerCase()];
}
- events.emit('warn', 'Unrecognized value for target-device preference: ' + value + '.');
+ events.emit('warn', `Unrecognized value for target-device preference: ${value}.`);
return null;
}
diff --git a/StoneIsland/platforms/ios/cordova/lib/projectFile.js b/StoneIsland/platforms/ios/cordova/lib/projectFile.js
index 8a3f7e51..3e1e8304 100755..100644
--- a/StoneIsland/platforms/ios/cordova/lib/projectFile.js
+++ b/StoneIsland/platforms/ios/cordova/lib/projectFile.js
@@ -17,47 +17,46 @@
under the License.
*/
-var xcode = require('xcode');
-var plist = require('plist');
-var _ = require('underscore');
-var path = require('path');
-var fs = require('fs');
-var shell = require('shelljs');
+const xcode = require('xcode');
+const plist = require('plist');
+const _ = require('underscore');
+const path = require('path');
+const fs = require('fs-extra');
-var pluginHandlers = require('./plugman/pluginHandlers');
-var CordovaError = require('cordova-common').CordovaError;
+const pluginHandlers = require('./plugman/pluginHandlers');
+const CordovaError = require('cordova-common').CordovaError;
-var cachedProjectFiles = {};
+const cachedProjectFiles = {};
function parseProjectFile (locations) {
- var project_dir = locations.root;
- var pbxPath = locations.pbxproj;
+ const project_dir = locations.root;
+ const pbxPath = locations.pbxproj;
if (cachedProjectFiles[project_dir]) {
return cachedProjectFiles[project_dir];
}
- var xcodeproj = xcode.project(pbxPath);
+ const xcodeproj = xcode.project(pbxPath);
xcodeproj.parseSync();
- var xcBuildConfiguration = xcodeproj.pbxXCBuildConfigurationSection();
- var plist_file_entry = _.find(xcBuildConfiguration, function (entry) { return entry.buildSettings && entry.buildSettings.INFOPLIST_FILE; });
- var plist_file = path.join(project_dir, plist_file_entry.buildSettings.INFOPLIST_FILE.replace(/^"(.*)"$/g, '$1').replace(/\\&/g, '&'));
- var config_file = path.join(path.dirname(plist_file), 'config.xml');
+ const xcBuildConfiguration = xcodeproj.pbxXCBuildConfigurationSection();
+ const plist_file_entry = _.find(xcBuildConfiguration, entry => entry.buildSettings && entry.buildSettings.INFOPLIST_FILE);
+ const plist_file = path.join(project_dir, plist_file_entry.buildSettings.INFOPLIST_FILE.replace(/^"(.*)"$/g, '$1').replace(/\\&/g, '&'));
+ const config_file = path.join(path.dirname(plist_file), 'config.xml');
if (!fs.existsSync(plist_file) || !fs.existsSync(config_file)) {
throw new CordovaError('Could not find *-Info.plist file, or config.xml file.');
}
- var frameworks_file = path.join(project_dir, 'frameworks.json');
- var frameworks = {};
+ const frameworks_file = path.join(project_dir, 'frameworks.json');
+ let frameworks = {};
try {
frameworks = require(frameworks_file);
} catch (e) { }
- var xcode_dir = path.dirname(plist_file);
- var pluginsDir = path.resolve(xcode_dir, 'Plugins');
- var resourcesDir = path.resolve(xcode_dir, 'Resources');
+ const xcode_dir = path.dirname(plist_file);
+ const pluginsDir = path.resolve(xcode_dir, 'Plugins');
+ const resourcesDir = path.resolve(xcode_dir, 'Resources');
cachedProjectFiles[project_dir] = {
plugins_dir: pluginsDir,
@@ -72,13 +71,21 @@ function parseProjectFile (locations) {
fs.writeFileSync(pbxPath, xcodeproj.writeSync());
if (Object.keys(this.frameworks).length === 0) {
// If there is no framework references remain in the project, just remove this file
- shell.rm('-rf', frameworks_file);
+ fs.removeSync(frameworks_file);
return;
}
fs.writeFileSync(frameworks_file, JSON.stringify(this.frameworks, null, 4));
},
getPackageName: function () {
- return plist.parse(fs.readFileSync(plist_file, 'utf8')).CFBundleIdentifier;
+ const packageName = plist.parse(fs.readFileSync(plist_file, 'utf8')).CFBundleIdentifier;
+ let bundleIdentifier = packageName;
+
+ const variables = packageName.match(/\$\((\w+)\)/); // match $(VARIABLE), if any
+ if (variables && variables.length >= 2) {
+ bundleIdentifier = xcodeproj.getBuildProperty(variables[1]);
+ }
+
+ return bundleIdentifier.replace(/^"/, '').replace(/"$/, '');
},
getInstaller: function (name) {
return pluginHandlers.getInstaller(name);
@@ -86,7 +93,7 @@ function parseProjectFile (locations) {
getUninstaller: function (name) {
return pluginHandlers.getUninstaller(name);
},
- frameworks: frameworks
+ frameworks
};
return cachedProjectFiles[project_dir];
}
@@ -97,7 +104,7 @@ function purgeProjectFileCache (project_dir) {
module.exports = {
parse: parseProjectFile,
- purgeProjectFileCache: purgeProjectFileCache
+ purgeProjectFileCache
};
xcode.project.prototype.pbxEmbedFrameworksBuildPhaseObj = function (target) {
@@ -105,25 +112,23 @@ xcode.project.prototype.pbxEmbedFrameworksBuildPhaseObj = function (target) {
};
xcode.project.prototype.addToPbxEmbedFrameworksBuildPhase = function (file) {
- var sources = this.pbxEmbedFrameworksBuildPhaseObj(file.target);
+ const sources = this.pbxEmbedFrameworksBuildPhaseObj(file.target);
if (sources) {
sources.files.push(pbxBuildPhaseObj(file));
}
};
xcode.project.prototype.removeFromPbxEmbedFrameworksBuildPhase = function (file) {
- var sources = this.pbxEmbedFrameworksBuildPhaseObj(file.target);
+ const sources = this.pbxEmbedFrameworksBuildPhaseObj(file.target);
if (sources) {
- sources.files = _.reject(sources.files, function (file) {
- return file.comment === longComment(file);
- });
+ sources.files = _.reject(sources.files, file => file.comment === longComment(file));
}
};
// special handlers to add frameworks to the 'Embed Frameworks' build phase, needed for custom frameworks
// see CB-9517. should probably be moved to node-xcode.
-var util = require('util');
+const util = require('util');
function pbxBuildPhaseObj (file) {
- var obj = Object.create(null);
+ const obj = Object.create(null);
obj.value = file.uuid;
obj.comment = longComment(file);
return obj;
diff --git a/StoneIsland/platforms/ios/cordova/lib/run.js b/StoneIsland/platforms/ios/cordova/lib/run.js
index 3a6246e1..f7fd8c13 100755..100644
--- a/StoneIsland/platforms/ios/cordova/lib/run.js
+++ b/StoneIsland/platforms/ios/cordova/lib/run.js
@@ -17,23 +17,23 @@
under the License.
*/
-var Q = require('q');
-var path = require('path');
-var iossim = require('ios-sim');
-var build = require('./build');
-var spawn = require('./spawn');
-var check_reqs = require('./check_reqs');
+const path = require('path');
+const build = require('./build');
+const {
+ CordovaError,
+ events,
+ superspawn: { spawn }
+} = require('cordova-common');
+const check_reqs = require('./check_reqs');
+const fs = require('fs-extra');
-var events = require('cordova-common').events;
-
-var cordovaPath = path.join(__dirname, '..');
-var projectPath = path.join(__dirname, '..', '..');
-
-module.exports.run = function (runOptions) {
+const cordovaPath = path.join(__dirname, '..');
+const projectPath = path.join(__dirname, '..', '..');
+module.exports.run = runOptions => {
// Validate args
if (runOptions.device && runOptions.emulator) {
- return Q.reject('Only one of "device"/"emulator" options should be specified');
+ return Promise.reject(new CordovaError('Only one of "device"/"emulator" options should be specified'));
}
// support for CB-8168 `cordova/run --list`
@@ -41,15 +41,13 @@ module.exports.run = function (runOptions) {
if (runOptions.device) return module.exports.listDevices();
if (runOptions.emulator) return module.exports.listEmulators();
// if no --device or --emulator flag is specified, list both devices and emulators
- return module.exports.listDevices().then(function () {
- return module.exports.listEmulators();
- });
+ return module.exports.listDevices().then(() => module.exports.listEmulators());
}
- var useDevice = !!runOptions.device;
+ let useDevice = !!runOptions.device;
- return require('./list-devices').run()
- .then(function (devices) {
+ return require('./listDevices').run()
+ .then(devices => {
if (devices.length > 0 && !(runOptions.emulator)) {
useDevice = true;
// we also explicitly set device flag in options as we pass
@@ -57,58 +55,56 @@ module.exports.run = function (runOptions) {
runOptions.device = true;
return check_reqs.check_ios_deploy();
}
- }).then(function () {
+ }).then(() => {
if (!runOptions.nobuild) {
return build.run(runOptions);
} else {
- return Q.resolve();
+ return Promise.resolve();
}
- }).then(function () {
- return build.findXCodeProjectIn(projectPath);
- }).then(function (projectName) {
- var appPath = path.join(projectPath, 'build', 'emulator', projectName + '.app');
- var buildOutputDir = path.join(projectPath, 'build', 'device');
+ }).then(() => build.findXCodeProjectIn(projectPath))
+ .then(projectName => {
+ let appPath = path.join(projectPath, 'build', 'emulator', `${projectName}.app`);
+ const buildOutputDir = path.join(projectPath, 'build', 'device');
// select command to run and arguments depending whether
// we're running on device/emulator
if (useDevice) {
return module.exports.checkDeviceConnected()
- .then(function () {
+ .then(() => {
// Unpack IPA
- var ipafile = path.join(buildOutputDir, projectName + '.ipa');
+ const ipafile = path.join(buildOutputDir, `${projectName}.ipa`);
// unpack the existing platform/ios/build/device/appname.ipa (zipfile), will create a Payload folder
- return spawn('unzip', [ '-o', '-qq', ipafile ], buildOutputDir);
+ return spawn('unzip', ['-o', '-qq', ipafile], { cwd: buildOutputDir, printCommand: true, stdio: 'inherit' });
})
- .then(function () {
+ .then(() => {
// Uncompress IPA (zip file)
- var appFileInflated = path.join(buildOutputDir, 'Payload', projectName + '.app');
- var appFile = path.join(buildOutputDir, projectName + '.app');
- var payloadFolder = path.join(buildOutputDir, 'Payload');
+ const appFileInflated = path.join(buildOutputDir, 'Payload', `${projectName}.app`);
+ const appFile = path.join(buildOutputDir, `${projectName}.app`);
+ const payloadFolder = path.join(buildOutputDir, 'Payload');
// delete the existing platform/ios/build/device/appname.app
- return spawn('rm', [ '-rf', appFile ], buildOutputDir)
- .then(function () {
- // move the platform/ios/build/device/Payload/appname.app to parent
- return spawn('mv', [ '-f', appFileInflated, buildOutputDir ], buildOutputDir);
- })
- .then(function () {
- // delete the platform/ios/build/device/Payload folder
- return spawn('rm', [ '-rf', payloadFolder ], buildOutputDir);
- });
+ fs.removeSync(appFile);
+ // move the platform/ios/build/device/Payload/appname.app to parent
+ fs.moveSync(appFileInflated, appFile);
+ // delete the platform/ios/build/device/Payload folder
+ fs.removeSync(payloadFolder);
+
+ return null;
})
- .then(function () {
- appPath = path.join(projectPath, 'build', 'device', projectName + '.app');
- var extraArgs = [];
- if (runOptions.argv) {
- // argv.slice(2) removes node and run.js, filterSupportedArgs removes the run.js args
- extraArgs = module.exports.filterSupportedArgs(runOptions.argv.slice(2));
- }
- return module.exports.deployToDevice(appPath, runOptions.target, extraArgs);
- }, function () {
+ .then(
+ () => {
+ appPath = path.join(projectPath, 'build', 'device', `${projectName}.app`);
+ let extraArgs = [];
+ if (runOptions.argv) {
+ // argv.slice(2) removes node and run.js, filterSupportedArgs removes the run.js args
+ extraArgs = module.exports.filterSupportedArgs(runOptions.argv.slice(2));
+ }
+ return module.exports.deployToDevice(appPath, runOptions.target, extraArgs);
+ },
// if device connection check failed use emulator then
- return module.exports.deployToSim(appPath, runOptions.target);
- });
+ () => module.exports.deployToSim(appPath, runOptions.target)
+ );
} else {
return module.exports.deployToSim(appPath, runOptions.target);
}
@@ -129,11 +125,11 @@ module.exports.listEmulators = listEmulators;
* @return {Array} array with unsupported args for the 'run' command
*/
function filterSupportedArgs (args) {
- var filtered = [];
- var sargs = ['--device', '--emulator', '--nobuild', '--list', '--target', '--debug', '--release'];
- var re = new RegExp(sargs.join('|'));
+ const filtered = [];
+ const sargs = ['--device', '--emulator', '--nobuild', '--list', '--target', '--debug', '--release'];
+ const re = new RegExp(sargs.join('|'));
- args.forEach(function (element) {
+ args.forEach(element => {
// supported args not found, we add
// we do a regex search because --target can be "--target=XXX"
if (element.search(re) === -1) {
@@ -149,7 +145,7 @@ function filterSupportedArgs (args) {
* @return {Promise} Fullfilled when any device is connected, rejected otherwise
*/
function checkDeviceConnected () {
- return spawn('ios-deploy', ['-c', '-t', '1']);
+ return spawn('ios-deploy', ['-c', '-t', '1'], { printCommand: true, stdio: 'inherit' });
}
/**
@@ -159,11 +155,12 @@ function checkDeviceConnected () {
* @return {Promise} Resolves when deploy succeeds otherwise rejects
*/
function deployToDevice (appPath, target, extraArgs) {
+ events.emit('log', 'Deploying to device');
// Deploying to device...
if (target) {
- return spawn('ios-deploy', ['--justlaunch', '-d', '-b', appPath, '-i', target].concat(extraArgs));
+ return spawn('ios-deploy', ['--justlaunch', '-d', '-b', appPath, '-i', target].concat(extraArgs), { printCommand: true, stdio: 'inherit' });
} else {
- return spawn('ios-deploy', ['--justlaunch', '--no-wifi', '-d', '-b', appPath].concat(extraArgs));
+ return spawn('ios-deploy', ['--justlaunch', '--no-wifi', '-d', '-b', appPath].concat(extraArgs), { printCommand: true, stdio: 'inherit' });
}
}
@@ -174,19 +171,20 @@ function deployToDevice (appPath, target, extraArgs) {
* @return {Promise} Resolves when deploy succeeds otherwise rejects
*/
function deployToSim (appPath, target) {
- // Select target device for emulator. Default is 'iPhone-6'
+ events.emit('log', 'Deploying to simulator');
if (!target) {
- return require('./list-emulator-images').run()
- .then(function (emulators) {
+ // Select target device for emulator
+ return require('./listEmulatorImages').run()
+ .then(emulators => {
if (emulators.length > 0) {
target = emulators[0];
}
- emulators.forEach(function (emulator) {
+ emulators.forEach(emulator => {
if (emulator.indexOf('iPhone') === 0) {
target = emulator;
}
});
- events.emit('log', 'No target specified for emulator. Deploying to ' + target + ' simulator');
+ events.emit('log', `No target specified for emulator. Deploying to "${target}" simulator.`);
return startSim(appPath, target);
});
} else {
@@ -195,32 +193,50 @@ function deployToSim (appPath, target) {
}
function startSim (appPath, target) {
- var logPath = path.join(cordovaPath, 'console.log');
+ const logPath = path.join(cordovaPath, 'console.log');
- return iossim.launch(appPath, 'com.apple.CoreSimulator.SimDeviceType.' + target, logPath, '--exit');
+ return iossimLaunch(appPath, `com.apple.CoreSimulator.SimDeviceType.${target}`, logPath, '--exit');
+}
+
+function iossimLaunch (appPath, devicetypeid, log, exit) {
+ return spawn(
+ require.resolve('ios-sim/bin/ios-sim'),
+ ['launch', appPath, '--devicetypeid', devicetypeid, '--log', log, exit],
+ { cwd: projectPath, printCommand: true }
+ ).progress(stdio => {
+ if (stdio.stderr) {
+ events.emit('error', `[ios-sim] ${stdio.stderr}`);
+ }
+ if (stdio.stdout) {
+ events.emit('log', `[ios-sim] ${stdio.stdout.trim()}`);
+ }
+ })
+ .then(result => {
+ events.emit('log', 'Simulator successfully started via `ios-sim`.');
+ });
}
function listDevices () {
- return require('./list-devices').run()
- .then(function (devices) {
+ return require('./listDevices').run()
+ .then(devices => {
events.emit('log', 'Available iOS Devices:');
- devices.forEach(function (device) {
- events.emit('log', '\t' + device);
+ devices.forEach(device => {
+ events.emit('log', `\t${device}`);
});
});
}
function listEmulators () {
- return require('./list-emulator-images').run()
- .then(function (emulators) {
+ return require('./listEmulatorImages').run()
+ .then(emulators => {
events.emit('log', 'Available iOS Simulators:');
- emulators.forEach(function (emulator) {
- events.emit('log', '\t' + emulator);
+ emulators.forEach(emulator => {
+ events.emit('log', `\t${emulator}`);
});
});
}
-module.exports.help = function () {
+module.exports.help = () => {
console.log('\nUsage: run [ --device | [ --emulator [ --target=<id> ] ] ] [ --debug | --release | --nobuild ]');
// TODO: add support for building different archs
// console.log(" [ --archs=\"<list of target architectures>\" ] ");
diff --git a/StoneIsland/platforms/ios/cordova/lib/spawn.js b/StoneIsland/platforms/ios/cordova/lib/spawn.js
deleted file mode 100755
index b5a56852..00000000
--- a/StoneIsland/platforms/ios/cordova/lib/spawn.js
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied. See the License for the
- specific language governing permissions and limitations
- under the License.
-*/
-
-var Q = require('q');
-var proc = require('child_process');
-
-/**
- * Run specified command with arguments
- * @param {String} cmd Command
- * @param {Array} args Array of arguments that should be passed to command
- * @param {String} opt_cwd Working directory for command
- * @param {String} opt_verbosity Verbosity level for command stdout output, "verbose" by default
- * @return {Promise} Promise either fullfilled or rejected with error code
- */
-module.exports = function (cmd, args, opt_cwd) {
- var d = Q.defer();
- try {
- var child = proc.spawn(cmd, args, {cwd: opt_cwd, stdio: 'inherit'});
-
- child.on('exit', function (code) {
- if (code) {
- d.reject('Error code ' + code + ' for command: ' + cmd + ' with args: ' + args);
- } else {
- d.resolve();
- }
- });
- } catch (e) {
- d.reject(e);
- }
- return d.promise;
-};
diff --git a/StoneIsland/platforms/ios/cordova/lib/versions.js b/StoneIsland/platforms/ios/cordova/lib/versions.js
index c6a41b83..f8914785 100755..100644
--- a/StoneIsland/platforms/ios/cordova/lib/versions.js
+++ b/StoneIsland/platforms/ios/cordova/lib/versions.js
@@ -1,5 +1,3 @@
-#!/usr/bin/env node
-
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
@@ -19,76 +17,43 @@
under the License.
*/
-var child_process = require('child_process');
-var Q = require('q');
+const {
+ CordovaError,
+ superspawn: { spawn }
+} = require('cordova-common');
+const semver = require('semver');
-exports.get_apple_ios_version = function () {
- var d = Q.defer();
- child_process.exec('xcodebuild -showsdks', function (error, stdout, stderr) {
- if (error) {
- d.reject(stderr);
- } else {
- d.resolve(stdout);
- }
- });
+function fetchSdkVersionByType (sdkType) {
+ return spawn('xcodebuild', ['-showsdks'])
+ .then(output => {
+ const regexSdk = new RegExp(`^${sdkType} \\d`);
- return d.promise.then(function (output) {
- var regex = /[0-9]*\.[0-9]*/;
- var versions = [];
- var regexIOS = /^iOS \d+/;
- output = output.split('\n');
- for (var i = 0; i < output.length; i++) {
- if (output[i].trim().match(regexIOS)) {
- versions[versions.length] = parseFloat(output[i].match(regex)[0]);
- }
- }
- versions.sort();
- console.log(versions[0]);
- return Q();
- }, function (stderr) {
- return Q.reject(stderr);
- });
-};
+ const versions = output.split('\n')
+ .filter(line => line.trim().match(regexSdk))
+ .map(line => line.match(/\d+\.\d+/)[0])
+ .sort(exports.compareVersions);
-exports.get_apple_osx_version = function () {
- var d = Q.defer();
- child_process.exec('xcodebuild -showsdks', function (error, stdout, stderr) {
- if (error) {
- d.reject(stderr);
- } else {
- d.resolve(stdout);
- }
- });
+ console.log(versions[0]);
+ });
+}
- return d.promise.then(function (output) {
- var regex = /[0-9]*\.[0-9]*/;
- var versions = [];
- var regexOSX = /^OS X \d+/;
- output = output.split('\n');
- for (var i = 0; i < output.length; i++) {
- if (output[i].trim().match(regexOSX)) {
- versions[versions.length] = parseFloat(output[i].match(regex)[0]);
- }
- }
- versions.sort();
- console.log(versions[0]);
- return Q();
- }, function (stderr) {
- return Q.reject(stderr);
- });
+exports.get_apple_ios_version = () => {
+ return fetchSdkVersionByType('iOS');
};
-exports.get_apple_xcode_version = function () {
- var d = Q.defer();
- child_process.exec('xcodebuild -version', function (error, stdout, stderr) {
- var versionMatch = /Xcode (.*)/.exec(stdout);
- if (error || !versionMatch) {
- d.reject(stderr);
- } else {
- d.resolve(versionMatch[1]);
- }
- });
- return d.promise;
+exports.get_apple_osx_version = () => {
+ return fetchSdkVersionByType('macOS');
+};
+
+exports.get_apple_xcode_version = () => {
+ return spawn('xcodebuild', ['-version'])
+ .then(output => {
+ const versionMatch = /Xcode (.*)/.exec(output);
+
+ if (!versionMatch) return Promise.reject(output);
+
+ return versionMatch[1];
+ });
};
/**
@@ -96,16 +61,8 @@ exports.get_apple_xcode_version = function () {
* @return {Promise} Promise that either resolved with ios-deploy version
* or rejected in case of error
*/
-exports.get_ios_deploy_version = function () {
- var d = Q.defer();
- child_process.exec('ios-deploy --version', function (error, stdout, stderr) {
- if (error) {
- d.reject(stderr);
- } else {
- d.resolve(stdout);
- }
- });
- return d.promise;
+exports.get_ios_deploy_version = () => {
+ return spawn('ios-deploy', ['--version']);
};
/**
@@ -113,16 +70,8 @@ exports.get_ios_deploy_version = function () {
* @return {Promise} Promise that either resolved with pod version
* or rejected in case of error
*/
-exports.get_cocoapods_version = function () {
- var d = Q.defer();
- child_process.exec('pod --version', function (error, stdout, stderr) {
- if (error) {
- d.reject(stderr);
- } else {
- d.resolve(stdout);
- }
- });
- return d.promise;
+exports.get_cocoapods_version = () => {
+ return spawn('pod', ['--version']);
};
/**
@@ -130,16 +79,8 @@ exports.get_cocoapods_version = function () {
* @return {Promise} Promise that either resolved with ios-sim version
* or rejected in case of error
*/
-exports.get_ios_sim_version = function () {
- var d = Q.defer();
- child_process.exec('ios-sim --version', function (error, stdout, stderr) {
- if (error) {
- d.reject(stderr);
- } else {
- d.resolve(stdout);
- }
- });
- return d.promise;
+exports.get_ios_sim_version = () => {
+ return spawn('ios-sim', ['--version']);
};
/**
@@ -148,47 +89,31 @@ exports.get_ios_sim_version = function () {
* @return {Promise} Promise that either resolved with tool version
* or rejected in case of error
*/
-exports.get_tool_version = function (toolName) {
+exports.get_tool_version = toolName => {
switch (toolName) {
case 'xcodebuild': return exports.get_apple_xcode_version();
case 'ios-sim': return exports.get_ios_sim_version();
case 'ios-deploy': return exports.get_ios_deploy_version();
case 'pod': return exports.get_cocoapods_version();
- default: return Q.reject(toolName + ' is not valid tool name. Valid names are: \'xcodebuild\', \'ios-sim\', \'ios-deploy\', and \'pod\'');
+ default: return Promise.reject(new CordovaError(`${toolName} is not valid tool name. Valid names are: 'xcodebuild', 'ios-sim', 'ios-deploy', and 'pod'`));
}
};
/**
- * Compares two semver-notated version strings. Returns number
- * that indicates equality of provided version strings.
+ * Compares two version strings that can be coerced to semver.
+ *
* @param {String} version1 Version to compare
* @param {String} version2 Another version to compare
* @return {Number} Negative number if first version is lower than the second,
* positive otherwise and 0 if versions are equal.
*/
-exports.compareVersions = function (version1, version2) {
- function parseVer (version) {
- return version.split('.').map(function (value) {
- // try to convert version segment to Number
- var parsed = Number(value);
- // Number constructor is strict enough and will return NaN
- // if conversion fails. In this case we won't be able to compare versions properly
- if (isNaN(parsed)) {
- throw 'Version should contain only numbers and dots';
- }
- return parsed;
- });
- }
- var parsedVer1 = parseVer(version1);
- var parsedVer2 = parseVer(version2);
+exports.compareVersions = (...args) => {
+ const coerceToSemverIfInvalid = v => {
+ const semverVersion = semver.parse(v) || semver.coerce(v);
+ if (!semverVersion) throw new TypeError(`Invalid Version: ${v}`);
+ return semverVersion;
+ };
- // Compare corresponding segments of each version
- for (var i = 0; i < Math.max(parsedVer1.length, parsedVer2.length); i++) {
- // if segment is not specified, assume that it is 0
- // E.g. 3.1 is equal to 3.1.0
- var ret = (parsedVer1[i] || 0) - (parsedVer2[i] || 0);
- // if segments are not equal, we're finished
- if (ret !== 0) return ret;
- }
- return 0;
+ const semverVersions = args.map(coerceToSemverIfInvalid);
+ return semver.compare(...semverVersions);
};
diff --git a/StoneIsland/platforms/ios/cordova/loggingHelper.js b/StoneIsland/platforms/ios/cordova/loggingHelper.js
index e353399c..871b6cf3 100755..100644
--- a/StoneIsland/platforms/ios/cordova/loggingHelper.js
+++ b/StoneIsland/platforms/ios/cordova/loggingHelper.js
@@ -17,7 +17,7 @@
under the License.
*/
-var CordovaLogger = require('cordova-common').CordovaLogger;
+const CordovaLogger = require('cordova-common').CordovaLogger;
module.exports = {
adjustLoggerLevel: function (opts) {
diff --git a/StoneIsland/platforms/ios/cordova/node_modules/nopt/LICENSE b/StoneIsland/platforms/ios/cordova/node_modules/nopt/LICENSE
deleted file mode 100755
index 19129e31..00000000
--- a/StoneIsland/platforms/ios/cordova/node_modules/nopt/LICENSE
+++ /dev/null
@@ -1,15 +0,0 @@
-The ISC License
-
-Copyright (c) Isaac Z. Schlueter and Contributors
-
-Permission to use, copy, modify, and/or distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
-IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
diff --git a/StoneIsland/platforms/ios/cordova/node_modules/nopt/lib/nopt.js b/StoneIsland/platforms/ios/cordova/node_modules/nopt/lib/nopt.js
deleted file mode 100755
index 97707e78..00000000
--- a/StoneIsland/platforms/ios/cordova/node_modules/nopt/lib/nopt.js
+++ /dev/null
@@ -1,415 +0,0 @@
-// info about each config option.
-
-var debug = process.env.DEBUG_NOPT || process.env.NOPT_DEBUG
- ? function () { console.error.apply(console, arguments) }
- : function () {}
-
-var url = require("url")
- , path = require("path")
- , Stream = require("stream").Stream
- , abbrev = require("abbrev")
-
-module.exports = exports = nopt
-exports.clean = clean
-
-exports.typeDefs =
- { String : { type: String, validate: validateString }
- , Boolean : { type: Boolean, validate: validateBoolean }
- , url : { type: url, validate: validateUrl }
- , Number : { type: Number, validate: validateNumber }
- , path : { type: path, validate: validatePath }
- , Stream : { type: Stream, validate: validateStream }
- , Date : { type: Date, validate: validateDate }
- }
-
-function nopt (types, shorthands, args, slice) {
- args = args || process.argv
- types = types || {}
- shorthands = shorthands || {}
- if (typeof slice !== "number") slice = 2
-
- debug(types, shorthands, args, slice)
-
- args = args.slice(slice)
- var data = {}
- , key
- , remain = []
- , cooked = args
- , original = args.slice(0)
-
- parse(args, data, remain, types, shorthands)
- // now data is full
- clean(data, types, exports.typeDefs)
- data.argv = {remain:remain,cooked:cooked,original:original}
- Object.defineProperty(data.argv, 'toString', { value: function () {
- return this.original.map(JSON.stringify).join(" ")
- }, enumerable: false })
- return data
-}
-
-function clean (data, types, typeDefs) {
- typeDefs = typeDefs || exports.typeDefs
- var remove = {}
- , typeDefault = [false, true, null, String, Array]
-
- Object.keys(data).forEach(function (k) {
- if (k === "argv") return
- var val = data[k]
- , isArray = Array.isArray(val)
- , type = types[k]
- if (!isArray) val = [val]
- if (!type) type = typeDefault
- if (type === Array) type = typeDefault.concat(Array)
- if (!Array.isArray(type)) type = [type]
-
- debug("val=%j", val)
- debug("types=", type)
- val = val.map(function (val) {
- // if it's an unknown value, then parse false/true/null/numbers/dates
- if (typeof val === "string") {
- debug("string %j", val)
- val = val.trim()
- if ((val === "null" && ~type.indexOf(null))
- || (val === "true" &&
- (~type.indexOf(true) || ~type.indexOf(Boolean)))
- || (val === "false" &&
- (~type.indexOf(false) || ~type.indexOf(Boolean)))) {
- val = JSON.parse(val)
- debug("jsonable %j", val)
- } else if (~type.indexOf(Number) && !isNaN(val)) {
- debug("convert to number", val)
- val = +val
- } else if (~type.indexOf(Date) && !isNaN(Date.parse(val))) {
- debug("convert to date", val)
- val = new Date(val)
- }
- }
-
- if (!types.hasOwnProperty(k)) {
- return val
- }
-
- // allow `--no-blah` to set 'blah' to null if null is allowed
- if (val === false && ~type.indexOf(null) &&
- !(~type.indexOf(false) || ~type.indexOf(Boolean))) {
- val = null
- }
-
- var d = {}
- d[k] = val
- debug("prevalidated val", d, val, types[k])
- if (!validate(d, k, val, types[k], typeDefs)) {
- if (exports.invalidHandler) {
- exports.invalidHandler(k, val, types[k], data)
- } else if (exports.invalidHandler !== false) {
- debug("invalid: "+k+"="+val, types[k])
- }
- return remove
- }
- debug("validated val", d, val, types[k])
- return d[k]
- }).filter(function (val) { return val !== remove })
-
- if (!val.length) delete data[k]
- else if (isArray) {
- debug(isArray, data[k], val)
- data[k] = val
- } else data[k] = val[0]
-
- debug("k=%s val=%j", k, val, data[k])
- })
-}
-
-function validateString (data, k, val) {
- data[k] = String(val)
-}
-
-function validatePath (data, k, val) {
- if (val === true) return false
- if (val === null) return true
-
- val = String(val)
- var homePattern = process.platform === 'win32' ? /^~(\/|\\)/ : /^~\//
- if (val.match(homePattern) && process.env.HOME) {
- val = path.resolve(process.env.HOME, val.substr(2))
- }
- data[k] = path.resolve(String(val))
- return true
-}
-
-function validateNumber (data, k, val) {
- debug("validate Number %j %j %j", k, val, isNaN(val))
- if (isNaN(val)) return false
- data[k] = +val
-}
-
-function validateDate (data, k, val) {
- debug("validate Date %j %j %j", k, val, Date.parse(val))
- var s = Date.parse(val)
- if (isNaN(s)) return false
- data[k] = new Date(val)
-}
-
-function validateBoolean (data, k, val) {
- if (val instanceof Boolean) val = val.valueOf()
- else if (typeof val === "string") {
- if (!isNaN(val)) val = !!(+val)
- else if (val === "null" || val === "false") val = false
- else val = true
- } else val = !!val
- data[k] = val
-}
-
-function validateUrl (data, k, val) {
- val = url.parse(String(val))
- if (!val.host) return false
- data[k] = val.href
-}
-
-function validateStream (data, k, val) {
- if (!(val instanceof Stream)) return false
- data[k] = val
-}
-
-function validate (data, k, val, type, typeDefs) {
- // arrays are lists of types.
- if (Array.isArray(type)) {
- for (var i = 0, l = type.length; i < l; i ++) {
- if (type[i] === Array) continue
- if (validate(data, k, val, type[i], typeDefs)) return true
- }
- delete data[k]
- return false
- }
-
- // an array of anything?
- if (type === Array) return true
-
- // NaN is poisonous. Means that something is not allowed.
- if (type !== type) {
- debug("Poison NaN", k, val, type)
- delete data[k]
- return false
- }
-
- // explicit list of values
- if (val === type) {
- debug("Explicitly allowed %j", val)
- // if (isArray) (data[k] = data[k] || []).push(val)
- // else data[k] = val
- data[k] = val
- return true
- }
-
- // now go through the list of typeDefs, validate against each one.
- var ok = false
- , types = Object.keys(typeDefs)
- for (var i = 0, l = types.length; i < l; i ++) {
- debug("test type %j %j %j", k, val, types[i])
- var t = typeDefs[types[i]]
- if (t &&
- ((type && type.name && t.type && t.type.name) ? (type.name === t.type.name) : (type === t.type))) {
- var d = {}
- ok = false !== t.validate(d, k, val)
- val = d[k]
- if (ok) {
- // if (isArray) (data[k] = data[k] || []).push(val)
- // else data[k] = val
- data[k] = val
- break
- }
- }
- }
- debug("OK? %j (%j %j %j)", ok, k, val, types[i])
-
- if (!ok) delete data[k]
- return ok
-}
-
-function parse (args, data, remain, types, shorthands) {
- debug("parse", args, data, remain)
-
- var key = null
- , abbrevs = abbrev(Object.keys(types))
- , shortAbbr = abbrev(Object.keys(shorthands))
-
- for (var i = 0; i < args.length; i ++) {
- var arg = args[i]
- debug("arg", arg)
-
- if (arg.match(/^-{2,}$/)) {
- // done with keys.
- // the rest are args.
- remain.push.apply(remain, args.slice(i + 1))
- args[i] = "--"
- break
- }
- var hadEq = false
- if (arg.charAt(0) === "-" && arg.length > 1) {
- if (arg.indexOf("=") !== -1) {
- hadEq = true
- var v = arg.split("=")
- arg = v.shift()
- v = v.join("=")
- args.splice.apply(args, [i, 1].concat([arg, v]))
- }
-
- // see if it's a shorthand
- // if so, splice and back up to re-parse it.
- var shRes = resolveShort(arg, shorthands, shortAbbr, abbrevs)
- debug("arg=%j shRes=%j", arg, shRes)
- if (shRes) {
- debug(arg, shRes)
- args.splice.apply(args, [i, 1].concat(shRes))
- if (arg !== shRes[0]) {
- i --
- continue
- }
- }
- arg = arg.replace(/^-+/, "")
- var no = null
- while (arg.toLowerCase().indexOf("no-") === 0) {
- no = !no
- arg = arg.substr(3)
- }
-
- if (abbrevs[arg]) arg = abbrevs[arg]
-
- var isArray = types[arg] === Array ||
- Array.isArray(types[arg]) && types[arg].indexOf(Array) !== -1
-
- // allow unknown things to be arrays if specified multiple times.
- if (!types.hasOwnProperty(arg) && data.hasOwnProperty(arg)) {
- if (!Array.isArray(data[arg]))
- data[arg] = [data[arg]]
- isArray = true
- }
-
- var val
- , la = args[i + 1]
-
- var isBool = typeof no === 'boolean' ||
- types[arg] === Boolean ||
- Array.isArray(types[arg]) && types[arg].indexOf(Boolean) !== -1 ||
- (typeof types[arg] === 'undefined' && !hadEq) ||
- (la === "false" &&
- (types[arg] === null ||
- Array.isArray(types[arg]) && ~types[arg].indexOf(null)))
-
- if (isBool) {
- // just set and move along
- val = !no
- // however, also support --bool true or --bool false
- if (la === "true" || la === "false") {
- val = JSON.parse(la)
- la = null
- if (no) val = !val
- i ++
- }
-
- // also support "foo":[Boolean, "bar"] and "--foo bar"
- if (Array.isArray(types[arg]) && la) {
- if (~types[arg].indexOf(la)) {
- // an explicit type
- val = la
- i ++
- } else if ( la === "null" && ~types[arg].indexOf(null) ) {
- // null allowed
- val = null
- i ++
- } else if ( !la.match(/^-{2,}[^-]/) &&
- !isNaN(la) &&
- ~types[arg].indexOf(Number) ) {
- // number
- val = +la
- i ++
- } else if ( !la.match(/^-[^-]/) && ~types[arg].indexOf(String) ) {
- // string
- val = la
- i ++
- }
- }
-
- if (isArray) (data[arg] = data[arg] || []).push(val)
- else data[arg] = val
-
- continue
- }
-
- if (types[arg] === String && la === undefined)
- la = ""
-
- if (la && la.match(/^-{2,}$/)) {
- la = undefined
- i --
- }
-
- val = la === undefined ? true : la
- if (isArray) (data[arg] = data[arg] || []).push(val)
- else data[arg] = val
-
- i ++
- continue
- }
- remain.push(arg)
- }
-}
-
-function resolveShort (arg, shorthands, shortAbbr, abbrevs) {
- // handle single-char shorthands glommed together, like
- // npm ls -glp, but only if there is one dash, and only if
- // all of the chars are single-char shorthands, and it's
- // not a match to some other abbrev.
- arg = arg.replace(/^-+/, '')
-
- // if it's an exact known option, then don't go any further
- if (abbrevs[arg] === arg)
- return null
-
- // if it's an exact known shortopt, same deal
- if (shorthands[arg]) {
- // make it an array, if it's a list of words
- if (shorthands[arg] && !Array.isArray(shorthands[arg]))
- shorthands[arg] = shorthands[arg].split(/\s+/)
-
- return shorthands[arg]
- }
-
- // first check to see if this arg is a set of single-char shorthands
- var singles = shorthands.___singles
- if (!singles) {
- singles = Object.keys(shorthands).filter(function (s) {
- return s.length === 1
- }).reduce(function (l,r) {
- l[r] = true
- return l
- }, {})
- shorthands.___singles = singles
- debug('shorthand singles', singles)
- }
-
- var chrs = arg.split("").filter(function (c) {
- return singles[c]
- })
-
- if (chrs.join("") === arg) return chrs.map(function (c) {
- return shorthands[c]
- }).reduce(function (l, r) {
- return l.concat(r)
- }, [])
-
-
- // if it's an arg abbrev, and not a literal shorthand, then prefer the arg
- if (abbrevs[arg] && !shorthands[arg])
- return null
-
- // if it's an abbr for a shorthand, then use that
- if (shortAbbr[arg])
- arg = shortAbbr[arg]
-
- // make it an array, if it's a list of words
- if (shorthands[arg] && !Array.isArray(shorthands[arg]))
- shorthands[arg] = shorthands[arg].split(/\s+/)
-
- return shorthands[arg]
-}
diff --git a/StoneIsland/platforms/ios/cordova/node_modules/nopt/package.json b/StoneIsland/platforms/ios/cordova/node_modules/nopt/package.json
deleted file mode 100755
index 3784dfb3..00000000
--- a/StoneIsland/platforms/ios/cordova/node_modules/nopt/package.json
+++ /dev/null
@@ -1,57 +0,0 @@
-{
- "_from": "nopt@^3.0.6",
- "_id": "nopt@3.0.6",
- "_inBundle": true,
- "_integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=",
- "_location": "/cordova-ios/nopt",
- "_phantomChildren": {},
- "_requested": {
- "type": "range",
- "registry": true,
- "raw": "nopt@^3.0.6",
- "name": "nopt",
- "escapedName": "nopt",
- "rawSpec": "^3.0.6",
- "saveSpec": null,
- "fetchSpec": "^3.0.6"
- },
- "_requiredBy": [
- "/cordova-ios"
- ],
- "_resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz",
- "_shasum": "c6465dbf08abcd4db359317f79ac68a646b28ff9",
- "_spec": "nopt@^3.0.6",
- "_where": "/Users/spindori/Documents/Cordova/cordova-ios",
- "author": {
- "name": "Isaac Z. Schlueter",
- "email": "i@izs.me",
- "url": "http://blog.izs.me/"
- },
- "bin": {
- "nopt": "./bin/nopt.js"
- },
- "bugs": {
- "url": "https://github.com/npm/nopt/issues"
- },
- "bundleDependencies": false,
- "dependencies": {
- "abbrev": "1"
- },
- "deprecated": false,
- "description": "Option parsing for Node, supporting types, shorthands, etc. Used by npm.",
- "devDependencies": {
- "tap": "^1.2.0"
- },
- "homepage": "https://github.com/npm/nopt#readme",
- "license": "ISC",
- "main": "lib/nopt.js",
- "name": "nopt",
- "repository": {
- "type": "git",
- "url": "git+https://github.com/npm/nopt.git"
- },
- "scripts": {
- "test": "tap test/*.js"
- },
- "version": "3.0.6"
-}
diff --git a/StoneIsland/platforms/ios/cordova/node_modules/q/LICENSE b/StoneIsland/platforms/ios/cordova/node_modules/q/LICENSE
deleted file mode 100755
index 9ce1ea59..00000000
--- a/StoneIsland/platforms/ios/cordova/node_modules/q/LICENSE
+++ /dev/null
@@ -1,18 +0,0 @@
-Copyright 2009–2017 Kristopher Michael Kowal. All rights reserved.
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to
-deal in the Software without restriction, including without limitation the
-rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
-sell copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-IN THE SOFTWARE.
diff --git a/StoneIsland/platforms/ios/cordova/node_modules/q/package.json b/StoneIsland/platforms/ios/cordova/node_modules/q/package.json
deleted file mode 100755
index 30e1b1b8..00000000
--- a/StoneIsland/platforms/ios/cordova/node_modules/q/package.json
+++ /dev/null
@@ -1,117 +0,0 @@
-{
- "_from": "q@^1.4.1",
- "_id": "q@1.5.0",
- "_inBundle": true,
- "_integrity": "sha1-3QG6ydBtMObyGa7LglPunr3DCPE=",
- "_location": "/cordova-ios/q",
- "_phantomChildren": {},
- "_requested": {
- "type": "range",
- "registry": true,
- "raw": "q@^1.4.1",
- "name": "q",
- "escapedName": "q",
- "rawSpec": "^1.4.1",
- "saveSpec": null,
- "fetchSpec": "^1.4.1"
- },
- "_requiredBy": [
- "/cordova-ios",
- "/cordova-ios/cordova-common"
- ],
- "_resolved": "https://registry.npmjs.org/q/-/q-1.5.0.tgz",
- "_shasum": "dd01bac9d06d30e6f219aecb8253ee9ebdc308f1",
- "_spec": "q@^1.4.1",
- "_where": "/Users/spindori/Documents/Cordova/cordova-ios",
- "author": {
- "name": "Kris Kowal",
- "email": "kris@cixar.com",
- "url": "https://github.com/kriskowal"
- },
- "bugs": {
- "url": "http://github.com/kriskowal/q/issues"
- },
- "bundleDependencies": false,
- "contributors": [
- {
- "name": "Kris Kowal",
- "email": "kris@cixar.com",
- "url": "https://github.com/kriskowal"
- },
- {
- "name": "Irakli Gozalishvili",
- "email": "rfobic@gmail.com",
- "url": "http://jeditoolkit.com"
- },
- {
- "name": "Domenic Denicola",
- "email": "domenic@domenicdenicola.com",
- "url": "http://domenicdenicola.com"
- }
- ],
- "dependencies": {},
- "deprecated": false,
- "description": "A library for promises (CommonJS/Promises/A,B,D)",
- "devDependencies": {
- "cover": "*",
- "grunt": "~0.4.1",
- "grunt-cli": "~0.1.9",
- "grunt-contrib-uglify": "~0.9.1",
- "jasmine-node": "1.11.0",
- "jshint": "~2.1.9",
- "matcha": "~0.2.0",
- "opener": "*",
- "promises-aplus-tests": "1.x"
- },
- "directories": {
- "test": "./spec"
- },
- "engines": {
- "node": ">=0.6.0",
- "teleport": ">=0.2.0"
- },
- "files": [
- "LICENSE",
- "q.js",
- "queue.js"
- ],
- "homepage": "https://github.com/kriskowal/q",
- "keywords": [
- "q",
- "promise",
- "promises",
- "promises-a",
- "promises-aplus",
- "deferred",
- "future",
- "async",
- "flow control",
- "fluent",
- "browser",
- "node"
- ],
- "license": "MIT",
- "main": "q.js",
- "name": "q",
- "overlay": {
- "teleport": {
- "dependencies": {
- "system": ">=0.0.4"
- }
- }
- },
- "repository": {
- "type": "git",
- "url": "git://github.com/kriskowal/q.git"
- },
- "scripts": {
- "benchmark": "matcha",
- "cover": "cover run jasmine-node spec && cover report html && opener cover_html/index.html",
- "lint": "jshint q.js",
- "minify": "grunt",
- "prepublish": "grunt",
- "test": "npm ls -s && jasmine-node spec && promises-aplus-tests spec/aplus-adapter && npm run -s lint",
- "test-browser": "opener spec/q-spec.html"
- },
- "version": "1.5.0"
-}
diff --git a/StoneIsland/platforms/ios/cordova/node_modules/q/q.js b/StoneIsland/platforms/ios/cordova/node_modules/q/q.js
deleted file mode 100755
index 14dc24a6..00000000
--- a/StoneIsland/platforms/ios/cordova/node_modules/q/q.js
+++ /dev/null
@@ -1,2073 +0,0 @@
-// vim:ts=4:sts=4:sw=4:
-/*!
- *
- * Copyright 2009-2017 Kris Kowal under the terms of the MIT
- * license found at https://github.com/kriskowal/q/blob/v1/LICENSE
- *
- * With parts by Tyler Close
- * Copyright 2007-2009 Tyler Close under the terms of the MIT X license found
- * at http://www.opensource.org/licenses/mit-license.html
- * Forked at ref_send.js version: 2009-05-11
- *
- * With parts by Mark Miller
- * Copyright (C) 2011 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-(function (definition) {
- "use strict";
-
- // This file will function properly as a <script> tag, or a module
- // using CommonJS and NodeJS or RequireJS module formats. In
- // Common/Node/RequireJS, the module exports the Q API and when
- // executed as a simple <script>, it creates a Q global instead.
-
- // Montage Require
- if (typeof bootstrap === "function") {
- bootstrap("promise", definition);
-
- // CommonJS
- } else if (typeof exports === "object" && typeof module === "object") {
- module.exports = definition();
-
- // RequireJS
- } else if (typeof define === "function" && define.amd) {
- define(definition);
-
- // SES (Secure EcmaScript)
- } else if (typeof ses !== "undefined") {
- if (!ses.ok()) {
- return;
- } else {
- ses.makeQ = definition;
- }
-
- // <script>
- } else if (typeof window !== "undefined" || typeof self !== "undefined") {
- // Prefer window over self for add-on scripts. Use self for
- // non-windowed contexts.
- var global = typeof window !== "undefined" ? window : self;
-
- // Get the `window` object, save the previous Q global
- // and initialize Q as a global.
- var previousQ = global.Q;
- global.Q = definition();
-
- // Add a noConflict function so Q can be removed from the
- // global namespace.
- global.Q.noConflict = function () {
- global.Q = previousQ;
- return this;
- };
-
- } else {
- throw new Error("This environment was not anticipated by Q. Please file a bug.");
- }
-
-})(function () {
-"use strict";
-
-var hasStacks = false;
-try {
- throw new Error();
-} catch (e) {
- hasStacks = !!e.stack;
-}
-
-// All code after this point will be filtered from stack traces reported
-// by Q.
-var qStartingLine = captureLine();
-var qFileName;
-
-// shims
-
-// used for fallback in "allResolved"
-var noop = function () {};
-
-// Use the fastest possible means to execute a task in a future turn
-// of the event loop.
-var nextTick =(function () {
- // linked list of tasks (single, with head node)
- var head = {task: void 0, next: null};
- var tail = head;
- var flushing = false;
- var requestTick = void 0;
- var isNodeJS = false;
- // queue for late tasks, used by unhandled rejection tracking
- var laterQueue = [];
-
- function flush() {
- /* jshint loopfunc: true */
- var task, domain;
-
- while (head.next) {
- head = head.next;
- task = head.task;
- head.task = void 0;
- domain = head.domain;
-
- if (domain) {
- head.domain = void 0;
- domain.enter();
- }
- runSingle(task, domain);
-
- }
- while (laterQueue.length) {
- task = laterQueue.pop();
- runSingle(task);
- }
- flushing = false;
- }
- // runs a single function in the async queue
- function runSingle(task, domain) {
- try {
- task();
-
- } catch (e) {
- if (isNodeJS) {
- // In node, uncaught exceptions are considered fatal errors.
- // Re-throw them synchronously to interrupt flushing!
-
- // Ensure continuation if the uncaught exception is suppressed
- // listening "uncaughtException" events (as domains does).
- // Continue in next event to avoid tick recursion.
- if (domain) {
- domain.exit();
- }
- setTimeout(flush, 0);
- if (domain) {
- domain.enter();
- }
-
- throw e;
-
- } else {
- // In browsers, uncaught exceptions are not fatal.
- // Re-throw them asynchronously to avoid slow-downs.
- setTimeout(function () {
- throw e;
- }, 0);
- }
- }
-
- if (domain) {
- domain.exit();
- }
- }
-
- nextTick = function (task) {
- tail = tail.next = {
- task: task,
- domain: isNodeJS && process.domain,
- next: null
- };
-
- if (!flushing) {
- flushing = true;
- requestTick();
- }
- };
-
- if (typeof process === "object" &&
- process.toString() === "[object process]" && process.nextTick) {
- // Ensure Q is in a real Node environment, with a `process.nextTick`.
- // To see through fake Node environments:
- // * Mocha test runner - exposes a `process` global without a `nextTick`
- // * Browserify - exposes a `process.nexTick` function that uses
- // `setTimeout`. In this case `setImmediate` is preferred because
- // it is faster. Browserify's `process.toString()` yields
- // "[object Object]", while in a real Node environment
- // `process.toString()` yields "[object process]".
- isNodeJS = true;
-
- requestTick = function () {
- process.nextTick(flush);
- };
-
- } else if (typeof setImmediate === "function") {
- // In IE10, Node.js 0.9+, or https://github.com/NobleJS/setImmediate
- if (typeof window !== "undefined") {
- requestTick = setImmediate.bind(window, flush);
- } else {
- requestTick = function () {
- setImmediate(flush);
- };
- }
-
- } else if (typeof MessageChannel !== "undefined") {
- // modern browsers
- // http://www.nonblocking.io/2011/06/windownexttick.html
- var channel = new MessageChannel();
- // At least Safari Version 6.0.5 (8536.30.1) intermittently cannot create
- // working message ports the first time a page loads.
- channel.port1.onmessage = function () {
- requestTick = requestPortTick;
- channel.port1.onmessage = flush;
- flush();
- };
- var requestPortTick = function () {
- // Opera requires us to provide a message payload, regardless of
- // whether we use it.
- channel.port2.postMessage(0);
- };
- requestTick = function () {
- setTimeout(flush, 0);
- requestPortTick();
- };
-
- } else {
- // old browsers
- requestTick = function () {
- setTimeout(flush, 0);
- };
- }
- // runs a task after all other tasks have been run
- // this is useful for unhandled rejection tracking that needs to happen
- // after all `then`d tasks have been run.
- nextTick.runAfter = function (task) {
- laterQueue.push(task);
- if (!flushing) {
- flushing = true;
- requestTick();
- }
- };
- return nextTick;
-})();
-
-// Attempt to make generics safe in the face of downstream
-// modifications.
-// There is no situation where this is necessary.
-// If you need a security guarantee, these primordials need to be
-// deeply frozen anyway, and if you don’t need a security guarantee,
-// this is just plain paranoid.
-// However, this **might** have the nice side-effect of reducing the size of
-// the minified code by reducing x.call() to merely x()
-// See Mark Miller’s explanation of what this does.
-// http://wiki.ecmascript.org/doku.php?id=conventions:safe_meta_programming
-var call = Function.call;
-function uncurryThis(f) {
- return function () {
- return call.apply(f, arguments);
- };
-}
-// This is equivalent, but slower:
-// uncurryThis = Function_bind.bind(Function_bind.call);
-// http://jsperf.com/uncurrythis
-
-var array_slice = uncurryThis(Array.prototype.slice);
-
-var array_reduce = uncurryThis(
- Array.prototype.reduce || function (callback, basis) {
- var index = 0,
- length = this.length;
- // concerning the initial value, if one is not provided
- if (arguments.length === 1) {
- // seek to the first value in the array, accounting
- // for the possibility that is is a sparse array
- do {
- if (index in this) {
- basis = this[index++];
- break;
- }
- if (++index >= length) {
- throw new TypeError();
- }
- } while (1);
- }
- // reduce
- for (; index < length; index++) {
- // account for the possibility that the array is sparse
- if (index in this) {
- basis = callback(basis, this[index], index);
- }
- }
- return basis;
- }
-);
-
-var array_indexOf = uncurryThis(
- Array.prototype.indexOf || function (value) {
- // not a very good shim, but good enough for our one use of it
- for (var i = 0; i < this.length; i++) {
- if (this[i] === value) {
- return i;
- }
- }
- return -1;
- }
-);
-
-var array_map = uncurryThis(
- Array.prototype.map || function (callback, thisp) {
- var self = this;
- var collect = [];
- array_reduce(self, function (undefined, value, index) {
- collect.push(callback.call(thisp, value, index, self));
- }, void 0);
- return collect;
- }
-);
-
-var object_create = Object.create || function (prototype) {
- function Type() { }
- Type.prototype = prototype;
- return new Type();
-};
-
-var object_defineProperty = Object.defineProperty || function (obj, prop, descriptor) {
- obj[prop] = descriptor.value;
- return obj;
-};
-
-var object_hasOwnProperty = uncurryThis(Object.prototype.hasOwnProperty);
-
-var object_keys = Object.keys || function (object) {
- var keys = [];
- for (var key in object) {
- if (object_hasOwnProperty(object, key)) {
- keys.push(key);
- }
- }
- return keys;
-};
-
-var object_toString = uncurryThis(Object.prototype.toString);
-
-function isObject(value) {
- return value === Object(value);
-}
-
-// generator related shims
-
-// FIXME: Remove this function once ES6 generators are in SpiderMonkey.
-function isStopIteration(exception) {
- return (
- object_toString(exception) === "[object StopIteration]" ||
- exception instanceof QReturnValue
- );
-}
-
-// FIXME: Remove this helper and Q.return once ES6 generators are in
-// SpiderMonkey.
-var QReturnValue;
-if (typeof ReturnValue !== "undefined") {
- QReturnValue = ReturnValue;
-} else {
- QReturnValue = function (value) {
- this.value = value;
- };
-}
-
-// long stack traces
-
-var STACK_JUMP_SEPARATOR = "From previous event:";
-
-function makeStackTraceLong(error, promise) {
- // If possible, transform the error stack trace by removing Node and Q
- // cruft, then concatenating with the stack trace of `promise`. See #57.
- if (hasStacks &&
- promise.stack &&
- typeof error === "object" &&
- error !== null &&
- error.stack
- ) {
- var stacks = [];
- for (var p = promise; !!p; p = p.source) {
- if (p.stack && (!error.__minimumStackCounter__ || error.__minimumStackCounter__ > p.stackCounter)) {
- object_defineProperty(error, "__minimumStackCounter__", {value: p.stackCounter, configurable: true});
- stacks.unshift(p.stack);
- }
- }
- stacks.unshift(error.stack);
-
- var concatedStacks = stacks.join("\n" + STACK_JUMP_SEPARATOR + "\n");
- var stack = filterStackString(concatedStacks);
- object_defineProperty(error, "stack", {value: stack, configurable: true});
- }
-}
-
-function filterStackString(stackString) {
- var lines = stackString.split("\n");
- var desiredLines = [];
- for (var i = 0; i < lines.length; ++i) {
- var line = lines[i];
-
- if (!isInternalFrame(line) && !isNodeFrame(line) && line) {
- desiredLines.push(line);
- }
- }
- return desiredLines.join("\n");
-}
-
-function isNodeFrame(stackLine) {
- return stackLine.indexOf("(module.js:") !== -1 ||
- stackLine.indexOf("(node.js:") !== -1;
-}
-
-function getFileNameAndLineNumber(stackLine) {
- // Named functions: "at functionName (filename:lineNumber:columnNumber)"
- // In IE10 function name can have spaces ("Anonymous function") O_o
- var attempt1 = /at .+ \((.+):(\d+):(?:\d+)\)$/.exec(stackLine);
- if (attempt1) {
- return [attempt1[1], Number(attempt1[2])];
- }
-
- // Anonymous functions: "at filename:lineNumber:columnNumber"
- var attempt2 = /at ([^ ]+):(\d+):(?:\d+)$/.exec(stackLine);
- if (attempt2) {
- return [attempt2[1], Number(attempt2[2])];
- }
-
- // Firefox style: "function@filename:lineNumber or @filename:lineNumber"
- var attempt3 = /.*@(.+):(\d+)$/.exec(stackLine);
- if (attempt3) {
- return [attempt3[1], Number(attempt3[2])];
- }
-}
-
-function isInternalFrame(stackLine) {
- var fileNameAndLineNumber = getFileNameAndLineNumber(stackLine);
-
- if (!fileNameAndLineNumber) {
- return false;
- }
-
- var fileName = fileNameAndLineNumber[0];
- var lineNumber = fileNameAndLineNumber[1];
-
- return fileName === qFileName &&
- lineNumber >= qStartingLine &&
- lineNumber <= qEndingLine;
-}
-
-// discover own file name and line number range for filtering stack
-// traces
-function captureLine() {
- if (!hasStacks) {
- return;
- }
-
- try {
- throw new Error();
- } catch (e) {
- var lines = e.stack.split("\n");
- var firstLine = lines[0].indexOf("@") > 0 ? lines[1] : lines[2];
- var fileNameAndLineNumber = getFileNameAndLineNumber(firstLine);
- if (!fileNameAndLineNumber) {
- return;
- }
-
- qFileName = fileNameAndLineNumber[0];
- return fileNameAndLineNumber[1];
- }
-}
-
-function deprecate(callback, name, alternative) {
- return function () {
- if (typeof console !== "undefined" &&
- typeof console.warn === "function") {
- console.warn(name + " is deprecated, use " + alternative +
- " instead.", new Error("").stack);
- }
- return callback.apply(callback, arguments);
- };
-}
-
-// end of shims
-// beginning of real work
-
-/**
- * Constructs a promise for an immediate reference, passes promises through, or
- * coerces promises from different systems.
- * @param value immediate reference or promise
- */
-function Q(value) {
- // If the object is already a Promise, return it directly. This enables
- // the resolve function to both be used to created references from objects,
- // but to tolerably coerce non-promises to promises.
- if (value instanceof Promise) {
- return value;
- }
-
- // assimilate thenables
- if (isPromiseAlike(value)) {
- return coerce(value);
- } else {
- return fulfill(value);
- }
-}
-Q.resolve = Q;
-
-/**
- * Performs a task in a future turn of the event loop.
- * @param {Function} task
- */
-Q.nextTick = nextTick;
-
-/**
- * Controls whether or not long stack traces will be on
- */
-Q.longStackSupport = false;
-
-/**
- * The counter is used to determine the stopping point for building
- * long stack traces. In makeStackTraceLong we walk backwards through
- * the linked list of promises, only stacks which were created before
- * the rejection are concatenated.
- */
-var longStackCounter = 1;
-
-// enable long stacks if Q_DEBUG is set
-if (typeof process === "object" && process && process.env && process.env.Q_DEBUG) {
- Q.longStackSupport = true;
-}
-
-/**
- * Constructs a {promise, resolve, reject} object.
- *
- * `resolve` is a callback to invoke with a more resolved value for the
- * promise. To fulfill the promise, invoke `resolve` with any value that is
- * not a thenable. To reject the promise, invoke `resolve` with a rejected
- * thenable, or invoke `reject` with the reason directly. To resolve the
- * promise to another thenable, thus putting it in the same state, invoke
- * `resolve` with that other thenable.
- */
-Q.defer = defer;
-function defer() {
- // if "messages" is an "Array", that indicates that the promise has not yet
- // been resolved. If it is "undefined", it has been resolved. Each
- // element of the messages array is itself an array of complete arguments to
- // forward to the resolved promise. We coerce the resolution value to a
- // promise using the `resolve` function because it handles both fully
- // non-thenable values and other thenables gracefully.
- var messages = [], progressListeners = [], resolvedPromise;
-
- var deferred = object_create(defer.prototype);
- var promise = object_create(Promise.prototype);
-
- promise.promiseDispatch = function (resolve, op, operands) {
- var args = array_slice(arguments);
- if (messages) {
- messages.push(args);
- if (op === "when" && operands[1]) { // progress operand
- progressListeners.push(operands[1]);
- }
- } else {
- Q.nextTick(function () {
- resolvedPromise.promiseDispatch.apply(resolvedPromise, args);
- });
- }
- };
-
- // XXX deprecated
- promise.valueOf = function () {
- if (messages) {
- return promise;
- }
- var nearerValue = nearer(resolvedPromise);
- if (isPromise(nearerValue)) {
- resolvedPromise = nearerValue; // shorten chain
- }
- return nearerValue;
- };
-
- promise.inspect = function () {
- if (!resolvedPromise) {
- return { state: "pending" };
- }
- return resolvedPromise.inspect();
- };
-
- if (Q.longStackSupport && hasStacks) {
- try {
- throw new Error();
- } catch (e) {
- // NOTE: don't try to use `Error.captureStackTrace` or transfer the
- // accessor around; that causes memory leaks as per GH-111. Just
- // reify the stack trace as a string ASAP.
- //
- // At the same time, cut off the first line; it's always just
- // "[object Promise]\n", as per the `toString`.
- promise.stack = e.stack.substring(e.stack.indexOf("\n") + 1);
- promise.stackCounter = longStackCounter++;
- }
- }
-
- // NOTE: we do the checks for `resolvedPromise` in each method, instead of
- // consolidating them into `become`, since otherwise we'd create new
- // promises with the lines `become(whatever(value))`. See e.g. GH-252.
-
- function become(newPromise) {
- resolvedPromise = newPromise;
-
- if (Q.longStackSupport && hasStacks) {
- // Only hold a reference to the new promise if long stacks
- // are enabled to reduce memory usage
- promise.source = newPromise;
- }
-
- array_reduce(messages, function (undefined, message) {
- Q.nextTick(function () {
- newPromise.promiseDispatch.apply(newPromise, message);
- });
- }, void 0);
-
- messages = void 0;
- progressListeners = void 0;
- }
-
- deferred.promise = promise;
- deferred.resolve = function (value) {
- if (resolvedPromise) {
- return;
- }
-
- become(Q(value));
- };
-
- deferred.fulfill = function (value) {
- if (resolvedPromise) {
- return;
- }
-
- become(fulfill(value));
- };
- deferred.reject = function (reason) {
- if (resolvedPromise) {
- return;
- }
-
- become(reject(reason));
- };
- deferred.notify = function (progress) {
- if (resolvedPromise) {
- return;
- }
-
- array_reduce(progressListeners, function (undefined, progressListener) {
- Q.nextTick(function () {
- progressListener(progress);
- });
- }, void 0);
- };
-
- return deferred;
-}
-
-/**
- * Creates a Node-style callback that will resolve or reject the deferred
- * promise.
- * @returns a nodeback
- */
-defer.prototype.makeNodeResolver = function () {
- var self = this;
- return function (error, value) {
- if (error) {
- self.reject(error);
- } else if (arguments.length > 2) {
- self.resolve(array_slice(arguments, 1));
- } else {
- self.resolve(value);
- }
- };
-};
-
-/**
- * @param resolver {Function} a function that returns nothing and accepts
- * the resolve, reject, and notify functions for a deferred.
- * @returns a promise that may be resolved with the given resolve and reject
- * functions, or rejected by a thrown exception in resolver
- */
-Q.Promise = promise; // ES6
-Q.promise = promise;
-function promise(resolver) {
- if (typeof resolver !== "function") {
- throw new TypeError("resolver must be a function.");
- }
- var deferred = defer();
- try {
- resolver(deferred.resolve, deferred.reject, deferred.notify);
- } catch (reason) {
- deferred.reject(reason);
- }
- return deferred.promise;
-}
-
-promise.race = race; // ES6
-promise.all = all; // ES6
-promise.reject = reject; // ES6
-promise.resolve = Q; // ES6
-
-// XXX experimental. This method is a way to denote that a local value is
-// serializable and should be immediately dispatched to a remote upon request,
-// instead of passing a reference.
-Q.passByCopy = function (object) {
- //freeze(object);
- //passByCopies.set(object, true);
- return object;
-};
-
-Promise.prototype.passByCopy = function () {
- //freeze(object);
- //passByCopies.set(object, true);
- return this;
-};
-
-/**
- * If two promises eventually fulfill to the same value, promises that value,
- * but otherwise rejects.
- * @param x {Any*}
- * @param y {Any*}
- * @returns {Any*} a promise for x and y if they are the same, but a rejection
- * otherwise.
- *
- */
-Q.join = function (x, y) {
- return Q(x).join(y);
-};
-
-Promise.prototype.join = function (that) {
- return Q([this, that]).spread(function (x, y) {
- if (x === y) {
- // TODO: "===" should be Object.is or equiv
- return x;
- } else {
- throw new Error("Q can't join: not the same: " + x + " " + y);
- }
- });
-};
-
-/**
- * Returns a promise for the first of an array of promises to become settled.
- * @param answers {Array[Any*]} promises to race
- * @returns {Any*} the first promise to be settled
- */
-Q.race = race;
-function race(answerPs) {
- return promise(function (resolve, reject) {
- // Switch to this once we can assume at least ES5
- // answerPs.forEach(function (answerP) {
- // Q(answerP).then(resolve, reject);
- // });
- // Use this in the meantime
- for (var i = 0, len = answerPs.length; i < len; i++) {
- Q(answerPs[i]).then(resolve, reject);
- }
- });
-}
-
-Promise.prototype.race = function () {
- return this.then(Q.race);
-};
-
-/**
- * Constructs a Promise with a promise descriptor object and optional fallback
- * function. The descriptor contains methods like when(rejected), get(name),
- * set(name, value), post(name, args), and delete(name), which all
- * return either a value, a promise for a value, or a rejection. The fallback
- * accepts the operation name, a resolver, and any further arguments that would
- * have been forwarded to the appropriate method above had a method been
- * provided with the proper name. The API makes no guarantees about the nature
- * of the returned object, apart from that it is usable whereever promises are
- * bought and sold.
- */
-Q.makePromise = Promise;
-function Promise(descriptor, fallback, inspect) {
- if (fallback === void 0) {
- fallback = function (op) {
- return reject(new Error(
- "Promise does not support operation: " + op
- ));
- };
- }
- if (inspect === void 0) {
- inspect = function () {
- return {state: "unknown"};
- };
- }
-
- var promise = object_create(Promise.prototype);
-
- promise.promiseDispatch = function (resolve, op, args) {
- var result;
- try {
- if (descriptor[op]) {
- result = descriptor[op].apply(promise, args);
- } else {
- result = fallback.call(promise, op, args);
- }
- } catch (exception) {
- result = reject(exception);
- }
- if (resolve) {
- resolve(result);
- }
- };
-
- promise.inspect = inspect;
-
- // XXX deprecated `valueOf` and `exception` support
- if (inspect) {
- var inspected = inspect();
- if (inspected.state === "rejected") {
- promise.exception = inspected.reason;
- }
-
- promise.valueOf = function () {
- var inspected = inspect();
- if (inspected.state === "pending" ||
- inspected.state === "rejected") {
- return promise;
- }
- return inspected.value;
- };
- }
-
- return promise;
-}
-
-Promise.prototype.toString = function () {
- return "[object Promise]";
-};
-
-Promise.prototype.then = function (fulfilled, rejected, progressed) {
- var self = this;
- var deferred = defer();
- var done = false; // ensure the untrusted promise makes at most a
- // single call to one of the callbacks
-
- function _fulfilled(value) {
- try {
- return typeof fulfilled === "function" ? fulfilled(value) : value;
- } catch (exception) {
- return reject(exception);
- }
- }
-
- function _rejected(exception) {
- if (typeof rejected === "function") {
- makeStackTraceLong(exception, self);
- try {
- return rejected(exception);
- } catch (newException) {
- return reject(newException);
- }
- }
- return reject(exception);
- }
-
- function _progressed(value) {
- return typeof progressed === "function" ? progressed(value) : value;
- }
-
- Q.nextTick(function () {
- self.promiseDispatch(function (value) {
- if (done) {
- return;
- }
- done = true;
-
- deferred.resolve(_fulfilled(value));
- }, "when", [function (exception) {
- if (done) {
- return;
- }
- done = true;
-
- deferred.resolve(_rejected(exception));
- }]);
- });
-
- // Progress propagator need to be attached in the current tick.
- self.promiseDispatch(void 0, "when", [void 0, function (value) {
- var newValue;
- var threw = false;
- try {
- newValue = _progressed(value);
- } catch (e) {
- threw = true;
- if (Q.onerror) {
- Q.onerror(e);
- } else {
- throw e;
- }
- }
-
- if (!threw) {
- deferred.notify(newValue);
- }
- }]);
-
- return deferred.promise;
-};
-
-Q.tap = function (promise, callback) {
- return Q(promise).tap(callback);
-};
-
-/**
- * Works almost like "finally", but not called for rejections.
- * Original resolution value is passed through callback unaffected.
- * Callback may return a promise that will be awaited for.
- * @param {Function} callback
- * @returns {Q.Promise}
- * @example
- * doSomething()
- * .then(...)
- * .tap(console.log)
- * .then(...);
- */
-Promise.prototype.tap = function (callback) {
- callback = Q(callback);
-
- return this.then(function (value) {
- return callback.fcall(value).thenResolve(value);
- });
-};
-
-/**
- * Registers an observer on a promise.
- *
- * Guarantees:
- *
- * 1. that fulfilled and rejected will be called only once.
- * 2. that either the fulfilled callback or the rejected callback will be
- * called, but not both.
- * 3. that fulfilled and rejected will not be called in this turn.
- *
- * @param value promise or immediate reference to observe
- * @param fulfilled function to be called with the fulfilled value
- * @param rejected function to be called with the rejection exception
- * @param progressed function to be called on any progress notifications
- * @return promise for the return value from the invoked callback
- */
-Q.when = when;
-function when(value, fulfilled, rejected, progressed) {
- return Q(value).then(fulfilled, rejected, progressed);
-}
-
-Promise.prototype.thenResolve = function (value) {
- return this.then(function () { return value; });
-};
-
-Q.thenResolve = function (promise, value) {
- return Q(promise).thenResolve(value);
-};
-
-Promise.prototype.thenReject = function (reason) {
- return this.then(function () { throw reason; });
-};
-
-Q.thenReject = function (promise, reason) {
- return Q(promise).thenReject(reason);
-};
-
-/**
- * If an object is not a promise, it is as "near" as possible.
- * If a promise is rejected, it is as "near" as possible too.
- * If it’s a fulfilled promise, the fulfillment value is nearer.
- * If it’s a deferred promise and the deferred has been resolved, the
- * resolution is "nearer".
- * @param object
- * @returns most resolved (nearest) form of the object
- */
-
-// XXX should we re-do this?
-Q.nearer = nearer;
-function nearer(value) {
- if (isPromise(value)) {
- var inspected = value.inspect();
- if (inspected.state === "fulfilled") {
- return inspected.value;
- }
- }
- return value;
-}
-
-/**
- * @returns whether the given object is a promise.
- * Otherwise it is a fulfilled value.
- */
-Q.isPromise = isPromise;
-function isPromise(object) {
- return object instanceof Promise;
-}
-
-Q.isPromiseAlike = isPromiseAlike;
-function isPromiseAlike(object) {
- return isObject(object) && typeof object.then === "function";
-}
-
-/**
- * @returns whether the given object is a pending promise, meaning not
- * fulfilled or rejected.
- */
-Q.isPending = isPending;
-function isPending(object) {
- return isPromise(object) && object.inspect().state === "pending";
-}
-
-Promise.prototype.isPending = function () {
- return this.inspect().state === "pending";
-};
-
-/**
- * @returns whether the given object is a value or fulfilled
- * promise.
- */
-Q.isFulfilled = isFulfilled;
-function isFulfilled(object) {
- return !isPromise(object) || object.inspect().state === "fulfilled";
-}
-
-Promise.prototype.isFulfilled = function () {
- return this.inspect().state === "fulfilled";
-};
-
-/**
- * @returns whether the given object is a rejected promise.
- */
-Q.isRejected = isRejected;
-function isRejected(object) {
- return isPromise(object) && object.inspect().state === "rejected";
-}
-
-Promise.prototype.isRejected = function () {
- return this.inspect().state === "rejected";
-};
-
-//// BEGIN UNHANDLED REJECTION TRACKING
-
-// This promise library consumes exceptions thrown in handlers so they can be
-// handled by a subsequent promise. The exceptions get added to this array when
-// they are created, and removed when they are handled. Note that in ES6 or
-// shimmed environments, this would naturally be a `Set`.
-var unhandledReasons = [];
-var unhandledRejections = [];
-var reportedUnhandledRejections = [];
-var trackUnhandledRejections = true;
-
-function resetUnhandledRejections() {
- unhandledReasons.length = 0;
- unhandledRejections.length = 0;
-
- if (!trackUnhandledRejections) {
- trackUnhandledRejections = true;
- }
-}
-
-function trackRejection(promise, reason) {
- if (!trackUnhandledRejections) {
- return;
- }
- if (typeof process === "object" && typeof process.emit === "function") {
- Q.nextTick.runAfter(function () {
- if (array_indexOf(unhandledRejections, promise) !== -1) {
- process.emit("unhandledRejection", reason, promise);
- reportedUnhandledRejections.push(promise);
- }
- });
- }
-
- unhandledRejections.push(promise);
- if (reason && typeof reason.stack !== "undefined") {
- unhandledReasons.push(reason.stack);
- } else {
- unhandledReasons.push("(no stack) " + reason);
- }
-}
-
-function untrackRejection(promise) {
- if (!trackUnhandledRejections) {
- return;
- }
-
- var at = array_indexOf(unhandledRejections, promise);
- if (at !== -1) {
- if (typeof process === "object" && typeof process.emit === "function") {
- Q.nextTick.runAfter(function () {
- var atReport = array_indexOf(reportedUnhandledRejections, promise);
- if (atReport !== -1) {
- process.emit("rejectionHandled", unhandledReasons[at], promise);
- reportedUnhandledRejections.splice(atReport, 1);
- }
- });
- }
- unhandledRejections.splice(at, 1);
- unhandledReasons.splice(at, 1);
- }
-}
-
-Q.resetUnhandledRejections = resetUnhandledRejections;
-
-Q.getUnhandledReasons = function () {
- // Make a copy so that consumers can't interfere with our internal state.
- return unhandledReasons.slice();
-};
-
-Q.stopUnhandledRejectionTracking = function () {
- resetUnhandledRejections();
- trackUnhandledRejections = false;
-};
-
-resetUnhandledRejections();
-
-//// END UNHANDLED REJECTION TRACKING
-
-/**
- * Constructs a rejected promise.
- * @param reason value describing the failure
- */
-Q.reject = reject;
-function reject(reason) {
- var rejection = Promise({
- "when": function (rejected) {
- // note that the error has been handled
- if (rejected) {
- untrackRejection(this);
- }
- return rejected ? rejected(reason) : this;
- }
- }, function fallback() {
- return this;
- }, function inspect() {
- return { state: "rejected", reason: reason };
- });
-
- // Note that the reason has not been handled.
- trackRejection(rejection, reason);
-
- return rejection;
-}
-
-/**
- * Constructs a fulfilled promise for an immediate reference.
- * @param value immediate reference
- */
-Q.fulfill = fulfill;
-function fulfill(value) {
- return Promise({
- "when": function () {
- return value;
- },
- "get": function (name) {
- return value[name];
- },
- "set": function (name, rhs) {
- value[name] = rhs;
- },
- "delete": function (name) {
- delete value[name];
- },
- "post": function (name, args) {
- // Mark Miller proposes that post with no name should apply a
- // promised function.
- if (name === null || name === void 0) {
- return value.apply(void 0, args);
- } else {
- return value[name].apply(value, args);
- }
- },
- "apply": function (thisp, args) {
- return value.apply(thisp, args);
- },
- "keys": function () {
- return object_keys(value);
- }
- }, void 0, function inspect() {
- return { state: "fulfilled", value: value };
- });
-}
-
-/**
- * Converts thenables to Q promises.
- * @param promise thenable promise
- * @returns a Q promise
- */
-function coerce(promise) {
- var deferred = defer();
- Q.nextTick(function () {
- try {
- promise.then(deferred.resolve, deferred.reject, deferred.notify);
- } catch (exception) {
- deferred.reject(exception);
- }
- });
- return deferred.promise;
-}
-
-/**
- * Annotates an object such that it will never be
- * transferred away from this process over any promise
- * communication channel.
- * @param object
- * @returns promise a wrapping of that object that
- * additionally responds to the "isDef" message
- * without a rejection.
- */
-Q.master = master;
-function master(object) {
- return Promise({
- "isDef": function () {}
- }, function fallback(op, args) {
- return dispatch(object, op, args);
- }, function () {
- return Q(object).inspect();
- });
-}
-
-/**
- * Spreads the values of a promised array of arguments into the
- * fulfillment callback.
- * @param fulfilled callback that receives variadic arguments from the
- * promised array
- * @param rejected callback that receives the exception if the promise
- * is rejected.
- * @returns a promise for the return value or thrown exception of
- * either callback.
- */
-Q.spread = spread;
-function spread(value, fulfilled, rejected) {
- return Q(value).spread(fulfilled, rejected);
-}
-
-Promise.prototype.spread = function (fulfilled, rejected) {
- return this.all().then(function (array) {
- return fulfilled.apply(void 0, array);
- }, rejected);
-};
-
-/**
- * The async function is a decorator for generator functions, turning
- * them into asynchronous generators. Although generators are only part
- * of the newest ECMAScript 6 drafts, this code does not cause syntax
- * errors in older engines. This code should continue to work and will
- * in fact improve over time as the language improves.
- *
- * ES6 generators are currently part of V8 version 3.19 with the
- * --harmony-generators runtime flag enabled. SpiderMonkey has had them
- * for longer, but under an older Python-inspired form. This function
- * works on both kinds of generators.
- *
- * Decorates a generator function such that:
- * - it may yield promises
- * - execution will continue when that promise is fulfilled
- * - the value of the yield expression will be the fulfilled value
- * - it returns a promise for the return value (when the generator
- * stops iterating)
- * - the decorated function returns a promise for the return value
- * of the generator or the first rejected promise among those
- * yielded.
- * - if an error is thrown in the generator, it propagates through
- * every following yield until it is caught, or until it escapes
- * the generator function altogether, and is translated into a
- * rejection for the promise returned by the decorated generator.
- */
-Q.async = async;
-function async(makeGenerator) {
- return function () {
- // when verb is "send", arg is a value
- // when verb is "throw", arg is an exception
- function continuer(verb, arg) {
- var result;
-
- // Until V8 3.19 / Chromium 29 is released, SpiderMonkey is the only
- // engine that has a deployed base of browsers that support generators.
- // However, SM's generators use the Python-inspired semantics of
- // outdated ES6 drafts. We would like to support ES6, but we'd also
- // like to make it possible to use generators in deployed browsers, so
- // we also support Python-style generators. At some point we can remove
- // this block.
-
- if (typeof StopIteration === "undefined") {
- // ES6 Generators
- try {
- result = generator[verb](arg);
- } catch (exception) {
- return reject(exception);
- }
- if (result.done) {
- return Q(result.value);
- } else {
- return when(result.value, callback, errback);
- }
- } else {
- // SpiderMonkey Generators
- // FIXME: Remove this case when SM does ES6 generators.
- try {
- result = generator[verb](arg);
- } catch (exception) {
- if (isStopIteration(exception)) {
- return Q(exception.value);
- } else {
- return reject(exception);
- }
- }
- return when(result, callback, errback);
- }
- }
- var generator = makeGenerator.apply(this, arguments);
- var callback = continuer.bind(continuer, "next");
- var errback = continuer.bind(continuer, "throw");
- return callback();
- };
-}
-
-/**
- * The spawn function is a small wrapper around async that immediately
- * calls the generator and also ends the promise chain, so that any
- * unhandled errors are thrown instead of forwarded to the error
- * handler. This is useful because it's extremely common to run
- * generators at the top-level to work with libraries.
- */
-Q.spawn = spawn;
-function spawn(makeGenerator) {
- Q.done(Q.async(makeGenerator)());
-}
-
-// FIXME: Remove this interface once ES6 generators are in SpiderMonkey.
-/**
- * Throws a ReturnValue exception to stop an asynchronous generator.
- *
- * This interface is a stop-gap measure to support generator return
- * values in older Firefox/SpiderMonkey. In browsers that support ES6
- * generators like Chromium 29, just use "return" in your generator
- * functions.
- *
- * @param value the return value for the surrounding generator
- * @throws ReturnValue exception with the value.
- * @example
- * // ES6 style
- * Q.async(function* () {
- * var foo = yield getFooPromise();
- * var bar = yield getBarPromise();
- * return foo + bar;
- * })
- * // Older SpiderMonkey style
- * Q.async(function () {
- * var foo = yield getFooPromise();
- * var bar = yield getBarPromise();
- * Q.return(foo + bar);
- * })
- */
-Q["return"] = _return;
-function _return(value) {
- throw new QReturnValue(value);
-}
-
-/**
- * The promised function decorator ensures that any promise arguments
- * are settled and passed as values (`this` is also settled and passed
- * as a value). It will also ensure that the result of a function is
- * always a promise.
- *
- * @example
- * var add = Q.promised(function (a, b) {
- * return a + b;
- * });
- * add(Q(a), Q(B));
- *
- * @param {function} callback The function to decorate
- * @returns {function} a function that has been decorated.
- */
-Q.promised = promised;
-function promised(callback) {
- return function () {
- return spread([this, all(arguments)], function (self, args) {
- return callback.apply(self, args);
- });
- };
-}
-
-/**
- * sends a message to a value in a future turn
- * @param object* the recipient
- * @param op the name of the message operation, e.g., "when",
- * @param args further arguments to be forwarded to the operation
- * @returns result {Promise} a promise for the result of the operation
- */
-Q.dispatch = dispatch;
-function dispatch(object, op, args) {
- return Q(object).dispatch(op, args);
-}
-
-Promise.prototype.dispatch = function (op, args) {
- var self = this;
- var deferred = defer();
- Q.nextTick(function () {
- self.promiseDispatch(deferred.resolve, op, args);
- });
- return deferred.promise;
-};
-
-/**
- * Gets the value of a property in a future turn.
- * @param object promise or immediate reference for target object
- * @param name name of property to get
- * @return promise for the property value
- */
-Q.get = function (object, key) {
- return Q(object).dispatch("get", [key]);
-};
-
-Promise.prototype.get = function (key) {
- return this.dispatch("get", [key]);
-};
-
-/**
- * Sets the value of a property in a future turn.
- * @param object promise or immediate reference for object object
- * @param name name of property to set
- * @param value new value of property
- * @return promise for the return value
- */
-Q.set = function (object, key, value) {
- return Q(object).dispatch("set", [key, value]);
-};
-
-Promise.prototype.set = function (key, value) {
- return this.dispatch("set", [key, value]);
-};
-
-/**
- * Deletes a property in a future turn.
- * @param object promise or immediate reference for target object
- * @param name name of property to delete
- * @return promise for the return value
- */
-Q.del = // XXX legacy
-Q["delete"] = function (object, key) {
- return Q(object).dispatch("delete", [key]);
-};
-
-Promise.prototype.del = // XXX legacy
-Promise.prototype["delete"] = function (key) {
- return this.dispatch("delete", [key]);
-};
-
-/**
- * Invokes a method in a future turn.
- * @param object promise or immediate reference for target object
- * @param name name of method to invoke
- * @param value a value to post, typically an array of
- * invocation arguments for promises that
- * are ultimately backed with `resolve` values,
- * as opposed to those backed with URLs
- * wherein the posted value can be any
- * JSON serializable object.
- * @return promise for the return value
- */
-// bound locally because it is used by other methods
-Q.mapply = // XXX As proposed by "Redsandro"
-Q.post = function (object, name, args) {
- return Q(object).dispatch("post", [name, args]);
-};
-
-Promise.prototype.mapply = // XXX As proposed by "Redsandro"
-Promise.prototype.post = function (name, args) {
- return this.dispatch("post", [name, args]);
-};
-
-/**
- * Invokes a method in a future turn.
- * @param object promise or immediate reference for target object
- * @param name name of method to invoke
- * @param ...args array of invocation arguments
- * @return promise for the return value
- */
-Q.send = // XXX Mark Miller's proposed parlance
-Q.mcall = // XXX As proposed by "Redsandro"
-Q.invoke = function (object, name /*...args*/) {
- return Q(object).dispatch("post", [name, array_slice(arguments, 2)]);
-};
-
-Promise.prototype.send = // XXX Mark Miller's proposed parlance
-Promise.prototype.mcall = // XXX As proposed by "Redsandro"
-Promise.prototype.invoke = function (name /*...args*/) {
- return this.dispatch("post", [name, array_slice(arguments, 1)]);
-};
-
-/**
- * Applies the promised function in a future turn.
- * @param object promise or immediate reference for target function
- * @param args array of application arguments
- */
-Q.fapply = function (object, args) {
- return Q(object).dispatch("apply", [void 0, args]);
-};
-
-Promise.prototype.fapply = function (args) {
- return this.dispatch("apply", [void 0, args]);
-};
-
-/**
- * Calls the promised function in a future turn.
- * @param object promise or immediate reference for target function
- * @param ...args array of application arguments
- */
-Q["try"] =
-Q.fcall = function (object /* ...args*/) {
- return Q(object).dispatch("apply", [void 0, array_slice(arguments, 1)]);
-};
-
-Promise.prototype.fcall = function (/*...args*/) {
- return this.dispatch("apply", [void 0, array_slice(arguments)]);
-};
-
-/**
- * Binds the promised function, transforming return values into a fulfilled
- * promise and thrown errors into a rejected one.
- * @param object promise or immediate reference for target function
- * @param ...args array of application arguments
- */
-Q.fbind = function (object /*...args*/) {
- var promise = Q(object);
- var args = array_slice(arguments, 1);
- return function fbound() {
- return promise.dispatch("apply", [
- this,
- args.concat(array_slice(arguments))
- ]);
- };
-};
-Promise.prototype.fbind = function (/*...args*/) {
- var promise = this;
- var args = array_slice(arguments);
- return function fbound() {
- return promise.dispatch("apply", [
- this,
- args.concat(array_slice(arguments))
- ]);
- };
-};
-
-/**
- * Requests the names of the owned properties of a promised
- * object in a future turn.
- * @param object promise or immediate reference for target object
- * @return promise for the keys of the eventually settled object
- */
-Q.keys = function (object) {
- return Q(object).dispatch("keys", []);
-};
-
-Promise.prototype.keys = function () {
- return this.dispatch("keys", []);
-};
-
-/**
- * Turns an array of promises into a promise for an array. If any of
- * the promises gets rejected, the whole array is rejected immediately.
- * @param {Array*} an array (or promise for an array) of values (or
- * promises for values)
- * @returns a promise for an array of the corresponding values
- */
-// By Mark Miller
-// http://wiki.ecmascript.org/doku.php?id=strawman:concurrency&rev=1308776521#allfulfilled
-Q.all = all;
-function all(promises) {
- return when(promises, function (promises) {
- var pendingCount = 0;
- var deferred = defer();
- array_reduce(promises, function (undefined, promise, index) {
- var snapshot;
- if (
- isPromise(promise) &&
- (snapshot = promise.inspect()).state === "fulfilled"
- ) {
- promises[index] = snapshot.value;
- } else {
- ++pendingCount;
- when(
- promise,
- function (value) {
- promises[index] = value;
- if (--pendingCount === 0) {
- deferred.resolve(promises);
- }
- },
- deferred.reject,
- function (progress) {
- deferred.notify({ index: index, value: progress });
- }
- );
- }
- }, void 0);
- if (pendingCount === 0) {
- deferred.resolve(promises);
- }
- return deferred.promise;
- });
-}
-
-Promise.prototype.all = function () {
- return all(this);
-};
-
-/**
- * Returns the first resolved promise of an array. Prior rejected promises are
- * ignored. Rejects only if all promises are rejected.
- * @param {Array*} an array containing values or promises for values
- * @returns a promise fulfilled with the value of the first resolved promise,
- * or a rejected promise if all promises are rejected.
- */
-Q.any = any;
-
-function any(promises) {
- if (promises.length === 0) {
- return Q.resolve();
- }
-
- var deferred = Q.defer();
- var pendingCount = 0;
- array_reduce(promises, function (prev, current, index) {
- var promise = promises[index];
-
- pendingCount++;
-
- when(promise, onFulfilled, onRejected, onProgress);
- function onFulfilled(result) {
- deferred.resolve(result);
- }
- function onRejected(err) {
- pendingCount--;
- if (pendingCount === 0) {
- err.message = ("Q can't get fulfillment value from any promise, all " +
- "promises were rejected. Last error message: " + err.message);
- deferred.reject(err);
- }
- }
- function onProgress(progress) {
- deferred.notify({
- index: index,
- value: progress
- });
- }
- }, undefined);
-
- return deferred.promise;
-}
-
-Promise.prototype.any = function () {
- return any(this);
-};
-
-/**
- * Waits for all promises to be settled, either fulfilled or
- * rejected. This is distinct from `all` since that would stop
- * waiting at the first rejection. The promise returned by
- * `allResolved` will never be rejected.
- * @param promises a promise for an array (or an array) of promises
- * (or values)
- * @return a promise for an array of promises
- */
-Q.allResolved = deprecate(allResolved, "allResolved", "allSettled");
-function allResolved(promises) {
- return when(promises, function (promises) {
- promises = array_map(promises, Q);
- return when(all(array_map(promises, function (promise) {
- return when(promise, noop, noop);
- })), function () {
- return promises;
- });
- });
-}
-
-Promise.prototype.allResolved = function () {
- return allResolved(this);
-};
-
-/**
- * @see Promise#allSettled
- */
-Q.allSettled = allSettled;
-function allSettled(promises) {
- return Q(promises).allSettled();
-}
-
-/**
- * Turns an array of promises into a promise for an array of their states (as
- * returned by `inspect`) when they have all settled.
- * @param {Array[Any*]} values an array (or promise for an array) of values (or
- * promises for values)
- * @returns {Array[State]} an array of states for the respective values.
- */
-Promise.prototype.allSettled = function () {
- return this.then(function (promises) {
- return all(array_map(promises, function (promise) {
- promise = Q(promise);
- function regardless() {
- return promise.inspect();
- }
- return promise.then(regardless, regardless);
- }));
- });
-};
-
-/**
- * Captures the failure of a promise, giving an oportunity to recover
- * with a callback. If the given promise is fulfilled, the returned
- * promise is fulfilled.
- * @param {Any*} promise for something
- * @param {Function} callback to fulfill the returned promise if the
- * given promise is rejected
- * @returns a promise for the return value of the callback
- */
-Q.fail = // XXX legacy
-Q["catch"] = function (object, rejected) {
- return Q(object).then(void 0, rejected);
-};
-
-Promise.prototype.fail = // XXX legacy
-Promise.prototype["catch"] = function (rejected) {
- return this.then(void 0, rejected);
-};
-
-/**
- * Attaches a listener that can respond to progress notifications from a
- * promise's originating deferred. This listener receives the exact arguments
- * passed to ``deferred.notify``.
- * @param {Any*} promise for something
- * @param {Function} callback to receive any progress notifications
- * @returns the given promise, unchanged
- */
-Q.progress = progress;
-function progress(object, progressed) {
- return Q(object).then(void 0, void 0, progressed);
-}
-
-Promise.prototype.progress = function (progressed) {
- return this.then(void 0, void 0, progressed);
-};
-
-/**
- * Provides an opportunity to observe the settling of a promise,
- * regardless of whether the promise is fulfilled or rejected. Forwards
- * the resolution to the returned promise when the callback is done.
- * The callback can return a promise to defer completion.
- * @param {Any*} promise
- * @param {Function} callback to observe the resolution of the given
- * promise, takes no arguments.
- * @returns a promise for the resolution of the given promise when
- * ``fin`` is done.
- */
-Q.fin = // XXX legacy
-Q["finally"] = function (object, callback) {
- return Q(object)["finally"](callback);
-};
-
-Promise.prototype.fin = // XXX legacy
-Promise.prototype["finally"] = function (callback) {
- if (!callback || typeof callback.apply !== "function") {
- throw new Error("Q can't apply finally callback");
- }
- callback = Q(callback);
- return this.then(function (value) {
- return callback.fcall().then(function () {
- return value;
- });
- }, function (reason) {
- // TODO attempt to recycle the rejection with "this".
- return callback.fcall().then(function () {
- throw reason;
- });
- });
-};
-
-/**
- * Terminates a chain of promises, forcing rejections to be
- * thrown as exceptions.
- * @param {Any*} promise at the end of a chain of promises
- * @returns nothing
- */
-Q.done = function (object, fulfilled, rejected, progress) {
- return Q(object).done(fulfilled, rejected, progress);
-};
-
-Promise.prototype.done = function (fulfilled, rejected, progress) {
- var onUnhandledError = function (error) {
- // forward to a future turn so that ``when``
- // does not catch it and turn it into a rejection.
- Q.nextTick(function () {
- makeStackTraceLong(error, promise);
- if (Q.onerror) {
- Q.onerror(error);
- } else {
- throw error;
- }
- });
- };
-
- // Avoid unnecessary `nextTick`ing via an unnecessary `when`.
- var promise = fulfilled || rejected || progress ?
- this.then(fulfilled, rejected, progress) :
- this;
-
- if (typeof process === "object" && process && process.domain) {
- onUnhandledError = process.domain.bind(onUnhandledError);
- }
-
- promise.then(void 0, onUnhandledError);
-};
-
-/**
- * Causes a promise to be rejected if it does not get fulfilled before
- * some milliseconds time out.
- * @param {Any*} promise
- * @param {Number} milliseconds timeout
- * @param {Any*} custom error message or Error object (optional)
- * @returns a promise for the resolution of the given promise if it is
- * fulfilled before the timeout, otherwise rejected.
- */
-Q.timeout = function (object, ms, error) {
- return Q(object).timeout(ms, error);
-};
-
-Promise.prototype.timeout = function (ms, error) {
- var deferred = defer();
- var timeoutId = setTimeout(function () {
- if (!error || "string" === typeof error) {
- error = new Error(error || "Timed out after " + ms + " ms");
- error.code = "ETIMEDOUT";
- }
- deferred.reject(error);
- }, ms);
-
- this.then(function (value) {
- clearTimeout(timeoutId);
- deferred.resolve(value);
- }, function (exception) {
- clearTimeout(timeoutId);
- deferred.reject(exception);
- }, deferred.notify);
-
- return deferred.promise;
-};
-
-/**
- * Returns a promise for the given value (or promised value), some
- * milliseconds after it resolved. Passes rejections immediately.
- * @param {Any*} promise
- * @param {Number} milliseconds
- * @returns a promise for the resolution of the given promise after milliseconds
- * time has elapsed since the resolution of the given promise.
- * If the given promise rejects, that is passed immediately.
- */
-Q.delay = function (object, timeout) {
- if (timeout === void 0) {
- timeout = object;
- object = void 0;
- }
- return Q(object).delay(timeout);
-};
-
-Promise.prototype.delay = function (timeout) {
- return this.then(function (value) {
- var deferred = defer();
- setTimeout(function () {
- deferred.resolve(value);
- }, timeout);
- return deferred.promise;
- });
-};
-
-/**
- * Passes a continuation to a Node function, which is called with the given
- * arguments provided as an array, and returns a promise.
- *
- * Q.nfapply(FS.readFile, [__filename])
- * .then(function (content) {
- * })
- *
- */
-Q.nfapply = function (callback, args) {
- return Q(callback).nfapply(args);
-};
-
-Promise.prototype.nfapply = function (args) {
- var deferred = defer();
- var nodeArgs = array_slice(args);
- nodeArgs.push(deferred.makeNodeResolver());
- this.fapply(nodeArgs).fail(deferred.reject);
- return deferred.promise;
-};
-
-/**
- * Passes a continuation to a Node function, which is called with the given
- * arguments provided individually, and returns a promise.
- * @example
- * Q.nfcall(FS.readFile, __filename)
- * .then(function (content) {
- * })
- *
- */
-Q.nfcall = function (callback /*...args*/) {
- var args = array_slice(arguments, 1);
- return Q(callback).nfapply(args);
-};
-
-Promise.prototype.nfcall = function (/*...args*/) {
- var nodeArgs = array_slice(arguments);
- var deferred = defer();
- nodeArgs.push(deferred.makeNodeResolver());
- this.fapply(nodeArgs).fail(deferred.reject);
- return deferred.promise;
-};
-
-/**
- * Wraps a NodeJS continuation passing function and returns an equivalent
- * version that returns a promise.
- * @example
- * Q.nfbind(FS.readFile, __filename)("utf-8")
- * .then(console.log)
- * .done()
- */
-Q.nfbind =
-Q.denodeify = function (callback /*...args*/) {
- if (callback === undefined) {
- throw new Error("Q can't wrap an undefined function");
- }
- var baseArgs = array_slice(arguments, 1);
- return function () {
- var nodeArgs = baseArgs.concat(array_slice(arguments));
- var deferred = defer();
- nodeArgs.push(deferred.makeNodeResolver());
- Q(callback).fapply(nodeArgs).fail(deferred.reject);
- return deferred.promise;
- };
-};
-
-Promise.prototype.nfbind =
-Promise.prototype.denodeify = function (/*...args*/) {
- var args = array_slice(arguments);
- args.unshift(this);
- return Q.denodeify.apply(void 0, args);
-};
-
-Q.nbind = function (callback, thisp /*...args*/) {
- var baseArgs = array_slice(arguments, 2);
- return function () {
- var nodeArgs = baseArgs.concat(array_slice(arguments));
- var deferred = defer();
- nodeArgs.push(deferred.makeNodeResolver());
- function bound() {
- return callback.apply(thisp, arguments);
- }
- Q(bound).fapply(nodeArgs).fail(deferred.reject);
- return deferred.promise;
- };
-};
-
-Promise.prototype.nbind = function (/*thisp, ...args*/) {
- var args = array_slice(arguments, 0);
- args.unshift(this);
- return Q.nbind.apply(void 0, args);
-};
-
-/**
- * Calls a method of a Node-style object that accepts a Node-style
- * callback with a given array of arguments, plus a provided callback.
- * @param object an object that has the named method
- * @param {String} name name of the method of object
- * @param {Array} args arguments to pass to the method; the callback
- * will be provided by Q and appended to these arguments.
- * @returns a promise for the value or error
- */
-Q.nmapply = // XXX As proposed by "Redsandro"
-Q.npost = function (object, name, args) {
- return Q(object).npost(name, args);
-};
-
-Promise.prototype.nmapply = // XXX As proposed by "Redsandro"
-Promise.prototype.npost = function (name, args) {
- var nodeArgs = array_slice(args || []);
- var deferred = defer();
- nodeArgs.push(deferred.makeNodeResolver());
- this.dispatch("post", [name, nodeArgs]).fail(deferred.reject);
- return deferred.promise;
-};
-
-/**
- * Calls a method of a Node-style object that accepts a Node-style
- * callback, forwarding the given variadic arguments, plus a provided
- * callback argument.
- * @param object an object that has the named method
- * @param {String} name name of the method of object
- * @param ...args arguments to pass to the method; the callback will
- * be provided by Q and appended to these arguments.
- * @returns a promise for the value or error
- */
-Q.nsend = // XXX Based on Mark Miller's proposed "send"
-Q.nmcall = // XXX Based on "Redsandro's" proposal
-Q.ninvoke = function (object, name /*...args*/) {
- var nodeArgs = array_slice(arguments, 2);
- var deferred = defer();
- nodeArgs.push(deferred.makeNodeResolver());
- Q(object).dispatch("post", [name, nodeArgs]).fail(deferred.reject);
- return deferred.promise;
-};
-
-Promise.prototype.nsend = // XXX Based on Mark Miller's proposed "send"
-Promise.prototype.nmcall = // XXX Based on "Redsandro's" proposal
-Promise.prototype.ninvoke = function (name /*...args*/) {
- var nodeArgs = array_slice(arguments, 1);
- var deferred = defer();
- nodeArgs.push(deferred.makeNodeResolver());
- this.dispatch("post", [name, nodeArgs]).fail(deferred.reject);
- return deferred.promise;
-};
-
-/**
- * If a function would like to support both Node continuation-passing-style and
- * promise-returning-style, it can end its internal promise chain with
- * `nodeify(nodeback)`, forwarding the optional nodeback argument. If the user
- * elects to use a nodeback, the result will be sent there. If they do not
- * pass a nodeback, they will receive the result promise.
- * @param object a result (or a promise for a result)
- * @param {Function} nodeback a Node.js-style callback
- * @returns either the promise or nothing
- */
-Q.nodeify = nodeify;
-function nodeify(object, nodeback) {
- return Q(object).nodeify(nodeback);
-}
-
-Promise.prototype.nodeify = function (nodeback) {
- if (nodeback) {
- this.then(function (value) {
- Q.nextTick(function () {
- nodeback(null, value);
- });
- }, function (error) {
- Q.nextTick(function () {
- nodeback(error);
- });
- });
- } else {
- return this;
- }
-};
-
-Q.noConflict = function() {
- throw new Error("Q.noConflict only works when Q is used as a global");
-};
-
-// All code before this point will be filtered from stack traces.
-var qEndingLine = captureLine();
-
-return Q;
-
-});
diff --git a/StoneIsland/platforms/ios/cordova/node_modules/q/queue.js b/StoneIsland/platforms/ios/cordova/node_modules/q/queue.js
deleted file mode 100755
index 1505fd0b..00000000
--- a/StoneIsland/platforms/ios/cordova/node_modules/q/queue.js
+++ /dev/null
@@ -1,35 +0,0 @@
-
-var Q = require("./q");
-
-module.exports = Queue;
-function Queue() {
- var ends = Q.defer();
- var closed = Q.defer();
- return {
- put: function (value) {
- var next = Q.defer();
- ends.resolve({
- head: value,
- tail: next.promise
- });
- ends.resolve = next.resolve;
- },
- get: function () {
- var result = ends.promise.get("head");
- ends.promise = ends.promise.get("tail");
- return result.fail(function (error) {
- closed.resolve(error);
- throw error;
- });
- },
- closed: closed.promise,
- close: function (error) {
- error = error || new Error("Can't get value from closed queue");
- var end = {head: Q.reject(error)};
- end.tail = end;
- ends.resolve(end);
- return closed.promise;
- }
- };
-}
-
diff --git a/StoneIsland/platforms/ios/cordova/node_modules/shelljs/LICENSE b/StoneIsland/platforms/ios/cordova/node_modules/shelljs/LICENSE
deleted file mode 100755
index 1b35ee9f..00000000
--- a/StoneIsland/platforms/ios/cordova/node_modules/shelljs/LICENSE
+++ /dev/null
@@ -1,26 +0,0 @@
-Copyright (c) 2012, Artur Adib <aadib@mozilla.com>
-All rights reserved.
-
-You may use this project under the terms of the New BSD license as follows:
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- * Neither the name of Artur Adib nor the
- names of the contributors may be used to endorse or promote products
- derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL ARTUR ADIB BE LIABLE FOR ANY
-DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/StoneIsland/platforms/ios/cordova/node_modules/shelljs/package.json b/StoneIsland/platforms/ios/cordova/node_modules/shelljs/package.json
deleted file mode 100755
index 24c80764..00000000
--- a/StoneIsland/platforms/ios/cordova/node_modules/shelljs/package.json
+++ /dev/null
@@ -1,67 +0,0 @@
-{
- "_from": "shelljs@^0.5.3",
- "_id": "shelljs@0.5.3",
- "_inBundle": true,
- "_integrity": "sha1-xUmCuZbHbvDB5rWfvcWCX1txMRM=",
- "_location": "/cordova-ios/shelljs",
- "_phantomChildren": {},
- "_requested": {
- "type": "range",
- "registry": true,
- "raw": "shelljs@^0.5.3",
- "name": "shelljs",
- "escapedName": "shelljs",
- "rawSpec": "^0.5.3",
- "saveSpec": null,
- "fetchSpec": "^0.5.3"
- },
- "_requiredBy": [
- "/cordova-ios",
- "/cordova-ios/cordova-common"
- ],
- "_resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.5.3.tgz",
- "_shasum": "c54982b996c76ef0c1e6b59fbdc5825f5b713113",
- "_spec": "shelljs@^0.5.3",
- "_where": "/Users/spindori/Documents/Cordova/cordova-ios",
- "author": {
- "name": "Artur Adib",
- "email": "arturadib@gmail.com"
- },
- "bin": {
- "shjs": "./bin/shjs"
- },
- "bugs": {
- "url": "https://github.com/arturadib/shelljs/issues"
- },
- "bundleDependencies": false,
- "dependencies": {},
- "deprecated": false,
- "description": "Portable Unix shell commands for Node.js",
- "devDependencies": {
- "jshint": "~2.1.11"
- },
- "engines": {
- "node": ">=0.8.0"
- },
- "homepage": "http://github.com/arturadib/shelljs",
- "keywords": [
- "unix",
- "shell",
- "makefile",
- "make",
- "jake",
- "synchronous"
- ],
- "license": "BSD*",
- "main": "./shell.js",
- "name": "shelljs",
- "optionalDependencies": {},
- "repository": {
- "type": "git",
- "url": "git://github.com/arturadib/shelljs.git"
- },
- "scripts": {
- "test": "node scripts/run-tests"
- },
- "version": "0.5.3"
-}
diff --git a/StoneIsland/platforms/ios/cordova/node_modules/shelljs/shell.js b/StoneIsland/platforms/ios/cordova/node_modules/shelljs/shell.js
deleted file mode 100755
index bdeb5597..00000000
--- a/StoneIsland/platforms/ios/cordova/node_modules/shelljs/shell.js
+++ /dev/null
@@ -1,159 +0,0 @@
-//
-// ShellJS
-// Unix shell commands on top of Node's API
-//
-// Copyright (c) 2012 Artur Adib
-// http://github.com/arturadib/shelljs
-//
-
-var common = require('./src/common');
-
-
-//@
-//@ All commands run synchronously, unless otherwise stated.
-//@
-
-//@include ./src/cd
-var _cd = require('./src/cd');
-exports.cd = common.wrap('cd', _cd);
-
-//@include ./src/pwd
-var _pwd = require('./src/pwd');
-exports.pwd = common.wrap('pwd', _pwd);
-
-//@include ./src/ls
-var _ls = require('./src/ls');
-exports.ls = common.wrap('ls', _ls);
-
-//@include ./src/find
-var _find = require('./src/find');
-exports.find = common.wrap('find', _find);
-
-//@include ./src/cp
-var _cp = require('./src/cp');
-exports.cp = common.wrap('cp', _cp);
-
-//@include ./src/rm
-var _rm = require('./src/rm');
-exports.rm = common.wrap('rm', _rm);
-
-//@include ./src/mv
-var _mv = require('./src/mv');
-exports.mv = common.wrap('mv', _mv);
-
-//@include ./src/mkdir
-var _mkdir = require('./src/mkdir');
-exports.mkdir = common.wrap('mkdir', _mkdir);
-
-//@include ./src/test
-var _test = require('./src/test');
-exports.test = common.wrap('test', _test);
-
-//@include ./src/cat
-var _cat = require('./src/cat');
-exports.cat = common.wrap('cat', _cat);
-
-//@include ./src/to
-var _to = require('./src/to');
-String.prototype.to = common.wrap('to', _to);
-
-//@include ./src/toEnd
-var _toEnd = require('./src/toEnd');
-String.prototype.toEnd = common.wrap('toEnd', _toEnd);
-
-//@include ./src/sed
-var _sed = require('./src/sed');
-exports.sed = common.wrap('sed', _sed);
-
-//@include ./src/grep
-var _grep = require('./src/grep');
-exports.grep = common.wrap('grep', _grep);
-
-//@include ./src/which
-var _which = require('./src/which');
-exports.which = common.wrap('which', _which);
-
-//@include ./src/echo
-var _echo = require('./src/echo');
-exports.echo = _echo; // don't common.wrap() as it could parse '-options'
-
-//@include ./src/dirs
-var _dirs = require('./src/dirs').dirs;
-exports.dirs = common.wrap("dirs", _dirs);
-var _pushd = require('./src/dirs').pushd;
-exports.pushd = common.wrap('pushd', _pushd);
-var _popd = require('./src/dirs').popd;
-exports.popd = common.wrap("popd", _popd);
-
-//@include ./src/ln
-var _ln = require('./src/ln');
-exports.ln = common.wrap('ln', _ln);
-
-//@
-//@ ### exit(code)
-//@ Exits the current process with the given exit code.
-exports.exit = process.exit;
-
-//@
-//@ ### env['VAR_NAME']
-//@ Object containing environment variables (both getter and setter). Shortcut to process.env.
-exports.env = process.env;
-
-//@include ./src/exec
-var _exec = require('./src/exec');
-exports.exec = common.wrap('exec', _exec, {notUnix:true});
-
-//@include ./src/chmod
-var _chmod = require('./src/chmod');
-exports.chmod = common.wrap('chmod', _chmod);
-
-
-
-//@
-//@ ## Non-Unix commands
-//@
-
-//@include ./src/tempdir
-var _tempDir = require('./src/tempdir');
-exports.tempdir = common.wrap('tempdir', _tempDir);
-
-
-//@include ./src/error
-var _error = require('./src/error');
-exports.error = _error;
-
-
-
-//@
-//@ ## Configuration
-//@
-
-exports.config = common.config;
-
-//@
-//@ ### config.silent
-//@ Example:
-//@
-//@ ```javascript
-//@ var sh = require('shelljs');
-//@ var silentState = sh.config.silent; // save old silent state
-//@ sh.config.silent = true;
-//@ /* ... */
-//@ sh.config.silent = silentState; // restore old silent state
-//@ ```
-//@
-//@ Suppresses all command output if `true`, except for `echo()` calls.
-//@ Default is `false`.
-
-//@
-//@ ### config.fatal
-//@ Example:
-//@
-//@ ```javascript
-//@ require('shelljs/global');
-//@ config.fatal = true;
-//@ cp('this_file_does_not_exist', '/dev/null'); // dies here
-//@ /* more commands... */
-//@ ```
-//@
-//@ If `true` the script will die on errors. Default is `false`.
diff --git a/StoneIsland/platforms/ios/cordova/run b/StoneIsland/platforms/ios/cordova/run
index 470384b5..9e6c8f91 100755
--- a/StoneIsland/platforms/ios/cordova/run
+++ b/StoneIsland/platforms/ios/cordova/run
@@ -19,45 +19,48 @@
under the License.
*/
-
var args = process.argv;
var Api = require('./Api');
var nopt = require('nopt');
// Handle help flag
-if(['--help', '/?', '-h', 'help', '-help', '/help'].indexOf(process.argv[2]) >= 0) {
+if (['--help', '/?', '-h', 'help', '-help', '/help'].indexOf(process.argv[2]) >= 0) {
require('./lib/run').help();
process.exit(0);
}
// Parse arguments (includes build params as well)
var opts = nopt({
- 'verbose' : Boolean,
- 'silent' : Boolean,
- 'debug': Boolean,
- 'release': Boolean,
- 'nobuild': Boolean,
- 'archs': String,
- 'list': Boolean,
- 'device': Boolean,
- 'emulator': Boolean,
- 'target' : String,
- 'codeSignIdentity': String,
- 'codeSignResourceRules': String,
- 'provisioningProfile': String,
- 'buildConfig' : String,
- 'noSign' : Boolean
-}, { 'd' : '--verbose' }, args);
+ verbose: Boolean,
+ silent: Boolean,
+ debug: Boolean,
+ release: Boolean,
+ nobuild: Boolean,
+ archs: String,
+ list: Boolean,
+ device: Boolean,
+ emulator: Boolean,
+ target: String,
+ codeSignIdentity: String,
+ codeSignResourceRules: String,
+ provisioningProfile: String,
+ automaticProvisioning: Boolean,
+ buildConfig: String,
+ noSign: Boolean
+}, { d: '--verbose' }, args);
// Make options compatible with PlatformApi build method spec
opts.argv = opts.argv.remain;
require('./loggingHelper').adjustLoggerLevel(opts);
-new Api().run(opts).done(function() {
+new Api().run(opts).then(
+ () => {
console.log('** RUN SUCCEEDED **');
- }, function (err) {
+ },
+ err => {
var errorMessage = (err && err.stack) ? err.stack : err;
console.error(errorMessage);
process.exit(2);
- });
+ }
+);
diff --git a/StoneIsland/platforms/ios/cordova/version b/StoneIsland/platforms/ios/cordova/version
index 979cba13..6bb657b4 100755
--- a/StoneIsland/platforms/ios/cordova/version
+++ b/StoneIsland/platforms/ios/cordova/version
@@ -26,10 +26,6 @@
*/
// Coho updates this line
-var VERSION="4.5.2";
+const Api = require('./Api');
-module.exports.version = VERSION;
-
-if (!module.parent) {
- console.log(VERSION);
-}
+console.log(Api.version());