Skip to content

Commit

Permalink
feat(generator): Upgrade to [email protected]
Browse files Browse the repository at this point in the history
Refactor from class structure to expanding the yeoman generator Base class
Move functions to appropriate run queues (prompting, writing, etc.)
Alter appJs and ensureStyles functions to use the in-memory file system
  • Loading branch information
chilltemp committed Jan 9, 2015
1 parent 06b7268 commit 72a04bb
Show file tree
Hide file tree
Showing 2 changed files with 193 additions and 161 deletions.
352 changes: 192 additions & 160 deletions app/index.js
Original file line number Diff line number Diff line change
@@ -1,174 +1,206 @@
'use strict';
var util = require('util');
var fs = require('fs');
var path = require('path');
var yeoman = require('yeoman-generator');
var generators = require('yeoman-generator');
var _ = require('lodash');
var mout = require('mout');
var cordova = require('cordova');
var chalk = require('chalk');
var ionicUtils = require('../utils');

var IonicGenerator = module.exports = function IonicGenerator(args, options) {
yeoman.generators.Base.apply(this, arguments);
console.log(ionicUtils.greeting);

this.argument('appName', { type: String, required: false });
this.appName = this.appName || path.basename(process.cwd());
this.appName = mout.string.pascalCase(this.appName);
this.appId = 'com.example.' + this.appName;
this.appPath = 'app';
this.root = process.cwd();

this.on('end', function () {
this.installDependencies({ skipInstall: options['skip-install'] });
});

this.pkg = JSON.parse(this.readFileAsString(path.join(__dirname, '../package.json')));
};

util.inherits(IonicGenerator, yeoman.generators.Base);

IonicGenerator.prototype.askForCompass = function askForCompass() {
var done = this.async();

this.prompt([{
type: 'confirm',
name: 'compass',
message: 'Would you like to use Sass with Compass (requires Ruby)?',
default: false
}], function (props) {
this.compass = props.compass;

done();
}.bind(this));
};

