UNPKG

nyx_server

Version:

Node内容发布

368 lines (338 loc) 9.96 kB
/* global __dirname */ /* global process */ var Optimist = require('../optimist/optimist'); var help = require('../optimist/help'); var optimist = new Optimist(); var Promise = require("bluebird"); var glob = require("glob"); var copy = require("../core/utils/copy"); var fs = require("fs"); var ejs = require("ejs") var mkdirp = require('mkdirp'); optimist .info('创建项目、模板、碎片') //可能需要有不需要id的碎片 .usage('nyx createor ([--project|-p] | [--template|-t] | [--chip|-c])') .define("project").alias("p").type("boolean").describe('创建项目') .define("template").alias("t").type("boolean").describe('创建模板') .define("chip").alias("c").type("boolean").describe('创建碎片') var argv = optimist.getArgv(); var path = require("path"); var prompt = require("prompt"); var projectSchema = { properties: { name: { pattern: /^[a-zA-Z_]+$/, message: '项目名称必须是英文', required: true, description:"项目名称" }, version: { default:"0.1.0", description:"版本" }, author:{ default:"", description:"作者" }, giturl:{ pattern: /^http:\/\/[a-zA-Z1-9\_.\/]*$/, required: true, description:"git地址", message: 'git地址以http://开头', }, descr:{ default:"", message:"描述" } } }; var templateSchema = { properties: { name: { pattern: /^[a-zA-Z_]+$/, message: '模板名称必须是英文', required: true, description:"模板名称" }, matchPath:{ pattern: /^[a-zA-Z\-1-9]+$/, message:"匹配路径必须是英文或数字", description:"匹配路径", required:true }, fileType:{ pattern: /^[a-zA-Z]+$/, message:"文件类型必须是英文或数字", description:"文件类型", required:true }, devices:{ pattern: /^[a-zA-Z1-9,]+$/, default:"pc", description:"支持设备", message:"设备以逗号分隔,不允许空格" }, extra:{ pattern: /^[a-zA-Z1-9,]+$/, description:"额外信息", } } } var chipSchema = { properties: { name: { pattern: /^[a-zA-Z_]+$/, message: '碎片名称必须是英文', required: true, description:"碎片名称" }, descr:{ default:"", message:"描述" } } } var selectSchema = { properties: { select:{ validator: /t[emplate]*|c[hip]*/, message:"选择类型(t[emplate]|c[hip])", default: 'template' } } } var canContinueSchema = { properties: { canContinue:{ validator: /y[es]*|n[o]?/, message:"是否继续创建模板或碎片?(y[es]|n[o])", warning: '必须是 yes 或 no', default: 'no' } } } function Creator(){ this._resolve = null; } Creator.prototype.execute = function(){ var _self = this; var argvAnalysis = optimist.analysis; if (argvAnalysis.options.hasOwnProperty('help') || argvAnalysis.shortKeys.hasOwnProperty('h')) { help.detailed(optimist); process.exit(1); } if(argv.project){ this.createProject(); }else if(argv.template){ this.createTemplate(); }else if(argv.chip){ this.createChip(); }else{ return Promise.resolve(true); } return new Promise(function(resolve , reject){ _self._resolve = resolve; }).then(function(result){ if(result){ } return true; }) } Creator.prototype.selectPrompt = function(){ var _self = this; prompt.start(); prompt.get(selectSchema, function (err, result) { if(err){ console.log(err); return _self._resolve(false); } var select = result.select; if(/t[emplate]*/.test(select)){ _self.createTemplate(); }else if(/c[hip]*/.test(select)){ _self.createChip(); } }); } Creator.prototype.continuePrompt = function(){ var _self = this; prompt.start(); prompt.get(canContinueSchema, function (err, result) { if(err){ console.log(err); return _self._resolve(false); } var canContinue = result.canContinue; if(/y[es]*/.test(canContinue)){ _self.selectPrompt(); }else{ _self._resolve(true); } }); } Creator.prototype.createProject = function(){ var _self = this; prompt.start(); prompt.get(projectSchema, function (err, result) { if(err){ console.log(err); return _self._resolve(false); } var dir = process.cwd(); validateProject(dir).then(function(){ var templateDir = path.join(__dirname ,"template/project/*") return create(templateDir ,result , dir).then(function(){ console.log("项目创建完成。") _self.continuePrompt(); }) }).catch(function(err){ console.log(err); _self._resolve(false); }) }); } Creator.prototype.createTemplate = function(){ var _self = this; prompt.start(); prompt.get(templateSchema, function (err, result) { if(err){ console.log(err); return _self._resolve(false); } var templateDir = path.join(__dirname ,"template/template") validateTemplate(result.name , templateDir).then(function(){ var todir = path.join(process.cwd() , result.name); return create(path.join(templateDir,"*") , result , todir).then(function(){ _self.continuePrompt(); }) }).catch(function(err){ console.log(err) _self.continuePrompt(); }) }); } Creator.prototype.createChip = function(){ var _self = this; prompt.start(); prompt.get(chipSchema, function (err, result) { if(err){ console.log(err); return _self._resolve(false); } var chipDir = path.join(__dirname ,"template/chip") validateChip(result.name , chipDir).then(function(){ var todir = path.join(process.cwd() , result.name); return create(path.join(chipDir,"*") , result , todir).then(function(){ _self.continuePrompt(); }) }).catch(function(err){ console.log(err); _self.continuePrompt(); }) }); } //验证项目是否已经创建 function validateProject(basePath){ //验证文件夹下不允许有文件 return new Promise(function(resolve , reject){ glob(path.join(basePath,"!(logs)") , function(err , files){ if(err){ return reject(err); } if(files.length>0){ reject(new Error("当前目录不是空目录!")); }else{ resolve(true); } }) }) } function create(templatedir , info , todir){ // if(fs.existsSync(todir)){ // return Promise.reject(new Error("目录已经存在!")) // } return new Promise(function(resolve , reject){ glob(templatedir,function(err , files){ if(err){ return reject(err); } var promises = []; files.forEach(function(file){ var d = path.join(todir , path.basename(file)); mkdirp.sync(d) var p = copy.copyFile(file , d); promises.push(p); }) Promise.all(promises).then(function(){ return new Promise(function(resolve , reject){ fs.readFile(path.join(todir,"package.json") , "utf-8" , function(err , data){ var template = ejs.compile(data); var retContent = template(info); resolve(retContent); }) }).then(function(content){ return new Promise(function(resolve , reject){ fs.writeFile(path.join(todir,"package.json") , content ,"utf-8" , function(err){ if(err){ reject(err) }else{ resolve(true); } }) }) }) }).then(function(){ resolve(true); }).catch(function(err){ reject(err); }); }) }) } //验证碎片是否重名 function validateChip(chipName , dir){ return validate(dir , function(type , name){ if(type == 'chip' && name == chipName){ return true; }else{ return false; } } , "碎片名称重复") } function validate(dir , fn , errMessage){ return new Promise(function(resolve , reject){ glob(path.join(dir , "package.json") , function(err , files){ if(files.length==0){ return reject(new Error("没有对应package.json文件!")) } files.forEach(function(file){ var package1 = require(file); var name = package1.name; var type = package1.type; //类型 if(fn(type , name)){ reject(new Error(errMessage)) }else{ resolve(true); } }) }) }) } //验证模板是否重名 function validateTemplate(templateName , dir){ return validate(dir , function(type , name){ if(type == 'template' && name == templateName){ return true; }else{ return false; } } , "模板名称重复") } Creator.prototype.showhelp = function(){ help.detailed(optimist); // console.log('show command start help'); }; Creator.prototype.optimist = function() { return optimist; } module.exports = new Creator();