code-simplifier 1.0.0 → 1.2.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.
@@ -0,0 +1,353 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Code-Simplifier Git 钩子集成
5
+ */
6
+
7
+ const fs = require('fs-extra')
8
+ const path = require('path')
9
+ const chalk = require('chalk')
10
+ const inquirer = require('inquirer')
11
+ const { exec } = require('child_process')
12
+ const util = require('util')
13
+ const execPromise = util.promisify(exec)
14
+
15
+ class GitHooks {
16
+ constructor() {
17
+ this.gitDir = '.git'
18
+ this.hooksDir = '.git/hooks'
19
+ }
20
+
21
+ /**
22
+ * 运行 Git 钩子管理
23
+ */
24
+ async run(options = {}) {
25
+ if (options.install) {
26
+ await this.install(options)
27
+ } else if (options.uninstall) {
28
+ await this.uninstall(options)
29
+ } else if (options.list) {
30
+ await this.list()
31
+ } else {
32
+ await this.interactive()
33
+ }
34
+ }
35
+
36
+ /**
37
+ * 交互式安装
38
+ */
39
+ async interactive() {
40
+ console.log(chalk.cyan.bold('\n🔧 Git 钩子管理'))
41
+ console.log(chalk.gray('='.repeat(50)))
42
+
43
+ const answers = await inquirer.prompt([
44
+ {
45
+ type: 'confirm',
46
+ name: 'preCommit',
47
+ message: '安装 pre-commit 钩子 (提交前检查代码质量)?',
48
+ default: true
49
+ },
50
+ {
51
+ type: 'confirm',
52
+ name: 'prePush',
53
+ message: '安装 pre-push 钩子 (推送前检查)?',
54
+ default: true
55
+ },
56
+ {
57
+ type: 'number',
58
+ name: 'threshold',
59
+ message: '质量评分阈值 (0-100):',
60
+ default: 70,
61
+ validate: val => val >= 0 && val <= 100
62
+ }
63
+ ])
64
+
65
+ await this.install({
66
+ preCommit: answers.preCommit,
67
+ prePush: answers.prePush,
68
+ threshold: answers.threshold
69
+ })
70
+ }
71
+
72
+ /**
73
+ * 安装钩子
74
+ */
75
+ async install(options = {}) {
76
+ console.log(chalk.blue.bold('\n📦 安装 Git 钩子'))
77
+ console.log(chalk.gray('='.repeat(50)))
78
+
79
+ if (!(await fs.pathExists(this.gitDir))) {
80
+ console.log(chalk.red('❌ 当前目录不是 Git 仓库'))
81
+ return { success: false, error: 'Not a git repository' }
82
+ }
83
+
84
+ const config = {
85
+ threshold: options.threshold || 70,
86
+ eslint: options.eslint !== false,
87
+ autoFix: options.autoFix || false
88
+ }
89
+
90
+ // 写入配置文件
91
+ await fs.writeJson('.code-simplifier/hooks-config.json', config, { spaces: 2 })
92
+
93
+ // 安装 pre-commit 钩子
94
+ if (options.preCommit !== false) {
95
+ await this.installPreCommit(config)
96
+ }
97
+
98
+ // 安装 pre-push 钩子
99
+ if (options.prePush !== false) {
100
+ await this.installPrePush(config)
101
+ }
102
+
103
+ console.log(chalk.green('\n✅ Git 钩子安装完成'))
104
+ return { success: true }
105
+ }
106
+
107
+ /**
108
+ * 安装 pre-commit 钩子
109
+ */
110
+ async installPreCommit(config) {
111
+ console.log(chalk.gray('正在安装 pre-commit 钩子...'))
112
+
113
+ const hookContent = this.generatePreCommitHook(config)
114
+ const hookPath = path.join(this.hooksDir, 'pre-commit')
115
+
116
+ await fs.writeFile(hookPath, hookContent)
117
+ await fs.chmod(hookPath, '755')
118
+
119
+ console.log(chalk.green('✓ pre-commit 钩子已安装'))
120
+ }
121
+
122
+ /**
123
+ * 安装 pre-push 钩子
124
+ */
125
+ async installPrePush(config) {
126
+ console.log(chalk.gray('正在安装 pre-push 钩子...'))
127
+
128
+ const hookContent = this.generatePrePushHook(config)
129
+ const hookPath = path.join(this.hooksDir, 'pre-push')
130
+
131
+ await fs.writeFile(hookPath, hookContent)
132
+ await fs.chmod(hookPath, '755')
133
+
134
+ console.log(chalk.green('✓ pre-push 钩子已安装'))
135
+ }
136
+
137
+ /**
138
+ * 生成 pre-commit 钩子内容
139
+ */
140
+ generatePreCommitHook(config) {
141
+ return `#!/bin/bash
142
+
143
+ # Code-Simplifier pre-commit hook
144
+ # 由 Code-Simplifier 自动生成
145
+
146
+ echo "🔍 正在运行代码质量检查..."
147
+
148
+ # 检查是否安装了 code-simplifier
149
+ if ! command -v code-simplifier &> /dev/null && ! command -v npx &> /dev/null; then
150
+ echo "❌ 未找到 code-simplifier,请先安装:"
151
+ echo " npm install -g code-simplifier"
152
+ exit 1
153
+ fi
154
+
155
+ # 获取待提交的文件
156
+ STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACM | grep -E '\\.(js|jsx|ts|tsx|vue)$' || true)
157
+
158
+ if [ -z "$STAGED_FILES" ]; then
159
+ echo "✓ 没有需要检查的代码文件"
160
+ exit 0
161
+ fi
162
+
163
+ echo "📝 检查文件: $STAGED_FILES"
164
+
165
+ # 运行质量检查
166
+ if command -v code-simplifier &> /dev/null; then
167
+ npx code-simplifier quality --threshold ${config.threshold} --dir .
168
+ else
169
+ npx code-simplifier quality --threshold ${config.threshold} --dir .
170
+ fi
171
+
172
+ QUALITY_EXIT_CODE=$?
173
+
174
+ if [ $QUALITY_EXIT_CODE -ne 0 ]; then
175
+ echo ""
176
+ echo "❌ 代码质量检查失败!"
177
+ echo "请修复问题后再提交,或使用 --no-verify 跳过检查"
178
+ exit 1
179
+ fi
180
+
181
+ # 运行 ESLint(如果配置了)
182
+ ${config.eslint ? `
183
+ if [ -f .eslintrc.js ] || [ -f .eslintrc.json ] || [ -f package.json ]; then
184
+ echo "🔍 运行 ESLint 检查..."
185
+ npx eslint --ext .js,.jsx,.ts,.tsx,.vue $STAGED_FILES
186
+ ESLINT_EXIT_CODE=$?
187
+
188
+ if [ $ESLINT_EXIT_CODE -ne 0 ]; then
189
+ echo ""
190
+ echo "❌ ESLint 检查失败!"
191
+ echo "请修复问题后再提交,或使用 --no-verify 跳过检查"
192
+ exit 1
193
+ fi
194
+ fi
195
+ ` : ''}
196
+
197
+ # 自动修复(如果配置了)
198
+ ${config.autoFix ? `
199
+ if [ -f .eslintrc.js ] || [ -f .eslintrc.json ] || [ -f package.json ]; then
200
+ echo "🔧 尝试自动修复..."
201
+ npx eslint --fix $STAGED_FILES 2>/dev/null || true
202
+
203
+ # 如果有修改,重新添加到暂存区
204
+ MODIFIED_FILES=$(git diff --name-only | grep -E '\\.(js|jsx|ts|tsx|vue)$' || true)
205
+
206
+ if [ -n "$MODIFIED_FILES" ]; then
207
+ echo "📝 添加自动修复的文件..."
208
+ git add $MODIFIED_FILES
209
+ fi
210
+ fi
211
+ ` : ''}
212
+
213
+ echo "✅ 代码质量检查通过"
214
+ exit 0
215
+ `
216
+ }
217
+
218
+ /**
219
+ * 生成 pre-push 钩子内容
220
+ */
221
+ generatePrePushHook(config) {
222
+ return `#!/bin/bash
223
+
224
+ # Code-Simplifier pre-push hook
225
+ # 由 Code-Simplifier 自动生成
226
+
227
+ echo "🔍 正在运行推送前检查..."
228
+
229
+ # 获取要推送的分支和远程
230
+ read -r LOCAL_REF LOCAL_SHA REMOTE_REF REMOTE_SHA
231
+
232
+ if [ "$REMOTE_SHA" = "0000000000000000000000000000000000000000" ]; then
233
+ # 新分支,检查所有文件
234
+ BRANCH_FILES=$(git diff $LOCAL_SHA --name-only | grep -E '\\.(js|jsx|ts|tsx|vue)$' || true)
235
+ else
236
+ # 更新分支
237
+ BRANCH_FILES=$(git diff $REMOTE_SHA..$LOCAL_SHA --name-only | grep -E '\\.(js|jsx|ts|tsx|vue)$' || true)
238
+ fi
239
+
240
+ if [ -z "$BRANCH_FILES" ]; then
241
+ echo "✓ 没有需要检查的代码文件"
242
+ exit 0
243
+ fi
244
+
245
+ echo "📝 检查分支: $(git rev-parse --abbrev-ref HEAD)"
246
+
247
+ # 运行全面质量检查
248
+ if command -v code-simplifier &> /dev/null; then
249
+ npx code-simplifier quality --threshold ${config.threshold}
250
+ else
251
+ npx code-simplifier quality --threshold ${config.threshold}
252
+ fi
253
+
254
+ QUALITY_EXIT_CODE=$?
255
+
256
+ if [ $QUALITY_EXIT_CODE -ne 0 ]; then
257
+ echo ""
258
+ echo "❌ 代码质量检查失败!"
259
+ echo "请修复问题后再推送,或使用 --no-verify 跳过检查"
260
+ exit 1
261
+ fi
262
+
263
+ # 运行完整工作流(可选)
264
+ if [ "$1" = "--full-check" ]; then
265
+ echo "🔄 运行完整质量检查工作流..."
266
+ npx code-simplifier workflow --all
267
+ WORKFLOW_EXIT_CODE=$?
268
+
269
+ if [ $WORKFLOW_EXIT_CODE -ne 0 ]; then
270
+ echo ""
271
+ echo "❌ 完整工作流检查失败!"
272
+ exit 1
273
+ fi
274
+ fi
275
+
276
+ echo "✅ 推送前检查通过"
277
+ exit 0
278
+ `
279
+ }
280
+
281
+ /**
282
+ * 卸载钩子
283
+ */
284
+ async uninstall(options = {}) {
285
+ console.log(chalk.blue.bold('\n🗑️ 卸载 Git 钩子'))
286
+
287
+ const hooks = [
288
+ { name: 'pre-commit', path: path.join(this.hooksDir, 'pre-commit') },
289
+ { name: 'pre-push', path: path.join(this.hooksDir, 'pre-push') }
290
+ ]
291
+
292
+ for (const hook of hooks) {
293
+ if (await fs.pathExists(hook.path)) {
294
+ await fs.remove(hook.path)
295
+ console.log(chalk.green(`✓ ${hook.name} 钩子已卸载`))
296
+ }
297
+ }
298
+
299
+ // 删除配置文件
300
+ if (await fs.pathExists('.code-simplifier/hooks-config.json')) {
301
+ await fs.remove('.code-simplifier/hooks-config.json')
302
+ }
303
+
304
+ console.log(chalk.green('\n✅ Git 钩子卸载完成'))
305
+ }
306
+
307
+ /**
308
+ * 列出钩子
309
+ */
310
+ async list() {
311
+ console.log(chalk.cyan.bold('\n📋 已安装的 Git 钩子'))
312
+ console.log(chalk.gray('='.repeat(50)))
313
+
314
+ const hooks = [
315
+ { name: 'pre-commit', path: path.join(this.hooksDir, 'pre-commit') },
316
+ { name: 'pre-push', path: path.join(this.hooksDir, 'pre-push') }
317
+ ]
318
+
319
+ let installedCount = 0
320
+ for (const hook of hooks) {
321
+ if (await fs.pathExists(hook.path)) {
322
+ console.log(chalk.green(`✓ ${hook.name} - 已安装`))
323
+ installedCount++
324
+ } else {
325
+ console.log(chalk.gray(`- ${hook.name} - 未安装`))
326
+ }
327
+ }
328
+
329
+ if (installedCount > 0) {
330
+ console.log(chalk.cyan(`\n总计: ${installedCount}/${hooks.length} 个钩子已安装`))
331
+ } else {
332
+ console.log(chalk.gray('\n没有安装任何钩子'))
333
+ }
334
+
335
+ // 显示配置
336
+ if (await fs.pathExists('.code-simplifier/hooks-config.json')) {
337
+ const config = await fs.readJson('.code-simplifier/hooks-config.json')
338
+ console.log(chalk.cyan('\n配置:'))
339
+ console.log(chalk.gray(` 质量阈值: ${config.threshold}`))
340
+ console.log(chalk.gray(` ESLint: ${config.eslint ? '启用' : '禁用'}`))
341
+ console.log(chalk.gray(` 自动修复: ${config.autoFix ? '启用' : '禁用'}`))
342
+ }
343
+ }
344
+
345
+ /**
346
+ * 检查是否为 Git 仓库
347
+ */
348
+ async isGitRepository() {
349
+ return await fs.pathExists(this.gitDir)
350
+ }
351
+ }
352
+
353
+ module.exports = new GitHooks()
package/lib/master.js CHANGED
@@ -354,6 +354,123 @@ function isSuperAdmin(data) {
354
354
 
355
355
  console.log('')
356
356
  }
