code-abyss 1.5.1
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/LICENSE +21 -0
- package/README.md +197 -0
- package/bin/install.js +193 -0
- package/bin/uninstall.js +42 -0
- package/config/AGENTS.md +247 -0
- package/config/CLAUDE.md +207 -0
- package/config/settings.example.json +27 -0
- package/output-styles/abyss-cultivator.md +399 -0
- package/package.json +41 -0
- package/skills/SKILL.md +115 -0
- package/skills/ai/SKILL.md +29 -0
- package/skills/ai/agent-dev.md +242 -0
- package/skills/ai/llm-security.md +288 -0
- package/skills/architecture/SKILL.md +41 -0
- package/skills/architecture/api-design.md +225 -0
- package/skills/architecture/caching.md +299 -0
- package/skills/architecture/cloud-native.md +285 -0
- package/skills/architecture/compliance.md +299 -0
- package/skills/architecture/data-security.md +184 -0
- package/skills/architecture/message-queue.md +329 -0
- package/skills/architecture/security-arch.md +210 -0
- package/skills/development/SKILL.md +43 -0
- package/skills/development/cpp.md +246 -0
- package/skills/development/go.md +323 -0
- package/skills/development/java.md +277 -0
- package/skills/development/python.md +288 -0
- package/skills/development/rust.md +313 -0
- package/skills/development/shell.md +313 -0
- package/skills/development/typescript.md +277 -0
- package/skills/devops/SKILL.md +36 -0
- package/skills/devops/cost-optimization.md +272 -0
- package/skills/devops/database.md +217 -0
- package/skills/devops/devsecops.md +198 -0
- package/skills/devops/git-workflow.md +181 -0
- package/skills/devops/observability.md +280 -0
- package/skills/devops/performance.md +273 -0
- package/skills/devops/testing.md +186 -0
- package/skills/gen-docs/SKILL.md +114 -0
- package/skills/gen-docs/scripts/doc_generator.py +491 -0
- package/skills/multi-agent/SKILL.md +268 -0
- package/skills/run_skill.py +88 -0
- package/skills/security/SKILL.md +51 -0
- package/skills/security/blue-team.md +379 -0
- package/skills/security/code-audit.md +265 -0
- package/skills/security/pentest.md +226 -0
- package/skills/security/red-team.md +321 -0
- package/skills/security/threat-intel.md +322 -0
- package/skills/security/vuln-research.md +369 -0
- package/skills/tests/README.md +225 -0
- package/skills/tests/SUMMARY.md +362 -0
- package/skills/tests/__init__.py +3 -0
- package/skills/tests/test_change_analyzer.py +558 -0
- package/skills/tests/test_doc_generator.py +538 -0
- package/skills/tests/test_module_scanner.py +376 -0
- package/skills/tests/test_quality_checker.py +516 -0
- package/skills/tests/test_security_scanner.py +426 -0
- package/skills/verify-change/SKILL.md +138 -0
- package/skills/verify-change/scripts/change_analyzer.py +529 -0
- package/skills/verify-module/SKILL.md +125 -0
- package/skills/verify-module/scripts/module_scanner.py +321 -0
- package/skills/verify-quality/SKILL.md +158 -0
- package/skills/verify-quality/scripts/quality_checker.py +481 -0
- package/skills/verify-security/SKILL.md +141 -0
- package/skills/verify-security/scripts/security_scanner.py +368 -0
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
模块结构扫描器
|
|
4
|
+
检测模块完整性:目录结构、必需文档、代码组织
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import os
|
|
8
|
+
import sys
|
|
9
|
+
import json
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
from dataclasses import dataclass, field
|
|
12
|
+
from typing import List, Dict, Optional
|
|
13
|
+
from enum import Enum
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class Severity(Enum):
|
|
17
|
+
ERROR = "error"
|
|
18
|
+
WARNING = "warning"
|
|
19
|
+
INFO = "info"
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@dataclass
|
|
23
|
+
class Issue:
|
|
24
|
+
severity: Severity
|
|
25
|
+
message: str
|
|
26
|
+
path: Optional[str] = None
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@dataclass
|
|
30
|
+
class ScanResult:
|
|
31
|
+
module_path: str
|
|
32
|
+
issues: List[Issue] = field(default_factory=list)
|
|
33
|
+
structure: Dict = field(default_factory=dict)
|
|
34
|
+
|
|
35
|
+
@property
|
|
36
|
+
def passed(self) -> bool:
|
|
37
|
+
return not any(i.severity == Severity.ERROR for i in self.issues)
|
|
38
|
+
|
|
39
|
+
@property
|
|
40
|
+
def error_count(self) -> int:
|
|
41
|
+
return sum(1 for i in self.issues if i.severity == Severity.ERROR)
|
|
42
|
+
|
|
43
|
+
@property
|
|
44
|
+
def warning_count(self) -> int:
|
|
45
|
+
return sum(1 for i in self.issues if i.severity == Severity.WARNING)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
REQUIRED_FILES = {
|
|
49
|
+
"README.md": "模块说明文档",
|
|
50
|
+
"DESIGN.md": "设计决策文档",
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
RECOMMENDED_DIRS = {
|
|
54
|
+
"src": "源代码目录",
|
|
55
|
+
"tests": "测试目录",
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
ALTERNATIVE_SRC_DIRS = ["src", "lib", "pkg", "internal", "cmd", "app"]
|
|
59
|
+
ALTERNATIVE_TEST_DIRS = ["tests", "test", "__tests__", "spec"]
|
|
60
|
+
ROOT_SCRIPT_FILES = {
|
|
61
|
+
"install.sh",
|
|
62
|
+
"uninstall.sh",
|
|
63
|
+
"install.ps1",
|
|
64
|
+
"uninstall.ps1",
|
|
65
|
+
"Dockerfile",
|
|
66
|
+
"Makefile",
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def scan_module(path: str) -> ScanResult:
|
|
71
|
+
"""扫描模块完整性"""
|
|
72
|
+
module_path = Path(path).resolve()
|
|
73
|
+
result = ScanResult(module_path=str(module_path))
|
|
74
|
+
|
|
75
|
+
if not module_path.exists():
|
|
76
|
+
result.issues.append(Issue(
|
|
77
|
+
severity=Severity.ERROR,
|
|
78
|
+
message=f"路径不存在: {module_path}"
|
|
79
|
+
))
|
|
80
|
+
return result
|
|
81
|
+
|
|
82
|
+
if not module_path.is_dir():
|
|
83
|
+
result.issues.append(Issue(
|
|
84
|
+
severity=Severity.ERROR,
|
|
85
|
+
message=f"不是目录: {module_path}"
|
|
86
|
+
))
|
|
87
|
+
return result
|
|
88
|
+
|
|
89
|
+
# 扫描目录结构
|
|
90
|
+
result.structure = scan_structure(module_path)
|
|
91
|
+
|
|
92
|
+
# 检查必需文档
|
|
93
|
+
check_required_files(module_path, result)
|
|
94
|
+
|
|
95
|
+
# 检查源码目录
|
|
96
|
+
check_source_dirs(module_path, result)
|
|
97
|
+
|
|
98
|
+
# 检查测试目录
|
|
99
|
+
check_test_dirs(module_path, result)
|
|
100
|
+
|
|
101
|
+
# 检查文档质量
|
|
102
|
+
check_doc_quality(module_path, result)
|
|
103
|
+
|
|
104
|
+
return result
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def scan_structure(path: Path, depth: int = 3) -> Dict:
|
|
108
|
+
"""递归扫描目录结构"""
|
|
109
|
+
structure = {"name": path.name, "type": "dir", "children": []}
|
|
110
|
+
|
|
111
|
+
if depth <= 0:
|
|
112
|
+
return structure
|
|
113
|
+
|
|
114
|
+
try:
|
|
115
|
+
for item in sorted(path.iterdir()):
|
|
116
|
+
if item.name.startswith('.'):
|
|
117
|
+
continue
|
|
118
|
+
if item.is_file():
|
|
119
|
+
structure["children"].append({
|
|
120
|
+
"name": item.name,
|
|
121
|
+
"type": "file",
|
|
122
|
+
"size": item.stat().st_size
|
|
123
|
+
})
|
|
124
|
+
elif item.is_dir():
|
|
125
|
+
structure["children"].append(
|
|
126
|
+
scan_structure(item, depth - 1)
|
|
127
|
+
)
|
|
128
|
+
except PermissionError:
|
|
129
|
+
pass
|
|
130
|
+
|
|
131
|
+
return structure
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
def check_required_files(path: Path, result: ScanResult):
|
|
135
|
+
"""检查必需文件"""
|
|
136
|
+
for filename, desc in REQUIRED_FILES.items():
|
|
137
|
+
filepath = path / filename
|
|
138
|
+
if not filepath.exists():
|
|
139
|
+
result.issues.append(Issue(
|
|
140
|
+
severity=Severity.ERROR,
|
|
141
|
+
message=f"缺少必需文档: {filename} ({desc})",
|
|
142
|
+
path=str(filepath)
|
|
143
|
+
))
|
|
144
|
+
elif filepath.stat().st_size < 50:
|
|
145
|
+
result.issues.append(Issue(
|
|
146
|
+
severity=Severity.WARNING,
|
|
147
|
+
message=f"文档内容过少: {filename} (< 50 bytes)",
|
|
148
|
+
path=str(filepath)
|
|
149
|
+
))
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
def check_source_dirs(path: Path, result: ScanResult):
|
|
153
|
+
"""检查源码目录"""
|
|
154
|
+
found = False
|
|
155
|
+
for dirname in ALTERNATIVE_SRC_DIRS:
|
|
156
|
+
if (path / dirname).is_dir():
|
|
157
|
+
found = True
|
|
158
|
+
break
|
|
159
|
+
|
|
160
|
+
# 检查是否有代码文件在根目录
|
|
161
|
+
code_extensions = {'.py', '.go', '.rs', '.ts', '.js', '.java', '.sh', '.ps1'}
|
|
162
|
+
root_code_files = [f for f in path.iterdir()
|
|
163
|
+
if f.is_file() and f.suffix in code_extensions]
|
|
164
|
+
root_script_files = [f for f in path.iterdir() if f.is_file() and f.name in ROOT_SCRIPT_FILES]
|
|
165
|
+
|
|
166
|
+
if root_code_files or root_script_files:
|
|
167
|
+
found = True
|
|
168
|
+
if len(root_code_files) > 5:
|
|
169
|
+
result.issues.append(Issue(
|
|
170
|
+
severity=Severity.WARNING,
|
|
171
|
+
message=f"根目录代码文件过多 ({len(root_code_files)}个),建议整理到 src/ 目录"
|
|
172
|
+
))
|
|
173
|
+
|
|
174
|
+
if not found:
|
|
175
|
+
result.issues.append(Issue(
|
|
176
|
+
severity=Severity.WARNING,
|
|
177
|
+
message="未找到源码目录或代码文件"
|
|
178
|
+
))
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
def check_test_dirs(path: Path, result: ScanResult):
|
|
182
|
+
"""检查测试目录"""
|
|
183
|
+
found = False
|
|
184
|
+
for dirname in ALTERNATIVE_TEST_DIRS:
|
|
185
|
+
if (path / dirname).is_dir():
|
|
186
|
+
found = True
|
|
187
|
+
break
|
|
188
|
+
|
|
189
|
+
# 检查是否有测试文件
|
|
190
|
+
test_patterns = ['test_', '_test.', '.test.', 'spec_', '_spec.']
|
|
191
|
+
for f in path.rglob('*'):
|
|
192
|
+
if f.is_file() and any(p in f.name for p in test_patterns):
|
|
193
|
+
found = True
|
|
194
|
+
break
|
|
195
|
+
|
|
196
|
+
if not found:
|
|
197
|
+
result.issues.append(Issue(
|
|
198
|
+
severity=Severity.WARNING,
|
|
199
|
+
message="未找到测试目录或测试文件"
|
|
200
|
+
))
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
def check_doc_quality(path: Path, result: ScanResult):
|
|
204
|
+
"""检查文档质量"""
|
|
205
|
+
readme = path / "README.md"
|
|
206
|
+
design = path / "DESIGN.md"
|
|
207
|
+
|
|
208
|
+
if readme.exists():
|
|
209
|
+
content = readme.read_text(encoding='utf-8', errors='ignore')
|
|
210
|
+
|
|
211
|
+
# 检查必要章节
|
|
212
|
+
required_sections = ['#'] # 至少有标题
|
|
213
|
+
if not any(s in content for s in required_sections):
|
|
214
|
+
result.issues.append(Issue(
|
|
215
|
+
severity=Severity.WARNING,
|
|
216
|
+
message="README.md 缺少标题",
|
|
217
|
+
path=str(readme)
|
|
218
|
+
))
|
|
219
|
+
|
|
220
|
+
# 检查使用说明
|
|
221
|
+
usage_keywords = ['usage', 'install', '使用', '安装', 'example', '示例']
|
|
222
|
+
if not any(k in content.lower() for k in usage_keywords):
|
|
223
|
+
result.issues.append(Issue(
|
|
224
|
+
severity=Severity.INFO,
|
|
225
|
+
message="README.md 建议添加使用说明或示例",
|
|
226
|
+
path=str(readme)
|
|
227
|
+
))
|
|
228
|
+
|
|
229
|
+
if design.exists():
|
|
230
|
+
content = design.read_text(encoding='utf-8', errors='ignore')
|
|
231
|
+
|
|
232
|
+
# 检查设计决策记录
|
|
233
|
+
decision_keywords = ['决策', 'decision', '选择', 'choice', '权衡', 'trade']
|
|
234
|
+
if not any(k in content.lower() for k in decision_keywords):
|
|
235
|
+
result.issues.append(Issue(
|
|
236
|
+
severity=Severity.INFO,
|
|
237
|
+
message="DESIGN.md 建议记录设计决策和权衡",
|
|
238
|
+
path=str(design)
|
|
239
|
+
))
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
def format_report(result: ScanResult, verbose: bool = False) -> str:
|
|
243
|
+
"""格式化扫描报告"""
|
|
244
|
+
lines = []
|
|
245
|
+
lines.append("=" * 60)
|
|
246
|
+
lines.append("模块完整性扫描报告")
|
|
247
|
+
lines.append("=" * 60)
|
|
248
|
+
lines.append(f"\n模块路径: {result.module_path}")
|
|
249
|
+
lines.append(f"扫描结果: {'✓ 通过' if result.passed else '✗ 未通过'}")
|
|
250
|
+
lines.append(f"错误: {result.error_count} | 警告: {result.warning_count}")
|
|
251
|
+
|
|
252
|
+
if result.issues:
|
|
253
|
+
lines.append("\n" + "-" * 40)
|
|
254
|
+
lines.append("问题列表:")
|
|
255
|
+
lines.append("-" * 40)
|
|
256
|
+
|
|
257
|
+
for issue in result.issues:
|
|
258
|
+
icon = {"error": "✗", "warning": "⚠", "info": "ℹ"}[issue.severity.value]
|
|
259
|
+
lines.append(f" {icon} [{issue.severity.value.upper()}] {issue.message}")
|
|
260
|
+
if issue.path and verbose:
|
|
261
|
+
lines.append(f" 路径: {issue.path}")
|
|
262
|
+
|
|
263
|
+
if verbose and result.structure:
|
|
264
|
+
lines.append("\n" + "-" * 40)
|
|
265
|
+
lines.append("目录结构:")
|
|
266
|
+
lines.append("-" * 40)
|
|
267
|
+
lines.append(format_structure(result.structure))
|
|
268
|
+
|
|
269
|
+
lines.append("\n" + "=" * 60)
|
|
270
|
+
return "\n".join(lines)
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
def format_structure(structure: Dict, indent: int = 0) -> str:
|
|
274
|
+
"""格式化目录结构"""
|
|
275
|
+
lines = []
|
|
276
|
+
prefix = " " * indent
|
|
277
|
+
|
|
278
|
+
if structure["type"] == "dir":
|
|
279
|
+
lines.append(f"{prefix}📁 {structure['name']}/")
|
|
280
|
+
for child in structure.get("children", []):
|
|
281
|
+
lines.append(format_structure(child, indent + 1))
|
|
282
|
+
else:
|
|
283
|
+
size = structure.get("size", 0)
|
|
284
|
+
size_str = f"({size} B)" if size < 1024 else f"({size // 1024} KB)"
|
|
285
|
+
lines.append(f"{prefix}📄 {structure['name']} {size_str}")
|
|
286
|
+
|
|
287
|
+
return "\n".join(lines)
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
def main():
|
|
291
|
+
import argparse
|
|
292
|
+
|
|
293
|
+
parser = argparse.ArgumentParser(description="模块完整性扫描器")
|
|
294
|
+
parser.add_argument("path", nargs="?", default=".", help="模块路径")
|
|
295
|
+
parser.add_argument("-v", "--verbose", action="store_true", help="详细输出")
|
|
296
|
+
parser.add_argument("--json", action="store_true", help="JSON 格式输出")
|
|
297
|
+
|
|
298
|
+
args = parser.parse_args()
|
|
299
|
+
|
|
300
|
+
result = scan_module(args.path)
|
|
301
|
+
|
|
302
|
+
if args.json:
|
|
303
|
+
output = {
|
|
304
|
+
"module_path": result.module_path,
|
|
305
|
+
"passed": result.passed,
|
|
306
|
+
"error_count": result.error_count,
|
|
307
|
+
"warning_count": result.warning_count,
|
|
308
|
+
"issues": [
|
|
309
|
+
{"severity": i.severity.value, "message": i.message, "path": i.path}
|
|
310
|
+
for i in result.issues
|
|
311
|
+
]
|
|
312
|
+
}
|
|
313
|
+
print(json.dumps(output, ensure_ascii=False, indent=2))
|
|
314
|
+
else:
|
|
315
|
+
print(format_report(result, args.verbose))
|
|
316
|
+
|
|
317
|
+
sys.exit(0 if result.passed else 1)
|
|
318
|
+
|
|
319
|
+
|
|
320
|
+
if __name__ == "__main__":
|
|
321
|
+
main()
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: verify-quality
|
|
3
|
+
description: 代码质量校验关卡。检测复杂度、重复代码、命名规范、函数长度等质量指标。当魔尊提到代码质量、复杂度检查、代码异味、重构建议、lint检查、代码规范时使用。在复杂模块、重构完成时自动触发。
|
|
4
|
+
user-invocable: true
|
|
5
|
+
disable-model-invocation: false
|
|
6
|
+
allowed-tools: Bash, Read, Glob
|
|
7
|
+
argument-hint: <扫描路径>
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# ⚖ 校验关卡 · 代码质量
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
## 核心原则
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
代码质量 = 可读性 + 可维护性 + 可测试性
|
|
17
|
+
劣质代码是技术债,技术债是道基裂痕
|
|
18
|
+
复杂度是 bug 的温床
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## 自动检查
|
|
22
|
+
|
|
23
|
+
运行质量检查脚本(跨平台):
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
# 在 skill 目录下运行
|
|
27
|
+
python scripts/quality_checker.py <扫描路径>
|
|
28
|
+
python scripts/quality_checker.py <扫描路径> -v # 详细模式
|
|
29
|
+
python scripts/quality_checker.py <扫描路径> --json # JSON 输出
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## 检测指标
|
|
33
|
+
|
|
34
|
+
### 复杂度指标
|
|
35
|
+
|
|
36
|
+
| 指标 | 阈值 | 超标后果 |
|
|
37
|
+
|------|------|----------|
|
|
38
|
+
| **圈复杂度** | ≤ 10 | 🟠 警告,建议拆分 |
|
|
39
|
+
| **函数长度** | ≤ 50 行 | 🟠 警告,建议拆分 |
|
|
40
|
+
| **文件长度** | ≤ 500 行 | 🟡 提示,考虑拆分 |
|
|
41
|
+
| **参数数量** | ≤ 5 | 🟠 警告,考虑封装 |
|
|
42
|
+
| **嵌套深度** | ≤ 4 | 🟠 警告,建议重构 |
|
|
43
|
+
| **行长度** | ≤ 120 | 🔵 提示 |
|
|
44
|
+
|
|
45
|
+
### 命名规范
|
|
46
|
+
|
|
47
|
+
| 类型 | 规范 | 示例 |
|
|
48
|
+
|------|------|------|
|
|
49
|
+
| **类名** | PascalCase | `UserService`, `HttpClient` |
|
|
50
|
+
| **函数名** | snake_case | `get_user`, `process_data` |
|
|
51
|
+
| **常量** | UPPER_SNAKE | `MAX_RETRY`, `DEFAULT_TIMEOUT` |
|
|
52
|
+
| **变量** | snake_case | `user_id`, `total_count` |
|
|
53
|
+
|
|
54
|
+
### 代码异味
|
|
55
|
+
|
|
56
|
+
| 异味 | 说明 | 严重度 |
|
|
57
|
+
|------|------|--------|
|
|
58
|
+
| 重复代码 | 相似代码块 > 10 行 | 🟠 High |
|
|
59
|
+
| 过长参数列表 | 参数 > 5 个 | 🟡 Medium |
|
|
60
|
+
| 魔法数字 | 未命名的常量 | 🟡 Medium |
|
|
61
|
+
| 死代码 | 未使用的函数/变量 | 🔵 Low |
|
|
62
|
+
| 注释代码 | 被注释的代码块 | 🔵 Low |
|
|
63
|
+
|
|
64
|
+
## 自动触发时机
|
|
65
|
+
|
|
66
|
+
| 场景 | 触发条件 |
|
|
67
|
+
|------|----------|
|
|
68
|
+
| 复杂模块 | 代码行数 > 200 |
|
|
69
|
+
| 重构完成 | 重构任务完成时 |
|
|
70
|
+
| 代码审查 | PR/MR 审查时 |
|
|
71
|
+
| 提交前 | 代码提交前检查 |
|
|
72
|
+
|
|
73
|
+
## 校验流程
|
|
74
|
+
|
|
75
|
+
```
|
|
76
|
+
1. 扫描代码文件
|
|
77
|
+
2. 计算复杂度指标
|
|
78
|
+
3. 检测代码异味
|
|
79
|
+
4. 验证命名规范
|
|
80
|
+
5. 输出质量校验报告
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## 校验报告格式
|
|
84
|
+
|
|
85
|
+
```
|
|
86
|
+
## 代码质量校验报告
|
|
87
|
+
|
|
88
|
+
✓ 通过 | ✗ 未通过
|
|
89
|
+
|
|
90
|
+
### 复杂度指标
|
|
91
|
+
- 平均函数复杂度: N
|
|
92
|
+
- 超标函数数: N
|
|
93
|
+
- 最大文件行数: N
|
|
94
|
+
|
|
95
|
+
### 代码异味
|
|
96
|
+
- 🟠 High: N
|
|
97
|
+
- 🟡 Medium: N
|
|
98
|
+
- 🔵 Low: N
|
|
99
|
+
|
|
100
|
+
### 问题清单
|
|
101
|
+
|
|
102
|
+
| 文件 | 行号 | 类型 | 严重度 | 描述 |
|
|
103
|
+
|------|------|------|--------|------|
|
|
104
|
+
| ... | ... | ... | ... | ... |
|
|
105
|
+
|
|
106
|
+
### 结论
|
|
107
|
+
可交付 / 需重构后交付
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## 重构建议
|
|
111
|
+
|
|
112
|
+
### 降低复杂度
|
|
113
|
+
|
|
114
|
+
```python
|
|
115
|
+
# 🔴 高复杂度 - 道基不稳
|
|
116
|
+
def process(data):
|
|
117
|
+
if condition1:
|
|
118
|
+
if condition2:
|
|
119
|
+
if condition3:
|
|
120
|
+
# 深层嵌套
|
|
121
|
+
pass
|
|
122
|
+
|
|
123
|
+
# ✅ 低复杂度 - 道基稳固
|
|
124
|
+
def process(data):
|
|
125
|
+
if not condition1:
|
|
126
|
+
return
|
|
127
|
+
if not condition2:
|
|
128
|
+
return
|
|
129
|
+
if not condition3:
|
|
130
|
+
return
|
|
131
|
+
# 主逻辑
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### 消除重复
|
|
135
|
+
|
|
136
|
+
```python
|
|
137
|
+
# 🔴 重复代码 - 异端
|
|
138
|
+
def func1():
|
|
139
|
+
# 10行相同逻辑
|
|
140
|
+
pass
|
|
141
|
+
|
|
142
|
+
def func2():
|
|
143
|
+
# 10行相同逻辑
|
|
144
|
+
pass
|
|
145
|
+
|
|
146
|
+
# ✅ 提取公共函数 - 正道
|
|
147
|
+
def common_logic():
|
|
148
|
+
# 公共逻辑
|
|
149
|
+
pass
|
|
150
|
+
|
|
151
|
+
def func1():
|
|
152
|
+
common_logic()
|
|
153
|
+
|
|
154
|
+
def func2():
|
|
155
|
+
common_logic()
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
---
|