@uinosoft/thing-cli-code-temp
Version:
287 lines (282 loc) • 7.75 kB
JavaScript
import inquirer from 'inquirer';
import fs from 'fs-extra';
import path from 'path';
import chalk from 'chalk';
import ora from 'ora';
import downloadGitRepo from 'download-git-repo';
import { exec, execSync } from 'child_process';
import { promisify } from 'util';
import { thing } from '@uinosoft/thing-cli-common';
const tempUrl = {
simple: "https://gitee.com:uinosoft/thingjs-template-simple",
"dev-base": `direct:https://git.uino.com/uino-3dapplication/component/cli-code-temp/dev-base.git`,
"pro-simple": `https://gitee.com:uinosoft/thingjs-template-simple-pro`
};
const setName = [
{
name: "name",
type: "input",
message: "Please enter a project name:"
}
];
const pickProjectQuesArr = (type, isPro) => {
const choices = isPro ? [
{
name: "Simple Pro",
value: "pro-simple"
}
] : [
{
name: "Simple",
value: "simple"
}
];
if (type === "in") {
choices.push({
name: "Dev Base",
value: "dev-base"
});
}
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 {
constructor(name, context, options) {
this.name = name;
this.context = context;
this.promptConfig = {};
this.isPro = options.pro;
this.userTempType = options.type;
}
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 environment = this.getCurEnvironment();
const { userTempType } = this;
if (userTempType && tempUrl[userTempType]) {
await this.download(userTempType, tempUrl[userTempType], this.name);
return;
}
if (this.isPro === void 0) {
const result = await inquirer.prompt([
{
name: "isPro",
type: "confirm",
message: "Do you want to use the pro version?",
default: false
}
]);
this.isPro = result.isPro;
}
const choices = pickProjectQuesArr(environment, this.isPro);
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);
}
async download(tempType, url, name) {
let success = await this.createProject(url, name);
if (!success) {
return;
}
const currentDirectory = process.cwd();
const childDirectory = path.join(currentDirectory, this.name);
process.chdir(childDirectory);
success = await thing.installDefaultThingJS(this.isPro);
if (!success) {
return;
}
if (["simple", "pro-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(`npm i, or pnpm i, or yarn`));
console.info(chalk.cyan(`npm run serve`));
}
}
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 Successful!");
return true;
} catch (error) {
console.info("Error", error.message);
spinner.fail("Download failed");
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;
}
}
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];
if (opts == null ? void 0 : opts.type) {
opts.type = opts.type.toLowerCase();
}
if ((opts == null ? void 0 : opts.type) && !tempUrl[opts.type]) {
console.info(
chalk.yellow(
`Template type does not exist, available types: ${Object.keys(
tempUrl
)}
`
)
);
process.exit(1);
}
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);
}
}
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(1);
}
console.info(`Removing ${chalk.blue(projUrl)}...
`);
fs.removeSync(projUrl);
}
const creator = new Creator(name, projUrl, {
pro: opts == null ? void 0 : opts.pro,
type: opts == null ? void 0 : opts.type
});
await creator.create();
}
export { create as default };