提交 4727bce4 作者: 潘亚楠

合并分支 'dev-feat/#6' 到 'dev'

从 dev-feat/#6 合并到 dev

查看合并请求 Platform/UPA/UPA_QJCLI/UPA_QJCLI!8
src
.gitlab
tsconfig.json
.gitignore
\ No newline at end of file
{
"name": "qj-vue-cli",
"version": "0.1.0",
"name": "qj-cli",
"version": "0.1.5",
"description": "qj-vue-cli",
"main": "index.js",
"bin": {
......@@ -11,8 +11,8 @@
"watch-bin": "nodemon dist/bin/index.js create vue2.0 hello",
"dev": "concurrently \"npm run watch-ts\" \"npm run watch-bin\"",
"build": "tsc",
"dev-link": "npm run build && npm unlink && npm link",
"test": "mocha -r ts-node/register src/test/**/*.test.ts"
"test-ts": "mocha -r ts-node/register src/test/**/*.test.ts",
"test": "mocha dist/test/**/*.test.js"
},
"repository": {
"type": "git",
......@@ -29,13 +29,13 @@
"@types/commander": "^2.12.2",
"@types/cross-spawn": "^6.0.1",
"@types/fs-extra": "^8.0.1",
"@types/inquirer": "^6.5.0",
"@types/mocha": "^5.2.7",
"@types/node": "^12.12.17",
"@types/power-assert": "^1.5.2",
"concurrently": "^5.0.1",
"mocha": "^6.2.2",
"nodemon": "^2.0.2",
"power-assert": "^1.6.1",
"ts-node": "^8.5.4",
"typescript": "^3.7.3"
},
......@@ -45,6 +45,8 @@
"cross-spawn": "^7.0.1",
"execa": "^3.4.0",
"fs-extra": "^8.1.0",
"ora": "^4.0.3"
"inquirer": "^7.0.1",
"ora": "^4.0.3",
"power-assert": "^1.6.1"
}
}
......@@ -2,18 +2,18 @@
import * as program from 'commander';
import { hasTemplate } from '../config/template.config';
import listTemplates from '../lib/listTemplates';
import { create } from '../lib/create'
// 版本号
program
.version(`${require('../../package.json').version}`)
.name('world')
.name('qj-cli')
.usage('<command> [options]');
// create command
program
.command('create <templateName> <projectName>')
.description('create a project from a template')
.action((templateName: string, projectName: string, cmd) => {
console.log(templateName);
console.log(projectName);
.action((templateName: string, projectName: string, options) => {
create(templateName, projectName, options);
})
// ls command
program
......
......@@ -3,18 +3,13 @@
* @author panyanan
* @information 框架模板配置文件
*/
export interface Repo {
readonly url: string, // 仓库地址
readonly username: string, // 用户名
readonly password: string, // 用户密码
}
export interface Template {
readonly name: string, // 模板名称
readonly desc: string, // 模板描述
readonly repo: Repo, // 模板仓库信息
readonly repo: string, // 模板仓库信息
}
export const Templates: Template[] = [
{ name: 'vue2.0', desc: '千家vue2.0项目模板,对接了组件库/标准库/用户操作埋点', repo: { url: 'git@git.allhome.com.cn:panyanan/my-vue-template.git', username: '', password: ''} },
{ name: 'vue2', desc: '千家vue2项目模板,对接了组件库/标准库/用户操作埋点', repo: 'https://git.allhome.com.cn/panyanan/my-vue-template.git' },
// todo other template
];
/**
......
import { Templates, hasTemplate } from '../config/template.config'
import * as chalk from 'chalk'
import * as path from 'path'
import { CreateVue2 } from './create_vue2'
export async function create(templateName: string, projectName: string, options: any) {
// 验证模板名称
let requireMessage = [];
if (!hasTemplate(templateName)) {
requireMessage.push('模板名称不正确')
}
// 验证项目名称
if (!projectName) {
requireMessage.push('缺少项目名')
}
if (requireMessage.length) {
console.log(chalk.red(requireMessage.join(' && ')));
return;
}
// 项目目录
const targetDir = path.join(process.cwd(), projectName);
// 模板
const template = Templates.find( ({ name }) => name === templateName );
// 不同的框架模板实现各自的创建逻辑
switch(templateName) {
case 'vue2':
const creator = new CreateVue2( template, projectName, targetDir);
await creator.create(options);
default:
}
}
import * as ora from 'ora'
import { Git } from '../util/Git'
import { Templates, Template } from '../config/template.config'
import * as inquirer from 'inquirer'
import * as chalk from 'chalk';
/**
* @date 2019.12.18
* @author panyanan
* @information 创建vue2项目
*/
export class CreateVue2 {
// 模板
private template: Template;
// 项目名称
private projectName: string;
// 项目目录
private targetDir: string;
constructor(template: Template, projectName: string, targetDir: string) {
this.template = template;
this.projectName = projectName;
this.targetDir = targetDir;
}
/**
* @date 2019.12.19
* @author panyanan
* @information 创建
* @param { Object } commander中设置的option
*/
public async create(options: any): Promise<void>{
try {
let spinner = ora('create new a project');
spinner.start(`拉取${this.template.name}模板`);
// 通过仓库地址和输出目录创建git实例
const pullGit = new Git(this.template.repo, this.targetDir);
pullGit.pull();
spinner.succeed('拉取模板成功');
// 是否推送到gitLab
let answer = await inquirer.prompt([
{ name: 'push', type: 'confirm', message: '是否将项目推送到gitlab',}
]);
// 如果推送
if (answer.push) {
const { repo } = await inquirer.prompt([
{ name: 'repo', type: 'input', message: '请输入gitlab项目地址:'}
]);
const pushGit = new Git(repo, this.targetDir);
try {
spinner.start(`正在推送到gitlab: ${repo}`)
pushGit.push();
spinner.succeed('推送成功')
} catch (error) {
spinner.fail(`推送失败: ${error.message}`);
}
}
} catch (error) {
console.log(`${chalk.red('创建失败')}: ${error.message}`);
}
}
}
\ No newline at end of file
......@@ -15,9 +15,9 @@ export default function () {
const tip = `
**********************************************
当你使用create命令时如:
${chalk.blueBright('"qj-cli create vue2.0 hello"')}
中的${chalk.blueBright('"vue2.0"')}就指的是下面框架名: vue2.0,
欢迎同学们积极提供框架模板,我们还需要vue2.0_ts, vue3.0, vue3.0_ts,node服务框架等等,
${chalk.blueBright('"qj-cli create vue2 hello"')}
中的${chalk.blueBright('"vue2"')}就指的是下面框架名: vue2,
欢迎同学们积极提供框架模板,我们还需要vue2_ts, vue3, vue3_ts,node服务框架等等,
**********************************************
`;
log(`${chalk.green(tip)}`);
......
import Git from '../../util/Git'
import { Git } from '../../util/Git'
import * as assert from 'power-assert'
import * as path from 'path'
import * as spawn from 'cross-spawn'
......
......@@ -8,7 +8,7 @@ import * as assert from 'power-assert'
import * as fs from 'fs-extra'
import * as chalk from 'chalk'
import * as spawn from 'cross-spawn'
class Git {
export class Git {
private gitURL: string; // 仓库地址
private dir: string; // 拉取或推送的目录
constructor(gitURL: string, dir: string) {
......@@ -21,22 +21,19 @@ class Git {
* @author panyanan
* @information 拉取
*/
async pull(): Promise<boolean> {
let res = false;
try {
pull(): void {
// 检测目录是否存在
const dirExits = await fs.pathExists(this.dir);
const dirExits = fs.pathExistsSync(this.dir);
// 目录存在需要删除,才能clone
if (dirExits) {
console.log(chalk.red(`delete ${this.dir}`));
await fs.remove(this.dir);
console.log(`${chalk.red('\n delete ')}${this.dir}`);
fs.removeSync(this.dir);
}
await execa('git', ['clone', this.gitURL, this.dir]);
res = true;
} catch (error) {
assert.ok(false, `拉取 ${this.gitURL} 失败: ${ error.message }`);
}
return res;
// 报告者用户拉取模板
const username = 'reporter';
const password = 'allqj123456'
const gitUrl = this.gitURL.replace('https://', `https://${username}:${password}@`);
execa.sync('git', ['clone', gitUrl, this.dir]);
}
/**
* @date 2019.12.17
......@@ -49,11 +46,11 @@ class Git {
cwd: this.dir,
}
// remove origin
spawn.sync('git', ['remote', 'remove', 'origin',], options);
spawn.sync('git', ['remote', 'remove', 'origin'], options);
// set origin 为当前url
spawn.sync('git', ['remote', 'add', 'origin', this.gitURL], options);
// 推送
const { status, stderr } = spawn.sync('git', ['push', '-u', 'origin', '--all'], options);
const { status, stderr, stdout } = spawn.sync('git', ['push', '-u', 'origin', '--all'], options);
// status 为0时命令执行成功, 为1是命令执行失败
if (status === 0) {
res = true;
......@@ -92,4 +89,3 @@ class Git {
return res;
}
}
\ No newline at end of file
export default Git;
\ No newline at end of file
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论