UNPKG

@vin_coder/pg-cli

Version:
292 lines (237 loc) 7.48 kB
const chalk = require("chalk"); const execa = require("execa"); const inquirer = require("inquirer"); const path = require("path"); const cloneDeep = require("lodash.clonedeep"); const writeFileTree = require("./utils/writeFileTree"); const { hasYarn } = require("./utils/env"); const PackageManager = require("./utils/packageManager"); const sortObject = require("./utils/sortObject"); const Generator = require("./utils/Generator"); const { loadModules } = require("./utils/module"); const generateReadme = require("./utils/generateReadme"); const { defaults, loadOptions, defaultFrame } = require("./options"); module.exports = class Initiator { constructor(name, context) { this.name = name; this.ctx = process.env.PG_CLI_RESOURCE = context; this.frameCtx = ""; const { framePrompt } = this.resolveFramePrompts(); const { projectPrompt } = this.resolveProjectPrompts(); this.framePrompt = framePrompt; this.projectPrompt = projectPrompt; this.run = this.run.bind(this); } async initiate(options) { let { name, ctx, run } = this; // 初始化 前端项目 package.json const plugs = {}; let frameName = ""; let projectName = ""; let f; let p; if ((f = options.frame)) { if (!defaultFrame.includes(f.toLowerCase())) { console.log(chalk.red(`暂不支持 框架${f}, vue, react 可任选其一`)); return; } else { frameName = f; } } else { // 提示 let answer = await inquirer.prompt([this.framePrompt]); frameName = answer.frame; } if ((p = options.project)) { projectName = p; } else { // 提示用户是否现在创建项目,是则 提示用户输入项目名称,否则提示用户可以通过 pg add project <projectName> 来手动添加项目 let answer = await inquirer.prompt(this.projectPrompt); if (!answer.addProject) { console.log( "提示:你可以后续通过 pg add project <projectName> 来添加项目" ); } else { if ((p = answer.projectName)) { projectName = p; } console.log(JSON.stringify(answer, null, " ")); } } this.frameCtx = path.join(ctx, frameName); plugs["@vin_coder/pg-cli-service"] = Object.assign({ projectName: name, }); plugs["@vin_coder/pg-cli-plugin-service"] = {}; plugs[`@vin_coder/pg-cli-template-frame-${frameName}`] = {}; if (projectName) { plugs[`@vin_coder/pg-cli-template-project-${frameName}`] = {}; } const packageManager = loadOptions().packageManager || (hasYarn() ? "yarn" : "npm"); const pm = new PackageManager({ ctx: this.frameCtx, forcePackageManager: packageManager, }); console.log(); console.log( chalk.green( `✨ 项目${chalk.bgBlack(`${name}`)}正在 目录 ${chalk.bgBlack( `${this.frameCtx}` )} 生成中...` ) ); console.log(); const pkg = { name, version: "0.1.0", private: true, devDependencies: {}, }; const deps = Object.keys(plugs); deps.forEach((dep) => { pkg.devDependencies[dep] = plugs[dep].version || "latest"; }); //写入package.json await writeFileTree(this.frameCtx, { "package.json": JSON.stringify(pkg, null, 2), }); // return; // 初始化git仓库 console.log(); console.log(chalk.green(`🗃 初始化git 仓库...`)); console.log(); await run("git init"); // 安装cli 插件 console.log(); console.log(chalk.green(`⚙ 安装命令行工具所需插件,可能需要等一会儿...`)); console.log(); await pm.install(); // 执行插件中的generator console.log(); console.log(chalk.green(`🚀 执行生成器...`)); console.log(); const plugins = await this.resolvePlugins(plugs); const generator = new Generator(this.frameCtx, { pkg, plugins, currentProjectName: projectName, }); await generator.generate(); // 安装条件依赖 console.log(); console.log(chalk.green(`📦 安装插件所需依赖...`)); console.log(); await pm.install(); //生成 read.me console.log(); console.log(chalk.green(`📄 生成READ.ME 文件...`)); console.log(); await writeFileTree(this.frameCtx, { "README.md": generateReadme(pkg, packageManager), }); await run("git add -A"); try { await run("git", ["commit", "-m", "初始化git提交"]); } catch (e) { console.log( chalk.yellow(`😈 项目 ${name} 初始化提交失败 ,请尝试手动提交`) ); } // 提示成功 console.log(); console.log(chalk.green(`🎉 成功创建项目仓库 ${name}.`)); console.log(); } resolveProjectPrompts() { const frames = defaultFrame; const projectPrompt = [ { type: "confirm", name: "addProject", message: "想要现在添加项目吗?", }, { type: "input", name: "projectName", message: "请输入所要添加的项目名称", when: function (answers) { return answers.addProject; }, validate: function (val) { if (!val || frames.includes(val.toLowerCase())) { return "项目名称不可为空或不可以和依赖框架同名"; } return true; }, }, ]; return { projectPrompt }; } // 返回 框架选择 prompt resolveFramePrompts() { const frames = defaultFrame; const frameChoices = frames.map((name) => ({ name, value: name, })); const framePrompt = { name: "frame", type: "list", message: "请选择一个依赖的前端框架:", choices: frameChoices, }; return { framePrompt }; } getPresets() { const savedOptions = loadOptions(); return Object.assign({}, savedOptions.presets, defaults.presets); } async promptAndResolvePreset(answers = null) { if (!answers) { answers = await inquirer.prompt([this.presetPrompt]); } let preset; if (answers.preset) { preset = await this.resolvePreset(answers.preset); } return preset; } async resolvePreset(name) { let preset; const savedPresets = loadOptions().presets; if (name in savedPresets) { preset = savedPresets[name]; } if (name === "default" && !preset) { preset = defaults.presets.default; } if (!preset) { console.log(chalk.yellow("preset 没有找到")); const presets = Object.keys(savedPresets); if (presets.length > 0) { console.log(chalk.green(`可能的preset 如下: ${presets.join("\n")}`)); } else { console.log(chalk.red("没有perset ,手动配置一下吧")); } process.exit(1); } return preset; } async resolvePlugins(rawPlugins) { rawPlugins = sortObject(rawPlugins, ["@vin_coder/pg-cli-service"], true); const plugins = []; for (const id of Object.keys(rawPlugins)) { let apply = loadModules(`${id}/generator`, this.frameCtx) || (() => {}); let options = rawPlugins[id] || {}; plugins.push({ id, apply, options }); } return plugins; } run(cmd, args) { if (!args) { [cmd, ...args] = cmd.split(/\s+/); } return execa(cmd, args, { cwd: process.env.PG_CLI_ROOT }); } };