UNPKG

ionic

Version:

A tool for creating and developing Ionic Framework mobile apps.

391 lines (328 loc) • 11.7 kB
var fs = require('fs'); var path = require('path'); var argv = require('optimist').argv; var exec = require('child_process').exec; var Q = require('q'); var IonicInfo = require('./info'); var IonicProject = require('./project'); var chalk = require('chalk'); var Utils = require('./utils'); var logging = require('./logging'); var Setup = module.exports; Setup.modifyIndexFile = function modifyIndexFile(appDirectory) { var indexPath = path.join(appDirectory, path.join('www', Utils.getContentSrc(appDirectory))); var lines; var line; var keepLine; var activeRemoving; var cleanedLines = []; logging.logger.debug('Setup.modifyIndexFile for ' + appDirectory); try { lines = fs.readFileSync(indexPath, 'utf8').split('\n'); } catch (e) { Q.reject(e); return Utils.fail('Error loading ' + indexPath); } try { activeRemoving = false; for (var x = 0; x < lines.length; x += 1) { line = lines[x]; keepLine = true; if (/<!--(.*?) sass (.*?)/gi.test(line)) { line = ' <!-- compiled css output -->'; activeRemoving = true; } else if (activeRemoving && /(.*?)-->(.*?)/gi.test(line)) { keepLine = false; activeRemoving = false; } else if (/lib\/ionic\/css\/ionic.css|css\/style.css/gi.test(line)) { keepLine = false; } if (keepLine) { cleanedLines.push(line); } } var project = null; try { project = IonicProject.load(); } catch (ex) { Utils.fail(ex.message); return; } var gulpStartupTasks = project.get('gulpStartupTasks') || []; var hasSass; var hasWatch; gulpStartupTasks.forEach(function(taskName) { if (taskName === 'sass') hasSass = true; if (taskName === 'watch') hasWatch = true; }); if (!hasSass) gulpStartupTasks.push('sass'); if (!hasWatch) gulpStartupTasks.push('watch'); project.set('gulpStartupTasks', gulpStartupTasks); if (!project.get('watchPatterns')) { project.set('watchPatterns', ['www/**/*', '!www/lib/**/*', '!www/**/*.map']); } project.save(); fs.writeFileSync(indexPath, cleanedLines.join('\n'), 'utf8'); logging.logger.info(chalk.green.bold('Updated ') + indexPath.bold + chalk.yellow.bold(' <link href>') + chalk.green.bold(' references to sass compiled css')); logging.logger.info(chalk.green.bold('\nIonic project ready to use Sass!')); logging.logger.info(chalk.yellow.bold(' * Customize the app using'), chalk.bold('scss/ionic.app.scss')); logging.logger.info(chalk.yellow.bold(' * Run'), chalk.bold('ionic serve'), chalk.yellow.bold('to start a local dev server and watch/compile Sass to CSS')); logging.logger.info(''); } catch (e) { throw new Error('Error parsing ' + indexPath + ': ' + e); } return Q(); }; Setup.sassSetup = function sassSetup(appDirectory) { var q = Q.defer(); if (!Utils.gulpInstalledGlobally()) { var gulpMessage = [ chalk.red('You have specified Ionic CLI to set up sass.'), '\n', chalk.red('However, you do not have Gulp installed globally. Please run '), chalk.green('`npm install -g gulp`') ].join(''); logging.logger.info(gulpMessage); return Q(gulpMessage); } logging.logger.debug('Setup.sassSetup for ' + appDirectory); Setup.npmInstall(appDirectory) .then(function(){ return Setup.modifyIndexFile(appDirectory); }) .then(function() { return Setup.buildSass(appDirectory); }) .then(q.resolve) .catch(function(ex) { q.reject(ex); return Utils.fail('Exception with '); }); return q.promise; }; Setup.buildSass = function buildSass(appDirectory) { logging.logger.debug('Setup.buildSass for ' + appDirectory); var q = Q.defer(); var prevDir = process.cwd(); process.chdir(appDirectory); var childProcess = exec('gulp sass'); childProcess.stdout.on('data', function(data) { process.stdout.write(data); }); childProcess.stderr.on('data', function(data) { if (data) { process.stderr.write(chalk.yellow(data.toString())); } }); childProcess.on('exit', function(code) { process.chdir(prevDir); process.stderr.write('\n'); if (code === 0) { logging.logger.info(chalk.green.bold('Successful ') + chalk.bold('sass build')); q.resolve(); } else { logging.logger.info(chalk.error.bold('Error running ') + chalk.bold('gulp sass')); q.reject(); } }); return q.promise; }; Setup.npmInstall = function npmInstall(appDirectory) { logging.logger.debug('Setup.npmInstall at ' + appDirectory); var q = Q.defer(); var prevDir = process.cwd(); process.chdir(appDirectory); var childProcess = exec('npm install'); childProcess.stdout.on('data', function(data) { process.stdout.write(data); }); childProcess.stderr.on('data', function(data) { if (data) { data = data.toString(); if (!/no repository field/gi.test(data)) { process.stderr.write(chalk.yellow(data)); } } }); childProcess.on('exit', function(code) { process.chdir(prevDir); process.stderr.write('\n'); if (code === 0) { logging.logger.info(chalk.green.bold('Successful ') + chalk.bold('npm install')); q.resolve(); } else { logging.logger.info(chalk.bold.red('Error running ') + chalk.bold('npm install')); q.reject(); } }); return q.promise; }; // Before any of this happens, check cordova CLI version. If they are prior to 4.3.0, they need // to install platforms first. Alert user of this. Setup.checkPreReqs = function checkPreReqs() { var semver = require('semver'); var envInfo = IonicInfo.gatherInfo(); var platformsExist = false; var platformsIosStats; var platformsAndroidStats; var hasPreReqs = true; try { platformsIosStats = fs.statSync(path.resolve('platforms', 'ios')); platformsAndroidStats = fs.statSync(path.resolve('platforms', 'android')); platformsExist = platformsIosStats.isDirectory() || platformsAndroidStats.isDirectory(); } catch (ex) { } // default to false. It wont reach last line if ENOENT for ios/android try { if (!platformsExist && semver.satisfies(envInfo.cordova, '<=4.3.0')) { logging.logger.info('You are using a version of Cordova less than 4.3.0. There is a ' + 'known issue if you add plugins before platforms are added.'); logging.logger.info('We highly suggest you add your platforms before running this command.'); hasPreReqs = false; } } catch (ex) { logging.logger.error('Error checking your Cordova CLI version: %s', ex, {}); } return hasPreReqs; }; Setup.setupFacebook = function setupFacebook(appDirectory) { var facebookAppUrl = 'https://developers.facebook.com/apps/'; var installMessage = [ 'The Facebook plugin will be setup.\nYou will now be prompted for your', 'App ID and Name.\nGet these settings from:', facebookAppUrl ].join(' '); logging.logger.info(chalk.blue.bold(installMessage)); // This wont work by downloading a release. // We will need to git clone it some how- // http://stackoverflow.com/questions/24626729/facebooksdk-facebooksdk-h-file-not-found var downloadUrl = 'https://github.com/Wizcorp/phonegap-facebook-plugin/archive/master.zip'; var zipOutPath = path.join(appDirectory, 'base'); var facebookAppInfo = {}; var promise; if (!Setup.checkPreReqs()) { logging.logger.error('prereq check fail'); promise = Setup.promptForPlatformInstall(); } else { promise = Q(); } return promise .then(Setup.promptForFacebookInfo) .then(function(facebookInfo) { facebookAppInfo = facebookInfo; return Setup.downloadZipToDir(downloadUrl, zipOutPath, path.join(zipOutPath, 'phonegap-facebook-plugin-master')); }) .then(function() { logging.logger.info('Installing Facebook Plugin'.info); return Setup.installFacebookPlugin(appDirectory, facebookAppInfo); }) .then(function() { Setup.showMarkup(); }) .catch(function(ex) { logging.logger.info('Error occurred: %s', ex, {}); logging.logger.info(ex.stack); }); }; Setup.installFacebookPlugin = function installFacebookPlugin(appDirectory, facebookInfo) { var basePath = path.join(appDirectory, 'base', 'phonegap-facebook-plugin-master'); var command = [ 'ionic plugin add ', basePath, ' --variable APP_ID="', facebookInfo.app_id, '" --variable APP_NAME="', facebookInfo.app_name, '"' ].join(''); var result = shelljs.exec(command); logging.logger.info('Running: ', command); if (result.code != 0) { var errorMessage = ['There was an error adding the Cordova Facebook Plugin', result.output].join('\n'); Utils.fail(errorMessage); throw new Error(errorMessage); } else { logging.logger.info('\nAdded Cordova Facebook Plugin') } }; Setup.showMarkup = function showMarkup() { var facebookSnippetPath = path.join(__dirname, 'assets', 'facebookSnippets.js'); var facebookSnippet = fs.readFileSync(facebookSnippetPath, 'utf8'); logging.logger.info(chalk.green('Put this JS in your Controller to use the Facebook plugin:')); logging.logger.info(chalk.blue(facebookSnippet)); logging.logger.info(chalk.green('Use this HTML to trigger the above login method')); logging.logger.info(chalk.blue('<button ng-click="login()">Login to Facebook!</button>')); }; Setup.promptForPlatformInstall = function promptForPlatformInstall() { var schema = [{ name: 'platform', description: chalk.yellow.bold('Install platforms? (ios|android|both): '), required: true }]; return Setup.promptUserPromise(schema) .then(function(result) { var platform = result.platform.toLowerCase().trim(); switch (platform) { case 'ios': shelljs.exec('ionic platform add ios'); break; case 'android': shelljs.exec('ionic platform add android'); break; case 'both': shelljs.exec('ionic platform add ios'); shelljs.exec('ionic platform add android'); break; } }); }; Setup.promptForFacebookInfo = function promptForFacebookInfo() { var schema = [{ name: 'app_id', description: chalk.yellow.bold('Facebook App ID:'), required: true }, { name: 'app_name', description: chalk.yellow.bold('App Name:'), required: true }]; return Setup.promptUserPromise(schema) .then(function(result) { var fbInfo = { app_id: result.app_id, app_name: result.app_name } return fbInfo; }); }; Setup.promptUserPromise = function promptUserPromise(schema) { var q = Q.defer(); var prompt = require('prompt'); prompt.override = argv; prompt.message = ''; prompt.delimiter = ''; prompt.start(); prompt.get(schema, function(err, result) { if (err) { q.reject(err); return Utils.fail('Error getting Facebook app information: ' + err); } q.resolve(result); }); return q.promise; }; Setup.downloadZipToDir = function downloadZipToDir(downloadUrl, zipOutPath, outputDir) { logging.logger.info(chalk.blue('Attemping to download the Facebook plugin')); var q = Q.defer(); if (!fs.existsSync(zipOutPath)) { shelljs.mkdir(zipOutPath); } if (fs.existsSync(outputDir)) { logging.logger.info(chalk.green('The Facebook plugin has already been downloaded. Skipping this step.')); return q.resolve(); } Utils.fetchArchive(zipOutPath, downloadUrl) .then(function() { logging.logger.info(chalk.green('The Facebook plugin has finished downloading.')); q.resolve(); }, function(error) { logging.logger.info(chalk.green('Failed to download Facebook plugin - ', error)); q.reject(); }); return q.promise; };