mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-20 12:29:55 +08:00
refactor(generators): make them more oo
This commit is contained in:
10
gulpfile.js
10
gulpfile.js
@ -581,3 +581,13 @@ function buildDemoBundle(opts, done) {
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
gulp.task('tooling', function(){
|
||||
gulp.src('*tooling/**/*')
|
||||
.pipe(gulp.dest('dist'));
|
||||
|
||||
watch('tooling/**/*', function(){
|
||||
gulp.src('*tooling/**/*')
|
||||
.pipe(gulp.dest('dist'));
|
||||
})
|
||||
})
|
||||
|
@ -1,11 +1,8 @@
|
||||
var _ = require('lodash'),
|
||||
fs = require('fs'),
|
||||
inquirer = require('inquirer'),
|
||||
var fs = require('fs'),
|
||||
path = require('path'),
|
||||
shell = require('shelljs'),
|
||||
Generate = module.exports;
|
||||
inquirer = require('inquirer');
|
||||
|
||||
Generate._generators;
|
||||
Generate = module.exports;
|
||||
|
||||
Generate.__defineGetter__('generators', function() {
|
||||
if (!Generate._generators) {
|
||||
@ -15,208 +12,50 @@ Generate.__defineGetter__('generators', function() {
|
||||
return Generate._generators;
|
||||
});
|
||||
|
||||
Generate.log = function log() {
|
||||
console.log('DEBUG'.red, arguments);
|
||||
};
|
||||
|
||||
// options: appDirectory, generator, name
|
||||
Generate.generate = function generate(options) {
|
||||
Generate.inquirer = inquirer;
|
||||
// Generate.log('Generate options', options);
|
||||
if (!options) {
|
||||
throw new Error('No options passed to generator');
|
||||
}
|
||||
|
||||
//add optional logger for CLI or other tools
|
||||
if (options.log) {
|
||||
Generate.log = options.log;
|
||||
}
|
||||
|
||||
if (options.generator && !Generate.generators[options.generator]) {
|
||||
throw new Error('There is no generator available with that name: ' + options.generator + '.');
|
||||
}
|
||||
|
||||
if (!options.generator) {
|
||||
options.generator = 'page';
|
||||
throw new Error('No generator passed to generate');
|
||||
}
|
||||
|
||||
var generateOptions = {
|
||||
appDirectory: options.appDirectory,
|
||||
cssClassName: Generate.cssClassName(options.name),
|
||||
fileName: Generate.fileName(options.name),
|
||||
jsClassName: Generate.jsClassName(options.name),
|
||||
name: options.name,
|
||||
template: options.generator
|
||||
};
|
||||
|
||||
try {
|
||||
//Try to run the generator if it supplies a run method.
|
||||
var generator = Generate.generators[options.generator];
|
||||
if (generator && generator.run) {
|
||||
return Generate.generators[options.generator].run(generateOptions);
|
||||
} else {
|
||||
return Generate.defaultTemplates(generateOptions);
|
||||
}
|
||||
} catch (ex) {
|
||||
console.log('Error with generation:', ex);
|
||||
console.log(ex.stack);
|
||||
}
|
||||
var GeneratorType = Generate.loadGenerator(options.generator);
|
||||
return new GeneratorType(options).run();
|
||||
};
|
||||
|
||||
Generate.defaultTemplates = function defaultTemplates(options) {
|
||||
var template = options.template ? options.template : 'page';
|
||||
|
||||
options.rootDirectory = options.rootDirectory || path.join('app');
|
||||
var savePath = path.join(options.appDirectory, options.rootDirectory, options.fileName);
|
||||
|
||||
var templates = Generate.loadGeneratorTemplates(path.join(__dirname, 'generators', options.template));
|
||||
|
||||
templates.forEach(function(template) {
|
||||
var templatePath = template.file;
|
||||
options.templatePath = templatePath;
|
||||
var renderedTemplate = Generate.renderTemplateFromFile(options);
|
||||
var saveFilePath = path.join(savePath, [options.fileName, template.type].join(''));
|
||||
// console.log('renderedTemplate', renderedTemplate, 'saving to', saveFilePath);
|
||||
console.log('√ Create'.blue, path.relative(options.appDirectory, saveFilePath));
|
||||
fs.writeFileSync(saveFilePath, renderedTemplate);
|
||||
});
|
||||
}
|
||||
|
||||
Generate.loadGeneratorTemplates = function loadGeneratorTemplates(generatorPath) {
|
||||
var templates = [];
|
||||
fs.readdirSync(generatorPath)
|
||||
.forEach(function(template) {
|
||||
var type;
|
||||
// Go through all the files in the folder, grab the templates, read in the file contents
|
||||
// return as template type, contents
|
||||
if (template.indexOf('.tmpl') == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
templates.push({file: path.join(generatorPath, template), type: path.extname(template)});
|
||||
});
|
||||
|
||||
return templates;
|
||||
};
|
||||
|
||||
Generate.loadGenerator = function loadGenerator(file) {
|
||||
var generatorPath = path.join(__dirname, 'generators', file);
|
||||
Generate.loadGenerator = function loadGenerator(generator) {
|
||||
var generateModule;
|
||||
try {
|
||||
generateModule = require(generatorPath);
|
||||
} catch (ex) {
|
||||
Generate.log('Error loading generator module', ex);
|
||||
Generate.log(ex.stack);
|
||||
generateModule = require(path.join(__dirname, 'generators', generator));
|
||||
} catch (err) {
|
||||
if (err.code === 'MODULE_NOT_FOUND') {
|
||||
throw new Error('There is no generator available with the name ' + generator + '.');
|
||||
} else {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
return generateModule;
|
||||
};
|
||||
|
||||
/*
|
||||
Return array of filenames in the generators directory
|
||||
*/
|
||||
Generate.loadGenerators = function loadGenerators() {
|
||||
var generators = {};
|
||||
fs.readdirSync(path.join(__dirname, 'generators'))
|
||||
.forEach(function (file) {
|
||||
if (file.indexOf('.') !== -1) {
|
||||
return;
|
||||
}
|
||||
var generatorName = file.replace('.js', '');
|
||||
var generator = Generate.loadGenerator(generatorName);
|
||||
generators[generatorName] = generator;
|
||||
});
|
||||
try {
|
||||
generators = fs.readdirSync(path.join(__dirname, 'generators'));
|
||||
} catch(err) {
|
||||
throw new Error('There was an error loading the generators list', err);
|
||||
}
|
||||
return generators;
|
||||
};
|
||||
|
||||
/*
|
||||
Will take options to render an html, js, or scss template.
|
||||
options:
|
||||
they differ based on what is needed in template
|
||||
For JavaScript file: filename, jsClassName
|
||||
For HTML file: name, nameUppercased
|
||||
templatePath: the path of the template to render (html/js/scss), ex: '/path/to/page.tmpl.html'
|
||||
*/
|
||||
Generate.renderTemplateFromFile = function renderTemplateFromFile(options) {
|
||||
var templateContents = fs.readFileSync(options.templatePath, 'utf8');
|
||||
var templateCompiler = _.template(templateContents);
|
||||
var result = templateCompiler(options);
|
||||
return result;
|
||||
};
|
||||
|
||||
// Tabs - name = name of the page with the tabs,
|
||||
// tabs = array of the tabs to create.
|
||||
// Generate.tabPages = function tabPages(appDirectory, name, tabs) {
|
||||
// Generate.createScaffoldDirectories(appDirectory, 'tabs', name);
|
||||
//
|
||||
// // Generate page with tabs:
|
||||
// var tabsfileName = Generate.fileName(name);
|
||||
//
|
||||
// var tabsHtml = Generate.generateTabsHtmlTemplate(appDirectory, name, tabs);
|
||||
// var tabsJs = Generate.generateTabsJsTemplate(appDirectory, name, tabs);
|
||||
// // var tabsScss = Generate.generateTabsScssTemplate(appDirectory, name, tabs);
|
||||
// var pagePath = path.join(appDirectory, 'app', tabsfileName),
|
||||
// jsPath = path.join(pagePath, [tabsfileName, '.js'].join('')),
|
||||
// htmlPath = path.join(pagePath, [tabsfileName, '.html'].join(''));
|
||||
// // scssPath = path.join(pagePath, [tabsfileName, '.scss'].join(''));
|
||||
//
|
||||
// tabs.forEach(function(tab) {
|
||||
// Generate.createScaffoldDirectories(appDirectory, 'tabs', tab);
|
||||
// var tabJs = Generate.generateJsTemplate(appDirectory, tab);
|
||||
// var tabHtml = Generate.generateHtmlTemplate(appDirectory, tab);
|
||||
//
|
||||
// })
|
||||
// };
|
||||
|
||||
Generate.generateTabJsTemplate = function generateTabJsTemplate(appDirectory, name) {
|
||||
throw new Error('not implemented');
|
||||
};
|
||||
|
||||
Generate.generateTabsJsTemplate = function generateTabsJsTemplate(appDirectory, name, tabs) {
|
||||
// import {NavController, Page} from 'ionic/ionic';
|
||||
// <% _.forEach(tabs, function(tab) { %>
|
||||
// import {<%= tab.jsClassName %>} from '../<%= tab.filename %>/<%= tab.filename %>';
|
||||
// <% }); %>
|
||||
// @Page({
|
||||
// templateUrl: 'app/<%= filename %>/<%= filename %>.html',
|
||||
// providers: [DataService]
|
||||
// })
|
||||
// class <%= jsClassName %> {
|
||||
// constructor(nav: NavController) {
|
||||
// // set the root pages for each tab
|
||||
// <% _.forEach(tabs, function(tab) { %>
|
||||
// this.{<%= tab.jsClassName %>} = <%= tab.jsClassName %>;
|
||||
// <% }); %>
|
||||
// }
|
||||
// }
|
||||
var fileName = Generate.fileName(name);
|
||||
var jsClassName = Generate.jsClassName(name);
|
||||
|
||||
var tabsData = [];
|
||||
tabs.forEach(function(tab) {
|
||||
var tabObj = { name: tab, filename: Generate.fileName(tab), jsClassName: Generate.jsClassName(tab)};
|
||||
tabsData.push(tabObj);
|
||||
Generate.printAvailableGenerators = function printAvailableGenerators() {
|
||||
console.log('Available generators:'.blue);
|
||||
Generate.generators.forEach(function(generator){
|
||||
console.log(' *'.blue, generator);
|
||||
});
|
||||
|
||||
var tabsHtmlTemplatePath = path.join(__dirname, 'tabs.tmpl.js');
|
||||
return Generate.renderTemplateFromFile({tabs: tabsData, templatePath: tabsHtmlTemplatePath, filename: fileName, jsClassName: jsClassName });
|
||||
};
|
||||
|
||||
Generate.createScaffoldDirectories = function createScaffoldDirectories(options) {
|
||||
console.log('createScaffoldDirectories', options);
|
||||
// Generate.log('Create', options.appDirectory, options.fileName);
|
||||
var componentPath = path.join(options.appDirectory, 'app', options.componentDirectory, options.fileName);
|
||||
shell.mkdir('-p', componentPath);
|
||||
};
|
||||
|
||||
Generate.fileName = function fileName(name) {
|
||||
return name.replace(/([a-z])([A-Z])/g, '$1-$2').replace('_', '-').toLowerCase();
|
||||
};
|
||||
|
||||
Generate.cssClassName = function cssClassName(name) {
|
||||
return Generate.fileName(name);
|
||||
}
|
||||
|
||||
Generate.capitalizeName = function capitalizeName(name) {
|
||||
return name.charAt(0).toUpperCase() + name.slice(1);
|
||||
};
|
||||
|
||||
Generate.jsClassName = function jsClassName(name) {
|
||||
return _.capitalize(_.camelCase(name));
|
||||
};
|
||||
|
67
tooling/generator.js
Normal file
67
tooling/generator.js
Normal file
@ -0,0 +1,67 @@
|
||||
var _ = require('lodash'),
|
||||
fs = require('fs'),
|
||||
path = require('path'),
|
||||
shell = require('shelljs');
|
||||
|
||||
module.exports = Generator;
|
||||
|
||||
function Generator(options) {
|
||||
this.name = options.name;
|
||||
this.type = options.generator;
|
||||
this.appDirectory = options.appDirectory;
|
||||
}
|
||||
|
||||
Generator.prototype.run = function(){
|
||||
this.makeDirectories();
|
||||
this.renderTemplates();
|
||||
}
|
||||
|
||||
Generator.prototype.makeDirectories = function(){
|
||||
if (!this.directory) {
|
||||
throw new Error('Generators must define their directory in their constructor');
|
||||
}
|
||||
shell.mkdir('-p', path.join(this.appDirectory, this.directory, this.name));
|
||||
}
|
||||
|
||||
Generator.prototype.renderTemplates = function renderTemplates() {
|
||||
var templates = this.loadTemplates();
|
||||
|
||||
templates.forEach(function(template) {
|
||||
var renderedTemplate = this.renderTemplate(template);
|
||||
var renderedTemplateDest = path.join(this.appDirectory, this.directory, this.name, this.name + template.extension);
|
||||
console.log('√ Create'.blue, path.relative(this.appDirectory, renderedTemplateDest));
|
||||
fs.writeFileSync(renderedTemplateDest, renderedTemplate);
|
||||
}, this);
|
||||
}
|
||||
|
||||
Generator.prototype.loadTemplates = function() {
|
||||
var generatorPath = path.join(__dirname, 'generators', this.type);
|
||||
var templates = [];
|
||||
fs.readdirSync(generatorPath)
|
||||
.forEach(function(template) {
|
||||
var type;
|
||||
// Go through all the files in the folder, grab the templates, read in the file contents
|
||||
// return as template type, contents
|
||||
if (template.indexOf('.tmpl') == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
templates.push({path: path.join(generatorPath, template), extension: path.extname(template)});
|
||||
}, this);
|
||||
|
||||
return templates;
|
||||
};
|
||||
|
||||
Generator.prototype.renderTemplate = function(template) {
|
||||
var templateVars = {
|
||||
fileName: _.kebabCase(this.name),
|
||||
directory: this.directory,
|
||||
cssClassName: _.kebabCase(this.name),
|
||||
jsClassName: _.capitalize(_.camelCase(this.name))
|
||||
}
|
||||
|
||||
var templateContents = fs.readFileSync(template.path, 'utf8');
|
||||
var templateCompiler = _.template(templateContents);
|
||||
var result = templateCompiler(templateVars);
|
||||
return result;
|
||||
};
|
@ -1,3 +1,9 @@
|
||||
<div *ng-if="value">
|
||||
<%= jsClassName %>
|
||||
<!--
|
||||
Generated template for <%= jsClassName %>.
|
||||
|
||||
See https://angular.io/docs/ts/latest/api/core/ComponentMetadata-class.html
|
||||
for more info on Components.
|
||||
-->
|
||||
<div>
|
||||
{{text}}
|
||||
</div>
|
||||
|
@ -1,14 +1,13 @@
|
||||
import {Component, NgIf} from 'angular2/angular2';
|
||||
import {NavController} from 'ionic/ionic';
|
||||
import {Component} from 'angular2/core';
|
||||
import {IONIC_DIRECTIVES} from 'ionic/ionic';
|
||||
|
||||
@Component({
|
||||
directives: [NgIf],
|
||||
properties: ['value'], //Change to be whatever properties you want, ex: <<%= fileName %> value="5">
|
||||
selector: '<%= fileName %>',
|
||||
templateUrl: 'app/<%= fileName %>/<%= fileName %>.html'
|
||||
templateUrl: '<%= directory %>/<%= fileName %>/<%= fileName %>.html',
|
||||
directives: [IONIC_DIRECTIVES] // makes all Ionic directives available to your component
|
||||
})
|
||||
export class <%= jsClassName %> {
|
||||
constructor(nav: NavController) {
|
||||
this.nav = nav;
|
||||
constructor() {
|
||||
this.text = 'Hello World, I\'m <%= jsClassName %>';
|
||||
}
|
||||
}
|
||||
|
@ -1,28 +1,12 @@
|
||||
var fs = require('fs'),
|
||||
Generator = module.exports,
|
||||
Generate = require('../../generate'),
|
||||
path = require('path'),
|
||||
Q = require('q');
|
||||
/*
|
||||
@options
|
||||
name: Page name
|
||||
appDirectory: App directory of where to save file
|
||||
*/
|
||||
Generator.run = function run(options) {
|
||||
Generate.createScaffoldDirectories({appDirectory: options.appDirectory, componentDirectory: 'components', fileName: options.fileName});
|
||||
|
||||
options.rootDirectory = options.rootDirectory || path.join('app', 'components');
|
||||
var path = require('path'),
|
||||
Generator = require('../../generator');
|
||||
|
||||
var savePath = path.join(options.appDirectory, options.rootDirectory, options.fileName);
|
||||
module.exports = ComponentGenerator;
|
||||
|
||||
var templates = Generate.loadGeneratorTemplates(__dirname);
|
||||
function ComponentGenerator(options) {
|
||||
Generator.call(this, options);
|
||||
this.directory = path.join('app', 'components');
|
||||
}
|
||||
|
||||
templates.forEach(function(template) {
|
||||
options.templatePath = template.file;
|
||||
var renderedTemplate = Generate.renderTemplateFromFile(options);
|
||||
var saveFilePath = path.join(savePath, [options.fileName, template.type].join(''));
|
||||
// console.log('renderedTemplate', renderedTemplate, 'saving to', saveFilePath);
|
||||
console.log('√ Create'.blue, path.relative(options.appDirectory, saveFilePath));
|
||||
fs.writeFileSync(saveFilePath, renderedTemplate);
|
||||
});
|
||||
};
|
||||
ComponentGenerator.prototype = Object.create(Generator.prototype);
|
||||
|
Reference in New Issue
Block a user