lizi-wxapp-cli
Version:
微信小程序快速创建cli脚手架
204 lines (169 loc) • 5.4 kB
text/typescript
import chalk from 'chalk'
import _process from 'child_process'
import inquirer, { Answers, InputQuestion, ListQuestion } from 'inquirer'
import jsonFormat from 'json-format'
import path from 'path'
import { config } from '../package.json'
import { log } from '../ulits/log'
import { regVersion } from '../ulits/ulits'
import Base from './base'
interface CliInterface {
openTool(): void
openThis(root: string): void
upload(root: string | object): void
login(): void
preview(root: string | object): void
auto(root: string | object): void
close(root: string | object): void
quit(): void
config(cmd: string, params: string): void
}
export default class Cli extends Base implements CliInterface {
protected cliRoot: string
private version: string = '1.0.0'
constructor() {
super()
this.cliRoot = config.cliRoot
}
public openTool(): void {
this._cli('-o')
}
public openThis(root = this.projectRoot): void {
if (this.checkFileIsExists(path.join(root, 'project.config.json'))) {
this._cli(`-o ${root}`)
} else {
log.error('当前目录不是小程序项目,默认打开开发工具', false)
this.openTool()
}
}
public upload(root: object | string): void {
const projectRoot = this.__checkRoot(root)
if (this.checkFileIsExists(path.join(projectRoot, 'project.config.json'))) {
// 获取默认的版本号
this.readFile(projectRoot, 'project.config.json').then(file => {
let projectInfo: any = JSON.parse(file)
let {version} = projectInfo
this.version = version
inquirer.prompt([
this._selectType(),
this._remark(),
this._version()
]).then((answers: any) => {
let {remark, version} = answers
this._cli(`-u ${version}@${projectRoot} --upload-desc ${remark}`).then(async () => {
projectInfo.version = version
this.version = version
await this.writeFile(projectRoot, 'project.config.json', jsonFormat(projectInfo))
})
}).catch((error) => {
console.log(error)
})
})
} else {
log.error('当前目录不是小程序项目,请重新选择目录路径')
}
}
public login(): void {
this._cli('-l')
}
public preview(root: string | object): void {
this._cli(`-p ${this.__checkRoot(root)}`)
}
public auto(root: string | object): void {
this._cli(`--auto-preview ${this.__checkRoot(root)}`)
}
private _selectType(): ListQuestion<Answers> {
const types: string[] = ['版本升级', '特性更新', '修订补丁']
return {
type: 'list',
name: 'selectType',
message: `当前版本号【${chalk.blue(this.version)}】请选择要更新的类型`,
choices: types,
default: types[0],
filter(input: string): number {
return types.findIndex(v => v === input)
}
}
}
private _remark(): InputQuestion<Answers> {
return {
type: 'input',
name: 'remark',
message: '请输入项目备注:',
default: `提交时间:${new Date().toLocaleString()}`
}
}
private _version(): InputQuestion<Answers> {
return {
type: 'input',
name: 'version',
message: answers => `推荐版本号【${chalk.blue(this.__setVersion(answers.selectType))}】`,
default: answers => this.__setVersion(answers.selectType),
validate: (input: any): Promise<boolean | string> => {
return new Promise(resolve => {
const state: string | boolean = regVersion.test(input) ?
true :
chalk.red('请输入正确的版本号,如:1.0.0')
resolve(state)
})
}
}
}
private __setVersion(index: number): string {
let v: any = this.version.split('.')
v[index]++
return v.join('.')
}
public close(root: string | object): void {
this._cli(`--close ${this.__checkRoot(root)}`)
}
public quit(): void {
this._cli('--quit')
}
public config(cmd: string, params: string): void {
switch (cmd) {
case 'tool':
this._modifyConfig(params)
break
default:
log.table([
['tool <path>', '设置微信开发工具路径']
], true)
break
}
}
private _modifyConfig(root: string): void {
if (this.checkFileIsExists(root)) {
this.readFile(this.root, 'package.json').then(file => {
let json = JSON.parse(file)
json.config.cliRoot = root
this.writeFile(this.root, 'package.json', jsonFormat(json)).then(() => {
log.success('修改cliRoot成功', false)
})
})
} else {
log.error('请输入正确的路径', false)
}
}
private _cli(cmd: string[] | string): Promise<any> {
return new Promise((resolve, reject) => {
const cli = _process.spawn('bash', {
shell: process.platform === 'win32'
})
cli.stdout.on('data', (res) => {
console.log(res.toString()) // .replace(/[\r\n]/g, '')
resolve()
})
cli.stdout.on('error', (err) => {
console.log(err)
reject(err)
})
cli.stdin.write(`${this.cliRoot} ${cmd}`)
cli.stdin.end()
})
}
private __checkRoot(root: string | object): string {
return typeof root === 'object' ? this.projectRoot : root
}
}
export const CliFs = new Cli()