#!/usr/bin/env node
import program from 'commander';
import inquirer from 'inquirer';
import downloadGit from 'download-git-repo';
import ora from 'ora';
import chalk from 'chalk';
import fs from 'fs/promises';
import path from 'path';
import { fileURLToPath } from 'url';
async function rmdirasync(filepath) {
let stat = await fs.stat(filepath)
if (stat.isfile()) {
await fs.unlink(filepath)
} else {
let dirs = await fs.readdir(filepath)
dirs = dirs.map(dir => rmdirasync(path.join(filepath, dir)))
await promise.all(dirs)
await fs.rmdir(filepath)
}
}
const projectList = [
{ name: 'site-m 移动端项目', value: { url: 'http://git.daicms.com/dai-cli.git#master', path: '/site-m/' } },
{ name: 'site-w 电脑端项目', value: { url: 'http://git.daicms.com/dai-cli.git#master', path: '/site-w/' } },
{
name: 'site-admin-iview 电脑端后台模板(iview)',
value: { url: 'http://git.daicms.com/dai-cli.git#master', path: '/site-admin-iview/' }
}
];
const moduleList = [
{ name: 'module-m 移动端模块', value: { url: 'http://git.daicms.com/dai-cli.git#master', path: '/module-m/' } },
{ name: 'module-w 电脑端模块', value: { url: 'http://git.daicms.com/dai-cli.git#master', path: '/module-w/' } }
];
//下载项目
let downloadProject = function (answers) {
return new Promise(function (a, b) {
//创建一个临时目录,因为git 只能在空目录 clone
let downDir = './';
let temporaryDir = downDir + '_gitDownload/';
const spinner = ora('下载中...');
spinner.start();
downloadGit('direct:' + answers.git.url, temporaryDir, { clone: true }, async (err) => {
if (err) {
spinner.fail();
// console.log(chalk.red(err));
b(err);
} else {
//转移
let list = await fs.readdir(temporaryDir + answers.git.path);
// console.log(list);
for (let file of list) {
await fs.rename(temporaryDir + answers.git.path + file, downDir + file);
}
await fs.rmdir(temporaryDir, { recursive: true, maxRetries: 5, retryDelay: 100 });
spinner.succeed();
a();
}
});
});
};
let downloadModule = function (options) {
return new Promise(function (a, b) {
//创建一个临时目录,因为git 只能在空目录 clone
let downDir = options.path;
let temporaryDir = downDir + '_gitDownload/';
const spinner = ora('下载中...');
spinner.start();
console.log(111,options);
downloadGit('direct:' + options.git.url, temporaryDir, { clone: true }, async (err) => {
if (err) {
spinner.fail();
// console.log(chalk.red(err));
b(err);
} else {
//转移
let list = await fs.readdir(temporaryDir + options.git.path);
// console.log(list);
for (let file of list) {
await fs.rename(temporaryDir + options.git.path + file, downDir + file);
}
await fs.rmdir(temporaryDir, { recursive: true, maxRetries: 5, retryDelay: 100 });
spinner.succeed();
a();
}
});
});
};
let runDev = async function () {
};
let exec = function () {
return new Promise(async function (a, b) {
program
.command('init')
// .alias('i')
// .description('初始化')
// .option('-x, --xxx', 'xxx') // 有参数时使用
.action(async () => {
let answers = await inquirer.prompt([
{
name: 'name',
message: '请输入项目名称'
},
{
name: 'description',
message: '请输入项目描述(可为空)',
default: 'description'
},
{
name: 'author',
message: '请输入作者名称(可为空)',
default: 'description'
},
{
type: 'list',
name: 'git',
message: '请选择项目类型',
choices: projectList
}
//目录方式
// {
// type: 'list',
// name: 'pathType',
// message: '请选择项目位置',
// choices: [
// { name: '当前目录', value: '0' },
// { name: '新建目录', value: '0' }
// ]
// }
]);
// console.log(answers);
//判断目录是否为空
let list = await fs.readdir('./');
if (list.length > 0) {
//允许在一个git 空目录中创建项目
if (list.length == 1 && list[0] == '.git') {
} else {
console.error(chalk.redBright('目录不为空,创建失败'));
return;
}
}
await downloadProject(answers);
//更改配置
const fileName = './package.json';
const meta = {
name: answers.name,
description: answers.description,
author: answers.author
};
let content = await fs.readFile(fileName);
content = JSON.parse(content.toString());
Object.assign(content, meta);
await fs.writeFile(fileName, JSON.stringify(content, null, 4));
console.log(chalk.green('项目创建成功,请使用 npm i 安装依赖,npm run dev 启动开发,npm run build 打包发布'));
});
program
.command('add')
// .alias('i')
// .description('初始化')
// .option('-x, --xxx', 'xxx') // 有参数时使用
.action(async () => {
let answers = await inquirer.prompt([
{
name: 'name',
message: '请输入功能模块名称(功能模块将添加到目录 modules 中)'
},
{
type: 'list',
name: 'git',
message: '请选择模块类型',
choices: moduleList
}
]);
console.log(answers);
let path = './modules/' + answers.name + '/';
//检测目录是否存在
{
let dir;
try {
dir = await fs.stat(path);
} catch (ex) {
//没有则创建目录
if (ex.errno == '-4058') {
console.log(chalk.green('目录没找到,创建 ' + path));
await fs.mkdir(path, { recursive: true });
dir = await fs.stat(path);
}
}
//判断是否为文件夹
if (!dir.isDirectory()) {
console.log(chalk.red('路径不是目录,模块添加失败'));
return;
}
//判断目录是否为空
let list = await fs.readdir(path);
if (list.length > 0) {
console.error(chalk.redBright('目录不为空,模块添加失败'));
return;
}
}
await downloadModule({ path, git: answers.git });
//替换文件内的关键字
{
let fileList = [path + 'static/style/style.less', path + 'api.js', path + 'routes.js'];
let keys = [
{ oldval: 'module__module_test', val: 'module-' + answers.name },
{ oldval: 'module__name_test', val: answers.name }
];
for (let file of fileList) {
let text = await fs.readFile(file);
text = text.toString();
for (let key of keys) {
// text = text.replaceAll(key.oldval, key.val);
text = text.replace(new RegExp(key.oldval, 'gm'), key.val);
}
await fs.writeFile(file, text);
}
}
//向项目中添加引用
{
let text = await fs.readFile('./main/modules.js');
text = text.toString();
text += `\r\nexport { default as ${answers.name} } from '../modules/${answers.name}/index.js'`;
await fs.writeFile('./main/modules.js', text);
}
//删除无用文件
await fs.unlink('./modules/' + answers.name + '/desktop.ini');
//添加模块描述文件
await fs.writeFile('./modules/' + answers.name + '/_.txt', '请输入模块描述信息');
//添加一些有用的文件夹
await fs.mkdir('./modules/' + answers.name + '/static/script');
await fs.mkdir('./modules/' + answers.name + '/static/svg');
await fs.mkdir('./modules/' + answers.name + '/static/font');
await fs.mkdir('./modules/' + answers.name + '/module');
// 添加快速描述
console.log(chalk.green('模块添加成功'));
});
program.command('dev').action(async () => {
console.log('启动 dev 服务');
runDev();
});
program.command('build').action(async () => {
console.log('启动 build 服务');
});
program.parse(process.argv);
});
};
exec()
.then(function () {
console.log('运行结束,退出');
process.exit(0);
})
.catch(function (ex) {
console.error(ex);
process.exit(0);
});