IonicGenerator.prototype.cordovaInit = function cordovaInit() {
var done = this.async();
cordova.create('.', this.appId, this.appName, function (error) {
if (error) {
console.log(chalk.yellow(error.message + ': Skipping `cordova create`'));
} else {
console.log(chalk.yellow('Created a new Cordova project with name "' + this.appName + '" and id "' + this.appId + '"'));
module.exports = generators.Base.extend({
constructor: function () {
generators.Base.apply(this, arguments);
console.log(ionicUtils.greeting);

this.argument('appName', { type: String, required: false });
this.appName = this.appName || path.basename(process.cwd());
this.appName = mout.string.pascalCase(this.appName);
this.appId = 'com.example.' + this.appName;
this.appPath = 'app';
this.root = process.cwd();

this.pkg = JSON.parse(this.readFileAsString(path.join(__dirname, '../package.json')));
},

prompting: {
askForCompass: function askForCompass() {
var done = this.async();

this.prompt([{
type: 'confirm',
name: 'compass',
message: 'Would you like to use Sass with Compass (requires Ruby)?',
default: false
}], function (props) {
this.compass = props.compass;

done();
}.bind(this));
},

askForPlugins: function askForPlugins() {
var done = this.async();

this.prompt(ionicUtils.plugins.prompts, function (props) {
this.plugins = props.plugins;

done();
}.bind(this));
},

askForStarter: function askForStarter() {
var done = this.async();

this.prompt([{
type: 'list',
name: 'starter',
message: 'Which starter template [T] or example app [A] would you like to use?',
choices: _.pluck(ionicUtils.starters.templates, 'name')
}], function (props) {
this.starter = _.find(ionicUtils.starters.templates, { name: props.starter });
done();
}.bind(this));
}
done();
}.bind(this));
};

IonicGenerator.prototype.askForPlugins = function askForPlugins() {
var done = this.async();

this.prompt(ionicUtils.plugins.prompts, function (props) {
this.plugins = props.plugins;

done();
}.bind(this));
};

IonicGenerator.prototype.askForStarter = function askForStarter() {
var done = this.async();

this.prompt([{
type: 'list',
name: 'starter',
message: 'Which starter template [T] or example app [A] would you like to use?',
choices: _.pluck(ionicUtils.starters.templates, 'name')
}], function (props) {
this.starter = _.find(ionicUtils.starters.templates, { name: props.starter });
done();
}.bind(this));
};

IonicGenerator.prototype.installPlugins = function installPlugins() {
console.log(chalk.yellow('\nInstall plugins registered at plugins.cordova.io: ') + chalk.green('grunt plugin:add:org.apache.cordova.globalization'));
console.log(chalk.yellow('Or install plugins direct from source: ') + chalk.green('grunt plugin:add:https://github.com/apache/cordova-plugin-console.git\n'));
if (this.plugins.length > 0) {
console.log(chalk.yellow('Installing selected Cordova plugins, please wait.'));
// Turns out plugin() doesn't accept a callback so we try/catch instead
try {
cordova.plugin('add', this.plugins);
} catch (e) {
console.log(e);
this.log.error(chalk.red('Please run `yo ionic` in an empty directory, or in that of an already existing cordova project.'));
process.exit(1);
}
}
};

IonicGenerator.prototype.installStarter = function installStarter() {
console.log(chalk.yellow('Installing starter template. Please wait'));
var done = this.async();

this.remote(this.starter.user, this.starter.repo, 'master', function (error, remote) {
if (error) {
done(error);
},

configuring: {
setupEnv: function setupEnv() {
// Copies the contents of the generator example app
// directory into your users new application path
this.sourceRoot(path.join(__dirname, '../templates/'));
this.directory('common/root', '.', true);
},

packageFiles: function packageFiles() {
this.template('common/_bower.json', 'bower.json');
this.template('common/_bowerrc', '.bowerrc');
this.template('common/_package.json', 'package.json');
this.template('common/Gruntfile.js', 'Gruntfile.js');
this.template('common/_gitignore', '.gitignore');
}
remote.directory('app', 'app');
this.starterCache = path.join(this.cacheRoot(), this.starter.user, this.starter.repo, 'master');
done();
}.bind(this), true);
};

IonicGenerator.prototype.setupEnv = function setupEnv() {
// Copies the contents of the generator example app
// directory into your users new application path
this.sourceRoot(path.join(__dirname, '../templates/'));
this.directory('common/root', '.', true);
};

IonicGenerator.prototype.readIndex = function readIndex() {
this.indexFile = this.engine(this.read(path.join(this.starterCache, 'index.html')), this);
};

IonicGenerator.prototype.appJs = function appJs() {
var scripts = ['config.js'];
scripts = scripts.concat(fs.readdirSync(path.join(process.cwd(), 'app/scripts')));
scripts = _.map(scripts, function (script) {
return 'scripts/' + script;
});
this.indexFile = this.appendScripts(this.indexFile, 'scripts/scripts.js', scripts);
};

IonicGenerator.prototype.createIndexHtml = function createIndexHtml() {
this.indexFile = this.indexFile.replace(/'/g, "'");
this.write(path.join(this.appPath, 'index.html'), this.indexFile);
};

IonicGenerator.prototype.ensureStyles = function ensureStyles() {
// Only create a main style file if the starter template didn't
// have any styles. In the case it does, the starter should
// supply both main.css and main.scss files, one of which
// will be deleted
var done = this.async();
var unusedFile = 'main.' + (this.compass ? 'css' : 'scss');
fs.unlink(path.resolve('app/styles', unusedFile), function (err) {
if (_.isEmpty(this.expand('app/styles/main.*'))) {
},

writing: {
cordovaInit: function cordovaInit() {
var done = this.async();
cordova.create('.', this.appId, this.appName, function (error) {
if (error) {
console.log(chalk.yellow(error.message + ': Skipping `cordova create`'));
} else {
console.log(chalk.yellow('Created a new Cordova project with name "' + this.appName + '" and id "' + this.appId + '"'));
}
done();
}.bind(this));
},

installPlugins: function installPlugins() {
console.log(chalk.yellow('\nInstall plugins registered at plugins.cordova.io: ') + chalk.green('grunt plugin:add:org.apache.cordova.globalization'));
console.log(chalk.yellow('Or install plugins direct from source: ') + chalk.green('grunt plugin:add:https://github.com/apache/cordova-plugin-console.git\n'));
if (this.plugins.length > 0) {
console.log(chalk.yellow('Installing selected Cordova plugins, please wait.'));
// Turns out plugin() doesn't accept a callback so we try/catch instead
try {
cordova.plugin('add', this.plugins);
} catch (e) {
console.log(e);
this.log.error(chalk.red('Please run `yo ionic` in an empty directory, or in that of an already existing cordova project.'));
process.exit(1);
}
}
},

installStarter: function installStarter() {
console.log(chalk.yellow('Installing starter template. Please wait'));
var done = this.async();

this.remote(this.starter.user, this.starter.repo, 'master', function (error, remote) {
if (error) {
done(error);
}
remote.directory('app', 'app');
this.starterCache = path.join(this.cacheRoot(), this.starter.user, this.starter.repo, 'master');
done();
}.bind(this), true);
},

readIndex: function readIndex() {
this.indexFile = this.engine(this.read(path.join(this.starterCache, 'index.html')), this);
},

appJs: function appJs() {
var appPath = path.join(process.cwd(), 'app');
var scriptPrefix = 'scripts' + path.sep;

var scripts = [scriptPrefix + 'config.js'];
this.fs.store.each(function (file, index) {
if (file.path.indexOf('.js') !== -1)
{
var relPath = path.relative(appPath, file.path);
if (relPath.indexOf(scriptPrefix) === 0) {
scripts.push(relPath);
}
}
});

this.indexFile = this.appendScripts(this.indexFile, 'scripts/scripts.js', scripts);
},

createIndexHtml: function createIndexHtml() {
this.indexFile = this.indexFile.replace(/'/g, "'");
this.write(path.join(this.appPath, 'index.html'), this.indexFile);
},

ensureStyles: function ensureStyles() {
// Only create a main style file if the starter template didn't
// have any styles. In the case it does, the starter should
// supply both main.css and main.scss files, one of which
// will be deleted

var cssFile = 'main.' + (this.compass ? 'scss' : 'css');
this.copy('styles/' + cssFile, 'app/styles/' + cssFile);
var unusedFile = 'main.' + (this.compass ? 'css' : 'scss');
var stylePath = path.join(process.cwd(), 'app', 'styles');
var found = false;

this.fs.store.each(function (file, index) {
if (path.dirname(file.path) === stylePath) {
var name = path.basename(file.path);

if (name === cssFile) {
found = true;
} else if (name === unusedFile) {
// BUG: The log will still report the the file was created
this.fs.delete(file.path);
}
}
}.bind(this));

if (!found) {
this.copy('styles/' + cssFile, 'app/styles/' + cssFile);
}

},

cordovaHooks: function cordovaHooks() {
this.directory('hooks', 'hooks', true);
},


testFiles: function testFiles() {
this.template('spec/controllers.js', 'test/spec/controllers.js');
},

packages: function () {
this.installDependencies({ skipInstall: this.options['skip-install'] });
}
done();
}.bind(this));

};

IonicGenerator.prototype.packageFiles = function packageFiles() {
this.template('common/_bower.json', 'bower.json');
this.template('common/_bowerrc', '.bowerrc');
this.template('common/_package.json', 'package.json');
this.template('common/Gruntfile.js', 'Gruntfile.js');
this.template('common/_gitignore', '.gitignore');
};

IonicGenerator.prototype.cordovaHooks = function cordovaHooks() {
this.directory('hooks', 'hooks', true);
};

IonicGenerator.prototype.hookPerms = function hookPerms() {
var iconsAndSplash = 'hooks/after_prepare/icons_and_splashscreens.js';
fs.chmodSync(iconsAndSplash, '755');
};

IonicGenerator.prototype.testFiles = function testFiles() {
this.template('spec/controllers.js', 'test/spec/controllers.js');
};
},

end: {
hookPerms: function hookPerms() {
var iconsAndSplash = 'hooks/after_prepare/icons_and_splashscreens.js';
fs.chmodSync(iconsAndSplash, '755');
},
}
});

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
"test": "mocha"
},
"dependencies": {
"yeoman-generator": "~0.14.0",
"yeoman-generator": "~0.18.6",
"mout": "~0.9.0",
"chalk": "~0.4.0",
"cordova": "~3.4.0-0.1.2",
Expand Down

0 comments on commit 72a04bb

Please sign in to comment.