UNPKG

mtl-cli

Version:
641 lines (527 loc) 19.2 kB
const shell = require('shelljs'); const fse = require('fs-extra');// fs-extra 扩展包 const xml2js = require('xml2js'); const mtlGit = require("./mtl_git"); const utils = require('./mtl').Utils; const inquirer = require('inquirer'); var path = require('path'); const configFile = require('./config'); const Configstore = require('configstore'); const conf = new Configstore(configFile.CONFIG_STORE_FILENAME); const mtlConfig = require('./mtl_config'); var unzip = require("unzip-stream"); // exports.MTLCreate = MTLCreate; const gitClone = "git clone "; const SUCCESS = "success"; const PROJECT_FILE = "project.json"; const CONFIG_XML = "config.xml"; const tplLibs = require("../res/templates.json"); const promptList = [{ type: 'list', message: '请选择工程模板:', name: 'name', choices: [ "empty", "ERP", ], filter: function (val) { // 使用filter将回答变为小写 return val; } }]; //an == appname //tl = template name var createApp = async function (an, tl) { if (!an) { console.log("必须录入工程名称") return utils.reportError("mtl lc appname"); } if (fse.existsSync(an)) { console.log("本地已存在- " + an + " -工程名称") return utils.reportError("请查看目录文件夹信息。"); } if (conf.get('username')) { //开发者中心 let tempNameList = await getTempList(); // console.log('tempNameList:'+tempNameList); promptList[0].choices = tempNameList; let template = ''; let appname = an; console.log("创建工程 - " + appname); if (tl) { template = tl; //判断模板是否存在 if (tempNameList.indexOf(template) === -1) { console.log("无效的模板名称 - " + template); return utils.reportError(); } console.log('选用模板名称' + template); //创建应用 downloadDevTemp(appname, template); } else { //命令行获取 inquirer.prompt(promptList).then(answers => { console.log('选用模板名称:' + answers.name); // 返回的结果 template = answers.name; downloadDevTemp(appname, template); }); } return; } else { //轻量级 promptList[0].choices = tplLibs.names; let template = ''; let appname = an; console.log("创建工程 - " + appname); if (tl) { template = tl; console.log('选用模板名称' + template); //创建应用 createBegin(appname, template); } else { //命令行获取 inquirer.prompt(promptList).then(answers => { console.log('选用模板名称:' + answers.name); // 返回的结果 template = answers.name; createBegin(appname, template); }); } } } /** * MTL工程 开发者中心版 创建工程前准备 * @param {String} appname * @param {String} template * */ var downloadDevTemp = async function (appname, template) { console.log("开始创建名称为 - " + appname + " - 的工程"); if (fse.existsSync(template + "/project.json")) { console.log('本地存在 ' + template + ' 模板....'); } else { if (fse.existsSync(template)) { console.log('error: 当前位置存在 ' + template + ' 目录,与模板名称冲突,请检查本地文件。'); return; } // 开始下载 await mtlConfig.download({ url: 'http://cloudcoding.dev.app.yyuap.com/codingcloud/genweb/downloadIuapFe?projectCode=' + template }, function () { // console.log('1111'); (async function () { await fse.createReadStream(template + '.zip').pipe(unzip.Extract({ path: './' })).on('close', () => { console.log('解压完成...') fse.removeSync(template + '.zip'); createDevPro(appname, template); }).on('error', (err) => { console.log(err); }) })() }, template + '.zip'); console.log('下载完成'); return; } createDevPro(appname, template); } /** * MTL工程 开发者中心版 创建工程 * @param {String} appname * @param {String} template * */ var createDevPro = function (appname, template) { //创建文件夹 fse.ensureDirSync(appname); //复制模板文件到工程 fse.copySync('/tmp/myfile', '/tmp/mynewfile'); //需要这些文件和目录存在 fse.copySync('./' + template + '/app', appname + '/app'); fse.copySync('./' + template + '/project.json', appname + '/project.json'); console.log('拷贝文件 success'); console.log("3、开始修改本地配置 - " + appname); // updateConfig(appname); } /** * MTL工程 更新配置 * @param {String} projfile * @param {String} gitUrl * 注:用户自己上传代码,不提供代码托管。 */ var configGitUrl = function (gitUrl) { if (!gitUrl) { console.log('输入gitUrl, eg: mtl gitUrl https://gogs.yonyoucloud.com/caiyi/mtl.git'); return; } if (fse.existsSync("./project.json")) { let projfile = './project.json'; let result = changeTheGit(projfile, gitUrl); if (result === utils.SUCCESS) { console.log('修改url 成功!'); } } else { console.log('未找到project.json,请执行cd命令进入工程目录。'); return; }; } var hasTemplet = function (template) { return fse.existsSync(template + "/project.json"); } /** * MTL工程 个人版 创建工程前准备 * @param {String} appname * @param {String} template * */ var createBegin = function (appname, template) { //判断模板是否存在 let tplItem = tplLibs[template]; if (!tplItem) { console.log("无效的模板名称 - " + template); console.log("您可以先不输入模板名称,在交互中选择工程模板。"); return utils.reportError(); } console.log("开始创建名称为 - " + appname + "- 的工程"); if (fse.existsSync(template)) { console.log('error: 当前位置存在 ' + template + ' 目录,与模板名称冲突,请检查本地文件。'); console.log('创建工程失败。'); return; } if (conf.get('localResource') == "true") { fse.copySync(configFile.CONFIG_PROJECT_TEMPLATE_PATH + template, appname); } else { // 开始下载模板工程 let rs = downloadTemplate(appname, template); if (rs != SUCCESS) { return; } //创建文件夹 fse.ensureDirSync(appname); //需要这些文件和目录存在 fse.copySync('./' + template + '/app', appname + '/app'); fse.copySync('./' + template + '/script', appname + '/script'); fse.copySync('./' + template + '/.vscode', appname + '/.vscode'); fse.copySync('./' + template + '/project.json', appname + '/project.json'); // 删除模板文件 fse.removeSync(template); } console.log("开始更新本地配置 - " + appname); // updateConfig(appname); console.log("初始化调试环境 - " + appname); console.log("--本地创建完成--先执行 cd " + appname + " 进入目标目录--"); shell.exec("cd ./" + appname); shell.exec("npm --save install express") shell.exec("cd .."); } /** * MTL工程 js 接口 创建工程前准备 * @param {String} appname * @param {String} template * */ var createBeginApi = function (appname, template, workSpace) { //判断模板是否存在 shell.exec("cd " + workSpace); let tplItem = tplLibs[template]; var result = []; if (!tplItem) { console.log("无效的模板名称 - " + template); console.log("您可以先不输入模板名称,在交互中选择工程模板。"); result.push("1"); result.push("模板名称错误,不能创建工程"); return result; } console.log("开始创建名称为 - " + appname + "- 的工程"); if (fse.existsSync(template)) { console.log('error: 当前位置存在 ' + template + ' 目录,与模板名称冲突,请检查本地文件。'); console.log('创建工程失败。'); result.push("1"); result.push("当前位置已经存在工程目录,与模板名称冲突,创建失败。"); return result; } if (conf.get('localResource') == "true") { try { fse.copySync(configFile.CONFIG_PROJECT_TEMPLATE_PATH + template, appname); } catch (e) { console.log(e); result.push("1"); result.push("模板本地拷贝创建失败。 " + e); return result; } } else { try { let tplLibs = require("../res/templates.json"); let tplItem = tplLibs[template]; var appDir = workSpace + '/' + template; if(utils.isWindows()){ // win console.log("WIN 系统"); appDir = workSpace + '\\' + template; }else{ // mac console.log("MAC 系统"); appDir = workSpace + '/' + template; } console.log("mtl git url - " + gitClone + tplItem.url); shell.exec(gitClone + tplItem.url + " --progress " + appDir); //创建文件夹 fse.ensureDirSync(workSpace + '/' + appname); //需要这些文件和目录存在 fse.copySync(workSpace + '/' + template + '/app', workSpace + '/' + appname + '/app'); fse.copySync(workSpace + '/' + template + '/script', workSpace + '/' + appname + '/script'); fse.copySync(workSpace + '/' + template + '/.vscode', workSpace + '/' + appname + '/.vscode'); fse.copySync(workSpace + '/' + template + '/project.json', workSpace + '/' + appname + '/project.json'); // 删除模板文件 fse.removeSync(workSpace + '/' + template); } catch (e) { console.log(e); result.push("1"); result.push("模板下载报错,创建失败。"); return result; } } console.log("开始更新本地配置 - " + appname); // updateConfig(workSpace + "/" + appname); console.log("初始化调试环境 - " + appname); console.log("--本地创建完成--先执行 cd " + appname + " 进入目标目录--"); shell.exec("cd " + workSpace + '/' + appname); shell.exec("npm --save install express") shell.exec("cd .."); if (fse.existsSync(workSpace + "/" + appname)) { result.push("0"); result.push(workSpace + "/" + appname); return result; } else { result.push("1"); result.push("工程目录创建失败。"); return result; } } /** * MTL工程 更新配置 * @param {String} appname * @param {String} gitUrl * */ function updateConfig(appname) { fse.exists(appname, function (exists) { if (exists) { shell.cd(appname); //进入工程目录操作 let projFile = "./" + PROJECT_FILE; let rs = changeTheAppName(projFile, appname); //x修改配置文件 if (rs == SUCCESS) { console.log("更新配置success"); console.log("--本地创建完成--先执行 cd " + appname + " 进入目标目录--"); } } else { return utils.reportError("模板下载失败,请检查您的网络是否正常"); } } ); } /** * MTL工程 更新配置 * @param {String} appname * @param {String} gitUrl * */ function changeTheAppName(projfile, appname) { var proj = JSON.parse(fse.readFileSync(projfile).toString()); var app = proj["config"]; if (!app) app = {}; //处理基本属性 app["appName"] = appname; let packageName = appname.toLowerCase(); app["packageName"] = "com.yonyou." + packageName; app["projectName"] = appname; //回写 proj["config"] = app; fse.writeFileSync(projfile, formatJson(proj), { flag: 'w', encoding: 'utf-8', mode: '0666' }); //修改config.xml // let xmlFile = "./app/" + CONFIG_XML; // var builder = new xml2js.Builder(); // var xml = builder.buildObject(proj); // fse.writeFileSync(xmlFile, xml,{flag:'w',encoding:'utf-8',mode:'0666'}); return utils.SUCCESS; } //下载工程模版 function downloadTemplate(appname, template) { console.log("开始下载工程模板 - " + template); let tplLibs = require("../res/templates.json"); let tplItem = tplLibs[template]; let appDir = './' + template; console.log("mtl git url - " + gitClone + tplItem.url); shell.exec(gitClone + tplItem.url + " --progress " + appDir); return utils.SUCCESS; } function formatJson(data) { return JSON.stringify(data, null, 4); } /** * 格式化输出JSON对象,返回String * @param {JSON} data */ function formatJson2(data) { let LN = "\r"; let TAB = "\t"; var rep = "~"; var jsonStr = JSON.stringify(data, null, rep) var str = ""; for (var i = 0; i < jsonStr.length; i++) { var text2 = jsonStr.charAt(i) if (i > 1) { var text = jsonStr.charAt(i - 1) if (rep != text && rep == text2) { str += LN } } str += text2; } jsonStr = ""; for (var i = 0; i < str.length; i++) { var text = str.charAt(i); if (rep == text) jsonStr += TAB; else { jsonStr += text; } if (i == str.length - 2) jsonStr += LN } return jsonStr; } /** * * @param {String} appname */ var pushRemote = function () { let appname = ''; let pwd = shell.pwd(); let index = pwd.split(path.sep).join('/').lastIndexOf("\/"); appname = pwd.substring(index + 1, pwd.length); console.log('开始执行 pushRemote - appname: ' + appname); if (!appname) { utils.reportError("项目名称: " + appname + ' ,请输入项目名。'); return; } if (!fse.existsSync("project.json")) { console.log('请进入要提交的工程目录进行操作,执行 cd appname'); return; } if (fse.existsSync(".git")) { console.log('本地存在仓库,请检查git'); return; } mtlGit.repo(appname, 'readme', function (gitUrl) { //console.log("--mtl_creat:-success-"+gitUrl); if (!gitUrl) { utils.reportError("远程仓库创建失败,可能已存在该工程导致,请检查git 是否存在项目: " + appname + ' 建议更换工程名重新创建。'); return; } else { //创建完成后 下载。 console.log(gitUrl); shell.exec(gitClone + gitUrl + " --progress tempDir"); //复制模板文件到工程 fse.copySync('/tmp/myfile', '/tmp/mynewfile'); //需要这些文件和目录存在 if (!fse.existsSync("tempDir/.git")) { console.log('gitClone 失败,请检查。'); } fse.copySync('tempDir/.git', './.git'); console.log('拷贝文件 success'); fse.removeSync('tempDir'); //移除 let projFile = "./" + PROJECT_FILE; let rs = changeTheGit(projFile, gitUrl); //x修改配置文件 if (rs == SUCCESS) { console.log("git地址写入配置success"); }; console.log("开始上传更新 - " + appname); commitAndPush(gitUrl, appname); } }); } /** * MTL工程 更新配置 * @param {String} projfile * @param {String} gitUrl * */ function changeTheGit(projfile, gitUrl) { var proj = JSON.parse(fse.readFileSync(projfile).toString()); var app = proj["config"]; if (!app) app = {}; if (!gitUrl) return utils.reportError("未找到远程仓库git - " + gitUrl); app.gitUrl = gitUrl; //回写 proj["config"] = app; fse.writeFileSync(projfile, formatJson(proj), { flag: 'w', encoding: 'utf-8', mode: '0666' }); //修改config.xml // let xmlFile = "./app/" + CONFIG_XML; // var builder = new xml2js.Builder(); // var xml = builder.buildObject(proj); // fse.writeFileSync(xmlFile, xml,{flag:'w',encoding:'utf-8',mode:'0666'}); return utils.SUCCESS; } /** * MTL工程 提交远程仓库 * @param {String} gitUrl * @param {String} appname */ function commitAndPush(gitUrl, appname) { let pwd = shell.pwd(); console.log('当前路径:' + pwd); if (!gitUrl) return utils.reportError("未找到远程仓库git - " + gitUrl); //first commit shell.exec("git add -A"); console.log('执行git commit'); let message = 'firstcommit'; //shell.exec("git status"); shell.exec("git commit -m " + message + ' -q'); shell.exec("git push"); console.log("初始化完成,本地工程提交成功,代码托管。"); console.log("具体查看git : " + gitUrl); return SUCCESS; } /** * MTL工程 多人协同 * @param {String} url * */ var pullRemote = function (url) { if (!url) { console.log("必须输入gitUrl"); return utils.reportError("mtl open gitUrl"); } let index = url.split(path.sep).join('/').lastIndexOf("\/"); appnameGit = url.substring(index + 1, url.length); appname = appnameGit.substring(0, appnameGit.length - 4); //去掉git console.log('appname: ' + appname); if (fse.existsSync(appname)) { //截取工程目录 console.log("本地已存在目录:" + appname + ",请检查目录。"); return utils.reportError("执行: dir 查看:"); } console.log("开始执行..."); shell.exec(gitClone + url); console.log("操作完成..."); console.log("执行 cd 工程名 进入工程目录"); } async function getTempList() { console.log('w'); let sendResultList = await mtlConfig.send({ url: 'http://cloudcoding.dev.app.yyuap.com/codingcloud/gentplrepweb/list/mtl', method: 'get' }); //console.log(sendResultList); sendResultList = JSON.parse(sendResultList); let tempInfo = sendResultList.detailMsg.data.content; var tempNameList = []; if (tempInfo.length) { for (var i = 0; i < tempInfo.length; i++) { tempNameList.push(tempInfo[i].tplRepName); } // console.log(tempNameList); return tempNameList; } else { return []; } } //createApp("xxxx",""); exports.createApp = createApp exports.pushRemote = pushRemote exports.configGitUrl = configGitUrl exports.createBeginApi = createBeginApi