appc-cli-ios
Version:
create an ios native project
133 lines (120 loc) • 3.84 kB
JavaScript
var fs = require('fs'),
os = require('os'),
path = require('path'),
exec = require('child_process').exec,
ioslib = require('ioslib');
var TYPE = require('../appc').TYPE;
module.exports = {
type: TYPE,
subtype: 'app',
execute: run,
when: function(opts) {
opts = opts || {};
// this command only runs when we are in a workspace directory or a specific titanium directory
if (opts.workspace) {
var workspace = isString(opts.workspace) ? opts.workspace : process.cwd();
var manifest = path.join(workspace, 'appc.json');
if (fs.existsSync(manifest)) {
return fs.existsSync(path.join(path.dirname(manifest), 'app', 'Info.plist'));
}
}
return fs.existsSync(path.join(process.cwd(), 'Info.plist'));
}
};
function run(appc, args, opts, callback) {
var _ = appc.lodash;
// are we running titanium directly or via an appc project?
var workspace = path.resolve(opts.workspace || '.'),
projectDir = workspace;
// check workspace and map path to projectDir
if (fs.existsSync(path.join(workspace, 'app', 'Info.plist'))) {
projectDir = path.join(workspace, 'app');
} else if (fs.existsSync(path.join(workspace, 'Info.plist'))) {
projectDir = workspace;
} else {
return callback(new Error('app project does not exist'));
}
var file = _.filter(fs.readdirSync(projectDir), function(e) {
return path.basename(e).indexOf('.xcodeproj')!==-1;
})[0],
name = path.basename(file).replace('.xcodeproj','');
launchSimulator(appc, opts, projectDir, name, callback);
}
function xcodebuild(appc, dir, configuration, sdk, target, callback) {
var cmd = 'xcodebuild -configuration '+configuration+' -sdk '+sdk+ ' -target '+target;
appc.log.debug(cmd);
appc.log.info('Building App');
exec(cmd, {cwd:dir}, callback);
}
function launchSimulator(appc, opts, dir, name, callback) {
var _ = appc.lodash,
spinner = appc.spinner;
spinner.start();
ioslib.detect(function (err, info) {
if (err) {
spinner.stop();
return callback(err);
} else {
if (info.selectedXcode) {
var selectedXcode = info.selectedXcode,
xcode = info.xcode[selectedXcode.version+':'+selectedXcode.build],
ver = xcode.sdks[0],
sim = xcode.sims[0],
findSimFilter = opts.udid ? function(s) { return s.udid === opts.udid; } :
function(s) { return s.name === 'iPhone 4s'; };
if (ver) {
var sims = info.simulators[sim],
found = _.filter(sims, findSimFilter);
if (found && found.length) {
return xcodebuild(appc, dir, 'Debug', 'iphonesimulator'+ver, name, function(err,stdout,stderr){
if (err) {
spinner.stop();
return callback(err);
}
var app = path.join(dir, 'build', 'Debug-iphonesimulator',name+'.app');
if (fs.existsSync(app)) {
var simchild = ioslib.simulator.launch(null,{
appPath:app,
appName:name,
simVersion: sim
});
var returned;
function next() {
if (returned) { return; }
returned = true;
callback();
}
simchild.on('app-started',function(handle){
appc.log.info('App launched in simulator');
next();
});
simchild.on('log',function(msg){
appc.log.info.wrap(msg);
});
simchild.on('error',next);
simchild.on('timeout',next);
simchild.on('app-quit',next);
spinner.stop();
}
else {
spinner.stop();
console.error(stderr);
return callback(new Error("xcodebuild failed"));
}
});
}
}
}
}
});
}
if (module.id === ".") {
launchSimulator({
log: { info: function(msg){ console.log(msg) } }
},{},path.join(__dirname,'../tmp'),'foo',function(err){
err && console.log(err);
});
}
function isString(o) {
return Object.prototype.toString.call(o) === '[object String]';
}