code-simplifier 1.0.0 → 1.1.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/README.md +56 -1
- package/bin/code-simplifier.js +73 -1
- package/cypress.config.js +45 -0
- package/jest.config.js +46 -0
- package/lib/auto-fix.js +382 -0
- package/lib/eslint-integration.js +328 -0
- package/lib/git-hooks.js +353 -0
- package/lib/master.js +117 -0
- package/lib/multi-language-analyzer.js +397 -0
- package/package.json +20 -4
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()
|
|
@@ -0,0 +1,397 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Code-Simplifier 多语言分析器
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const fs = require('fs-extra')
|
|
8
|
+
const path = require('path')
|
|
9
|
+
const chalk = require('chalk')
|
|
10
|
+
|
|
11
|
+
class MultiLanguageAnalyzer {
|
|
12
|
+
constructor() {
|
|
13
|
+
this.languageConfigs = {
|
|
14
|
+
javascript: {
|
|
15
|
+
name: 'JavaScript',
|
|
16
|
+
extensions: ['.js', '.jsx'],
|
|
17
|
+
patterns: ['**/*.js', '**/*.jsx'],
|
|
18
|
+
complexityKeywords: ['if', 'for', 'while', 'switch', 'catch', 'try'],
|
|
19
|
+
fileIndicators: ['package.json', '.eslintrc.js']
|
|
20
|
+
},
|
|
21
|
+
typescript: {
|
|
22
|
+
name: 'TypeScript',
|
|
23
|
+
extensions: ['.ts', '.tsx'],
|
|
24
|
+
patterns: ['**/*.ts', '**/*.tsx'],
|
|
25
|
+
complexityKeywords: ['if', 'for', 'while', 'switch', 'catch', 'try'],
|
|
26
|
+
fileIndicators: ['tsconfig.json', '.eslintrc.js']
|
|
27
|
+
},
|
|
28
|
+
python: {
|
|
29
|
+
name: 'Python',
|
|
30
|
+
extensions: ['.py'],
|
|
31
|
+
patterns: ['**/*.py'],
|
|
32
|
+
complexityKeywords: ['if', 'for', 'while', 'try', 'except'],
|
|
33
|
+
fileIndicators: ['requirements.txt', 'setup.py', 'Pipfile']
|
|
34
|
+
},
|
|
35
|
+
java: {
|
|
36
|
+
name: 'Java',
|
|
37
|
+
extensions: ['.java'],
|
|
38
|
+
patterns: ['**/*.java'],
|
|
39
|
+
complexityKeywords: ['if', 'for', 'while', 'switch', 'try', 'catch'],
|
|
40
|
+
fileIndicators: ['pom.xml', 'build.gradle', 'build.xml']
|
|
41
|
+
},
|
|
42
|
+
csharp: {
|
|
43
|
+
name: 'C#',
|
|
44
|
+
extensions: ['.cs'],
|
|
45
|
+
patterns: ['**/*.cs'],
|
|
46
|
+
complexityKeywords: ['if', 'for', 'while', 'switch', 'try', 'catch'],
|
|
47
|
+
fileIndicators: ['*.csproj', '*.sln']
|
|
48
|
+
},
|
|
49
|
+
cpp: {
|
|
50
|
+
name: 'C++',
|
|
51
|
+
extensions: ['.cpp', '.cc', '.cxx', '.h', '.hpp'],
|
|
52
|
+
patterns: ['**/*.cpp', '**/*.cc', '**/*.cxx', '**/*.h', '**/*.hpp'],
|
|
53
|
+
complexityKeywords: ['if', 'for', 'while', 'switch', 'try', 'catch'],
|
|
54
|
+
fileIndicators: ['CMakeLists.txt', 'Makefile']
|
|
55
|
+
},
|
|
56
|
+
php: {
|
|
57
|
+
name: 'PHP',
|
|
58
|
+
extensions: ['.php'],
|
|
59
|
+
patterns: ['**/*.php'],
|
|
60
|
+
complexityKeywords: ['if', 'for', 'while', 'switch', 'try', 'catch'],
|
|
61
|
+
fileIndicators: ['composer.json', '*.phpproj']
|
|
62
|
+
},
|
|
63
|
+
ruby: {
|
|
64
|
+
name: 'Ruby',
|
|
65
|
+
extensions: ['.rb'],
|
|
66
|
+
patterns: ['**/*.rb'],
|
|
67
|
+
complexityKeywords: ['if', 'unless', 'while', 'for', 'case', 'begin'],
|
|
68
|
+
fileIndicators: ['Gemfile', '*.gemspec']
|
|
69
|
+
},
|
|
70
|
+
go: {
|
|
71
|
+
name: 'Go',
|
|
72
|
+
extensions: ['.go'],
|
|
73
|
+
patterns: ['**/*.go'],
|
|
74
|
+
complexityKeywords: ['if', 'for', 'switch', 'select'],
|
|
75
|
+
fileIndicators: ['go.mod', 'go.sum']
|
|
76
|
+
},
|
|
77
|
+
rust: {
|
|
78
|
+
name: 'Rust',
|
|
79
|
+
extensions: ['.rs'],
|
|
80
|
+
patterns: ['**/*.rs'],
|
|
81
|
+
complexityKeywords: ['if', 'for', 'while', 'match', 'try'],
|
|
82
|
+
fileIndicators: ['Cargo.toml', 'Cargo.lock']
|
|
83
|
+
},
|
|
84
|
+
kotlin: {
|
|
85
|
+
name: 'Kotlin',
|
|
86
|
+
extensions: ['.kt', '.kts'],
|
|
87
|
+
patterns: ['**/*.kt', '**/*.kts'],
|
|
88
|
+
complexityKeywords: ['if', 'for', 'while', 'when', 'try', 'catch'],
|
|
89
|
+
fileIndicators: ['build.gradle.kts', 'pom.xml']
|
|
90
|
+
},
|
|
91
|
+
swift: {
|
|
92
|
+
name: 'Swift',
|
|
93
|
+
extensions: ['.swift'],
|
|
94
|
+
patterns: ['**/*.swift'],
|
|
95
|
+
complexityKeywords: ['if', 'for', 'while', 'switch', 'guard'],
|
|
96
|
+
fileIndicators: ['Package.swift', '*.xcodeproj']
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* 检测项目语言
|
|
103
|
+
*/
|
|
104
|
+
async detectLanguage(projectDir) {
|
|
105
|
+
const detectedLanguages = []
|
|
106
|
+
|
|
107
|
+
for (const [langKey, config] of Object.entries(this.languageConfigs)) {
|
|
108
|
+
// 检查文件指示符
|
|
109
|
+
for (const indicator of config.fileIndicators) {
|
|
110
|
+
const matches = await this.findFiles(projectDir, indicator)
|
|
111
|
+
if (matches.length > 0) {
|
|
112
|
+
detectedLanguages.push({
|
|
113
|
+
key: langKey,
|
|
114
|
+
name: config.name,
|
|
115
|
+
confidence: 'high',
|
|
116
|
+
matches: matches.length,
|
|
117
|
+
indicator
|
|
118
|
+
})
|
|
119
|
+
break
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// 检查文件扩展名
|
|
125
|
+
for (const [langKey, config] of Object.entries(this.languageConfigs)) {
|
|
126
|
+
const files = await this.scanFiles(projectDir, config.patterns)
|
|
127
|
+
if (files.length > 0) {
|
|
128
|
+
// 检查是否已经检测到
|
|
129
|
+
const alreadyDetected = detectedLanguages.find(l => l.key === langKey)
|
|
130
|
+
if (!alreadyDetected) {
|
|
131
|
+
detectedLanguages.push({
|
|
132
|
+
key: langKey,
|
|
133
|
+
name: config.name,
|
|
134
|
+
confidence: files.length > 10 ? 'medium' : 'low',
|
|
135
|
+
files: files.length
|
|
136
|
+
})
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// 按置信度排序
|
|
142
|
+
return detectedLanguages.sort((a, b) => {
|
|
143
|
+
const confidenceOrder = { high: 3, medium: 2, low: 1 }
|
|
144
|
+
return confidenceOrder[b.confidence] - confidenceOrder[a.confidence]
|
|
145
|
+
})
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* 扫描文件
|
|
150
|
+
*/
|
|
151
|
+
async scanFiles(projectDir, patterns) {
|
|
152
|
+
const files = []
|
|
153
|
+
|
|
154
|
+
for (const pattern of patterns) {
|
|
155
|
+
const glob = require('glob')
|
|
156
|
+
const matches = await new Promise((resolve, reject) => {
|
|
157
|
+
try {
|
|
158
|
+
glob(pattern, {
|
|
159
|
+
cwd: projectDir,
|
|
160
|
+
ignore: ['node_modules/**', 'dist/**', 'build/**', 'vendor/**', '.git/**'],
|
|
161
|
+
nodir: true
|
|
162
|
+
}, (err, matches) => {
|
|
163
|
+
if (err) resolve([])
|
|
164
|
+
else resolve(matches)
|
|
165
|
+
})
|
|
166
|
+
} catch (e) {
|
|
167
|
+
resolve([])
|
|
168
|
+
}
|
|
169
|
+
})
|
|
170
|
+
files.push(...matches)
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
return files
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* 查找文件
|
|
178
|
+
*/
|
|
179
|
+
async findFiles(projectDir, pattern) {
|
|
180
|
+
const glob = require('glob')
|
|
181
|
+
return await new Promise((resolve) => {
|
|
182
|
+
try {
|
|
183
|
+
glob(pattern, {
|
|
184
|
+
cwd: projectDir,
|
|
185
|
+
ignore: ['node_modules/**', 'dist/**', 'build/**', 'vendor/**', '.git/**']
|
|
186
|
+
}, (err, matches) => {
|
|
187
|
+
resolve(err ? [] : matches)
|
|
188
|
+
})
|
|
189
|
+
} catch (e) {
|
|
190
|
+
resolve([])
|
|
191
|
+
}
|
|
192
|
+
})
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* 分析代码
|
|
197
|
+
*/
|
|
198
|
+
async analyze(projectDir, options = {}) {
|
|
199
|
+
console.log(chalk.blue.bold('\n🌐 多语言代码分析'))
|
|
200
|
+
console.log(chalk.gray('='.repeat(70)))
|
|
201
|
+
|
|
202
|
+
const detected = await this.detectLanguage(projectDir)
|
|
203
|
+
|
|
204
|
+
if (detected.length === 0) {
|
|
205
|
+
console.log(chalk.yellow('⚠️ 未检测到支持的编程语言'))
|
|
206
|
+
return {
|
|
207
|
+
success: false,
|
|
208
|
+
message: 'No supported languages detected',
|
|
209
|
+
languages: []
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
console.log(chalk.cyan(`\n📋 检测到 ${detected.length} 种语言:`))
|
|
214
|
+
detected.forEach(lang => {
|
|
215
|
+
const confidence = lang.confidence === 'high' ? chalk.green('✓') :
|
|
216
|
+
lang.confidence === 'medium' ? chalk.yellow('⚠') : chalk.gray('?')
|
|
217
|
+
console.log(` ${confidence} ${lang.name} (${lang.confidence})`)
|
|
218
|
+
})
|
|
219
|
+
|
|
220
|
+
// 分析每种语言
|
|
221
|
+
const results = []
|
|
222
|
+
for (const lang of detected) {
|
|
223
|
+
console.log(chalk.cyan(`\n分析 ${lang.name}...`))
|
|
224
|
+
const result = await this.analyzeLanguage(projectDir, lang)
|
|
225
|
+
results.push(result)
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
return {
|
|
229
|
+
success: true,
|
|
230
|
+
languages: detected,
|
|
231
|
+
results
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* 分析特定语言
|
|
237
|
+
*/
|
|
238
|
+
async analyzeLanguage(projectDir, language) {
|
|
239
|
+
const config = this.languageConfigs[language.key]
|
|
240
|
+
const files = await this.scanFiles(projectDir, config.patterns)
|
|
241
|
+
|
|
242
|
+
if (files.length === 0) {
|
|
243
|
+
return {
|
|
244
|
+
language: language.name,
|
|
245
|
+
files: 0,
|
|
246
|
+
lines: 0,
|
|
247
|
+
complexity: 0,
|
|
248
|
+
issues: []
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
let totalLines = 0
|
|
253
|
+
let totalComplexity = 0
|
|
254
|
+
let issues = []
|
|
255
|
+
|
|
256
|
+
// 分析前 100 个文件(避免性能问题)
|
|
257
|
+
const filesToAnalyze = files.slice(0, 100)
|
|
258
|
+
|
|
259
|
+
for (const file of filesToAnalyze) {
|
|
260
|
+
const filePath = path.join(projectDir, file)
|
|
261
|
+
|
|
262
|
+
try {
|
|
263
|
+
const content = await fs.readFile(filePath, 'utf8')
|
|
264
|
+
const lines = content.split('\n').length
|
|
265
|
+
totalLines += lines
|
|
266
|
+
|
|
267
|
+
// 计算复杂度
|
|
268
|
+
const complexity = this.calculateComplexity(content, config.complexityKeywords)
|
|
269
|
+
totalComplexity += complexity
|
|
270
|
+
|
|
271
|
+
// 检查代码问题
|
|
272
|
+
const fileIssues = this.checkCodeIssues(content, file, config)
|
|
273
|
+
issues.push(...fileIssues)
|
|
274
|
+
} catch (error) {
|
|
275
|
+
// 忽略无法读取的文件
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
const avgComplexity = filesToAnalyze.length > 0 ? totalComplexity / filesToAnalyze.length : 0
|
|
280
|
+
|
|
281
|
+
return {
|
|
282
|
+
language: language.name,
|
|
283
|
+
files: filesToAnalyze.length,
|
|
284
|
+
lines: totalLines,
|
|
285
|
+
avgComplexity: Math.round(avgComplexity),
|
|
286
|
+
totalComplexity,
|
|
287
|
+
issues: issues.slice(0, 50) // 最多显示 50 个问题
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* 计算复杂度
|
|
293
|
+
*/
|
|
294
|
+
calculateComplexity(code, keywords) {
|
|
295
|
+
let complexity = 1
|
|
296
|
+
|
|
297
|
+
for (const keyword of keywords) {
|
|
298
|
+
const regex = new RegExp(`\\b${keyword}\\b`, 'g')
|
|
299
|
+
const matches = code.match(regex)
|
|
300
|
+
if (matches) {
|
|
301
|
+
complexity += matches.length
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
return complexity
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
/**
|
|
309
|
+
* 检查代码问题
|
|
310
|
+
*/
|
|
311
|
+
checkCodeIssues(code, filePath, config) {
|
|
312
|
+
const issues = []
|
|
313
|
+
const lines = code.split('\n')
|
|
314
|
+
|
|
315
|
+
lines.forEach((line, index) => {
|
|
316
|
+
const lineNumber = index + 1
|
|
317
|
+
|
|
318
|
+
// 检查长函数(超过 100 行)
|
|
319
|
+
if (lineNumber === 100) {
|
|
320
|
+
issues.push({
|
|
321
|
+
file: filePath,
|
|
322
|
+
line: lineNumber,
|
|
323
|
+
severity: 'warning',
|
|
324
|
+
message: 'Function or file exceeds 100 lines',
|
|
325
|
+
type: 'complexity'
|
|
326
|
+
})
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
// 检查 TODO 注释
|
|
330
|
+
if (line.includes('TODO') || line.includes('FIXME')) {
|
|
331
|
+
issues.push({
|
|
332
|
+
file: filePath,
|
|
333
|
+
line: lineNumber,
|
|
334
|
+
severity: 'warning',
|
|
335
|
+
message: 'Contains TODO/FIXME comment',
|
|
336
|
+
type: 'documentation'
|
|
337
|
+
})
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
// 检查 console.log(JavaScript/TypeScript)
|
|
341
|
+
if (config.name.includes('JavaScript') || config.name.includes('TypeScript')) {
|
|
342
|
+
if (line.includes('console.log') || line.includes('console.error')) {
|
|
343
|
+
issues.push({
|
|
344
|
+
file: filePath,
|
|
345
|
+
line: lineNumber,
|
|
346
|
+
severity: 'warning',
|
|
347
|
+
message: 'Contains console statement',
|
|
348
|
+
type: 'debug'
|
|
349
|
+
})
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
})
|
|
353
|
+
|
|
354
|
+
return issues
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
/**
|
|
358
|
+
* 生成多语言报告
|
|
359
|
+
*/
|
|
360
|
+
generateReport(analysisResult) {
|
|
361
|
+
const timestamp = new Date().toLocaleString()
|
|
362
|
+
|
|
363
|
+
let report = `# 多语言代码质量分析报告\n\n`
|
|
364
|
+
report += `**生成时间**: ${timestamp}\n\n`
|
|
365
|
+
report += `## 检测到的语言\n\n`
|
|
366
|
+
|
|
367
|
+
analysisResult.results.forEach(result => {
|
|
368
|
+
report += `### ${result.language}\n\n`
|
|
369
|
+
report += `- 文件数: ${result.files}\n`
|
|
370
|
+
report += `- 代码行数: ${result.lines}\n`
|
|
371
|
+
report += `- 平均复杂度: ${result.avgComplexity}\n`
|
|
372
|
+
report += `- 问题数: ${result.issues.length}\n\n`
|
|
373
|
+
})
|
|
374
|
+
|
|
375
|
+
report += `## 问题详情\n\n`
|
|
376
|
+
|
|
377
|
+
let allIssues = []
|
|
378
|
+
analysisResult.results.forEach(result => {
|
|
379
|
+
allIssues = allIssues.concat(result.issues)
|
|
380
|
+
})
|
|
381
|
+
|
|
382
|
+
if (allIssues.length === 0) {
|
|
383
|
+
report += `✅ 没有发现问题\n\n`
|
|
384
|
+
} else {
|
|
385
|
+
allIssues.forEach(issue => {
|
|
386
|
+
report += `- **${issue.severity.toUpperCase()}**: ${issue.message} in ${issue.file}:${issue.line}\n`
|
|
387
|
+
})
|
|
388
|
+
report += `\n`
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
report += `---\n*由 Code-Simplifier 多语言分析器生成*\n`
|
|
392
|
+
|
|
393
|
+
return report
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
module.exports = new MultiLanguageAnalyzer()
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "code-simplifier",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "Code-Simplifier持续改进系统 -
|
|
3
|
+
"version": "1.1.0",
|
|
4
|
+
"description": "Code-Simplifier持续改进系统 - 自动化的代码质量监控、持续改进和知识管理工具(支持 ESLint、Git 钩子、自动修复、多语言分析、完整测试套件)",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"code-quality",
|
|
7
7
|
"continuous-improvement",
|
|
@@ -9,7 +9,14 @@
|
|
|
9
9
|
"quality-monitor",
|
|
10
10
|
"best-practices",
|
|
11
11
|
"code-simplification",
|
|
12
|
-
"developer-tools"
|
|
12
|
+
"developer-tools",
|
|
13
|
+
"eslint",
|
|
14
|
+
"git-hooks",
|
|
15
|
+
"auto-fix",
|
|
16
|
+
"multi-language",
|
|
17
|
+
"testing",
|
|
18
|
+
"jest",
|
|
19
|
+
"cypress"
|
|
13
20
|
],
|
|
14
21
|
"author": "Claude Code <noreply@anthropic.com>",
|
|
15
22
|
"license": "MIT",
|
|
@@ -29,7 +36,9 @@
|
|
|
29
36
|
"bin/",
|
|
30
37
|
"lib/",
|
|
31
38
|
"README.md",
|
|
32
|
-
"LICENSE"
|
|
39
|
+
"LICENSE",
|
|
40
|
+
"jest.config.js",
|
|
41
|
+
"cypress.config.js"
|
|
33
42
|
],
|
|
34
43
|
"engines": {
|
|
35
44
|
"node": ">=14.0.0"
|
|
@@ -37,7 +46,13 @@
|
|
|
37
46
|
"scripts": {
|
|
38
47
|
"test": "jest",
|
|
39
48
|
"test:watch": "jest --watch",
|
|
49
|
+
"test:unit": "jest tests/unit",
|
|
50
|
+
"test:integration": "jest tests/integration",
|
|
51
|
+
"test:e2e": "cypress run",
|
|
52
|
+
"test:e2e:open": "cypress open",
|
|
53
|
+
"test:coverage": "jest --coverage",
|
|
40
54
|
"lint": "eslint bin lib",
|
|
55
|
+
"lint:fix": "eslint bin lib --fix",
|
|
41
56
|
"prepare": "husky install || echo 'husky not installed, skipping'"
|
|
42
57
|
},
|
|
43
58
|
"dependencies": {
|
|
@@ -52,6 +67,7 @@
|
|
|
52
67
|
},
|
|
53
68
|
"devDependencies": {
|
|
54
69
|
"jest": "^29.7.0",
|
|
70
|
+
"cypress": "^13.6.0",
|
|
55
71
|
"eslint": "^8.57.0",
|
|
56
72
|
"husky": "^8.0.3"
|
|
57
73
|
},
|