357
+
358
+ /**
359
+ * 增强质量分析(集成 ESLint、多语言、自动修复)
360
+ */
361
+ async enhancedQualityAnalysis(options = {}) {
362
+ console.log(chalk.cyan.bold('\n🔍 增强质量分析'))
363
+ console.log(chalk.gray('='.repeat(70)))
364
+
365
+ const {
366
+ dir = 'src',
367
+ eslint = true,
368
+ multilang = true,
369
+ autofix = false
370
+ } = options
371
+
372
+ const results = {}
373
+
374
+ // 1. 基础质量分析
375
+ console.log(chalk.blue('\n1️⃣ 基础质量分析'))
376
+ const analyzer = require('./quality-analyzer')
377
+ const analysisResult = await analyzer.runQuickCheck()
378
+ results.basic = analysisResult
379
+
380
+ // 2. ESLint 分析(如果启用)
381
+ if (eslint) {
382
+ console.log(chalk.blue('\n2️⃣ ESLint 分析'))
383
+ try {
384
+ const eslintIntegration = require('./eslint-integration')
385
+ const eslintResult = await eslintIntegration.runAnalysis('.', {
386
+ format: 'json',
387
+ fix: autofix
388
+ })
389
+
390
+ if (eslintResult.success) {
391
+ results.eslint = eslintIntegration.integrateWithQualityAnalysis(eslintResult, analysisResult)
392
+ console.log(chalk.green(`✓ ESLint: ${eslintResult.summary.totalErrors} 错误, ${eslintResult.summary.totalWarnings} 警告`))
393
+ } else {
394
+ console.log(chalk.yellow('⚠ ESLint 未配置或不可用'))
395
+ }
396
+ } catch (error) {
397
+ console.log(chalk.gray(`⚠ ESLint 分析失败: ${error.message}`))
398
+ }
399
+ }
400
+
401
+ // 3. 多语言分析(如果启用)
402
+ if (multilang) {
403
+ console.log(chalk.blue('\n3️⃣ 多语言分析'))
404
+ try {
405
+ const multiLang = require('./multi-language-analyzer')
406
+ const langResult = await multiLang.analyze('.')
407
+
408
+ if (langResult.success) {
409
+ results.languages = langResult.languages
410
+ console.log(chalk.green(`✓ 检测到 ${langResult.languages.length} 种语言`))
411
+ langResult.languages.forEach(lang => {
412
+ console.log(chalk.gray(` - ${lang.name} (${lang.confidence})`))
413
+ })
414
+ }
415
+ } catch (error) {
416
+ console.log(chalk.gray(`⚠ 多语言分析失败: ${error.message}`))
417
+ }
418
+ }
419
+
420
+ // 4. 自动修复(如果启用)
421
+ if (autofix) {
422
+ console.log(chalk.blue('\n4️⃣ 自动修复'))
423
+ try {
424
+ const autoFix = require('./auto-fix')
425
+ const fixResult = await autoFix.run({
426
+ dir,
427
+ dryRun: false
428
+ })
429
+
430
+ if (fixResult.success) {
431
+ results.fixes = fixResult
432
+ console.log(chalk.green(`✓ 已修复 ${fixResult.applied} 个问题`))
433
+ }
434
+ } catch (error) {
435
+ console.log(chalk.gray(`⚠ 自动修复失败: ${error.message}`))
436
+ }
437
+ }
438
+
439
+ // 生成综合报告
440
+ console.log(chalk.cyan('\n📊 综合结果'))
441
+ const finalScore = results.eslint?.score || results.basic.score
442
+ console.log(chalk.cyan(` 最终评分: ${finalScore}/100`))
443
+ console.log(chalk.cyan(` 问题总数: ${results.basic.totalIssues}`))
444
+ if (results.eslint) {
445
+ console.log(chalk.red(` ESLint错误: ${results.eslint.eslint.totalErrors}`))
446
+ console.log(chalk.yellow(` ESLint警告: ${results.eslint.eslint.totalWarnings}`))
447
+ }
448
+
449
+ return {
450
+ success: true,
451
+ results,
452
+ score: finalScore
453
+ }
454
+ }
455
+
456
+ /**
457
+ * Git 钩子管理
458
+ */
459
+ async manageGitHooks(options = {}) {
460
+ const gitHooks = require('./git-hooks')
461
+ return await gitHooks.run(options)
462
+ }
463
+
464
+ /**
465
+ * 安装 Git 钩子
466
+ */
467
+ async installGitHooks(options = {}) {
468
+ console.log(chalk.cyan.bold('\n🔧 安装 Git 钩子'))
469
+ console.log(chalk.gray('='.repeat(70)))
470
+
471
+ const gitHooks = require('./git-hooks')
472
+ return await gitHooks.install(options)
473
+ }
357
474
  }
358
475
 
359
476
  module.exports = new ContinuousImprovementMaster()