sdata-cli
Version:
smardaten二次开发插件脚手架
233 lines (230 loc) • 8.96 kB
JavaScript
const {prompt} = require("enquirer");
const ora = require("ora");
const execa = require("execa");
const chalk = require("chalk");
const execSync = require('child_process').execSync;
const path = require("path");
const {v4: uuidv4} = require("uuid");
const fse = require("fs-extra");
const os = require('os');
const {
getModuleList,
urlObjMap,
frameMap,
} = require("../config/gitUrlMap");
const {errLog} = require("../src/utils/log.js");
const getFirstDate = require("./getFirstDate.js")
const axios = require('axios');
function executeCommand(command, cwd = process.cwd()) {
return new Promise((resolve, reject) => {
const child = execa.command(command, {cwd});
child.on("close", code => {
if (code !== 0) {
reject(new Error(`command failed: ${command}, ${code}`));
return;
}
resolve();
});
});
}
module.exports = (options) => {
let promptList = [
{
type: "input",
name: "project-name",
message: "请输入所属项目名称(飞书需求文档复制)",
transformer: (res) => {
return res.replaceAll("(", "(").replaceAll(")", ")").replaceAll(" ", "")
},
validate(val) {
if (val.trim() === "") {
return "所属项目不能为空";
}
return true
}
},
{
type: "input",
name: "requirement-number",
message: "请输入需求编号(飞书需求文档复制)",
validate(val) {
if (val.trim() === "") {
return "需求编号不能为空";
}
return true
}
},
{
type: "input",
name: "requirement-name",
message: "请输入需求名称(飞书需求文档复制)",
validate(val) {
if (val.trim() === "") {
return "需求名称不能为空";
}
if (val.length >= 20) {
return "需求名称不能大于20字符,请适当缩减名称长度"
}
return true
}
},
{
type: "input",
name: "baseVersion",
message: "请输入需求的开发分支(飞书需求文档复制,若飞书为空则填入当前最新分支)",
validate(val) {
if (val.trim() === "") {
return "需求开发分支不能为空";
}
return true
}
},
{
type: "autocomplete",
name: "pluginType",
message: "请选择插件类型",
limit: 7,
initial: 0,
choices: () => {
return getModuleList(effectiveObj);
},
},
{
type: "select",
name: "templeteType",
message: "请选择开发框架",
choices() {
let {pluginType} = this.enquirer.answers
return effectiveObj[pluginType].frame
},
},
];
let effectiveObj
let {branch, origin} = options
axios.get(`${origin ? origin : "https://gitee.com/njsmartdata/sdata-plugins"}/raw/${branch
? branch
: "master"}/templates.json`).then(async ({data}) => {
effectiveObj = data || urlObjMap
const latestVersion = execSync(`npm view sdata-cli version`, {"encoding": "utf8"}).replace("\n", "");
if (require("../package.json").version != latestVersion) {
console.log(chalk.red(`${require("../package.json").version}-->${latestVersion},请执行npm i sdata-cli -g 获取最新版本,以达到最佳使用体验\n`));
let {description} = (await axios.get("https://gitee.com/njsmartdata/sdata-cli/raw/master/update_log.json"))?.data[latestVersion] || {}
description && console.log(`${latestVersion}更新:${description}`);
}
prompt(promptList).then(async answer => {
const spinner = ora();
spinner.text = "开始生成项目,请等待...";
spinner.start();
try {
const templateMap = {
"Vue 3": "vue3",
"Vue 2": "vue",
Svelte: "svelte",
React: "react",
};
let firstDate = getFirstDate();
let requirementNumber = answer["requirement-number"]?.replaceAll(" ", "");
let requirementName = answer["requirement-name"]?.replaceAll(" ", "");
let pluginType = answer.pluginType;
let templeteType = templateMap[answer.templeteType];
let projectName = answer["project-name"]?.replaceAll("(", "(").replaceAll(")", ")").replaceAll(" ", "")
let floderName = `${firstDate}-${requirementNumber}-${requirementName}-${pluginType}-${templeteType}-plugin`;
let floderPath = ""
!fse.existsSync(path.resolve(process.cwd(), projectName)) && execSync(`mkdir ${projectName}`)
floderPath = `${projectName}/${floderName}`
if (fse.existsSync(path.resolve(process.cwd(), floderPath))) {
fse.removeSync(path.resolve(process.cwd(), floderPath))
}
await executeCommand(`mkdir ${floderName}`, path.join(process.cwd(), projectName));
await executeCommand("git init", path.join(process.cwd(), floderPath));
await executeCommand(
`git remote add -f origin ${origin ? origin + ".git" : "https://gitee.com/njsmartdata/sdata-plugins.git"}`,
path.join(process.cwd(), floderPath)
);
await executeCommand(
`git config core.sparsecheckout true`,
path.join(process.cwd(), floderPath)
);
let infoPath = path.join(process.cwd(), floderPath, ".git/info");
if (!fse.existsSync(infoPath)) {
fse.mkdirSync(infoPath);
}
const packagePath = `packages/${answer.pluginType}${
frameMap[answer.templeteType]
}-plugin`;
fse.writeFileSync(
path.join(process.cwd(), floderPath, ".git/info/sparse-checkout"),
packagePath
);
await executeCommand(
`git pull origin ${branch ? branch : "master"}`,
path.join(process.cwd(), floderPath)
);
fse.copySync(
path.join(process.cwd(), floderPath, packagePath),
path.join(process.cwd(), floderPath)
);
fse.removeSync(path.join(process.cwd(), floderPath, "/packages"));
fse.removeSync(path.join(process.cwd(), floderPath, "/.git"));
let configJson;
try {
configJson = require(path.join(
process.cwd(),
`${floderPath}/pluginTemp/config.json`
));
configJson.id = uuidv4();
configJson["requirement-number"] = requirementNumber
configJson["requirement-name"] = requirementName
configJson.suggestedFolderName = floderName
configJson.templeteType = answer.templeteType
configJson.baseVersion = answer.baseVersion
fse.writeFileSync(
path.join(process.cwd(), `${floderPath}/pluginTemp/config.json`),
JSON.stringify(configJson, null, 2),
"utf8"
);
} catch (e) {
configJson = require(path.join(
process.cwd(),
`${floderPath}/config.json`
));
configJson.id = uuidv4();
configJson["requirement-number"] = requirementNumber
configJson["requirement-name"] = requirementName
configJson.suggestedFolderName = floderName
configJson.templeteType = answer.templeteType
configJson.baseVersion = answer.baseVersion
fse.writeFileSync(
path.join(process.cwd(), `${floderPath}/config.json`),
JSON.stringify(configJson, null, 2),
"utf8"
);
}
spinner.succeed(chalk.green(`${floderName} 项目生成完毕!`));
console.log(chalk.green(`cd ${floderPath} && npm install \n`));
try {
if (os.type() === "Darwin") {
execSync(`open ${path.resolve(process.cwd(), floderPath)}`)
} else {
execSync(`start ${path.resolve(process.cwd(), floderPath)}`)
}
} catch (e) {
console.log("自动打开文件夹失败,请手动打开,目录名:" + path.resolve(process.cwd(), floderPath))
}
} catch (error) {
spinner.fail("模板下载失败,请先按照以下步骤排查问题");
spinner.fail("1.请使用管理员权限运行命令行程序");
spinner.fail("2.本程序依赖git运行,请确保安装git并将git命令添加到系统环境变量");
spinner.fail("3.请检查网络是否连接正常,如有VPN请关闭后重试");
spinner.fail("4.请检查命令行是否使用utf-8编码运行");
spinner.fail("以上排查项均ok,请联系管理员");
errLog(error);
process.exit();
}
});
}).catch((reason) => {
console.log(reason);
console.log("请检查网络是否连接正常,如有VPN请关闭后重试");
})
};
;