commit-pack 1.1.4 → 1.1.7
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/README.md +336 -55
- package/bin/index.mjs +295 -91
- package/bin/installWithProgress.js +29 -11
- package/lib/index.mjs +274 -94
- package/package.json +2 -2
- package/setup-script/husky.sh +23 -5
- package/setup-script/lintstagedrc.sh +1 -1
package/bin/index.mjs
CHANGED
|
@@ -10,10 +10,40 @@ import { fileURLToPath } from 'url'
|
|
|
10
10
|
import { log } from './chalkColor.js'
|
|
11
11
|
import { installWithProgress } from './installWithProgress.js'
|
|
12
12
|
|
|
13
|
+
const printBanner = () => {
|
|
14
|
+
const top = '╭' + '─'.repeat(40) + '╮'
|
|
15
|
+
const bottom = '╰' + '─'.repeat(40) + '╯'
|
|
16
|
+
const middle = `│ ${chalk.bold.cyan('🚀 Commit Pack 初始化中...')} │`
|
|
17
|
+
|
|
18
|
+
console.log('\n' + top)
|
|
19
|
+
console.log(middle)
|
|
20
|
+
console.log(bottom + '\n')
|
|
21
|
+
}
|
|
22
|
+
|
|
13
23
|
// 模拟 CommonJS 的 __dirname
|
|
14
24
|
const __filename = fileURLToPath(import.meta.url)
|
|
15
25
|
const __dirname = path.dirname(__filename)
|
|
16
26
|
|
|
27
|
+
// 解析命令行参数
|
|
28
|
+
const args = process.argv.slice(2)
|
|
29
|
+
const workspaceArgIndex = args.findIndex(
|
|
30
|
+
(arg) => arg.startsWith('--workspace=') || arg.startsWith('-w=')
|
|
31
|
+
)
|
|
32
|
+
let workspaceName = ''
|
|
33
|
+
if (workspaceArgIndex !== -1) {
|
|
34
|
+
const arg = args[workspaceArgIndex]
|
|
35
|
+
workspaceName = arg.split('=')[1]
|
|
36
|
+
} else {
|
|
37
|
+
// 查找是否有单独的 -w 或 --workspace 参数
|
|
38
|
+
const wIndex = args.findIndex((arg) => arg === '-w')
|
|
39
|
+
const workspaceIndex = args.findIndex((arg) => arg === '--workspace')
|
|
40
|
+
if (wIndex !== -1 && wIndex + 1 < args.length) {
|
|
41
|
+
workspaceName = args[wIndex + 1]
|
|
42
|
+
} else if (workspaceIndex !== -1 && workspaceIndex + 1 < args.length) {
|
|
43
|
+
workspaceName = args[workspaceIndex + 1]
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
17
47
|
// 向上查找带锁文件的根目录
|
|
18
48
|
function findProjectRootWithLockFile() {
|
|
19
49
|
let dir = __dirname
|
|
@@ -46,19 +76,99 @@ function detectPackageManager() {
|
|
|
46
76
|
}
|
|
47
77
|
|
|
48
78
|
const packageManager = detectPackageManager()
|
|
79
|
+
|
|
80
|
+
// 计算实际的工作目录
|
|
81
|
+
let actualProjectRoot = projectRoot
|
|
82
|
+
if (workspaceName) {
|
|
83
|
+
const packageJsonContent = JSON.parse(
|
|
84
|
+
fs.readFileSync(path.join(projectRoot, 'package.json'), 'utf8')
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
// 根据包管理器确定工作spaces路径
|
|
88
|
+
let workspaces = []
|
|
89
|
+
if (packageJsonContent.workspaces) {
|
|
90
|
+
if (Array.isArray(packageJsonContent.workspaces)) {
|
|
91
|
+
workspaces = packageJsonContent.workspaces
|
|
92
|
+
} else if (packageJsonContent.workspaces.packages) {
|
|
93
|
+
workspaces = packageJsonContent.workspaces.packages
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// 查找workspace包的路径
|
|
98
|
+
if (workspaces.length > 0) {
|
|
99
|
+
for (const workspacePattern of workspaces) {
|
|
100
|
+
// 处理通配符模式,例如 'packages/*'
|
|
101
|
+
if (workspacePattern.includes('*')) {
|
|
102
|
+
const basePath = workspacePattern.replace('/*', '')
|
|
103
|
+
const packagesDir = path.join(projectRoot, basePath)
|
|
104
|
+
if (fs.existsSync(packagesDir)) {
|
|
105
|
+
const packageDirs = fs.readdirSync(packagesDir)
|
|
106
|
+
for (const dir of packageDirs) {
|
|
107
|
+
const dirPath = path.join(packagesDir, dir)
|
|
108
|
+
if (fs.statSync(dirPath).isDirectory()) {
|
|
109
|
+
try {
|
|
110
|
+
const pkgPath = path.join(dirPath, 'package.json')
|
|
111
|
+
if (fs.existsSync(pkgPath)) {
|
|
112
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'))
|
|
113
|
+
if (pkg.name === workspaceName || dir === workspaceName) {
|
|
114
|
+
actualProjectRoot = dirPath
|
|
115
|
+
break
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
} catch (e) {
|
|
119
|
+
console.log(e)
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
} else {
|
|
125
|
+
// 直接路径匹配
|
|
126
|
+
const dirPath = path.join(projectRoot, workspacePattern)
|
|
127
|
+
if (fs.existsSync(dirPath) && fs.statSync(dirPath).isDirectory()) {
|
|
128
|
+
try {
|
|
129
|
+
const pkgPath = path.join(dirPath, 'package.json')
|
|
130
|
+
if (fs.existsSync(pkgPath)) {
|
|
131
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'))
|
|
132
|
+
if (
|
|
133
|
+
pkg.name === workspaceName ||
|
|
134
|
+
path.basename(dirPath) === workspaceName
|
|
135
|
+
) {
|
|
136
|
+
actualProjectRoot = dirPath
|
|
137
|
+
break
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
} catch (e) {
|
|
141
|
+
console.log(e)
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
console.log('')
|
|
150
|
+
printBanner()
|
|
151
|
+
console.log('')
|
|
49
152
|
console.log('')
|
|
50
153
|
console.log(`🍀 包管理器:${packageManager}`)
|
|
51
|
-
console.log(`📁 根目录:${
|
|
154
|
+
console.log(`📁 根目录:${actualProjectRoot}`)
|
|
155
|
+
if (workspaceName) {
|
|
156
|
+
console.log(`📦 工作空间: ${workspaceName}`)
|
|
157
|
+
}
|
|
52
158
|
|
|
53
|
-
const packageJsonPath = path.join(
|
|
159
|
+
const packageJsonPath = path.join(actualProjectRoot, 'package.json')
|
|
54
160
|
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'))
|
|
55
161
|
|
|
56
162
|
// 检查是否已经初始化过
|
|
57
|
-
const initFlagPath = path.join(
|
|
163
|
+
const initFlagPath = path.join(actualProjectRoot, '.commit-pack-init')
|
|
58
164
|
if (fs.existsSync(initFlagPath)) {
|
|
165
|
+
console.log(log.warn('⚠️ 该工作空间/项目已被初始化,跳过初始化'))
|
|
59
166
|
process.exit(0)
|
|
60
167
|
}
|
|
61
168
|
|
|
169
|
+
// 回滚机制:记录初始状态
|
|
170
|
+
const initialPackageJson = JSON.stringify(packageJson, null, 2)
|
|
171
|
+
|
|
62
172
|
// 确保 devDependencies 存在
|
|
63
173
|
if (!packageJson.devDependencies) {
|
|
64
174
|
packageJson.devDependencies = {}
|
|
@@ -100,55 +210,57 @@ for (const [dep, version] of Object.entries(devDependenciesWithVersion)) {
|
|
|
100
210
|
}
|
|
101
211
|
}
|
|
102
212
|
|
|
103
|
-
installWithProgress(dependenciesToInstall, packageManager, projectRoot)
|
|
104
|
-
|
|
105
|
-
let isGitRepo = false
|
|
106
|
-
|
|
107
213
|
try {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
214
|
+
installWithProgress(dependenciesToInstall, packageManager, actualProjectRoot)
|
|
215
|
+
|
|
216
|
+
let isGitRepo = false
|
|
217
|
+
|
|
218
|
+
try {
|
|
219
|
+
// 获取 Git 仓库的顶级目录
|
|
220
|
+
const gitTopLevel = execSync('git rev-parse --show-toplevel', {
|
|
221
|
+
cwd: actualProjectRoot
|
|
222
|
+
})
|
|
223
|
+
.toString()
|
|
224
|
+
.trim()
|
|
225
|
+
// 比较顶级目录与当前项目目录
|
|
226
|
+
if (path.resolve(gitTopLevel) === path.resolve(actualProjectRoot)) {
|
|
227
|
+
isGitRepo = true
|
|
228
|
+
} else {
|
|
229
|
+
isGitRepo = false
|
|
230
|
+
}
|
|
231
|
+
} catch {
|
|
116
232
|
isGitRepo = false
|
|
117
233
|
}
|
|
118
|
-
} catch {
|
|
119
|
-
isGitRepo = false
|
|
120
|
-
}
|
|
121
234
|
|
|
122
|
-
if (isGitRepo) {
|
|
123
|
-
|
|
124
|
-
} else {
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
}
|
|
235
|
+
if (isGitRepo) {
|
|
236
|
+
console.log(log.success('👍 Git仓库已存在'))
|
|
237
|
+
} else {
|
|
238
|
+
console.log(log.warn('👌 Git仓库初始化...'))
|
|
239
|
+
execSync('git init', { stdio: 'inherit', cwd: actualProjectRoot })
|
|
240
|
+
}
|
|
128
241
|
|
|
129
|
-
// 根据包管理器,执行对应的 Husky 初始化命令
|
|
130
|
-
let huskyInitCommand = ''
|
|
131
|
-
switch (packageManager) {
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
}
|
|
242
|
+
// 根据包管理器,执行对应的 Husky 初始化命令
|
|
243
|
+
let huskyInitCommand = ''
|
|
244
|
+
switch (packageManager) {
|
|
245
|
+
case 'pnpm':
|
|
246
|
+
huskyInitCommand = 'pnpm exec husky init'
|
|
247
|
+
break
|
|
248
|
+
case 'yarn':
|
|
249
|
+
huskyInitCommand = 'yarn dlx husky init'
|
|
250
|
+
break
|
|
251
|
+
case 'bun':
|
|
252
|
+
huskyInitCommand = 'bunx husky init'
|
|
253
|
+
break
|
|
254
|
+
default:
|
|
255
|
+
huskyInitCommand = 'npx husky init'
|
|
256
|
+
break
|
|
257
|
+
}
|
|
145
258
|
|
|
146
|
-
console.log(chalk.green(`🐶 Husky初始化...`))
|
|
147
|
-
execSync(huskyInitCommand, { stdio: 'inherit', cwd:
|
|
259
|
+
console.log(chalk.green(`🐶 Husky初始化...`))
|
|
260
|
+
execSync(huskyInitCommand, { stdio: 'inherit', cwd: actualProjectRoot })
|
|
148
261
|
|
|
149
|
-
// 执行 setup-script 中的所有文件
|
|
150
|
-
console.log('🚀 创建配置文件...')
|
|
151
|
-
try {
|
|
262
|
+
// 执行 setup-script 中的所有文件
|
|
263
|
+
console.log('🚀 创建配置文件...')
|
|
152
264
|
const setupScripts = [
|
|
153
265
|
'prettier.sh',
|
|
154
266
|
'lintstagedrc.sh',
|
|
@@ -161,61 +273,153 @@ try {
|
|
|
161
273
|
|
|
162
274
|
for (const script of setupScripts) {
|
|
163
275
|
const scriptPath = path.join(__dirname, '..', 'setup-script', script)
|
|
164
|
-
execSync(`sh ${scriptPath}`, { stdio: 'inherit', cwd:
|
|
276
|
+
execSync(`sh ${scriptPath}`, { stdio: 'inherit', cwd: actualProjectRoot })
|
|
165
277
|
}
|
|
166
|
-
} catch (error) {
|
|
167
|
-
console.error(log.warn('❌ 文件创建出错'), error)
|
|
168
|
-
}
|
|
169
278
|
|
|
170
|
-
// 创建或更新脚本
|
|
171
|
-
if (!packageJson.scripts) {
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
}
|
|
279
|
+
// 创建或更新脚本
|
|
280
|
+
if (!packageJson.scripts) {
|
|
281
|
+
packageJson.scripts = {}
|
|
282
|
+
console.log('🔥 创建或更新脚本...')
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
let modified = false
|
|
286
|
+
|
|
287
|
+
if (!packageJson.scripts.lint) {
|
|
288
|
+
if (workspaceName) {
|
|
289
|
+
// 为workspace项目使用工作空间命令
|
|
290
|
+
if (packageManager === 'pnpm') {
|
|
291
|
+
packageJson.scripts.lint = `pnpm -F ${workspaceName} exec eslint ./ --ext .ts,.tsx,.json --max-warnings=0`
|
|
292
|
+
} else if (packageManager === 'yarn') {
|
|
293
|
+
packageJson.scripts.lint = `yarn workspace ${workspaceName} exec eslint ./ --ext .ts,.tsx,.json --max-warnings=0`
|
|
294
|
+
} else {
|
|
295
|
+
packageJson.scripts.lint = 'eslint ./ --ext .ts,.tsx,.json --max-warnings=0'
|
|
296
|
+
}
|
|
297
|
+
} else {
|
|
298
|
+
packageJson.scripts.lint = 'eslint ./ --ext .ts,.tsx,.json --max-warnings=0'
|
|
299
|
+
}
|
|
300
|
+
console.log(log.success('✅ 已添加 "lint" 至 package.json'))
|
|
301
|
+
modified = true
|
|
302
|
+
} else {
|
|
303
|
+
console.log(log.warn('⚠️ package.json 中已存在 "lint" 未作修改'))
|
|
304
|
+
}
|
|
175
305
|
|
|
176
|
-
|
|
306
|
+
if (!packageJson.scripts.format) {
|
|
307
|
+
if (workspaceName) {
|
|
308
|
+
// 为workspace项目使用工作空间命令
|
|
309
|
+
if (packageManager === 'pnpm') {
|
|
310
|
+
packageJson.scripts.format = `pnpm -F ${workspaceName} exec prettier --config .prettierrc '.' --write`
|
|
311
|
+
} else if (packageManager === 'yarn') {
|
|
312
|
+
packageJson.scripts.format = `yarn workspace ${workspaceName} exec prettier --config .prettierrc '.' --write`
|
|
313
|
+
} else {
|
|
314
|
+
packageJson.scripts.format = "prettier --config .prettierrc '.' --write"
|
|
315
|
+
}
|
|
316
|
+
} else {
|
|
317
|
+
packageJson.scripts.format = "prettier --config .prettierrc '.' --write"
|
|
318
|
+
}
|
|
319
|
+
console.log(log.success('✅ 已添加 "format" 至 package.json'))
|
|
320
|
+
modified = true
|
|
321
|
+
} else {
|
|
322
|
+
console.log(log.warn('⚠️ package.json 中已存在 "format" 未作修改'))
|
|
323
|
+
}
|
|
177
324
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
325
|
+
// 添加或更新 "commit" 脚本
|
|
326
|
+
if (workspaceName) {
|
|
327
|
+
// 为workspace项目使用工作空间命令
|
|
328
|
+
if (packageManager === 'pnpm') {
|
|
329
|
+
packageJson.scripts.commit = `pnpm -F ${workspaceName} exec cz`
|
|
330
|
+
} else if (packageManager === 'yarn') {
|
|
331
|
+
packageJson.scripts.commit = `yarn workspace ${workspaceName} exec cz`
|
|
332
|
+
} else {
|
|
333
|
+
packageJson.scripts.commit = 'cz'
|
|
334
|
+
}
|
|
335
|
+
} else {
|
|
336
|
+
packageJson.scripts.commit = 'cz'
|
|
337
|
+
}
|
|
338
|
+
console.log(log.success('✅ 已添加 "commit" 至 package.json'))
|
|
181
339
|
modified = true
|
|
182
|
-
} else {
|
|
183
|
-
console.log(log.warn('package.json 中已存在 "lint" 未作修改'))
|
|
184
|
-
}
|
|
185
340
|
|
|
186
|
-
|
|
187
|
-
packageJson.
|
|
188
|
-
|
|
341
|
+
// 添加或更新 "config.commitizen" 配置
|
|
342
|
+
if (!packageJson.config) {
|
|
343
|
+
packageJson.config = {}
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
packageJson.config.commitizen = {
|
|
347
|
+
path: 'node_modules/cz-customizable'
|
|
348
|
+
}
|
|
189
349
|
modified = true
|
|
190
|
-
} else {
|
|
191
|
-
console.log(log.warn('package.json 中已存在 "format" 未作修改'))
|
|
192
|
-
}
|
|
193
350
|
|
|
194
|
-
//
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
351
|
+
// 写入修改后的 package.json
|
|
352
|
+
if (modified) {
|
|
353
|
+
fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2), 'utf8')
|
|
354
|
+
console.log(chalk.green('✅ 已更新 package.json'))
|
|
355
|
+
console.log('')
|
|
356
|
+
console.log('')
|
|
357
|
+
}
|
|
198
358
|
|
|
199
|
-
//
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
359
|
+
// 创建初始化标志文件
|
|
360
|
+
fs.writeFileSync(initFlagPath, 'initialized', 'utf8')
|
|
361
|
+
console.log(log.success(' 🎉🎉🎉 完成啦!'))
|
|
362
|
+
console.log('')
|
|
363
|
+
if (workspaceName) {
|
|
364
|
+
console.log(
|
|
365
|
+
` 在 ${workspaceName} 工作空间中,运行: git add . && ${packageManager} run commit`
|
|
366
|
+
)
|
|
367
|
+
} else {
|
|
368
|
+
console.log(` 运行 git add 后 | 运行 ${packageManager} run commit 即可`)
|
|
369
|
+
}
|
|
370
|
+
} catch (error) {
|
|
371
|
+
console.error(log.error('❌ 初始化过程中发生错误,正在执行回滚...'))
|
|
372
|
+
console.error('错误详情:', error.message)
|
|
373
|
+
console.error('错误堆栈:', error.stack)
|
|
374
|
+
if (error.stdout) console.error('标准输出:', error.stdout.toString())
|
|
375
|
+
if (error.stderr) console.error('错误输出:', error.stderr.toString())
|
|
376
|
+
|
|
377
|
+
try {
|
|
378
|
+
// 回滚:恢复原始的package.json
|
|
379
|
+
fs.writeFileSync(packageJsonPath, initialPackageJson, 'utf8')
|
|
380
|
+
console.log(log.warn('✅ 已恢复原始 package.json'))
|
|
381
|
+
|
|
382
|
+
// 删除可能创建的配置文件
|
|
383
|
+
const configFiles = [
|
|
384
|
+
'.prettierrc',
|
|
385
|
+
'.eslintrc',
|
|
386
|
+
'.commitlintrc.json',
|
|
387
|
+
'.cz-config.js',
|
|
388
|
+
'.czrc',
|
|
389
|
+
'.lintstagedrc',
|
|
390
|
+
'.prettierignore',
|
|
391
|
+
'.eslintignore'
|
|
392
|
+
]
|
|
393
|
+
for (const configFile of configFiles) {
|
|
394
|
+
const configPath = path.join(actualProjectRoot, configFile)
|
|
395
|
+
if (fs.existsSync(configPath)) {
|
|
396
|
+
fs.unlinkSync(configPath)
|
|
397
|
+
console.log(log.warn(`✅ 已删除临时配置文件: ${configFile}`))
|
|
398
|
+
}
|
|
399
|
+
}
|
|
203
400
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
401
|
+
// 删除可能创建的.husky目录
|
|
402
|
+
const huskyDir = path.join(actualProjectRoot, '.husky')
|
|
403
|
+
if (fs.existsSync(huskyDir)) {
|
|
404
|
+
fs.rmSync(huskyDir, { recursive: true, force: true })
|
|
405
|
+
console.log(log.warn('✅ 已删除临时 .husky 目录'))
|
|
406
|
+
}
|
|
208
407
|
|
|
209
|
-
//
|
|
210
|
-
if (
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
console.log('')
|
|
214
|
-
console.log('')
|
|
215
|
-
}
|
|
408
|
+
// 删除初始化标志文件
|
|
409
|
+
if (fs.existsSync(initFlagPath)) {
|
|
410
|
+
fs.unlinkSync(initFlagPath)
|
|
411
|
+
}
|
|
216
412
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
console.
|
|
220
|
-
console.
|
|
221
|
-
console.
|
|
413
|
+
console.log(log.success(' 🔄 回滚完成'))
|
|
414
|
+
} catch (rollbackError) {
|
|
415
|
+
console.error(log.error('❌ 回滚过程中也发生了错误,请手动检查项目状态'))
|
|
416
|
+
console.error('回滚错误详情:', rollbackError.message)
|
|
417
|
+
console.error('回滚错误堆栈:', rollbackError.stack)
|
|
418
|
+
if (rollbackError.stdout)
|
|
419
|
+
console.error('回滚标准输出:', rollbackError.stdout.toString())
|
|
420
|
+
if (rollbackError.stderr)
|
|
421
|
+
console.error('回滚错误输出:', rollbackError.stderr.toString())
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
process.exit(1) // 确保进程以错误码退出
|
|
425
|
+
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
/* eslint-env node */
|
|
2
2
|
import chalk from 'chalk'
|
|
3
3
|
import { execSync } from 'child_process'
|
|
4
|
+
import fs from 'fs'
|
|
5
|
+
import path from 'path'
|
|
4
6
|
import cliProgress from 'cli-progress'
|
|
5
7
|
|
|
6
8
|
export function installWithProgress(dependencies, packageManager, projectRoot) {
|
|
@@ -10,10 +12,17 @@ export function installWithProgress(dependencies, packageManager, projectRoot) {
|
|
|
10
12
|
}
|
|
11
13
|
|
|
12
14
|
console.log('')
|
|
13
|
-
console.log(
|
|
15
|
+
console.log(`⬇️ 开始安装依赖...`)
|
|
16
|
+
|
|
17
|
+
// 检查是否为 monorepo(检查是否有 pnpm-workspace.yaml 或 package.json 中的 workspaces 字段)
|
|
18
|
+
const isMonorepo =
|
|
19
|
+
fs.existsSync(path.join(projectRoot, 'pnpm-workspace.yaml')) ||
|
|
20
|
+
(fs.existsSync(path.join(projectRoot, 'package.json')) &&
|
|
21
|
+
JSON.parse(fs.readFileSync(path.join(projectRoot, 'package.json'), 'utf8'))
|
|
22
|
+
.workspaces)
|
|
14
23
|
|
|
15
24
|
const bar = new cliProgress.SingleBar({
|
|
16
|
-
format:
|
|
25
|
+
format: ` [${chalk.cyan('{bar}')}]{percentage}% | 正在安装: {dep}`,
|
|
17
26
|
barCompleteChar: '▰',
|
|
18
27
|
barIncompleteChar: '▱',
|
|
19
28
|
hideCursor: true
|
|
@@ -25,26 +34,35 @@ export function installWithProgress(dependencies, packageManager, projectRoot) {
|
|
|
25
34
|
for (let i = 0; i < dependencies.length; i++) {
|
|
26
35
|
const dep = dependencies[i]
|
|
27
36
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
37
|
+
let installCommand
|
|
38
|
+
if (packageManager === 'pnpm' && isMonorepo) {
|
|
39
|
+
installCommand = `pnpm add -w -D ${dep}`
|
|
40
|
+
} else {
|
|
41
|
+
installCommand = {
|
|
42
|
+
pnpm: `pnpm add -D ${dep}`,
|
|
43
|
+
yarn: `yarn add ${dep} --dev`,
|
|
44
|
+
bun: `bun add -d ${dep}`,
|
|
45
|
+
npm: `npm install ${dep} --save-dev`
|
|
46
|
+
}[packageManager]
|
|
47
|
+
}
|
|
34
48
|
|
|
35
49
|
bar.update(i, { dep })
|
|
36
50
|
|
|
37
|
-
execSync(installCommand, { cwd: projectRoot, stdio: '
|
|
51
|
+
execSync(installCommand, { cwd: projectRoot, stdio: ['pipe', 'pipe', 'pipe'] })
|
|
38
52
|
|
|
39
53
|
bar.update(i + 1, { dep })
|
|
40
54
|
}
|
|
41
|
-
bar.update(dependencies.length, { dep: chalk.green('
|
|
55
|
+
bar.update(dependencies.length, { dep: chalk.green(' ✔ ') })
|
|
42
56
|
bar.stop()
|
|
43
57
|
console.log('')
|
|
44
58
|
console.log('')
|
|
45
59
|
} catch (err) {
|
|
46
60
|
bar.stop()
|
|
47
|
-
console.log(chalk.red('❌ 安装过程中出错')
|
|
61
|
+
console.log(chalk.red('❌ 安装过程中出错'))
|
|
62
|
+
console.error('错误详情:', err.message)
|
|
63
|
+
console.error('错误堆栈:', err.stack)
|
|
64
|
+
if (err.stdout) console.error('标准输出:', err.stdout.toString())
|
|
65
|
+
if (err.stderr) console.error('错误输出:', err.stderr.toString())
|
|
48
66
|
throw err
|
|
49
67
|
}
|
|
50
68
|
}
|