UNPKG

ionic

Version:

A tool for creating and developing Ionic Framework mobile apps.

291 lines (252 loc) • 8.53 kB
var Task = require('./task').Task, IonicStats = require('./stats').IonicStats, fs = require('fs'), Q = require('q'), // argv = require('optimist').boolean(['nohooks', 'n', 'r', 'noresources', 'nosave', 'e']).argv, path = require('path'), exec = require('child_process').exec, colors = require('colors'), shelljs = require('shelljs'), generate = require('./resources/generate'), settings = require('./resources/settings'), ionicAppLib = require('ionic-app-lib'), ConfigXml = ionicAppLib.configXml, Cordova = ionicAppLib.cordova, Hooks = ionicAppLib.hooks, Serve = ionicAppLib.serve, State = ionicAppLib.state, Utils = ionicAppLib.utils; var IonicTask = function() {}; IonicTask.prototype = new Task(); IonicTask.prototype.run = function(ionic, argv) { this.ionic = ionic; var self = this; var cmdName = process.argv[2].toLowerCase(); var q; try { this.isLiveReload = ((cmdName == 'run' || cmdName == 'emulate') && (argv.livereload || argv['live-reload'] || argv.l)); this.addIcons = !(argv.noresources || argv.r); if(this.isLiveReload) { q = self.setupLiveReload(argv); } else { // ensure the content node was set back to its original q = self.ionic.setConfigXml({ resetContent: true, errorWhenNotFound: false }); } var addDefaultResources = false; var isPlatformCmd = argv._.indexOf('platform') != -1 || argv._.indexOf('platforms') != -1; var isAddCmd = argv._.indexOf('add') != -1; var isPluginCmd = argv._.indexOf('plugin') != -1; var isRmCmd = argv._.indexOf('rm') != -1 || argv._.indexOf('remove') != -1; if (isPlatformCmd || isAddCmd) { Hooks.setHooksPermission(process.cwd()); } if(isPlatformCmd && isAddCmd) { addDefaultResources = true; } return q.then(function(serveOptions){ if (self.isLiveReload) { self.options = serveOptions; } if(addDefaultResources && self.addIcons) { return generate.copyIconFilesIntoResources() .then(function() { return generate.addIonicIcons(argv._[2]); }) } else { return false; } }) .then(function() { return self.runCordova(cmdName, argv); }) .then(function(runCode) { //We dont want to do anything if the cordova command failed if(runCode !== 0 || argv.nosave) { return } var argumentName = argv._[2]; if (isPlatformCmd && isAddCmd) { addDefaultResources = true; console.log('Saving platform to package.json file'.blue) return State.savePlatform(process.cwd(), argumentName); } else if (isPlatformCmd && isRmCmd) { console.log('Removing platform from package.json file'.blue) return State.removePlatform(process.cwd(), argumentName); } else if (isPluginCmd && isAddCmd) { console.log('Saving plugin to package.json file'.blue) return State.savePlugin(process.cwd(), argumentName, argv.variable); } else if (isPluginCmd && isRmCmd) { console.log('Removing plugin from package.json file'.blue) return State.removePlugin(process.cwd(), argumentName); } }) .catch(function(ex) { console.log('Error happened', ex) console.log(ex.stack); throw ex; }); } catch (ex) { Utils.fail('An error occurred running a Cordova command:' + ex); } } IonicTask.prototype.runCordova = function(cmdName, argv) { var deferred = Q.defer(); var self = this; var cmdArgs = (process.argv.length > 3 ? process.argv.slice(3) : []); var cmdArg, x, y; // backwards compatibility prior to fully wrapping cordova cmds if(cmdName == 'platform') { // `ionic platform <PLATFORM>` used to actually run `ionic platform add <PLATFORM>` // if a cordova platform cmd isn't the cmd then automatically insert `add` var hasCordovaCmd = false; var validCommands = 'add remove rm list ls update up check'.split(' '); for(x=0; x<cmdArgs.length; x++) { cmdArg = cmdArgs[x].toLowerCase(); for(y=0; y<validCommands.length; y++) { if(cmdArg == validCommands[y]) { hasCordovaCmd = true; break; } } } if(!hasCordovaCmd) { cmdArgs.unshift('add'); } } cmdArgs.unshift(cmdName); // clean out any cmds that may confuse cordova var cleanArgs = []; var port = argv.port || argv.p || ''; var liveReloadPort = argv.livereloadport || argv['livereload-port'] || argv.r || ''; var ignoreCmds = '--livereload -l --consolelogs -c --serverlogs -s --port -p --livereload-port -i -r'.split(' '); var isValdCmd; for(x=0; x<cmdArgs.length; x++) { cmdArg = cmdArgs[x]; if(port && cmdArg == port) continue; if(liveReloadPort && cmdArg == liveReloadPort) continue; isValdCmd = true; for(y=0; y<ignoreCmds.length; y++) { if(cmdArg == ignoreCmds[y]) { isValdCmd = false; break; } } if(isValdCmd) { // make sure --target= has double quotes around it (process.argv removes them) if(cmdArg.indexOf('--target=') === 0 && cmdArg.indexOf('"') === -1) { cmdArg = cmdArg.replace('--target=', '--target="') + '"'; } cleanArgs.push(cmdArg); } } var cordovaProcess = exec('cordova ' + cleanArgs.join(' ')); // console.log('running cordova ' + cleanArgs.join(' ')); cordovaProcess.stdout.on('data', function (data) { process.stdout.write(data); }); cordovaProcess.stderr.on('data', function (data) { if(data) { process.stderr.write(data.toString().error.bold); } }); cordovaProcess.on('close', function(code) { deferred.resolve(code); }); if(self.isLiveReload) { cordovaProcess.on('exit', function(){ // Serve.showFinishedServeMessage(self.options); Serve.printCommandTips(self.options); setTimeout(function(){ // set it back to the original src after a few seconds ConfigXml.setConfigXml(process.cwd(), { resetContent: true, errorWhenNotFound: true }); // deferred.resolve(); }, 5000); }); process.on('exit', function(){ // verify it was set back self.ionic.setConfigXml( process.cwd(), { resetContent: true, errorWhenNotFound: false }); }); var readLine = require("readline"); if(process.platform === "win32") { var rl = readLine.createInterface ({ input: process.stdin, output: process.stdout }); rl.on("SIGINT", function (){ process.emit("SIGINT"); }); } process.on("SIGINT", function(){ process.exit(); }); } IonicStats.t(); return deferred.promise; }; IonicTask.prototype.setupLiveReload = function(argv) { var d = Q.defer(); console.log('Setup Live Reload'.green.bold); var project = null; try { project = IonicProject.load(process.cwd()); } catch (ex) { console.log('Error occured', ex); return Utils.fail(ex.message); } var options = Serve.loadSettings(argv, project); // options.address = '0.0.0.0'; options.appDirectory = process.cwd();//called from cli - ionic serve - cwd is this options.runLivereload = true; options.launchBrowser = false; options.launchLab = false; options.isPlatformServe = true; // First ask user for the IP selection // Check ports not used // Set up config.xml src url // run the cordova command var promise; if (argv.all) { promise = Q(); console.log('Defaulting address to 0.0.0.0'); options.address = '0.0.0.0'; } else { promise = Serve.getAddress(options); } return promise .then(function() { options.devServer = Serve.host(options.address, options.port); return Serve.checkPorts(true, options.port, options.address, options); }) .then(function() { if(options.runLivereload) { return Serve.checkPorts(false, options.liveReloadPort, options.address, options); } }) .then(function() { ConfigXml.setConfigXml( process.cwd(), { devServer: Serve.host(options.address, options.port) }).then(function(){ d.resolve(); }); return Serve.start(options); }) .then(function() { Serve.showFinishedServeMessage(options); return options; }) .catch(function(error) { console.log('There was an error serving your Ionic application for run', error); console.log(error.stack); throw error; }); }; exports.IonicTask = IonicTask;