mine-auto-cli 2.2.0 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/publish.yml +26 -0
- package/.prettierignore +12 -0
- package/.prettierrc +12 -0
- package/.vscode/settings.json +3 -0
- package/README.md +37 -0
- package/assets/check.png +0 -0
- package/bin/mine-auto-cli.js +1 -1
- package/package.json +23 -6
- package/scripts/build.js +9 -0
- package/scripts/hooks.js +61 -0
- package/scripts/path.js +15 -0
- package/scripts/rollup-plugin-copy.ts +12 -0
- package/src/commander/actions.ts +127 -0
- package/src/commander/cmds.ts +9 -0
- package/src/commander/commands/check.ts +233 -0
- package/src/commander/commands/index.ts +3 -0
- package/src/commander/commands/mkdir.ts +94 -0
- package/src/commander/index.ts +24 -0
- package/src/commander/types.ts +20 -0
- package/src/config/check.config.jsonc +7 -0
- package/src/config/config.ts +38 -0
- package/src/config/index.ts +19 -0
- package/src/index.ts +29 -0
- package/src/module.d.ts +1 -0
- package/src/types.ts +26 -0
- package/src/utils/functions.ts +56 -0
- package/src/utils/log.ts +24 -0
- package/src/utils/types.ts +10 -0
- package/tsconfig.json +26 -0
- package/vite.config.ts +35 -0
- package/dist/index.js +0 -198
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
name: Publish Package to npmjs
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- 'v*'
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
build:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
permissions:
|
|
12
|
+
contents: read
|
|
13
|
+
id-token: write
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v4
|
|
16
|
+
- uses: actions/setup-node@v4
|
|
17
|
+
with:
|
|
18
|
+
node-version: '20.x'
|
|
19
|
+
registry-url: 'https://registry.npmjs.org'
|
|
20
|
+
- run: npm install -g npm
|
|
21
|
+
- run: npm ci
|
|
22
|
+
- run: npm run build
|
|
23
|
+
- run: cd dist
|
|
24
|
+
- run: npm publish
|
|
25
|
+
env:
|
|
26
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
package/.prettierignore
ADDED
package/.prettierrc
ADDED
package/README.md
CHANGED
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
- [x] [简化打包提交命令](#简化打包提交命令)
|
|
16
16
|
- [x] [简化手动更改版本号命令](#简化手动更改版本号命令)
|
|
17
17
|
- [x] [生成工作目录结构文件](#生成工作目录结构文件)
|
|
18
|
+
- [x] [检查 `package.json` 依赖版本](#检查-packagejson-依赖版本)
|
|
18
19
|
|
|
19
20
|
## 全局安装
|
|
20
21
|
|
|
@@ -99,6 +100,39 @@ auto mkdir -l 10 -n demo
|
|
|
99
100
|
└ └── README.md ----------------------
|
|
100
101
|
```
|
|
101
102
|
|
|
103
|
+
### 检查 package.json 依赖版本
|
|
104
|
+
|
|
105
|
+
```sh
|
|
106
|
+
auto check
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+

|
|
110
|
+
|
|
111
|
+
#### `check.config.json`
|
|
112
|
+
|
|
113
|
+
- 自动生成初始化 `check.config.json` 文件
|
|
114
|
+
|
|
115
|
+
```sh
|
|
116
|
+
npm check -i
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
- 字段解析:
|
|
120
|
+
- `prefix`: 版本前缀,默认为 `^`
|
|
121
|
+
- `registry`: 依赖来源,默认为 `https://registry.npmmirror.com/`
|
|
122
|
+
- `check`: 是否更新 `package.json` 文件,为 `true` 时等同于 `auto check -u`, `-u` 优先级最高, 默认为 `false`
|
|
123
|
+
- `reject`: 拒绝检查的依赖,默认为 `[]`
|
|
124
|
+
- `resolve`: 指定版本检查的标签,默认为 `[]`,例如:['mine-auto-cli@beta'],默认标签为 `latest`
|
|
125
|
+
|
|
126
|
+
```json
|
|
127
|
+
{
|
|
128
|
+
"prefix": "^",
|
|
129
|
+
"registry": "https://registry.npmmirror.com/",
|
|
130
|
+
"check": false,
|
|
131
|
+
"reject": [],
|
|
132
|
+
"resolve": []
|
|
133
|
+
}
|
|
134
|
+
```
|
|
135
|
+
|
|
102
136
|
### 技术栈
|
|
103
137
|
|
|
104
138
|
- `Vite` + `TypeScript` + `Node`
|
|
@@ -111,11 +145,14 @@ auto mkdir -l 10 -n demo
|
|
|
111
145
|
- `commander`: 命令
|
|
112
146
|
- `log-symbols`: 图标
|
|
113
147
|
- `ora`: 动画效果
|
|
148
|
+
- `pacote`: 包信息请求器
|
|
149
|
+
- `strip-json-comments`: 移除 json 注释
|
|
114
150
|
- `update-notifier`: 检查更新
|
|
115
151
|
|
|
116
152
|
#### devDependencies
|
|
117
153
|
|
|
118
154
|
- `@types/node`: `node` 类型
|
|
155
|
+
- `@types/pacote`: `pacote` 类型
|
|
119
156
|
- `@types/update-notifier`: `update-notifier` 类型
|
|
120
157
|
- `prettier`: 格式化工具
|
|
121
158
|
- `typescript`: 编程语言
|
package/assets/check.png
ADDED
|
Binary file
|
package/bin/mine-auto-cli.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
1
|
+
#!/usr/bin/env node
|
|
2
2
|
import '../dist/index.js'
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mine-auto-cli",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "2.
|
|
4
|
+
"version": "2.3.0",
|
|
5
5
|
"exports": "./dist/index.js",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
7
|
"type": "module",
|
|
@@ -14,12 +14,20 @@
|
|
|
14
14
|
"url": "https://biaov.cn"
|
|
15
15
|
},
|
|
16
16
|
"description": "一个将多个命令简化成一个命令的项目 😆",
|
|
17
|
-
"scripts": {
|
|
17
|
+
"scripts": {
|
|
18
|
+
"start": "npm run dev",
|
|
19
|
+
"dev": "npm run build -- --watch",
|
|
20
|
+
"build": "node scripts/build && vite build",
|
|
21
|
+
"prettier": "prettier --write '**/*.{js,ts,md,json}'",
|
|
22
|
+
"ncu": "ncu --configFileName .ncurc.json && npm i"
|
|
23
|
+
},
|
|
18
24
|
"publishConfig": {
|
|
19
|
-
"registry": "https://registry.npmjs.org/"
|
|
25
|
+
"registry": "https://registry.npmjs.org/",
|
|
26
|
+
"engine-strict": true,
|
|
27
|
+
"provenance": true
|
|
20
28
|
},
|
|
21
29
|
"engines": {
|
|
22
|
-
"node": ">=20"
|
|
30
|
+
"node": ">=20.12"
|
|
23
31
|
},
|
|
24
32
|
"keywords": [
|
|
25
33
|
"auto",
|
|
@@ -47,7 +55,16 @@
|
|
|
47
55
|
"commander": "^12.0.0",
|
|
48
56
|
"log-symbols": "^6.0.0",
|
|
49
57
|
"ora": "^8.0.1",
|
|
58
|
+
"pacote": "^18.0.2",
|
|
59
|
+
"strip-json-comments": "^5.0.1",
|
|
50
60
|
"update-notifier": "^7.0.0"
|
|
51
61
|
},
|
|
52
|
-
"devDependencies": {
|
|
53
|
-
|
|
62
|
+
"devDependencies": {
|
|
63
|
+
"@types/node": "^20.12.7",
|
|
64
|
+
"@types/pacote": "^11.1.8",
|
|
65
|
+
"@types/update-notifier": "^6.0.8",
|
|
66
|
+
"prettier": "^3.2.5",
|
|
67
|
+
"typescript": "^5.4.5",
|
|
68
|
+
"vite": "^5.2.10"
|
|
69
|
+
}
|
|
70
|
+
}
|
package/scripts/build.js
ADDED
package/scripts/hooks.js
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { writeFileSync, copyFileSync, existsSync, readdirSync, mkdirSync, statSync, unlinkSync } from 'fs'
|
|
2
|
+
import { join } from 'path'
|
|
3
|
+
import { resetPath } from './path.js'
|
|
4
|
+
import packageJson from '../package.json' assert { type: 'json' }
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* 重写 package.json
|
|
8
|
+
*/
|
|
9
|
+
export const rewritePackage = () => {
|
|
10
|
+
/**
|
|
11
|
+
* 重置输出目录
|
|
12
|
+
*/
|
|
13
|
+
const output = resetPath('@/dist')
|
|
14
|
+
!existsSync(output) && mkdirSync(output)
|
|
15
|
+
|
|
16
|
+
packageJson.devDependencies = packageJson.scripts = {}
|
|
17
|
+
/**
|
|
18
|
+
* 写入最新的
|
|
19
|
+
*/
|
|
20
|
+
writeFileSync(resetPath('@/dist/package.json'), JSON.stringify(packageJson, null, 2))
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* 拷贝目录
|
|
25
|
+
*/
|
|
26
|
+
const copyDirectory = (source, destination) => {
|
|
27
|
+
const stat = statSync(source)
|
|
28
|
+
if (stat.isFile()) {
|
|
29
|
+
/**
|
|
30
|
+
* 复制文件
|
|
31
|
+
*/
|
|
32
|
+
existsSync(destination) && unlinkSync(destination)
|
|
33
|
+
copyFileSync(source, destination)
|
|
34
|
+
} else if (stat.isDirectory()) {
|
|
35
|
+
/**
|
|
36
|
+
* 创建目录
|
|
37
|
+
*/
|
|
38
|
+
!existsSync(destination) && mkdirSync(destination)
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* 原有目录
|
|
42
|
+
*/
|
|
43
|
+
const directory = readdirSync(source)
|
|
44
|
+
directory.forEach(file => {
|
|
45
|
+
copyDirectory(join(source, file), join(destination, file))
|
|
46
|
+
})
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* 复制资源
|
|
52
|
+
*/
|
|
53
|
+
export const copyAssets = () => {
|
|
54
|
+
/**
|
|
55
|
+
* 根目录需要复制的文件和目录
|
|
56
|
+
*/
|
|
57
|
+
const filePaths = ['bin', 'README.md', 'LICENSE']
|
|
58
|
+
filePaths.forEach(path => {
|
|
59
|
+
copyDirectory(resetPath(`@/${path}`), resetPath(`@/dist/${path}`))
|
|
60
|
+
})
|
|
61
|
+
}
|
package/scripts/path.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { resolve, dirname } from 'path'
|
|
2
|
+
import { fileURLToPath } from 'url'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* 相对目录
|
|
6
|
+
*/
|
|
7
|
+
export const __dirname = dirname(fileURLToPath(import.meta.url))
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* 重置路径, @ 表示根目录
|
|
11
|
+
*/
|
|
12
|
+
export const resetPath = (filePath, defaultPrefix = '../') => {
|
|
13
|
+
const prefix = filePath.slice(0, 1) === '@' ? defaultPrefix : ''
|
|
14
|
+
return resolve(__dirname, prefix + filePath.slice(1))
|
|
15
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { copyFileSync } from 'fs'
|
|
2
|
+
|
|
3
|
+
const fileName = 'check.config.jsonc'
|
|
4
|
+
const inputPath = `./src/config/${fileName}`
|
|
5
|
+
const outputPath = `./dist/dist/${fileName}`
|
|
6
|
+
|
|
7
|
+
export default () => ({
|
|
8
|
+
name: 'rollup-plugin-copy',
|
|
9
|
+
closeBundle: () => {
|
|
10
|
+
copyFileSync(inputPath, outputPath)
|
|
11
|
+
}
|
|
12
|
+
})
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { program } from 'commander'
|
|
2
|
+
import chalk from 'chalk'
|
|
3
|
+
import ora from 'ora'
|
|
4
|
+
import { execSync } from 'child_process'
|
|
5
|
+
import { readFileSync, writeFileSync } from 'fs'
|
|
6
|
+
import { join } from 'path'
|
|
7
|
+
import { success, info, error } from '@/utils/log'
|
|
8
|
+
import { gitCmds, buildCmds } from './cmds'
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* 执行命令
|
|
12
|
+
*/
|
|
13
|
+
const execCommand = (cmd: string) => {
|
|
14
|
+
info(`开始执行 ${chalk.cyanBright(cmd)} 命令`)
|
|
15
|
+
const spinner = ora({ text: '正在执行命令中...', color: 'yellow' })
|
|
16
|
+
spinner.start()
|
|
17
|
+
const childProcess = execSync(cmd, { cwd: process.cwd() })
|
|
18
|
+
info(childProcess.toString())
|
|
19
|
+
spinner.succeed(`${chalk.green(cmd)} 命令执行成功`)
|
|
20
|
+
info()
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* 简化 Git 提交命令
|
|
25
|
+
*/
|
|
26
|
+
export const simplifyGit = async (desc = '更新代码') => {
|
|
27
|
+
info()
|
|
28
|
+
info(`${chalk.yellow('>>')} 开始依次执行命令...`)
|
|
29
|
+
info()
|
|
30
|
+
gitCmds(desc).forEach(execCommand)
|
|
31
|
+
success('全部命令执行完成')
|
|
32
|
+
info()
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* 简化打包提交命令
|
|
37
|
+
*/
|
|
38
|
+
export const simplifyBuild = async (cmd: string, desc = '打包') => {
|
|
39
|
+
info()
|
|
40
|
+
info(`${chalk.yellow('>>')} 开始依次执行命令...`)
|
|
41
|
+
info()
|
|
42
|
+
buildCmds(cmd, desc).map(execCommand)
|
|
43
|
+
success('全部命令执行完成')
|
|
44
|
+
info()
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const errorTips = (cmd: string) => {
|
|
48
|
+
info()
|
|
49
|
+
error(`\`${cmd}\` 命令错误,请检查你的命令`)
|
|
50
|
+
info()
|
|
51
|
+
program.help()
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* 更新版本号
|
|
56
|
+
*/
|
|
57
|
+
const updateVersion = (customVersion: string) => {
|
|
58
|
+
const fileList: Record<string, string>[] = ['package.json', 'README.md'].map(name => {
|
|
59
|
+
const path = join(process.cwd(), name)
|
|
60
|
+
const content = readFileSync(path).toString()
|
|
61
|
+
return { path, content }
|
|
62
|
+
})
|
|
63
|
+
const [packageJsonItem, readmeItem] = fileList
|
|
64
|
+
const packageJson = JSON.parse(packageJsonItem.content)
|
|
65
|
+
|
|
66
|
+
// 修改 package.json
|
|
67
|
+
if (customVersion) {
|
|
68
|
+
packageJson.version = customVersion
|
|
69
|
+
} else {
|
|
70
|
+
const newVersion = packageJson.version.split('.').reduce((prev: string, item: string, i: number, arr: string[]) => prev + (i === arr.length - 1 ? +item + 1 : `${item}.`), '')
|
|
71
|
+
packageJson.version = newVersion
|
|
72
|
+
}
|
|
73
|
+
writeFileSync(packageJsonItem.path, JSON.stringify(packageJson, null, 2))
|
|
74
|
+
|
|
75
|
+
// 修改 README.md
|
|
76
|
+
readmeItem.content = readmeItem.content.replace(/version\-v.+\-blue/, () => `version-v${packageJson.version}-blue`)
|
|
77
|
+
writeFileSync(readmeItem.path, readmeItem.content)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* 简化手动修改版本号命令
|
|
82
|
+
*/
|
|
83
|
+
export const simplifyVersion = async (cmd: string) => {
|
|
84
|
+
const arg = cmd.split('version')[1]
|
|
85
|
+
if (!arg) return errorTips(cmd)
|
|
86
|
+
|
|
87
|
+
const packageJson = JSON.parse(readFileSync(join(process.cwd(), 'package.json'), 'utf-8'))
|
|
88
|
+
if (arg === '++') {
|
|
89
|
+
const newVersion = packageJson.version.split('.').reduce((prev: string, item: string, i: number, arr: string[]) => prev + (i === arr.length - 1 ? +item + 1 : `${item}.`), '')
|
|
90
|
+
updateVersion(newVersion)
|
|
91
|
+
info()
|
|
92
|
+
success('命令执行完成')
|
|
93
|
+
return
|
|
94
|
+
}
|
|
95
|
+
const customVersion = arg.split('@')[1]
|
|
96
|
+
if (customVersion) {
|
|
97
|
+
updateVersion(customVersion)
|
|
98
|
+
info()
|
|
99
|
+
success('命令执行完成')
|
|
100
|
+
} else {
|
|
101
|
+
errorTips(cmd)
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* 定义顶级命令的 action
|
|
107
|
+
*/
|
|
108
|
+
export const handleArguments = (cmd: string, env?: string) => {
|
|
109
|
+
/**
|
|
110
|
+
* 处理 build[:环境] 命令
|
|
111
|
+
*/
|
|
112
|
+
if (cmd.includes('build')) return simplifyBuild(cmd, env)
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* 处理 version[++][@<版本> 命令
|
|
116
|
+
*/
|
|
117
|
+
if (cmd.includes('version')) return simplifyVersion(cmd)
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* 输出错误
|
|
121
|
+
*/
|
|
122
|
+
error(chalk.hex('#f56c6c')(`\`auto ${cmd}${env ? ` ${env}` : ''}\` 命令不存在`))
|
|
123
|
+
/**
|
|
124
|
+
* 显示全部命令
|
|
125
|
+
*/
|
|
126
|
+
program.help()
|
|
127
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* git 命令集合
|
|
3
|
+
*/
|
|
4
|
+
export const gitCmds = (desc: string) => ['git add -A', `git commit -m ${desc}`, 'git push']
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* 打包的命令
|
|
8
|
+
*/
|
|
9
|
+
export const buildCmds = (suffix: string, desc: string) => [`npm run ${suffix}`, 'git add -A', `git commit -m ${desc}`, 'git push']
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
import { program } from 'commander'
|
|
2
|
+
import { readFileSync, existsSync, writeFileSync } from 'fs'
|
|
3
|
+
import { resolve } from 'path'
|
|
4
|
+
import chalk from 'chalk'
|
|
5
|
+
import pacote from 'pacote'
|
|
6
|
+
import stripJsonComments from 'strip-json-comments'
|
|
7
|
+
import { success, error, info } from '@/utils/log'
|
|
8
|
+
import type { NPMResponse } from '@/types'
|
|
9
|
+
import type { DefaultConfig, VersionLog } from '../types'
|
|
10
|
+
|
|
11
|
+
const fileOption: Record<string, string> = { encoding: 'utf-8' }
|
|
12
|
+
|
|
13
|
+
const checkConfigDefault = readFileSync(resolve(import.meta.dirname, './check.config.jsonc')).toString()
|
|
14
|
+
const defaultConfig: DefaultConfig = JSON.parse(stripJsonComments(checkConfigDefault.toString()))
|
|
15
|
+
const checkConfigName = 'check.config.jsonc'
|
|
16
|
+
const jsonFiles = [checkConfigName, 'package.json']
|
|
17
|
+
const [checkConfigPath, packagePath] = jsonFiles.map(name => resolve(process.cwd(), name))
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* 初始化
|
|
21
|
+
*/
|
|
22
|
+
const initConfigJson = () => {
|
|
23
|
+
info()
|
|
24
|
+
if (existsSync(checkConfigPath)) {
|
|
25
|
+
info(chalk.yellow(`${checkConfigName} 文件已存在`))
|
|
26
|
+
info()
|
|
27
|
+
info(chalk.yellow(`文件目录 ${checkConfigPath}`))
|
|
28
|
+
return
|
|
29
|
+
}
|
|
30
|
+
writeFileSync(checkConfigPath, checkConfigDefault)
|
|
31
|
+
success(`${checkConfigName} 文件创建成功`)
|
|
32
|
+
info()
|
|
33
|
+
info(chalk.green(`文件目录 ${checkConfigPath}`))
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* 进度条日志
|
|
38
|
+
*/
|
|
39
|
+
const progressLog = (progress: number, total: number) => {
|
|
40
|
+
const equal = Array.from({ length: total }, (_, i) => (i < progress ? '=' : ' ')).join('')
|
|
41
|
+
const percentage = ~~((progress / total) * 100)
|
|
42
|
+
const text = `\r查找进度:[${equal}] ${progress}/${total} ${percentage}%\r`
|
|
43
|
+
const outText = progress === total ? chalk.green(text) : chalk.yellow(text)
|
|
44
|
+
process.stdout.write(outText)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* 获取版本日志
|
|
49
|
+
*/
|
|
50
|
+
const getVersionLog = (name: string, value: string, distTags: NPMResponse['dist-tags']) => {
|
|
51
|
+
let tag = 'latest'
|
|
52
|
+
defaultConfig.resolve.some(item => {
|
|
53
|
+
const [curName, curTag] = item.split('@')
|
|
54
|
+
if (name === curName) {
|
|
55
|
+
tag = curTag
|
|
56
|
+
return true
|
|
57
|
+
}
|
|
58
|
+
})
|
|
59
|
+
const newVersion = defaultConfig.prefix + distTags[tag]
|
|
60
|
+
|
|
61
|
+
return { text: { name, value, newVersion, tag }, newVersion }
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* 获取空格
|
|
66
|
+
*/
|
|
67
|
+
const getSpace = (length: number, maxLength: number) => Array.from({ length: maxLength - length }, () => ' ').join('')
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* 获取长度
|
|
71
|
+
*/
|
|
72
|
+
const getValueLength = (value: string, i: number) => (+!i + 1) * value.length
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* 格式化版本
|
|
76
|
+
*/
|
|
77
|
+
export const formatterVersion = (oldVersion: string, newVersion: string): string | false => {
|
|
78
|
+
const oldV = oldVersion.match(/\d.+/g)![0].split('.')
|
|
79
|
+
const newV = newVersion.match(/\d.+/g)![0].split('.')
|
|
80
|
+
const index = newV.findIndex((item, i) => +item > +oldV[i])
|
|
81
|
+
|
|
82
|
+
const mainName = defaultConfig.prefix + newV[0]
|
|
83
|
+
|
|
84
|
+
switch (index) {
|
|
85
|
+
case 0:
|
|
86
|
+
return chalk.red(newVersion)
|
|
87
|
+
case 1:
|
|
88
|
+
return `${mainName}.${chalk.yellow(newV[1])}.${chalk.yellow(newV[2])}`
|
|
89
|
+
case 2:
|
|
90
|
+
return `${mainName}.${newV[1]}.${chalk.green(newV[2])}`
|
|
91
|
+
default:
|
|
92
|
+
return false
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* 计算版本日志
|
|
98
|
+
*/
|
|
99
|
+
const outVersionLog = (versionLogs: VersionLog[]) => {
|
|
100
|
+
const fieldMax: Record<string, number> = {}
|
|
101
|
+
versionLogs.forEach(item => {
|
|
102
|
+
Object.entries(item).forEach(([key, value]) => {
|
|
103
|
+
fieldMax[key] = Math.max(value.length, fieldMax[key] ?? 0)
|
|
104
|
+
})
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
versionLogs.unshift({ name: '包名', value: '版本', newVersion: '新版本', tag: '标签' })
|
|
108
|
+
|
|
109
|
+
const outLog: string[] = []
|
|
110
|
+
versionLogs.forEach(({ name, value, newVersion, tag }, i) => {
|
|
111
|
+
const [nameSpace, valueSpace, newVersionSpace, tagSpace] = Object.entries({ name, value, newVersion, tag }).map(([key, value]) => getSpace(getValueLength(value, i), fieldMax[key]))
|
|
112
|
+
let spacer = chalk.yellow('→')
|
|
113
|
+
let showLog = true
|
|
114
|
+
if (i) {
|
|
115
|
+
const formatVer = formatterVersion(value, newVersion)
|
|
116
|
+
if (formatVer) {
|
|
117
|
+
newVersion = formatVer
|
|
118
|
+
} else {
|
|
119
|
+
showLog = false
|
|
120
|
+
}
|
|
121
|
+
} else {
|
|
122
|
+
name = chalk.green(name)
|
|
123
|
+
value = chalk.green(value)
|
|
124
|
+
newVersion = chalk.green(newVersion)
|
|
125
|
+
tag = chalk.green(tag)
|
|
126
|
+
spacer = ' '
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
const text = `${name + nameSpace} ${valueSpace + value} ${spacer} ${newVersionSpace + newVersion} ${tagSpace + tag}`
|
|
130
|
+
showLog && outLog.push(text)
|
|
131
|
+
})
|
|
132
|
+
if (outLog.length > 1) {
|
|
133
|
+
outLog.forEach(info)
|
|
134
|
+
} else {
|
|
135
|
+
success('所有版本已是最新')
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* 进度条任务
|
|
141
|
+
*/
|
|
142
|
+
const taskProgress = async (allPackages: Record<string, string>, keys: string[], newPackages: Record<string, any>) => {
|
|
143
|
+
info()
|
|
144
|
+
/**
|
|
145
|
+
* 进度条
|
|
146
|
+
*/
|
|
147
|
+
let progress = 0
|
|
148
|
+
const versionLogs: VersionLog[] = []
|
|
149
|
+
const allPackagesArray = Object.entries(allPackages)
|
|
150
|
+
const packageTask = allPackagesArray.map(async ([name, value]) => {
|
|
151
|
+
/**
|
|
152
|
+
* 获取包最新消息
|
|
153
|
+
*/
|
|
154
|
+
const data = await pacote.packument(name, { registry: defaultConfig.registry })
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* 获取日志信息
|
|
158
|
+
*/
|
|
159
|
+
const { text, newVersion } = getVersionLog(name, value, data['dist-tags'])
|
|
160
|
+
versionLogs.push(text)
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* 收集新包信息
|
|
164
|
+
*/
|
|
165
|
+
keys.forEach(key => {
|
|
166
|
+
const item = newPackages[key]
|
|
167
|
+
item && item[name] && (item[name] = newVersion)
|
|
168
|
+
})
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* 开启进度条
|
|
172
|
+
*/
|
|
173
|
+
progress++
|
|
174
|
+
await progressLog(progress, allPackagesArray.length)
|
|
175
|
+
})
|
|
176
|
+
await Promise.all(packageTask)
|
|
177
|
+
info()
|
|
178
|
+
info()
|
|
179
|
+
return versionLogs
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* 升级
|
|
184
|
+
*/
|
|
185
|
+
const simplifyUpgrade = async ({ update, init }: Record<string, boolean>) => {
|
|
186
|
+
if (init) return initConfigJson()
|
|
187
|
+
if (!existsSync(packagePath)) return error('package.json 文件不存在')
|
|
188
|
+
|
|
189
|
+
existsSync(checkConfigPath) && Object.assign(defaultConfig, JSON.parse(stripJsonComments(readFileSync(checkConfigPath, fileOption).toString())))
|
|
190
|
+
|
|
191
|
+
const newUpdate = update || defaultConfig.check
|
|
192
|
+
const packageJsonString = readFileSync(packagePath, fileOption).toString()
|
|
193
|
+
const packageJson: Record<string, any> = JSON.parse(packageJsonString)
|
|
194
|
+
const keys = ['dependencies', 'devDependencies', 'optionalDependencies']
|
|
195
|
+
const allPackages: Record<string, string> = {}
|
|
196
|
+
const newPackages = JSON.parse(packageJsonString)
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* 收集所有的包
|
|
200
|
+
*/
|
|
201
|
+
keys.forEach(key => {
|
|
202
|
+
if (!packageJson[key]) return
|
|
203
|
+
Object.entries(packageJson[key]).forEach(([key, value]) => {
|
|
204
|
+
!defaultConfig.reject.includes(key) && (allPackages[key] = value as string)
|
|
205
|
+
})
|
|
206
|
+
})
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* 进度条
|
|
210
|
+
*/
|
|
211
|
+
const versionLogs = await taskProgress(allPackages, keys, newPackages)
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* 更新包内容
|
|
215
|
+
*/
|
|
216
|
+
if (newUpdate) {
|
|
217
|
+
writeFileSync(packagePath, JSON.stringify(newPackages, null, 2))
|
|
218
|
+
success('文件 package.json 已更新')
|
|
219
|
+
info()
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* 输出包信息
|
|
224
|
+
*/
|
|
225
|
+
outVersionLog(versionLogs)
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
program
|
|
229
|
+
.command('check')
|
|
230
|
+
.option('-u, --update', `更新 package.json 依赖内容 或者配置 ${checkConfigName} 文件`, false)
|
|
231
|
+
.option('-i, --init', `仅初始化 ${checkConfigName} 文件,不检查依赖版本`, false)
|
|
232
|
+
.description('升级 package.json 依赖版本')
|
|
233
|
+
.action(simplifyUpgrade)
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { program } from 'commander'
|
|
2
|
+
import { readdirSync, writeFileSync, readFileSync, existsSync } from 'fs'
|
|
3
|
+
import { join } from 'path'
|
|
4
|
+
import type { MkdirTree } from '@/types'
|
|
5
|
+
|
|
6
|
+
const topIgnore = ['dist', 'node_modules', '.git', 'miniprogram_npm']
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* 最大值
|
|
10
|
+
*/
|
|
11
|
+
let maxLength = 0
|
|
12
|
+
/**
|
|
13
|
+
* 是否计算了最大值
|
|
14
|
+
*/
|
|
15
|
+
let isMax = false
|
|
16
|
+
/**
|
|
17
|
+
* 是否有横线
|
|
18
|
+
*/
|
|
19
|
+
let hasLine = false
|
|
20
|
+
/**
|
|
21
|
+
* 初始化横线数量
|
|
22
|
+
*/
|
|
23
|
+
let initLine = 20
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* 获取 suffix
|
|
27
|
+
*/
|
|
28
|
+
const getItemText = ({ prev, i, index, arr, curText }: Record<string, any>) => {
|
|
29
|
+
const prefix = Array.from({ length: i }).reduce(prev => prev + `${i === 1 && index === arr.length - 1 ? '└ ' : '│ '} `, '') as string
|
|
30
|
+
const newPrev = prev + prefix
|
|
31
|
+
const curLen = (prefix + curText).length
|
|
32
|
+
const suffix = Array.from({ length: initLine + maxLength - curLen }).reduce(prev => `${prev}-`, ' ')
|
|
33
|
+
!isMax && (maxLength = Math.max(maxLength, curLen))
|
|
34
|
+
return `${newPrev}${curText}${hasLine ? suffix : ''}\n`
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* 获取文本
|
|
38
|
+
*/
|
|
39
|
+
const getText = (tree: MkdirTree[], i = 0): string =>
|
|
40
|
+
tree.reduce((prev, item, index, arr) => {
|
|
41
|
+
let curText
|
|
42
|
+
if (item.children) {
|
|
43
|
+
curText = `├── ${item.name}`
|
|
44
|
+
return getItemText({ prev, i, index, arr, curText }) + getText(item.children, i + 1)
|
|
45
|
+
} else {
|
|
46
|
+
curText = `${index === arr.length - 1 ? '└── ' : '├── '}${item.name}`
|
|
47
|
+
return getItemText({ prev, i, index, arr, curText })
|
|
48
|
+
}
|
|
49
|
+
}, '')
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* 排序,文件夹在文件的前面
|
|
53
|
+
*/
|
|
54
|
+
const sort = (path: string) => readdirSync(path, { withFileTypes: true }).sort((a, b) => +b.isDirectory() - +a.isDirectory())
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* 简化 mkdir 操作
|
|
58
|
+
*/
|
|
59
|
+
export const simplifyMkdir = ({ line, name }: Record<string, string | boolean>) => {
|
|
60
|
+
hasLine = !!line
|
|
61
|
+
typeof line === 'string' && (initLine = +line)
|
|
62
|
+
|
|
63
|
+
const rootDir = process.cwd()
|
|
64
|
+
|
|
65
|
+
const gitignorePath = join(rootDir, '.gitignore')
|
|
66
|
+
if (existsSync(gitignorePath)) {
|
|
67
|
+
const ignoreFile = readFileSync(gitignorePath, { encoding: 'utf-8' }).split('\r\n')
|
|
68
|
+
topIgnore.push(...ignoreFile)
|
|
69
|
+
}
|
|
70
|
+
const rootName = rootDir.split('\\').at(-1)!
|
|
71
|
+
const dirs = sort(rootDir)
|
|
72
|
+
const children = dirs.map(dir => {
|
|
73
|
+
const { name } = dir
|
|
74
|
+
const item: MkdirTree = { name }
|
|
75
|
+
!topIgnore.includes(name) && dir.isDirectory() && (item.children = sort(join(dir.path, name)).map(({ name }) => ({ name })))
|
|
76
|
+
return item
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
const tree: MkdirTree[] = [{ name: rootName, children }]
|
|
80
|
+
|
|
81
|
+
if (hasLine) {
|
|
82
|
+
getText(tree)
|
|
83
|
+
isMax = true
|
|
84
|
+
}
|
|
85
|
+
writeFileSync(join(rootDir, `${(typeof name === 'string' && name) || 'directory'}.md`), getText(tree))
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
program
|
|
89
|
+
.command('mkdir')
|
|
90
|
+
.option('-l, --line [数量]', '数量', false)
|
|
91
|
+
.option('-n, --name [文件名称]', '文件名称', false)
|
|
92
|
+
.option('-d, --depth [深度值]', '深度值', '3')
|
|
93
|
+
.description('生成目录结构文件')
|
|
94
|
+
.action(simplifyMkdir)
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { program } from 'commander'
|
|
2
|
+
import { version } from '~/package.json'
|
|
3
|
+
import { simplifyGit, handleArguments } from './actions'
|
|
4
|
+
import './commands'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* 重置版本
|
|
8
|
+
*/
|
|
9
|
+
program.usage('[commands] [options]').version(version, '-v, --version', '输出版本号').helpOption('-h, --help', '输出所有命令')
|
|
10
|
+
program.command('git [描述]').description('简化 Git 提交命令').action(simplifyGit)
|
|
11
|
+
program.command('build[:环境] [描述]').description('简化打包提交命令')
|
|
12
|
+
program.command('version<[++]|[@<版本号>]>').description('例如:version++ 或者 version@1.0.0;自动更新 package.json 版本号,自动更新 `README.md` 中的 `version-v<version>-blue` 图标版本')
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* 定义顶级命令的参数语法
|
|
16
|
+
*/
|
|
17
|
+
program.arguments('<cmd> [env]').action((cmd: any, env: any) => {
|
|
18
|
+
handleArguments(cmd, env)
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* 处理参数
|
|
23
|
+
*/
|
|
24
|
+
process.argv.length < 3 ? program.help() : program.parse(process.argv)
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* defaultConfig
|
|
3
|
+
*/
|
|
4
|
+
export interface DefaultConfig {
|
|
5
|
+
prefix: string
|
|
6
|
+
registry: string
|
|
7
|
+
check: boolean
|
|
8
|
+
reject: string[]
|
|
9
|
+
resolve: string[]
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* versionLogs
|
|
14
|
+
*/
|
|
15
|
+
export interface VersionLog {
|
|
16
|
+
name: string
|
|
17
|
+
value: string
|
|
18
|
+
newVersion: string
|
|
19
|
+
tag: string
|
|
20
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"prefix": "^", // 版本前缀,默认为 `^`
|
|
3
|
+
"registry": "https://registry.npmmirror.com/", // 依赖来源,默认为 `https://registry.npmmirror.com/`
|
|
4
|
+
"check": false, // 是否更新 `package.json` 文件,为 `true` 时等同于 `auto check -u`, `-u` 优先级最 高, 默认为 `false`
|
|
5
|
+
"reject": [], // 拒绝检查的依赖,默认为 `[]`
|
|
6
|
+
"resolve": [] // 指定版本检查的标签,默认为 `[]`,例如:['mine-auto-cli@beta'],默认标签为 `latest`
|
|
7
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 默认的模板地址,也可以配置其它模板地址
|
|
3
|
+
*/
|
|
4
|
+
const defaultTemplateUrl = 'https://gitee.com/biaovorg/project-template.git'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* 模板下载地址
|
|
8
|
+
*/
|
|
9
|
+
export const templateUrls = {
|
|
10
|
+
vue: defaultTemplateUrl,
|
|
11
|
+
react: defaultTemplateUrl,
|
|
12
|
+
'uni-app': defaultTemplateUrl,
|
|
13
|
+
electron: defaultTemplateUrl,
|
|
14
|
+
node: defaultTemplateUrl,
|
|
15
|
+
'node-simple': defaultTemplateUrl
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* 工具对应命令
|
|
20
|
+
*/
|
|
21
|
+
export const toolCommands = {
|
|
22
|
+
npm: {
|
|
23
|
+
install: 'npm i',
|
|
24
|
+
start: 'npm start'
|
|
25
|
+
},
|
|
26
|
+
cnpm: {
|
|
27
|
+
install: 'cnpm i',
|
|
28
|
+
start: 'cnpm start'
|
|
29
|
+
},
|
|
30
|
+
pnpm: {
|
|
31
|
+
install: 'pnpm i',
|
|
32
|
+
start: 'pnpm start'
|
|
33
|
+
},
|
|
34
|
+
yarn: {
|
|
35
|
+
install: 'yarn',
|
|
36
|
+
start: 'yarn start'
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { InstallToolKey, TemplateUrlKey } from '@/types'
|
|
2
|
+
import { templateUrls, toolCommands } from './config'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* 模板名称
|
|
6
|
+
*/
|
|
7
|
+
export const templateNames = Object.keys(templateUrls) as TemplateUrlKey[]
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* 模板名称拼接
|
|
11
|
+
*/
|
|
12
|
+
export const templateNameString = templateNames.reduce((prev, item, i) => prev + (i ? ', ' : '') + item, '')
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* 工具名称
|
|
16
|
+
*/
|
|
17
|
+
export const installTools = Object.keys(toolCommands) as InstallToolKey[]
|
|
18
|
+
|
|
19
|
+
export { templateUrls, toolCommands }
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/// <reference path="./module.d.ts" />
|
|
2
|
+
|
|
3
|
+
import updateNotifier from 'update-notifier'
|
|
4
|
+
import chalk from 'chalk'
|
|
5
|
+
import pkg from '../package.json'
|
|
6
|
+
import './commander' // 命令
|
|
7
|
+
|
|
8
|
+
const notifier = updateNotifier({ pkg })
|
|
9
|
+
|
|
10
|
+
if (notifier.update && notifier.update.latest !== pkg.version) {
|
|
11
|
+
let msg = ''
|
|
12
|
+
switch (notifier.update.type) {
|
|
13
|
+
case 'major':
|
|
14
|
+
msg = chalk.red('{latestVersion}')
|
|
15
|
+
break
|
|
16
|
+
case 'minor':
|
|
17
|
+
msg = chalk.yellow('{latestVersion}')
|
|
18
|
+
break
|
|
19
|
+
default:
|
|
20
|
+
msg = chalk.green('{latestVersion}')
|
|
21
|
+
break
|
|
22
|
+
}
|
|
23
|
+
const compareUrl = `https://github.com/biaov/${pkg.name}/compare/v${pkg.version}...v{latestVersion}`
|
|
24
|
+
notifier.notify({
|
|
25
|
+
defer: false,
|
|
26
|
+
isGlobal: true,
|
|
27
|
+
message: `有更新 ${chalk.dim('{currentVersion}')}${chalk.reset(' → ')}${msg}\n运行 ${chalk.cyan('{updateCommand}')} 命令更新\n${chalk.dim.underline(compareUrl)}`
|
|
28
|
+
})
|
|
29
|
+
}
|
package/src/module.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
declare module 'inquirer'
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { templateUrls, toolCommands } from './config/config'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* 安装工具 key
|
|
5
|
+
*/
|
|
6
|
+
export type InstallToolKey = keyof typeof toolCommands
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* 模板 key
|
|
10
|
+
*/
|
|
11
|
+
export type TemplateUrlKey = keyof typeof templateUrls
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* mkdir tree
|
|
15
|
+
*/
|
|
16
|
+
export interface MkdirTree {
|
|
17
|
+
name: string
|
|
18
|
+
children?: MkdirTree[]
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* `https://registry.npmjs.org/包名/` 返回信息
|
|
23
|
+
*/
|
|
24
|
+
export interface NPMResponse {
|
|
25
|
+
'dist-tags': Record<string, string>
|
|
26
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { writeFile, readFileSync } from 'fs'
|
|
2
|
+
import { resolve, dirname } from 'path'
|
|
3
|
+
import chalk from 'chalk'
|
|
4
|
+
import { fileURLToPath } from 'url'
|
|
5
|
+
import { PresetInfo } from './types'
|
|
6
|
+
|
|
7
|
+
export const __dirname = dirname(fileURLToPath(import.meta.url))
|
|
8
|
+
/**
|
|
9
|
+
* 预设数据路径
|
|
10
|
+
*/
|
|
11
|
+
const presetPath = resolve(__dirname, './presetData.json')
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* 保存本地预设信息
|
|
15
|
+
* @param { string } name - 对象名称
|
|
16
|
+
* @param { PresetInfo } data - 对象值
|
|
17
|
+
* @returns { void }
|
|
18
|
+
*/
|
|
19
|
+
export const SavePresetInfo = (name: string, data: PresetInfo) => {
|
|
20
|
+
/**
|
|
21
|
+
* 保存对象键值对
|
|
22
|
+
*/
|
|
23
|
+
const saveData = GetPresetInfo()
|
|
24
|
+
saveData[name] = data
|
|
25
|
+
writeFile(presetPath, JSON.stringify(saveData), err => {
|
|
26
|
+
err && console.log('保存预设失败')
|
|
27
|
+
})
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* 读取本地预设信息
|
|
32
|
+
* @param { void }
|
|
33
|
+
* @returns { Partial<PresetInfo> }
|
|
34
|
+
*/
|
|
35
|
+
export const GetPresetInfo = (): Partial<PresetInfo> => {
|
|
36
|
+
let info: Buffer
|
|
37
|
+
try {
|
|
38
|
+
info = readFileSync(presetPath) // 读取文件
|
|
39
|
+
} catch {
|
|
40
|
+
return {} // 返回空对象
|
|
41
|
+
}
|
|
42
|
+
return JSON.parse(`${info}`)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* 格式化预设值
|
|
47
|
+
* @param { Partial<PresetInfo> }
|
|
48
|
+
* @returns { string[] }
|
|
49
|
+
*/
|
|
50
|
+
export const FormatePreset = (presetInfo: Partial<PresetInfo>): string[] =>
|
|
51
|
+
Object.entries(presetInfo).map(
|
|
52
|
+
([key, value]) =>
|
|
53
|
+
`${key}(${Object.values(value)
|
|
54
|
+
.map(item => `${chalk.yellow(item)}`)
|
|
55
|
+
.join(', ')})`
|
|
56
|
+
)
|
package/src/utils/log.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import chalk from 'chalk'
|
|
2
|
+
import logSymbols from 'log-symbols'
|
|
3
|
+
import { name } from '~/package.json'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* 成功日志
|
|
7
|
+
*/
|
|
8
|
+
export const success = (text?: string | number) => {
|
|
9
|
+
console.log(`${logSymbols.success} ${chalk.green('SUCCESS')} ${text}`)
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* 失败日志
|
|
14
|
+
*/
|
|
15
|
+
export const error = (text?: string | number) => {
|
|
16
|
+
console.log(`${name} ${logSymbols.error} ${chalk.red('ERROR')} ${text}`)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* 信息日志
|
|
21
|
+
*/
|
|
22
|
+
export const info = (text?: string | number) => {
|
|
23
|
+
console.log(text ?? '')
|
|
24
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"incremental": false,
|
|
4
|
+
"composite": false,
|
|
5
|
+
"target": "esnext",
|
|
6
|
+
"useDefineForClassFields": true,
|
|
7
|
+
"module": "ESNext",
|
|
8
|
+
"moduleResolution": "node",
|
|
9
|
+
"strict": true,
|
|
10
|
+
"jsx": "preserve",
|
|
11
|
+
"sourceMap": true,
|
|
12
|
+
"resolveJsonModule": true,
|
|
13
|
+
"isolatedModules": true,
|
|
14
|
+
"esModuleInterop": true,
|
|
15
|
+
"lib": ["esnext"],
|
|
16
|
+
"types": ["node"],
|
|
17
|
+
"skipLibCheck": true,
|
|
18
|
+
"baseUrl": "./",
|
|
19
|
+
"paths": {
|
|
20
|
+
"@/*": ["./src/*"],
|
|
21
|
+
"~/*": ["./*"]
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"include": ["src/**/*.ts"],
|
|
25
|
+
"exclude": ["node_modules", "dist", ".git"]
|
|
26
|
+
}
|
package/vite.config.ts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { defineConfig } from 'vite'
|
|
2
|
+
import { resolve } from 'path'
|
|
3
|
+
import rollupPluginCopy from './scripts/rollup-plugin-copy'
|
|
4
|
+
|
|
5
|
+
const { dirname } = import.meta
|
|
6
|
+
|
|
7
|
+
const outDir = resolve(dirname, './dist/dist')
|
|
8
|
+
|
|
9
|
+
export default defineConfig({
|
|
10
|
+
root: dirname,
|
|
11
|
+
resolve: {
|
|
12
|
+
alias: {
|
|
13
|
+
'@': resolve(dirname, './src'),
|
|
14
|
+
'~': resolve(dirname, './')
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
build: {
|
|
18
|
+
target: 'node20',
|
|
19
|
+
outDir,
|
|
20
|
+
lib: {
|
|
21
|
+
entry: resolve(dirname, './src/index.ts'),
|
|
22
|
+
formats: ['es']
|
|
23
|
+
},
|
|
24
|
+
rollupOptions: {
|
|
25
|
+
external: ['update-notifier', 'url', 'path', 'child_process', 'fs', 'chalk', 'commander', 'log-symbols', 'ora', 'pacote', 'strip-json-comments'],
|
|
26
|
+
output: {
|
|
27
|
+
entryFileNames: '[name].js'
|
|
28
|
+
},
|
|
29
|
+
plugins: [rollupPluginCopy()]
|
|
30
|
+
},
|
|
31
|
+
ssr: false,
|
|
32
|
+
ssrManifest: false,
|
|
33
|
+
emptyOutDir: true
|
|
34
|
+
}
|
|
35
|
+
})
|
package/dist/index.js
DELETED
|
@@ -1,198 +0,0 @@
|
|
|
1
|
-
import N from "update-notifier";
|
|
2
|
-
import c from "chalk";
|
|
3
|
-
import { program as m } from "commander";
|
|
4
|
-
import q from "ora";
|
|
5
|
-
import { execSync as O } from "child_process";
|
|
6
|
-
import { readFileSync as k, writeFileSync as b, existsSync as G, readdirSync as P } from "fs";
|
|
7
|
-
import { join as u } from "path";
|
|
8
|
-
import A from "log-symbols";
|
|
9
|
-
const E = "mine-auto-cli", J = "2.2.0", B = "./dist/index.js", R = "./dist/index.js", U = "module", _ = {
|
|
10
|
-
auto: "bin/mine-auto-cli.js"
|
|
11
|
-
}, z = {
|
|
12
|
-
name: "biaov",
|
|
13
|
-
email: "biaov@qq.com",
|
|
14
|
-
url: "https://biaov.cn"
|
|
15
|
-
}, H = "一个将多个命令简化成一个命令的项目 😆", K = {
|
|
16
|
-
start: "npm run dev",
|
|
17
|
-
dev: "npm run build -- --watch",
|
|
18
|
-
build: "node scripts/build && vite build",
|
|
19
|
-
prettier: "prettier --write '**/*.{js,ts,md,json}'",
|
|
20
|
-
ncu: "ncu --configFileName .ncurc.json && npm i"
|
|
21
|
-
}, Q = {
|
|
22
|
-
registry: "https://registry.npmjs.org/"
|
|
23
|
-
}, W = {
|
|
24
|
-
node: ">=20"
|
|
25
|
-
}, X = [
|
|
26
|
-
"auto",
|
|
27
|
-
"cli",
|
|
28
|
-
"vite",
|
|
29
|
-
"typescript"
|
|
30
|
-
], Y = {
|
|
31
|
-
type: "git",
|
|
32
|
-
url: "git+https://github.com/biaov/mine-auto-cli.git"
|
|
33
|
-
}, Z = "https://github.com/biaov/mine-auto-cli.git", ee = {
|
|
34
|
-
url: "https://github.com/biaov/mine-auto-cli/issues"
|
|
35
|
-
}, te = "ISC", oe = [
|
|
36
|
-
{
|
|
37
|
-
name: "biaov",
|
|
38
|
-
email: "biaov@qq.com"
|
|
39
|
-
}
|
|
40
|
-
], ne = {
|
|
41
|
-
chalk: "^5.3.0",
|
|
42
|
-
commander: "^12.0.0",
|
|
43
|
-
"log-symbols": "^6.0.0",
|
|
44
|
-
ora: "^8.0.1",
|
|
45
|
-
"update-notifier": "^7.0.0"
|
|
46
|
-
}, se = {
|
|
47
|
-
"@types/node": "^20.11.30",
|
|
48
|
-
"@types/update-notifier": "^6.0.8",
|
|
49
|
-
prettier: "^3.2.5",
|
|
50
|
-
typescript: "^5.4.3",
|
|
51
|
-
vite: "^5.2.6"
|
|
52
|
-
}, f = {
|
|
53
|
-
name: E,
|
|
54
|
-
private: !1,
|
|
55
|
-
version: J,
|
|
56
|
-
exports: B,
|
|
57
|
-
main: R,
|
|
58
|
-
type: U,
|
|
59
|
-
bin: _,
|
|
60
|
-
author: z,
|
|
61
|
-
description: H,
|
|
62
|
-
scripts: K,
|
|
63
|
-
publishConfig: Q,
|
|
64
|
-
engines: W,
|
|
65
|
-
keywords: X,
|
|
66
|
-
repository: Y,
|
|
67
|
-
homepage: Z,
|
|
68
|
-
bugs: ee,
|
|
69
|
-
license: te,
|
|
70
|
-
contributors: oe,
|
|
71
|
-
dependencies: ne,
|
|
72
|
-
devDependencies: se
|
|
73
|
-
}, y = {}, ie = [
|
|
74
|
-
{
|
|
75
|
-
name: "success",
|
|
76
|
-
color: c.green
|
|
77
|
-
},
|
|
78
|
-
{
|
|
79
|
-
name: "error",
|
|
80
|
-
color: c.red,
|
|
81
|
-
prefix: E
|
|
82
|
-
},
|
|
83
|
-
{
|
|
84
|
-
name: "warning",
|
|
85
|
-
color: c.red
|
|
86
|
-
},
|
|
87
|
-
{
|
|
88
|
-
name: "info"
|
|
89
|
-
}
|
|
90
|
-
];
|
|
91
|
-
ie.forEach(({ name: e, color: t, prefix: n = "" }) => {
|
|
92
|
-
y[e] = (o = "") => {
|
|
93
|
-
if (typeof o == "object") {
|
|
94
|
-
const { text: s = "", prefix: r = "" } = o;
|
|
95
|
-
s && console.log(`${r + " "}${o}`);
|
|
96
|
-
} else
|
|
97
|
-
console.log(t ? `${n + " "}${t(e.toUpperCase())} ${o}` : o);
|
|
98
|
-
};
|
|
99
|
-
});
|
|
100
|
-
y.iconError = A.error;
|
|
101
|
-
y.iconSuccess = A.success;
|
|
102
|
-
const re = (e) => ["git add -A", `git commit -m ${e}`, "git push"], ce = (e, t) => [`npm run ${e}`, "git add -A", `git commit -m ${t}`, "git push"], { success: h, info: a, error: T } = y, F = (e) => {
|
|
103
|
-
a(`开始执行 ${c.cyanBright(e)} 命令`);
|
|
104
|
-
const t = q({ text: "正在执行命令中...", color: "yellow" });
|
|
105
|
-
t.start();
|
|
106
|
-
const n = O(e, { cwd: process.cwd() });
|
|
107
|
-
a(n.toString()), t.succeed(`${c.green(e)} 命令执行成功`), a();
|
|
108
|
-
}, ae = async (e = "更新代码") => {
|
|
109
|
-
a(), a(`${c.yellow(">>")} 开始依次执行命令...`), a(), re(e).forEach(F), h("全部命令执行完成"), a();
|
|
110
|
-
}, pe = async (e, t = "打包") => {
|
|
111
|
-
a(), a(`${c.yellow(">>")} 开始依次执行命令...`), a(), ce(e, t).map(F), h("全部命令执行完成"), a();
|
|
112
|
-
}, j = (e) => {
|
|
113
|
-
a(), T(`\`${e}\` 命令错误,请检查你的命令`), a(), m.help();
|
|
114
|
-
}, S = (e) => {
|
|
115
|
-
const t = ["package.json", "README.md"].map((r) => {
|
|
116
|
-
const i = u(process.cwd(), r), p = k(i).toString();
|
|
117
|
-
return { path: i, content: p };
|
|
118
|
-
}), [n, o] = t, s = JSON.parse(n.content);
|
|
119
|
-
if (e)
|
|
120
|
-
s.version = e;
|
|
121
|
-
else {
|
|
122
|
-
const r = s.version.split(".").reduce((i, p, l, d) => i + (l === d.length - 1 ? +p + 1 : `${p}.`), "");
|
|
123
|
-
s.version = r;
|
|
124
|
-
}
|
|
125
|
-
b(n.path, JSON.stringify(s, null, 2)), o.content = o.content.replace(/version\-v.+\-blue/, () => `version-v${s.version}-blue`), b(o.path, o.content);
|
|
126
|
-
}, le = async (e) => {
|
|
127
|
-
const t = e.split("version")[1];
|
|
128
|
-
if (!t)
|
|
129
|
-
return j(e);
|
|
130
|
-
const n = JSON.parse(k(u(process.cwd(), "package.json"), "utf-8"));
|
|
131
|
-
if (t === "++") {
|
|
132
|
-
const s = n.version.split(".").reduce((r, i, p, l) => r + (p === l.length - 1 ? +i + 1 : `${i}.`), "");
|
|
133
|
-
S(s), a(), h("命令执行完成");
|
|
134
|
-
return;
|
|
135
|
-
}
|
|
136
|
-
const o = t.split("@")[1];
|
|
137
|
-
o ? (S(o), a(), h("命令执行完成")) : j(e);
|
|
138
|
-
}, me = (e, t) => {
|
|
139
|
-
if (console.log(e.includes("mkdir"), "--"), e.includes("build"))
|
|
140
|
-
return pe(e, t);
|
|
141
|
-
if (e.includes("version"))
|
|
142
|
-
return le(e);
|
|
143
|
-
T(c.hex("#f56c6c")(`\`auto ${e}${t ? ` ${t}` : ""}\` 命令不存在`)), m.help();
|
|
144
|
-
}, V = ["dist", "node_modules", ".git", "miniprogram_npm"];
|
|
145
|
-
let v = 0, I = !1, $ = !1, L = 20;
|
|
146
|
-
const C = ({ prev: e, i: t, index: n, arr: o, curText: s }) => {
|
|
147
|
-
const r = Array.from({ length: t }).reduce((d) => d + `${t === 1 && n === o.length - 1 ? "└ " : "│ "} `, ""), i = e + r, p = (r + s).length, l = Array.from({ length: L + v - p }).reduce((d) => `${d}-`, " ");
|
|
148
|
-
return !I && (v = Math.max(v, p)), `${i}${s}${$ ? l : ""}
|
|
149
|
-
`;
|
|
150
|
-
}, w = (e, t = 0) => e.reduce((n, o, s, r) => {
|
|
151
|
-
let i;
|
|
152
|
-
return o.children ? (i = `├── ${o.name}`, C({ prev: n, i: t, index: s, arr: r, curText: i }) + w(o.children, t + 1)) : (i = `${s === r.length - 1 ? "└── " : "├── "}${o.name}`, C({ prev: n, i: t, index: s, arr: r, curText: i }));
|
|
153
|
-
}, ""), D = (e) => P(e, { withFileTypes: !0 }).sort((t, n) => +n.isDirectory() - +t.isDirectory()), de = ({ line: e, name: t }) => {
|
|
154
|
-
$ = !!e, typeof e == "string" && (L = +e);
|
|
155
|
-
const n = process.cwd(), o = u(n, ".gitignore");
|
|
156
|
-
if (G(o)) {
|
|
157
|
-
const l = k(o, { encoding: "utf-8" }).split(`\r
|
|
158
|
-
`);
|
|
159
|
-
V.push(...l);
|
|
160
|
-
}
|
|
161
|
-
const s = n.split("\\").at(-1), i = D(n).map((l) => {
|
|
162
|
-
const { name: d } = l, x = { name: d };
|
|
163
|
-
return !V.includes(d) && l.isDirectory() && (x.children = D(u(l.path, d)).map(({ name: M }) => ({ name: M }))), x;
|
|
164
|
-
}), p = [{ name: s, children: i }];
|
|
165
|
-
$ && (w(p), I = !0), b(u(n, `${typeof t == "string" && t || "directory"}.md`), w(p));
|
|
166
|
-
};
|
|
167
|
-
m.usage("[commands] [options]").version(J, "-v, --version", "输出版本号").helpOption("-h, --help", "输出所有命令");
|
|
168
|
-
m.command("git [描述]").description("简化 Git 提交命令").action(ae);
|
|
169
|
-
m.command("build[:环境] [描述]").description("简化打包提交命令");
|
|
170
|
-
m.command("version<[++]|[@<版本号>]>").description("例如:version++ 或者 version@1.0.0;自动更新 package.json 版本号,自动更新 `README.md` 中的 `version-v<version>-blue` 图标版本");
|
|
171
|
-
m.command("mkdir").option("-l, --line [数量]", "数量", !1).option("-n, --name [文件名称]", "文件名称", !1).description("生成目录结构文件").action(de);
|
|
172
|
-
m.arguments("<cmd> [env]").action((e, t) => {
|
|
173
|
-
me(e, t);
|
|
174
|
-
});
|
|
175
|
-
process.argv.length < 3 ? m.help() : m.parse(process.argv);
|
|
176
|
-
const g = N({ pkg: f });
|
|
177
|
-
if (g.update && g.update.latest !== f.version) {
|
|
178
|
-
let e = "";
|
|
179
|
-
switch (g.update.type) {
|
|
180
|
-
case "major":
|
|
181
|
-
e = c.red("{latestVersion}");
|
|
182
|
-
break;
|
|
183
|
-
case "minor":
|
|
184
|
-
e = c.yellow("{latestVersion}");
|
|
185
|
-
break;
|
|
186
|
-
default:
|
|
187
|
-
e = c.green("{latestVersion}");
|
|
188
|
-
break;
|
|
189
|
-
}
|
|
190
|
-
const t = `https://github.com/biaov/${f.name}/compare/v${f.version}...v{latestVersion}`;
|
|
191
|
-
g.notify({
|
|
192
|
-
defer: !1,
|
|
193
|
-
isGlobal: !0,
|
|
194
|
-
message: `有更新 ${c.dim("{currentVersion}")}${c.reset(" → ")}${e}
|
|
195
|
-
运行 ${c.cyan("{updateCommand}")} 命令更新
|
|
196
|
-
${c.dim.underline(t)}`
|
|
197
|
-
});
|
|
198
|
-
}
|