UNPKG

appc-cli-titanium

Version:
254 lines (230 loc) 7.28 kB
/** * This code is closed source and Confidential and Proprietary to * Appcelerator, Inc. All Rights Reserved. This code MUST not be * modified, copied or otherwise redistributed without express * written permission of Appcelerator. This file is licensed as * part of the Appcelerator Platform and governed under the terms * of the Appcelerator license agreement. */ var async = require('async'), util = require('./util'); var TYPE = require('../appc').TYPE; module.exports = { type: TYPE, name: 'Cross Platform Mobile App Setup', execute: execute }; function execute(appc, args, opts, callback) { appc.inquirer.prompt([ { message: 'Do you plan on developing Titanium apps?', name: 'confirm', type: 'confirm', default: 'Y' } ], function (answers) { if (!answers.confirm) { return callback(); } else { var config, latestVersion; async.series([ // launch info (which will automatically install sdk) function (cb) { console.log('\nChecking your environment...\n'); appc.spinner.start(); cb(); }, function (cb) { util.getLatestTiSDK(appc, function (err, latest) { if (latest) { latestVersion = latest; } cb(err); }); }, function (cb) { util.launchTi(appc, [ 'sdk', '-o', 'json', '--no-banner', '--no-prompt' ], opts, function (err, ti) { if (err) { return cb(err); } var stdout = '', stderr = ''; ti.stdout.on('data', function (buf) { buf = String(buf).replace(/\s$/, ''); appc.log.trace(buf); stdout += buf; }); ti.on('close', function (err) { if (err) { appc.log.debug(err); appc.log.debug(stderr); return cb(new Error('titanium exited with ' + err + ' exit code')); } try { config = JSON.parse(stdout); // check if active sdk is installed if (!(config.activeSDK in config.installed)) { // active sdk is not installed // select latest installed sdk var version = Object.keys(config.installed)[0]; async.series([ function (cb) { // select most recent installed sdk util.launchTi(appc, [ 'sdk', 'select', version ], opts, cb); }, function (cb) { // check for new version util.installTi(appc, cb); } ], function () { cb(); } ); } else if (util.ltSdkVersion(config.activeSDK, latestVersion)) { if (latestVersion in config.installed) { appc.log.info('You have the latest Titanium SDK release ' + appc.chalk.blue(latestVersion) + ', but it\'s not currently set as the active SDK.'); appc.log.info('Changing your active version to the latest. You can reset it to the previous version by running:\n'); appc.log.info('\t' + appc.chalk.cyan('appc ti sdk select ' + config.activeSDK) + '\n'); util.launchTi(appc, [ 'sdk', 'select', latestVersion ], opts, cb); } else { // need to get the latest appc.log.info('A new version of the Titanium SDK is available, will download it...'); util.installTi(appc, cb); } } else { appc.log.info('You have the latest Titanium SDK release ' + appc.chalk.blue(config.activeSDK)); cb(); } } catch (E) { appc.log.trace(stdout); appc.log.trace(E.message || E); appc.log.trace(E.stack); return cb(new Error('invalid config results returned from titanium. (JSON parse error)')); } }); }); }, function (cb) { util.launchTi(appc, [ 'info', '-o', 'json', '--no-banner', '--no-prompt' ], opts, function (err, ti) { appc.spinner.stop(); if (err) { return cb(err); } var stdout = '', stderr = ''; ti.stdout.on('data', function (buf) { buf = String(buf).replace(/\s$/, ''); appc.log.trace(buf); stdout += buf; }); ti.stderr.on('data', function (buf) { buf = String(buf).replace(/\s$/, ''); appc.log.trace(buf); stderr += buf + '\n'; }); ti.on('close', function (err) { if (err) { appc.log.debug(err); appc.log.debug(stderr); return cb(new Error('titanium exited with ' + err + ' exit code')); } try { config = JSON.parse(stdout); cb(); } catch (E) { appc.log.trace(stdout); appc.log.trace(E.message || E); return cb(new Error('invalid config results returned from titanium. (JSON parse error)')); } }); }); }, // now see what's missing function (cb) { var count = 0; Object.keys(config).forEach(function (key) { var obj = config[key]; count += dumpIssues(appc, obj, key); }); if (count) { appc.log.warn(appc.chalk.white.underline('Some issues were detected for your environment\n')); console.log(appc.chalk.yellow('\tPlease review the above found issues that were detected for your environment.')); console.log(appc.chalk.yellow('\tYou should resolve these issues before building or running a cross platform app.')); console.log(appc.chalk.yellow('\tYou can re-run setup once they are resolved to validate.')); console.log(); } else { console.log(appc.chalk.green('Congrats! No issues detected for developing cross-platform mobile apps!')); console.log(); } cb(); } ], function (err) { appc.spinner.stop(); return callback(err); }); } }); } /** * tokenize a string a word breaks (spaces) such that we have a line * no longer than maxwidth */ function tokenize(line, maxwidth, result) { var toks = line.split(' '), len = 0, tokenizedLine = '', i = 0; while (i < toks.length) { var token = toks[i]; if (token.length + len >= maxwidth) { len = 0; result.push(tokenizedLine); line = ''; } tokenizedLine += token + ' '; len += token.length; i++; } if (len < maxwidth && line) { result.push(tokenizedLine); } } /** * do a nice dump of the issues found by ti info */ function dumpIssues(appc, obj, label) { var issues = getErrors(obj), issueLinkRegex = /__(.*)__/g; if (!issues) { return 0; } var msgs = []; var maxwidth = Math.max(Math.floor(process.stdout.columns * 0.75), 70); issues.forEach(function (issue) { var lines = []; util.patchTiCommand(issue.message).split('\n').forEach(function (line) { tokenize(line, maxwidth, lines); }); var msg = lines.map(function (line, index) { return '\t' + line.replace(issueLinkRegex, function (msg) { return appc.chalk.blue.underline(issueLinkRegex.exec(msg)[1]); }); }).join('\n') + '\n'; msgs.push(appc.chalk.red(msg)); }); appc.log.warn(appc.chalk.yellow('The following ' + appc.chalk.green.underline(label.toUpperCase()) + ' issues were found in your environment:\n\n') + msgs.join('\n')); return issues.length; } function getErrors(obj) { if (!obj || !obj.issues || !obj.issues.length) { return null; } var errors = []; obj.issues.forEach(function (o) { if (o.type === 'error') { errors.push(o); } }); return errors.length ? errors : null; }