UNPKG

ionic

Version:

A tool for creating and developing Ionic Framework mobile apps.

337 lines (284 loc) • 9.72 kB
var fs = require('fs'), Q = require('q'), path = require('path'), argv = require('optimist').argv, connect = require('connect'), finalhandler = require('finalhandler'), http = require('http'), serveStatic = require('serve-static'), tinylr = require('tiny-lr-fork'), lr = require('connect-livereload'), vfs = require('vinyl-fs'), request = require('request'), IonicProject = require('./project'), Task = require('./task').Task, proxyMiddleware = require('proxy-middleware'), url = require('url'), xml2js = require('xml2js'), IonicStats = require('./stats').IonicStats, ionicCliLib = require('ionic-app-lib'), Serve = ionicCliLib.serve, shelljs = require('shelljs'), events = ionicCliLib.events, ports = require('./ports'); var DEFAULT_HTTP_PORT = 8100; var DEFAULT_LIVE_RELOAD_PORT = 35729; var IONIC_LAB_URL = '/ionic-lab'; var IonicTask = function() {}; IonicTask.prototype = new Task(); IonicTask.prototype.run = function(ionic) { var self = this; this.ionic = ionic; this.port = argv._[1]; this.liveReloadPort = argv._[2]; var options = Serve.loadSettings(argv); options.appDirectory = process.cwd();//called from cli - ionic serve - cwd is this //TODO: Look up address stuffs var promise; try { if (argv.all || argv.a) { options.address = '0.0.0.0'; promise = Q(); } else { promise = Serve.getAddress(options); } return promise .then(function() { 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() { return Serve.start(options); }) .then(function() { return Serve.showFinishedServeMessage(options); }) .then(function() { // return Serve.listenToServeLogs(options); events.on('serverlog', console.log); events.on('consolelog', console.log); }) .catch(function(error) { console.log('There was an error serving your Ionic application:', error); throw error; }) } catch (ex) { Utils.fail('Error with serve- ' + ex); console.log(ex.stack); } // return; // this.loadSettings(); // this.getAddress() // .then(function() { // return self.checkPorts(true, self.port, self.address); // }) // .then(function() { // if(self.runLivereload) { // return self.checkPorts(false, self.liveReloadPort, self.address); // } // }) // .then(function() { // if(self.isAddressCmd) { // console.log( self.address ); // process.exit(); // } // self.start(ionic) // // self.printCommandTips(); // // console.log('listenForServerCommands') // // self.listenForServerCommands(); // if(ionic.hasFailed) return; // ionic.latestVersion.promise.then(function(){ // ionic.printVersionWarning(); // }); // }) // .catch(function(error) { // }) }; //isIonicServer = true when serving www directory, false when live reload IonicTask.prototype.checkPorts = function(isIonicServer, testPort, testHost) { var q = Q.defer(); var self = this, message = []; if(isIonicServer) { testHost = this.address == 'localhost' ? null : this.address; } else { testHost = null; } ports.getPort({port: testPort, host: testHost}, function(err, port) { if(port != testPort) { message = ['The port ', testPort, ' was taken on the host ', self.address, ' - using port ', port, ' instead'].join(''); console.log(message.yellow.bold); if(isIonicServer) { self.port = port; } else { self.liveReloadPort = port; } } q.resolve(); }); return q.promise; } IonicTask.prototype.loadSettings = function(cb) { var project = null; try { project = IonicProject.load(); } catch (ex) { this.ionic.fail(ex.message); return } var self = this; this.port = this.port || argv.port || argv.p || DEFAULT_HTTP_PORT; this.liveReloadPort = this.liveReloadPort || argv.livereloadport || argv.r || argv['livereload-port'] || argv.i || DEFAULT_LIVE_RELOAD_PORT; this.launchBrowser = !argv.nobrowser && !argv.b; this.launchLab = this.launchBrowser && (argv.lab || argv.l); this.runLivereload = !(argv.nolivereload || argv.d); this.useProxy = !argv.noproxy && !argv.x; this.proxies = project.get('proxies') || []; this.watchSass = project.get('sass') === true && !argv.nosass && !argv.n; this.gulpStartupTasks = project.get('gulpStartupTasks'); this.browser = argv.browser || argv.w || ''; this.browserOption = argv.browserOption || argv.o || ''; //Check for default browser being specified this.defaultBrowser = argv.defaultBrowser || argv.f || project.get('defaultBrowser'); if(this.defaultBrowser) { project.set('defaultBrowser', this.defaultBrowser); project.save(); } this.browser = this.browser || this.defaultBrowser; this.watchPatterns = project.get('watchPatterns') || ['www/**/*', '!www/lib/**/*']; this.printConsoleLogs = argv.consolelogs || argv['console-logs'] || argv.c; this.printServerLogs = argv.serverlogs || argv['server-logs'] || argv.s; this.isAddressCmd = argv._[0].toLowerCase() == 'address'; this.documentRoot = project.get('documentRoot') || 'www'; this.createDocumentRoot = project.get('createDocumentRoot') || null; this.contentSrc = path.join(this.documentRoot, this.ionic.getContentSrc()); }; IonicTask.prototype.getAddress = function(cb) { var q = Q.defer(); try { var self = this; var addresses = []; var os = require('os'); var ifaces = os.networkInterfaces(); var ionicConfig = require('./config').load(); var addressConfigKey = (self.isPlatformServe ? 'platformServeAddress' : 'ionicServeAddress'); var tryAddress; if(self.isAddressCmd) { // reset any address configs ionicConfig.set('ionicServeAddress', null); ionicConfig.set('platformServeAddress', null); } else { if(!argv.address) tryAddress = ionicConfig.get(addressConfigKey); else tryAddress = argv.address; } if(ifaces){ for (var dev in ifaces) { if(!dev) continue; ifaces[dev].forEach(function(details){ if (details && details.family == 'IPv4' && !details.internal && details.address) { addresses.push({ address: details.address, dev: dev }); } }); } } if(tryAddress) { if(tryAddress == 'localhost') { self.address = tryAddress; // cb(); q.resolve(); return q.promise; } for(var x=0; x<addresses.length; x++) { // double check if this address is still available if(addresses[x].address == tryAddress) { self.address = addresses[x].address; // cb(); q.resolve(); return q.promise; } } if (argv.address) { self.ionic.fail('Address ' + argv.address + ' not available.'); return q.promise; } } if(addresses.length > 0) { if(!self.isPlatformServe) { addresses.push({ address: 'localhost' }); } if(addresses.length === 1) { self.address = addresses[0].address; // cb(); q.resolve(); return q.promise; } console.log('\nMultiple addresses available.'.error.bold); console.log('Please select which address to use by entering its number from the list below:'.error.bold); if(self.isPlatformServe) { console.log('Note that the emulator/device must be able to access the given IP address'.small); } for(var x=0; x<addresses.length; x++) { console.log( (' ' + (x+1) + ') ' + addresses[x].address + ( addresses[x].dev ? ' (' + addresses[x].dev + ')' : '' )).yellow ); } console.log('Std in before prompt') // console.log(process.stdin) var prompt = require('prompt'); var promptProperties = { selection: { name: 'selection', description: 'Address Selection: '.yellow.bold, required: true } }; prompt.override = argv; prompt.message = ''; prompt.delimiter = ''; prompt.start(); prompt.get({properties: promptProperties}, function (err, promptResult) { if(err) { return console.log(err); } var selection = promptResult.selection; for(var x=0; x<addresses.length; x++) { if(selection == (x + 1) || selection == addresses[x].address || selection == addresses[x].dev) { self.address = addresses[x].address; if(!self.isAddressCmd) { console.log('Selected address: '.green.bold + self.address); } ionicConfig.set(addressConfigKey, self.address); // cb(); prompt.resume(); q.resolve(); return q.promise; } } self.ionic.fail('Invalid address selection'); }); } else if(self.isPlatformServe) { // no addresses found self.ionic.fail('Unable to find an IPv4 address for run/emulate live reload.\nIs WiFi disabled or LAN disconnected?'); } else { // no address found, but doesn't matter if it doesn't need an ip address and localhost will do self.address = 'localhost'; // cb(); q.resolve(); } } catch(e) { self.ionic.fail('Error getting IPv4 address: ' + e); } return q.promise; }; exports.IonicTask = IonicTask;