diff options
Diffstat (limited to 'StoneIsland/platforms/ios/cordova/lib')
| -rwxr-xr-x | StoneIsland/platforms/ios/cordova/lib/build.js | 148 | ||||
| -rwxr-xr-x | StoneIsland/platforms/ios/cordova/lib/check_reqs.js | 94 | ||||
| -rwxr-xr-x | StoneIsland/platforms/ios/cordova/lib/clean.js | 46 | ||||
| -rwxr-xr-x | StoneIsland/platforms/ios/cordova/lib/copy-www-build-step.sh | 87 | ||||
| -rwxr-xr-x | StoneIsland/platforms/ios/cordova/lib/list-devices | 62 | ||||
| -rwxr-xr-x | StoneIsland/platforms/ios/cordova/lib/list-emulator-images | 53 | ||||
| -rwxr-xr-x | StoneIsland/platforms/ios/cordova/lib/list-started-emulators | 51 | ||||
| -rwxr-xr-x | StoneIsland/platforms/ios/cordova/lib/run.js | 177 | ||||
| -rwxr-xr-x | StoneIsland/platforms/ios/cordova/lib/spawn.js | 50 | ||||
| -rwxr-xr-x | StoneIsland/platforms/ios/cordova/lib/start-emulator | 30 | ||||
| -rwxr-xr-x | StoneIsland/platforms/ios/cordova/lib/versions.js | 178 |
11 files changed, 976 insertions, 0 deletions
diff --git a/StoneIsland/platforms/ios/cordova/lib/build.js b/StoneIsland/platforms/ios/cordova/lib/build.js new file mode 100755 index 00000000..153a4ec3 --- /dev/null +++ b/StoneIsland/platforms/ios/cordova/lib/build.js @@ -0,0 +1,148 @@ +/** + * 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. + */ + +/*jshint node: true*/ + +var Q = require('q'), + nopt = require('nopt'), + path = require('path'), + shell = require('shelljs'), + spawn = require('./spawn'), + check_reqs = require('./check_reqs'); + +var projectPath = path.join(__dirname, '..', '..'); + +module.exports.run = function (argv) { + + var args = nopt({ + // "archs": String, // TODO: add support for building different archs + 'debug': Boolean, + 'release': Boolean, + 'device': Boolean, + 'emulator': Boolean, + }, {'-r': '--release'}, argv); + + if (args.debug && args.release) { + return Q.reject('Only one of "debug"/"release" options should be specified'); + } + + if (args.device && args.emulator) { + return Q.reject('Only one of "device"/"emulator" options should be specified'); + } + + return check_reqs.run().then(function () { + return findXCodeProjectIn(projectPath); + }).then(function (projectName) { + var configuration = args.release ? 'Release' : 'Debug'; + + console.log('Building project : ' + path.join(projectPath, projectName + '.xcodeproj')); + console.log('\tConfiguration : ' + configuration); + console.log('\tPlatform : ' + (args.device ? 'device' : 'emulator')); + + var xcodebuildArgs = getXcodeArgs(projectName, projectPath, configuration, args.device); + return spawn('xcodebuild', xcodebuildArgs, projectPath); + }); +}; + +/** + * Searches for first XCode project in specified folder + * @param {String} projectPath Path where to search project + * @return {Promise} Promise either fulfilled with project name or rejected + */ +function findXCodeProjectIn(projectPath) { + // 'Searching for Xcode project in ' + projectPath); + var xcodeProjFiles = shell.ls(projectPath).filter(function (name) { + return path.extname(name) === '.xcodeproj'; + }); + + if (xcodeProjFiles.length === 0) { + return Q.reject('No Xcode project found in ' + projectPath); + } + if (xcodeProjFiles.length > 1) { + console.warn('Found multiple .xcodeproj directories in \n' + + projectPath + '\nUsing first one'); + } + + var projectName = path.basename(xcodeProjFiles[0], '.xcodeproj'); + return Q.resolve(projectName); +} + +module.exports.findXCodeProjectIn = findXCodeProjectIn; + +/** + * Returns array of arguments for xcodebuild + * @param {String} projectName Name of xcode project + * @param {String} projectPath Path to project file. Will be used to set CWD for xcodebuild + * @param {String} configuration Configuration name: debug|release + * @param {Boolean} isDevice Flag that specify target for package (device/emulator) + * @return {Array} Array of arguments that could be passed directly to spawn method + */ +function getXcodeArgs(projectName, projectPath, configuration, isDevice) { + var xcodebuildArgs; + if (isDevice) { + xcodebuildArgs = [ + '-xcconfig', path.join(__dirname, '..', 'build-' + configuration.toLowerCase() + '.xcconfig'), + '-project', projectName + '.xcodeproj', + 'ARCHS=armv7 armv7s arm64', + '-target', projectName, + '-configuration', configuration, + '-sdk', 'iphoneos', + 'build', + 'VALID_ARCHS=armv7 armv7s arm64', + 'CONFIGURATION_BUILD_DIR=' + path.join(projectPath, 'build', 'device'), + 'SHARED_PRECOMPS_DIR=' + path.join(projectPath, 'build', 'sharedpch') + ]; + } else { // emulator + xcodebuildArgs = [ + '-xcconfig', path.join(__dirname, '..', 'build-' + configuration.toLowerCase() + '.xcconfig'), + '-project', projectName + '.xcodeproj', + 'ARCHS=i386', + '-target', projectName , + '-configuration', configuration, + '-sdk', 'iphonesimulator', + 'build', + 'VALID_ARCHS=i386', + 'CONFIGURATION_BUILD_DIR=' + path.join(projectPath, 'build', 'emulator'), + 'SHARED_PRECOMPS_DIR=' + path.join(projectPath, 'build', 'sharedpch') + ]; + } + return xcodebuildArgs; +} + +// help/usage function +module.exports.help = function help() { + console.log(''); + console.log('Usage: build [ --debug | --release ] [--archs=\"<list of architectures...>\"] [--device | --simulator]'); + console.log(' --help : Displays this dialog.'); + console.log(' --debug : Builds project in debug mode. (Default)'); + console.log(' --release : Builds project in release mode.'); + console.log(' -r : Shortcut :: builds project in release mode.'); + // TODO: add support for building different archs + // console.log(" --archs : Builds project binaries for specific chip architectures (`anycpu`, `arm`, `x86`, `x64`)."); + console.log(' --device, --simulator'); + console.log(' : Specifies, what type of project to build'); + console.log('examples:'); + console.log(' build '); + console.log(' build --debug'); + console.log(' build --release'); + // TODO: add support for building different archs + // console.log(" build --release --archs=\"armv7\""); + console.log(''); + process.exit(0); +}; diff --git a/StoneIsland/platforms/ios/cordova/lib/check_reqs.js b/StoneIsland/platforms/ios/cordova/lib/check_reqs.js new file mode 100755 index 00000000..6b4cce56 --- /dev/null +++ b/StoneIsland/platforms/ios/cordova/lib/check_reqs.js @@ -0,0 +1,94 @@ +/* + 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. +*/ + +/* jshint node:true, bitwise:true, undef:true, trailing:true, quotmark:true, + indent:4, unused:vars, latedef:nofunc, + sub:true, laxcomma:true, laxbreak:true +*/ + +var Q = require('Q'), + os = require('os'), + shell = require('shelljs'), + versions = require('./versions'); + +var XCODEBUILD_MIN_VERSION = '4.6.0'; + +var IOS_SIM_MIN_VERSION = '3.0.0'; +var IOS_SIM_NOT_FOUND_MESSAGE = 'ios-sim was not found. Please download, build and install version ' + IOS_SIM_MIN_VERSION + + ' or greater from https://github.com/phonegap/ios-sim into your path.' + + ' Or \'npm install -g ios-sim\' using node.js: http://nodejs.org'; + +var IOS_DEPLOY_MIN_VERSION = '1.2.0'; +var IOS_DEPLOY_NOT_FOUND_MESSAGE = 'ios-deploy was not found. Please download, build and install version ' + IOS_DEPLOY_MIN_VERSION + + ' or greater from https://github.com/phonegap/ios-deploy into your path.' + + ' Or \'npm install -g ios-deploy\' using node.js: http://nodejs.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 () { + return checkTool('xcodebuild', XCODEBUILD_MIN_VERSION); +}; + +/** + * 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 () { + return checkTool('ios-deploy', IOS_DEPLOY_MIN_VERSION, IOS_DEPLOY_NOT_FOUND_MESSAGE); +}; + +/** + * Checks if ios-sim util is available + * @return {Promise} Returns a promise either resolved with ios-sim version or rejected + */ +module.exports.check_ios_sim = function () { + return checkTool('ios-sim', IOS_SIM_MIN_VERSION, IOS_SIM_NOT_FOUND_MESSAGE); +}; + +module.exports.help = function () { + console.log('Usage: check_reqs or node check_reqs'); +}; + +/** + * Checks if specific tool is available. + * @param {String} tool Tool name to check. Known tools are 'xcodebuild', 'ios-sim' and 'ios-deploy' + * @param {Number} minVersion Min allowed tool version. + * @param {String} optMessage Message that will be used to reject promise. + * @return {Promise} Returns a promise either resolved with tool version or rejected + */ +function checkTool (tool, minVersion, optMessage) { + if (os.platform() !== 'darwin'){ + // Build iOS apps available for OSX platform only, so we reject on others platforms + return Q.reject('Cordova tooling for iOS requires Apple OS X'); + } + // Check whether tool command is available at all + var tool_command = shell.which(tool); + if (!tool_command) { + return Q.reject(optMessage || (tool + 'command is unavailable.')); + } + // check if tool version is greater than specified one + return versions.get_tool_version(tool).then(function (version) { + return versions.compareVersions(version, minVersion) >= 0 ? + Q.resolve(version) : + Q.reject('Cordova needs ' + tool + ' version ' + minVersion + + ' or greater, you have version ' + version + '.'); + }); +} diff --git a/StoneIsland/platforms/ios/cordova/lib/clean.js b/StoneIsland/platforms/ios/cordova/lib/clean.js new file mode 100755 index 00000000..6d955cf1 --- /dev/null +++ b/StoneIsland/platforms/ios/cordova/lib/clean.js @@ -0,0 +1,46 @@ +/** + * 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. + */ + +/*jshint node: true*/ + +var Q = require('q'), + path = require('path'), + shell = require('shelljs'), + spawn = require('./spawn'), + check_reqs = require('./check_reqs'); + +var projectPath = path.join(__dirname, '..', '..'); + +module.exports.run = function() { + var projectName = shell.ls(projectPath).filter(function (name) { + return path.extname(name) === '.xcodeproj'; + })[0]; + + if (!projectName) { + return Q.reject('No Xcode project found in ' + projectPath); + } + + return check_reqs.run().then(function() { + 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')); + }); +}; diff --git a/StoneIsland/platforms/ios/cordova/lib/copy-www-build-step.sh b/StoneIsland/platforms/ios/cordova/lib/copy-www-build-step.sh new file mode 100755 index 00000000..7b934d5f --- /dev/null +++ b/StoneIsland/platforms/ios/cordova/lib/copy-www-build-step.sh @@ -0,0 +1,87 @@ +#!/bin/sh +# +# 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. + +SRC_DIR="www/" +DST_DIR="$BUILT_PRODUCTS_DIR/$FULL_PRODUCT_NAME/www" +COPY_HIDDEN= +ORIG_IFS=$IFS +IFS=$(echo -en "\n\b") + +if [[ -z "$BUILT_PRODUCTS_DIR" ]]; then + echo "The script is meant to be run as an Xcode build step and relies on env variables set by Xcode." + exit 1 +fi +if [[ ! -e "$SRC_DIR" ]]; then + echo "Path does not exist: $SRC_DIR" + exit 1 +fi + +# Use full path to find to avoid conflict with macports find (CB-6383). +if [[ -n $COPY_HIDDEN ]]; then + alias do_find='/usr/bin/find "$SRC_DIR"' +else + alias do_find='/usr/bin/find -L "$SRC_DIR" -name ".*" -prune -o' +fi + +time ( +# Code signing files must be removed or else there are +# resource signing errors. +rm -rf "$DST_DIR" \ + "$BUILT_PRODUCTS_DIR/$FULL_PRODUCT_NAME/_CodeSignature" \ + "$BUILT_PRODUCTS_DIR/$FULL_PRODUCT_NAME/PkgInfo" \ + "$BUILT_PRODUCTS_DIR/$FULL_PRODUCT_NAME/embedded.mobileprovision" + +# Directories +for p in $(do_find -type d -print); do + subpath="${p#$SRC_DIR}" + mkdir "$DST_DIR$subpath" || exit 1 +done + +# Symlinks +for p in $(do_find -type l -print); do + subpath="${p#$SRC_DIR}" + source=$(readlink $SRC_DIR$subpath) + sourcetype=$(stat -f "%HT%SY" $source) + if [ "$sourcetype" = "Directory" ]; then + mkdir "$DST_DIR$subpath" || exit 2 + else + rsync -a "$source" "$DST_DIR$subpath" || exit 3 + fi +done + +# Files +for p in $(do_find -type f -print); do + subpath="${p#$SRC_DIR}" + if ! ln "$SRC_DIR$subpath" "$DST_DIR$subpath" 2>/dev/null; then + rsync -a "$SRC_DIR$subpath" "$DST_DIR$subpath" || exit 4 + fi +done + +# Copy the config.xml file. +cp -f "${PROJECT_FILE_PATH%.xcodeproj}/config.xml" "$BUILT_PRODUCTS_DIR/$FULL_PRODUCT_NAME" + +) +IFS=$ORIG_IFS + diff --git a/StoneIsland/platforms/ios/cordova/lib/list-devices b/StoneIsland/platforms/ios/cordova/lib/list-devices new file mode 100755 index 00000000..a12abd74 --- /dev/null +++ b/StoneIsland/platforms/ios/cordova/lib/list-devices @@ -0,0 +1,62 @@ +#!/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. +*/ + +/*jshint node: true*/ + +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 (promises) { + var accumulator = []; + promises.forEach(function (promise) { + if (promise.state === 'fulfilled') { + // Each command promise resolves with array [stout, stderr], and we need stdout only + // Append stdout lines to accumulator + accumulator.concat(promise.value[0].trim().split('\n')); + } + }); + 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); + }); + }); +} diff --git a/StoneIsland/platforms/ios/cordova/lib/list-emulator-images b/StoneIsland/platforms/ios/cordova/lib/list-emulator-images new file mode 100755 index 00000000..0c7f0c55 --- /dev/null +++ b/StoneIsland/platforms/ios/cordova/lib/list-emulator-images @@ -0,0 +1,53 @@ +#!/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. +*/ + +/*jshint node: true*/ + +var Q = require('q'), + 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 check_reqs.check_ios_sim().then(function () { + return Q.nfcall(exec, 'ios-sim showdevicetypes 2>&1 | ' + + 'sed "s/com.apple.CoreSimulator.SimDeviceType.//g" | ' + + 'awk -F\',\' \'{print $1}\''); + }).then(function (stdio) { + // Exec promise resolves with array [stout, stderr], and we need stdout only + return stdio[0].trim().split('\n'); + }); +} + +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); + }); + }); +} diff --git a/StoneIsland/platforms/ios/cordova/lib/list-started-emulators b/StoneIsland/platforms/ios/cordova/lib/list-started-emulators new file mode 100755 index 00000000..1269e47a --- /dev/null +++ b/StoneIsland/platforms/ios/cordova/lib/list-started-emulators @@ -0,0 +1,51 @@ +#!/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. +*/ + +/*jshint node: true*/ + +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); + }); + }); +} diff --git a/StoneIsland/platforms/ios/cordova/lib/run.js b/StoneIsland/platforms/ios/cordova/lib/run.js new file mode 100755 index 00000000..151cad2a --- /dev/null +++ b/StoneIsland/platforms/ios/cordova/lib/run.js @@ -0,0 +1,177 @@ +/* + 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. +*/ + +/*jshint node: true*/ + +var Q = require('q'), + nopt = require('nopt'), + path = require('path'), + build = require('./build'), + spawn = require('./spawn'), + check_reqs = require('./check_reqs'); + +var cordovaPath = path.join(__dirname, '..'); +var projectPath = path.join(__dirname, '..', '..'); + +module.exports.run = function (argv) { + + // parse args here + // --debug and --release args not parsed here + // but still valid since they can be passed down to build command + var args = nopt({ + // "archs": String, // TODO: add support for building different archs + 'list': Boolean, + 'nobuild': Boolean, + 'device': Boolean, 'emulator': Boolean, 'target': String + }, {}, argv); + + // Validate args + if (args.device && args.emulator) { + return Q.reject('Only one of "device"/"emulator" options should be specified'); + } + + // validate target device for ios-sim + // Valid values for "--target" (case sensitive): + var validTargets = ['iPhone-4s', 'iPhone-5', 'iPhone-5s', 'iPhone-6-Plus', 'iPhone-6', + 'iPad-2', 'iPad-Retina', 'iPad-Air', 'Resizable-iPhone', 'Resizable-iPad']; + if (args.target && validTargets.indexOf(args.target) < 0 ) { + return Q.reject(args.target + ' is not a valid target for emulator'); + } + + // support for CB-8168 `cordova/run --list` + if (args.list) { + if (args.device) return listDevices(); + if (args.emulator) return listEmulators(); + // if no --device or --emulator flag is specified, list both devices and emulators + return listDevices().then(function () { + return listEmulators(); + }); + } + + // check for either ios-sim or ios-deploy is available + // depending on arguments provided + var checkTools = args.device ? check_reqs.check_ios_deploy() : check_reqs.check_ios_sim(); + + return checkTools.then(function () { + // if --nobuild isn't specified then build app first + if (!args.nobuild) { + return build.run(argv); + } + }).then(function () { + return build.findXCodeProjectIn(projectPath); + }).then(function (projectName) { + var appPath = path.join(projectPath, 'build', (args.device ? 'device' : 'emulator'), projectName + '.app'); + // select command to run and arguments depending whether + // we're running on device/emulator + if (args.device) { + return checkDeviceConnected().then(function () { + return deployToDevice(appPath); + }, function () { + // if device connection check failed use emulator then + return deployToSim(appPath, args.target); + }); + } else { + return deployToSim(appPath, args.target); + } + }); +}; + +/** + * Checks if any iOS device is connected + * @return {Promise} Fullfilled when any device is connected, rejected otherwise + */ +function checkDeviceConnected() { + return spawn('ios-deploy', ['-c']); +} + +/** + * Deploy specified app package to connected device + * using ios-deploy command + * @param {String} appPath Path to application package + * @return {Promise} Resolves when deploy succeeds otherwise rejects + */ +function deployToDevice(appPath) { + // Deploying to device... + return spawn('ios-deploy', ['-d', '-b', appPath]); +} + +/** + * Deploy specified app package to ios-sim simulator + * @param {String} appPath Path to application package + * @param {String} target Target device type + * @return {Promise} Resolves when deploy succeeds otherwise rejects + */ +function deployToSim(appPath, target) { + // Select target device for emulator. Default is 'iPhone-6' + if (!target) { + target = 'iPhone-6'; + console.log('No target specified for emulator. Deploying to ' + target + ' simulator'); + } + var logPath = path.join(cordovaPath, 'console.log'); + var simArgs = ['launch', appPath, + '--devicetypeid', 'com.apple.CoreSimulator.SimDeviceType.' + target, + // We need to redirect simulator output here to use cordova/log command + // TODO: Is there any other way to get emulator's output to use in log command? + '--stderr', logPath, '--stdout', logPath, + '--exit']; + return spawn('ios-sim', simArgs); +} + +function listDevices() { + return require('./list-devices').run() + .then(function (devices) { + console.log('Available iOS Devices:'); + devices.forEach(function (device) { + console.log('\t' + device); + }); + }); +} + +function listEmulators() { + return require('./list-emulator-images').run() + .then(function (emulators) { + console.log('Available iOS Virtual Devices:'); + emulators.forEach(function (emulator) { + console.log('\t' + emulator); + }); + }); +} + +module.exports.help = function () { + 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>\" ] "); + console.log(' --device : Deploys and runs the project on the connected device.'); + console.log(' --emulator : Deploys and runs the project on an emulator.'); + console.log(' --target=<id> : Deploys and runs the project on the specified target.'); + console.log(' --debug : Builds project in debug mode. (Passed down to build command, if necessary)'); + console.log(' --release : Builds project in release mode. (Passed down to build command, if necessary)'); + console.log(' --nobuild : Uses pre-built package, or errors if project is not built.'); + // TODO: add support for building different archs + // console.log(" --archs : Specific chip architectures (`anycpu`, `arm`, `x86`, `x64`)."); + console.log(''); + console.log('Examples:'); + console.log(' run'); + console.log(' run --device'); + console.log(' run --emulator --target=\"iPhone-6-Plus\"'); + console.log(' run --device --release'); + console.log(' run --emulator --debug'); + console.log(''); + process.exit(0); +};
\ No newline at end of file diff --git a/StoneIsland/platforms/ios/cordova/lib/spawn.js b/StoneIsland/platforms/ios/cordova/lib/spawn.js new file mode 100755 index 00000000..1cb31615 --- /dev/null +++ b/StoneIsland/platforms/ios/cordova/lib/spawn.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. +*/ + +/*jshint node: true*/ + +var Q = require('q'), + 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) { + console.error('error caught: ' + e); + d.reject(e); + } + return d.promise; +}; diff --git a/StoneIsland/platforms/ios/cordova/lib/start-emulator b/StoneIsland/platforms/ios/cordova/lib/start-emulator new file mode 100755 index 00000000..624335b1 --- /dev/null +++ b/StoneIsland/platforms/ios/cordova/lib/start-emulator @@ -0,0 +1,30 @@ +#!/usr/bin/env bash +# +# 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. +# +# Run the below to get the device targets: +# xcrun instruments -s + +set -e + + +DEFAULT_TARGET="iPhone 5s" +TARGET=${1:-$DEFAULT_TARGET} +LIB_PATH=$( cd "$( dirname "$0" )" && pwd -P) + +xcrun instruments -w "$TARGET" &> /dev/null
\ No newline at end of file diff --git a/StoneIsland/platforms/ios/cordova/lib/versions.js b/StoneIsland/platforms/ios/cordova/lib/versions.js new file mode 100755 index 00000000..e22e499a --- /dev/null +++ b/StoneIsland/platforms/ios/cordova/lib/versions.js @@ -0,0 +1,178 @@ +#!/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. +*/ + +var child_process = require('child_process'), + Q = require('q'); + +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); + } + }); + + return d.promise.then(function(output) { + var regex = /[0-9]*\.[0-9]*/, + versions = [], + 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); + }); +}; + +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); + } + }); + + return d.promise.then(function(output) { + var regex = /[0-9]*\.[0-9]*/, + versions = [], + 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_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; +}; + +/** + * Gets ios-deploy util version + * @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; +}; + +/** + * Gets ios-sim util version + * @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; +}; + +/** + * Gets specific tool version + * @param {String} toolName Tool name to check. Known tools are 'xcodebuild', 'ios-sim' and 'ios-deploy' + * @return {Promise} Promise that either resolved with tool version + * or rejected in case of error + */ +exports.get_tool_version = function (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(); + default: return Q.reject(toolName + ' is not valid tool name. Valid names are: \'xcodebuild\', \'ios-sim\' and \'ios-deploy\''); + } +}; + +/** + * Compares two semver-notated version strings. Returns number + * that indicates equality of provided version strings. + * @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); + + // 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; +}; |
