File: lib\CodeGenerator.js
var fs = require('fs');
var path = require('path');
var _ = require('underscore');
var _s = require('underscore.string');
var ejs = require('ejs');
var dbc = require('happy.dbc').DesignByContract;
var FileSystemUtil = require('happy.util').FileSystemUtil;
/**
* 代码生成器,根据ejs模板生成代码或代码文件。
*
* @class CodeGenerator
* @extends Object
* @constructor
* @param {String} ejsTemplateFile 模板文件
* @param {String} [encoding='utf8'] 文件编码
* @example
var CodeGenerator = require('code_generator');
var ejsOptions = {
user: {
name: 'happy framework'
}
};
var generator = new CodeGenerator('./templates/hello.ejs');
var content = generator.generateToString(ejsOptions);
console.log(content);
generator.generateToTargetFile(ejsOptions);
CodeGenerator.executeTemplateDirectory('./templates', ejsOptions);
*/
var CodeGenerator = function (ejsTemplateFile, encoding) {
var me = this;
dbc.mustBeDefined('ejsTemplateFile', ejsTemplateFile);
_.extend(me, {
ejsTemplateFile: ejsTemplateFile,
encoding: (encoding || 'utf8'),
defautEjsOptions: {
_: require('underscore'),
util: require('util'),
filename: path.resolve(path.dirname(require.main.filename), './templates/ejs_cahce.ejs'),
}
});
};
module.exports = CodeGenerator;
/**
* @private
* @readOnly
* @property ejsTemplateFile
* @type String
*/
/**
* @private
* @readOnly
* @property encoding
* @default 'utf8'
* @type String
*/
/**
* @private
* @readOnly
* @property defautEjsOptions
* @type Object
*/
_.extend(CodeGenerator, {
/**
* 递归执行指定目录下的所有模板文件。
*
* @static
* @method executeTemplateDirectory
* @param {String} ejsTemplateDirectory 模板目录
* @param {Object} ejsOptions 执行模板的上下文对象
* @param {String} [encoding='utf8'] 文件编码
* @return
* @example
CodeGenerator.executeTemplateDirectory('./templates', ejsOptions);
*/
executeTemplateDirectory: function (ejsTemplateDirectory, ejsOptions, encoding) {
var me = this;
dbc.mustBeDefined('ejsTemplateDirectory', ejsTemplateDirectory);
dbc.mustBeDefined('ejsOptions', ejsOptions);
FileSystemUtil.eachFileSync(ejsTemplateDirectory, function (filename) {
return _s.endsWith(filename, '.ejs');
}, function (filepath) {
var generator = new CodeGenerator(filepath, encoding);
generator.generateToTargetFile(ejsOptions);
});
}
});
_.extend(CodeGenerator.prototype, {
/**
* 生成为字符串。
*
* @method generateToString
* @param {Object} ejsOptions 执行模板的上下文对象
* @return
* @example
var content = generator.generateToString(ejsOptions);
console.log(content);
*/
generateToString: function (ejsOptions) {
var me = this;
dbc.mustBeDefined('ejsOptions', ejsOptions);
var templateContent = fs.readFileSync(me.ejsTemplateFile, me.encoding);
_.defaults(ejsOptions, me.defautEjsOptions);
_.extend(ejsOptions, { _out: {} });
return ejs.render(templateContent, ejsOptions);
},
/**
* 生成为目标文件。
*
* @method generateToTargetFile
* @param {Object} ejsOptions 执行模板的上下文对象
* @param {String} [targetFile] 如果该参数为空,模板中必须包含如下代码:<% _out.targetFile = './outputs/hello.generator.html'; %>
* @param {Boolean} [cover=true] 如果目标文件已经存在,true 为覆盖,false为不覆盖。
* @return
* @example
generator.generateToTargetFile(ejsOptions);
*/
generateToTargetFile: function (ejsOptions, targetFile, cover) {
var me = this;
dbc.mustBeDefined('ejsOptions', ejsOptions);
var outputContent = me.generateToString(ejsOptions);
targetFile = targetFile || ejsOptions._out.targetFile;
if (cover !== false) {
cover = true;
}
if (ejsOptions._out.cover === false) {
cover = false;
}
if (cover === false) {
if (fs.existsSync(targetFile)) {
console.log(targetFile + ' is exists!');
return;
}
}
FileSystemUtil.writeFileSync(targetFile, outputContent, me.encoding);
console.log(targetFile + ' generate success!');
},
/**
* 使模板的每次执行,都能访问到 defautEjsOptions 中的属性。
*
* @method setDefautEjsOptions
* @param {Object} defautEjsOptions
* @return
*/
setDefautEjsOptions: function (defautEjsOptions) {
var me = this;
dbc.mustBeDefined('defautEjsOptions', defautEjsOptions);
_.extend(me.defautEjsOptions, defautEjsOptions);
}
});