UNPKG

@thingjs/cli-code-temp

Version:

292 lines (287 loc) 8.26 kB
import chalk from 'chalk'; import fs from 'fs-extra'; import inquirer from 'inquirer'; import path from 'path'; import { thing } from '@thingjs/cli-common'; import { exec, execSync } from 'child_process'; import downloadGitRepo from 'download-git-repo'; import ora from 'ora'; import { promisify } from 'util'; const tempUrl = { // simple: 'https://gitee.com:uinosoft/thingjs-template-simple', // vue: 'https://gitee.com:thingjs-code-temp/vue', // vue3: 'https://gitee.com:thingjs-code-temp/vue3', // react: 'https://gitee.com:thingjs-code-temp/react', // prefab: 'https://gitee.com:uinosoft/thingjs-template-prefab', // plugin: 'https://gitee.com:uinosoft/thingjs-template-plugin', // 'dev-base': `direct:https://git.uino.com/uino-3dapplication/component/cli-code-temp/dev-base.git`, simple: `https://gitee.com:uinosoft/thingjs-template-simple-pro`, editor: `https://gitee.com:uinosoft/thingjs-project-template-simple`, "vue-editor": `https://gitee.com:uinosoft/thingjs-project-js-template`, "vue-editor-ts": `https://gitee.com:uinosoft/thingjs-project-template#main` // project: `https://gitee.com:uinosoft/thingjs-template-simple-pro` // 'pro-plugin': `https://gitee.com:uinosoft/thingjs-template-plugin-pro`, // 'pro-prefab': `https://gitee.com:uinosoft/thingjs-template-prefab-pro`, }; const setName = [ { name: "name", type: "input", message: "Please enter a project name:" } ]; const pickProjectQuesArr = () => { const choices = [ { name: "Simple", value: "simple" } ]; return choices; }; const tempAction = (projUrl) => { return [ { name: "action", type: "list", message: `The file: ${projUrl} has existed, Please choose:`, choices: [ { name: "Overwrite", value: "overwrite" }, { name: "Cancel", value: "cancel" } ] } ]; }; const downloadGitRepoAsync = promisify(downloadGitRepo); const execAsync = promisify(exec); class Creator { name; context; promptConfig; userTempType; // User-specified template type constructor(name, context, options) { this.name = name; this.context = context; this.promptConfig = {}; this.userTempType = options.type; } /** * @description get current npm environment * @deprecated * @returns {String} in / out */ getCurEnvironment() { const registryUrl = execSync("npm config get registry"); const emailUrl = execSync("git config user.email"); const environment = registryUrl.toString().includes("npm.uino.cn") && emailUrl.toString().includes("uino") ? "in" : "out"; return environment; } async create() { const { userTempType } = this; if (userTempType && tempUrl[userTempType]) { await this.download(userTempType, tempUrl[userTempType], this.name); return; } const choices = pickProjectQuesArr(); let tempType; if (choices.length > 0) { if (choices.length === 1) { tempType = choices[0].value; this.promptConfig.TempType = tempType; } else { const obj1 = { name: "tempType", type: "list", message: "Please pick a preset:", pageSize: 12, choices }; const arr = [obj1]; const result = await inquirer.prompt(arr); Object.assign(this.promptConfig, result); tempType = result.tempType; } } await this.download(tempType, tempUrl[tempType], this.name); } /** * @description Download the remote template * @param {String} tempType type of template * @param {String} url download links * @param {String} name filename */ async download(tempType, url, name) { let success = await this.createProject(url, name); if (!success) { return; } if (tempType === "simple") { const currentDirectory = process.cwd(); const childDirectory = path.join(currentDirectory, this.name); process.chdir(childDirectory); success = await thing.installDefaultThingJS(); if (!success) { return; } } if (["simple"].includes(tempType)) { console.info(chalk.cyan(`Starting the index.html with live-server`)); return; } else { console.info(chalk.cyan(`cd ${name}`)); console.info(chalk.cyan(`pnpm i`)); console.info(chalk.cyan(`pnpm dev`)); } } async createProject(url, name) { let spinner = ora( "Downloading project. This might take a while...\n\n" ).start(); try { await downloadGitRepoAsync(url, name, { clone: true }); spinner.succeed("Download project successful!"); return true; } catch (error) { console.error("Error", error.message); spinner.fail("Download failed, error message: " + error.message); return false; } } async installNodeModules(name) { const spinner = ora( "Installing project. This might take a while...\n" ).start(); try { await execAsync("npm i"); spinner.succeed("Install Successful!"); console.info(chalk.green(`Successfully install project: ${name} `)); return true; } catch (error) { console.info("Error", error.message); spinner.fail("npm install failed"); return false; } } async buildProject(name) { const spinner = ora( "Building project. This might take a while...\n" ).start(); try { await execAsync("npm run build"); spinner.succeed("Building Successful!"); console.info(chalk.green(`Successfully build project: ${name} `)); console.info(chalk.green("Get started with the following commands: ")); console.info(chalk.cyan(`cd ${name}`)); console.info(chalk.cyan(`npm run serve`)); return true; } catch (error) { console.info("Error", error.message); spinner.fail("npm build failed"); return false; } } /** * Manually select features */ async customPrompts() { const customPromptConfig = [ { name: "Library", type: "checkbox", message: "Check the features needed for your project", pageSize: 12, choices: [ { name: "CSS Pre-processors", value: "cssPreprocessors" }, { name: "Linter/Formatters", value: "linter" }, { name: "Unit Testing", value: "unit" } ] } ]; try { const result = await inquirer.prompt(customPromptConfig); Object.assign(this.promptConfig, result); await this.getPromptModules(result.Library); } catch (error) { console.log(error); } } async getPromptModules(library = []) { library.unshift("version"); const list = library.map((file) => require(`./promptModules/${file}`)); await this.resolvePrompt(list); } async resolvePrompt(list) { let result = list.shift(); const config = await inquirer.prompt([result]); Object.assign(this.promptConfig, config); if (list.length > 0) await this.resolvePrompt(list); } } async function create(param) { const { command: { args, opts } } = param; let name = args[0]; let type = opts.template || "simple"; if (!name) { const res = await inquirer.prompt(setName); name = res.name; if (!name) { console.info( chalk.yellow( `Missing required argument <app-name>, exit the process! ` ) ); process.exit(1); } } if (type === "vue-editor") { const { isTs } = await inquirer.prompt({ name: "isTs", type: "confirm", message: "Do you want to use TypeScript?", default: false }); if (isTs) { type = "vue-editor-ts"; } } const cwd = process.cwd(); const projUrl = path.join(cwd, name); if (fs.existsSync(projUrl)) { const { action } = await inquirer.prompt( tempAction(projUrl) ); if (action === "cancel") { process.exit(0); } console.info(`Removing ${chalk.blue(projUrl)}... `); fs.removeSync(projUrl); } const creator = new Creator(name, projUrl, { type }); await creator.create(); } export { create as default };