vcode-analysis 0.2.0__tar.gz → 0.4.0__tar.gz

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.
Files changed (53) hide show
  1. {vcode_analysis-0.2.0/vcode_analysis.egg-info → vcode_analysis-0.4.0}/PKG-INFO +67 -18
  2. {vcode_analysis-0.2.0 → vcode_analysis-0.4.0}/README.md +66 -17
  3. {vcode_analysis-0.2.0 → vcode_analysis-0.4.0}/analyzers/__init__.py +3 -0
  4. {vcode_analysis-0.2.0 → vcode_analysis-0.4.0}/analyzers/architecture.py +11 -1
  5. vcode_analysis-0.4.0/analyzers/code_review.py +307 -0
  6. vcode_analysis-0.4.0/analyzers/context_builder.py +420 -0
  7. {vcode_analysis-0.2.0 → vcode_analysis-0.4.0}/analyzers/security.py +12 -1
  8. vcode_analysis-0.4.0/cli.py +1190 -0
  9. {vcode_analysis-0.2.0 → vcode_analysis-0.4.0}/core/analyzer.py +46 -13
  10. {vcode_analysis-0.2.0 → vcode_analysis-0.4.0}/docs/USER_MANUAL.md +39 -24
  11. {vcode_analysis-0.2.0 → vcode_analysis-0.4.0}/pyproject.toml +8 -1
  12. {vcode_analysis-0.2.0 → vcode_analysis-0.4.0/vcode_analysis.egg-info}/PKG-INFO +67 -18
  13. {vcode_analysis-0.2.0 → vcode_analysis-0.4.0}/vcode_analysis.egg-info/SOURCES.txt +2 -0
  14. {vcode_analysis-0.2.0 → vcode_analysis-0.4.0}/vcode_analysis.egg-info/top_level.txt +1 -0
  15. vcode_analysis-0.2.0/analyzers/code_review.py +0 -150
  16. {vcode_analysis-0.2.0 → vcode_analysis-0.4.0}/LICENSE +0 -0
  17. {vcode_analysis-0.2.0 → vcode_analysis-0.4.0}/MANIFEST.in +0 -0
  18. {vcode_analysis-0.2.0 → vcode_analysis-0.4.0}/analyzers/directory.py +0 -0
  19. {vcode_analysis-0.2.0 → vcode_analysis-0.4.0}/analyzers/documentation.py +0 -0
  20. {vcode_analysis-0.2.0 → vcode_analysis-0.4.0}/core/__init__.py +0 -0
  21. {vcode_analysis-0.2.0 → vcode_analysis-0.4.0}/core/config.py +0 -0
  22. {vcode_analysis-0.2.0 → vcode_analysis-0.4.0}/core/git_handler.py +0 -0
  23. {vcode_analysis-0.2.0 → vcode_analysis-0.4.0}/core/ignore.py +0 -0
  24. {vcode_analysis-0.2.0 → vcode_analysis-0.4.0}/core/llm_client.py +0 -0
  25. {vcode_analysis-0.2.0 → vcode_analysis-0.4.0}/docs/design/c-parser-design.md +0 -0
  26. {vcode_analysis-0.2.0 → vcode_analysis-0.4.0}/docs/design/code-analysis-tool.md +0 -0
  27. {vcode_analysis-0.2.0 → vcode_analysis-0.4.0}/docs/design/kotlin-parser-design.md +0 -0
  28. {vcode_analysis-0.2.0 → vcode_analysis-0.4.0}/parsers/__init__.py +0 -0
  29. {vcode_analysis-0.2.0 → vcode_analysis-0.4.0}/parsers/c/__init__.py +0 -0
  30. {vcode_analysis-0.2.0 → vcode_analysis-0.4.0}/parsers/c/ast_parser.py +0 -0
  31. {vcode_analysis-0.2.0 → vcode_analysis-0.4.0}/parsers/c/models.py +0 -0
  32. {vcode_analysis-0.2.0 → vcode_analysis-0.4.0}/parsers/c/patterns.py +0 -0
  33. {vcode_analysis-0.2.0 → vcode_analysis-0.4.0}/parsers/c/regex_parser.py +0 -0
  34. {vcode_analysis-0.2.0 → vcode_analysis-0.4.0}/parsers/c_parser.py +0 -0
  35. {vcode_analysis-0.2.0 → vcode_analysis-0.4.0}/parsers/java_parser.py +0 -0
  36. {vcode_analysis-0.2.0 → vcode_analysis-0.4.0}/parsers/javascript_parser.py +0 -0
  37. {vcode_analysis-0.2.0 → vcode_analysis-0.4.0}/parsers/kotlin/__init__.py +0 -0
  38. {vcode_analysis-0.2.0 → vcode_analysis-0.4.0}/parsers/kotlin/ast_parser.py +0 -0
  39. {vcode_analysis-0.2.0 → vcode_analysis-0.4.0}/parsers/kotlin/models.py +0 -0
  40. {vcode_analysis-0.2.0 → vcode_analysis-0.4.0}/parsers/kotlin/patterns.py +0 -0
  41. {vcode_analysis-0.2.0 → vcode_analysis-0.4.0}/parsers/kotlin/regex_parser.py +0 -0
  42. {vcode_analysis-0.2.0 → vcode_analysis-0.4.0}/parsers/kotlin_parser.py +0 -0
  43. {vcode_analysis-0.2.0 → vcode_analysis-0.4.0}/parsers/python_parser.py +0 -0
  44. {vcode_analysis-0.2.0 → vcode_analysis-0.4.0}/parsers/typescript_parser.py +0 -0
  45. {vcode_analysis-0.2.0 → vcode_analysis-0.4.0}/requirements.txt +0 -0
  46. {vcode_analysis-0.2.0 → vcode_analysis-0.4.0}/setup.cfg +0 -0
  47. {vcode_analysis-0.2.0 → vcode_analysis-0.4.0}/tests/test_batch_operations.py +0 -0
  48. {vcode_analysis-0.2.0 → vcode_analysis-0.4.0}/tests/test_c_parser.py +0 -0
  49. {vcode_analysis-0.2.0 → vcode_analysis-0.4.0}/tests/test_kotlin_parser.py +0 -0
  50. {vcode_analysis-0.2.0 → vcode_analysis-0.4.0}/tests/test_security_rules.py +0 -0
  51. {vcode_analysis-0.2.0 → vcode_analysis-0.4.0}/vcode_analysis.egg-info/dependency_links.txt +0 -0
  52. {vcode_analysis-0.2.0 → vcode_analysis-0.4.0}/vcode_analysis.egg-info/entry_points.txt +0 -0
  53. {vcode_analysis-0.2.0 → vcode_analysis-0.4.0}/vcode_analysis.egg-info/requires.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: vcode-analysis
3
- Version: 0.2.0
3
+ Version: 0.4.0
4
4
  Summary: 基于大模型的智能代码分析工具,支持代码审查、文档生成、架构分析和安全扫描
5
5
  Author-email: Wellchang <2483808264@qq.com>
6
6
  License: MIT
@@ -40,7 +40,8 @@ Dynamic: license-file
40
40
 
41
41
  # Code Analysis - 智能代码分析工具
42
42
 
43
- [![Python 3.8+](https://img.shields.io/badge/python-3.8+-blue.svg)](https://www.python.org/downloads/)
43
+ [![PyPI version](https://img.shields.io/pypi/v/vcode-analysis.svg)](https://pypi.org/project/vcode-analysis/)
44
+ [![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
44
45
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
45
46
 
46
47
  基于私有化部署大模型的智能代码分析工具,支持代码审查、文档生成、架构分析和安全扫描。
@@ -53,6 +54,7 @@ Dynamic: license-file
53
54
  | 📝 **文档生成** | 自动生成模块文档、API 文档 |
54
55
  | 🏗️ **架构分析** | 分析项目结构、依赖关系、代码度量 |
55
56
  | 🔒 **安全扫描** | 检测常见安全漏洞和风险代码 |
57
+ | ⚡ **并发分析** | 支持多线程并发分析,默认 5 个线程 |
56
58
  | 📦 **批量操作** | 批量克隆、批量 Git 操作、多仓库管理 |
57
59
  | 📂 **目录分析** | 扫描项目结构、识别技术栈 |
58
60
  | 🌐 **多语言支持** | Python, Java, Kotlin, C, JavaScript, TypeScript 等 |
@@ -62,20 +64,32 @@ Dynamic: license-file
62
64
 
63
65
  ### 安装
64
66
 
67
+ **方式一:从 PyPI 安装(推荐)**
68
+
69
+ ```bash
70
+ # 基础安装
71
+ pip install vcode-analysis
72
+
73
+ # 安装额外解析器支持
74
+ pip install vcode-analysis[parsers]
75
+
76
+ # 安装所有可选依赖
77
+ pip install vcode-analysis[parsers,rich]
78
+ ```
79
+
80
+ **方式二:从源码安装**
81
+
65
82
  ```bash
66
- # 克隆项目
67
83
  git clone https://gitcode.com/wellchang/code-analysis.git
68
84
  cd code-analysis
69
-
70
- # 安装依赖
71
- pip install httpx docopt pyyaml
85
+ pip install -e .
72
86
  ```
73
87
 
74
88
  ### 配置
75
89
 
76
90
  ```bash
77
91
  # 初始化配置文件
78
- python cli.py config --init
92
+ vcode-analysis config --init
79
93
 
80
94
  # 编辑配置文件
81
95
  # ~/.code-analysis/config.yaml
@@ -84,17 +98,20 @@ python cli.py config --init
84
98
  ### 使用
85
99
 
86
100
  ```bash
87
- # 代码审查
88
- python cli.py review ./src
101
+ # 代码审查(结果自动保存到 result/目录名_review_时间戳.md)
102
+ vcode-analysis review ./src
89
103
 
90
104
  # 架构分析
91
- python cli.py arch ./src
105
+ vcode-analysis arch ./src
92
106
 
93
107
  # 安全扫描
94
- python cli.py security ./src --deep
108
+ vcode-analysis security ./src --deep
109
+
110
+ # 使用 10 个并发线程加速分析
111
+ vcode-analysis review ./src --workers 10
95
112
 
96
113
  # 目录扫描
97
- python cli.py scan-dir ./project
114
+ vcode-analysis scan-dir ./project
98
115
  ```
99
116
 
100
117
  ## 📖 命令概览
@@ -161,28 +178,37 @@ code-analysis/
161
178
  ### 代码审查
162
179
 
163
180
  ```bash
164
- # 审查整个项目
165
- python cli.py review ./src --output report.md
181
+ # 审查整个项目(结果保存到 result/src_review_20260320_120000.md)
182
+ vcode-analysis review ./src
183
+
184
+ # 使用 10 个线程加速分析
185
+ vcode-analysis review ./src --workers 10
186
+
187
+ # 自定义输出路径
188
+ vcode-analysis review ./src --output custom_report.md
166
189
 
167
190
  # 审查最新提交
168
- python cli.py review-commit HEAD
191
+ vcode-analysis review-commit HEAD
169
192
  ```
170
193
 
171
194
  ### 安全扫描
172
195
 
173
196
  ```bash
174
197
  # 深度安全扫描
175
- python cli.py security ./src --deep --output security.md
198
+ vcode-analysis security ./src --deep
199
+
200
+ # 快速扫描
201
+ vcode-analysis security ./src
176
202
  ```
177
203
 
178
204
  ### 批量操作
179
205
 
180
206
  ```bash
181
207
  # 批量克隆(从文件读取 URL 列表)
182
- python cli.py batch-clone repos.txt ./projects --parallel
208
+ vcode-analysis batch-clone repos.txt ./projects --parallel
183
209
 
184
210
  # 查看多仓库状态
185
- python cli.py git-status ~/projects
211
+ vcode-analysis git-status ~/projects
186
212
  ```
187
213
 
188
214
  ## ⚙️ 配置示例
@@ -242,11 +268,34 @@ parser = CASTParser()
242
268
  result = parser.parse_file('main.c', mode='fast')
243
269
  ```
244
270
 
271
+ ## 📦 发布到 PyPI
272
+
273
+ ### 发布新版本
274
+
275
+ ```bash
276
+ # 安装发布工具
277
+ pip install build twine
278
+
279
+ # 构建包
280
+ python -m build
281
+
282
+ # 上传到 PyPI
283
+ twine upload dist/*
284
+ ```
285
+
286
+ ### 发布到 TestPyPI(测试)
287
+
288
+ ```bash
289
+ # 上传到 TestPyPI
290
+ twine upload --repository testpypi dist/*
291
+ ```
292
+
245
293
  ## 📄 许可证
246
294
 
247
295
  [MIT License](LICENSE)
248
296
 
249
297
  ## 🔗 链接
250
298
 
299
+ - [PyPI 包地址](https://pypi.org/project/vcode-analysis/)
251
300
  - [项目主页](https://gitcode.com/wellchang/code-analysis)
252
301
  - [问题反馈](https://gitcode.com/wellchang/code-analysis/issues)
@@ -1,6 +1,7 @@
1
1
  # Code Analysis - 智能代码分析工具
2
2
 
3
- [![Python 3.8+](https://img.shields.io/badge/python-3.8+-blue.svg)](https://www.python.org/downloads/)
3
+ [![PyPI version](https://img.shields.io/pypi/v/vcode-analysis.svg)](https://pypi.org/project/vcode-analysis/)
4
+ [![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
4
5
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
6
 
6
7
  基于私有化部署大模型的智能代码分析工具,支持代码审查、文档生成、架构分析和安全扫描。
@@ -13,6 +14,7 @@
13
14
  | 📝 **文档生成** | 自动生成模块文档、API 文档 |
14
15
  | 🏗️ **架构分析** | 分析项目结构、依赖关系、代码度量 |
15
16
  | 🔒 **安全扫描** | 检测常见安全漏洞和风险代码 |
17
+ | ⚡ **并发分析** | 支持多线程并发分析,默认 5 个线程 |
16
18
  | 📦 **批量操作** | 批量克隆、批量 Git 操作、多仓库管理 |
17
19
  | 📂 **目录分析** | 扫描项目结构、识别技术栈 |
18
20
  | 🌐 **多语言支持** | Python, Java, Kotlin, C, JavaScript, TypeScript 等 |
@@ -22,20 +24,32 @@
22
24
 
23
25
  ### 安装
24
26
 
27
+ **方式一:从 PyPI 安装(推荐)**
28
+
29
+ ```bash
30
+ # 基础安装
31
+ pip install vcode-analysis
32
+
33
+ # 安装额外解析器支持
34
+ pip install vcode-analysis[parsers]
35
+
36
+ # 安装所有可选依赖
37
+ pip install vcode-analysis[parsers,rich]
38
+ ```
39
+
40
+ **方式二:从源码安装**
41
+
25
42
  ```bash
26
- # 克隆项目
27
43
  git clone https://gitcode.com/wellchang/code-analysis.git
28
44
  cd code-analysis
29
-
30
- # 安装依赖
31
- pip install httpx docopt pyyaml
45
+ pip install -e .
32
46
  ```
33
47
 
34
48
  ### 配置
35
49
 
36
50
  ```bash
37
51
  # 初始化配置文件
38
- python cli.py config --init
52
+ vcode-analysis config --init
39
53
 
40
54
  # 编辑配置文件
41
55
  # ~/.code-analysis/config.yaml
@@ -44,17 +58,20 @@ python cli.py config --init
44
58
  ### 使用
45
59
 
46
60
  ```bash
47
- # 代码审查
48
- python cli.py review ./src
61
+ # 代码审查(结果自动保存到 result/目录名_review_时间戳.md)
62
+ vcode-analysis review ./src
49
63
 
50
64
  # 架构分析
51
- python cli.py arch ./src
65
+ vcode-analysis arch ./src
52
66
 
53
67
  # 安全扫描
54
- python cli.py security ./src --deep
68
+ vcode-analysis security ./src --deep
69
+
70
+ # 使用 10 个并发线程加速分析
71
+ vcode-analysis review ./src --workers 10
55
72
 
56
73
  # 目录扫描
57
- python cli.py scan-dir ./project
74
+ vcode-analysis scan-dir ./project
58
75
  ```
59
76
 
60
77
  ## 📖 命令概览
@@ -121,28 +138,37 @@ code-analysis/
121
138
  ### 代码审查
122
139
 
123
140
  ```bash
124
- # 审查整个项目
125
- python cli.py review ./src --output report.md
141
+ # 审查整个项目(结果保存到 result/src_review_20260320_120000.md)
142
+ vcode-analysis review ./src
143
+
144
+ # 使用 10 个线程加速分析
145
+ vcode-analysis review ./src --workers 10
146
+
147
+ # 自定义输出路径
148
+ vcode-analysis review ./src --output custom_report.md
126
149
 
127
150
  # 审查最新提交
128
- python cli.py review-commit HEAD
151
+ vcode-analysis review-commit HEAD
129
152
  ```
130
153
 
131
154
  ### 安全扫描
132
155
 
133
156
  ```bash
134
157
  # 深度安全扫描
135
- python cli.py security ./src --deep --output security.md
158
+ vcode-analysis security ./src --deep
159
+
160
+ # 快速扫描
161
+ vcode-analysis security ./src
136
162
  ```
137
163
 
138
164
  ### 批量操作
139
165
 
140
166
  ```bash
141
167
  # 批量克隆(从文件读取 URL 列表)
142
- python cli.py batch-clone repos.txt ./projects --parallel
168
+ vcode-analysis batch-clone repos.txt ./projects --parallel
143
169
 
144
170
  # 查看多仓库状态
145
- python cli.py git-status ~/projects
171
+ vcode-analysis git-status ~/projects
146
172
  ```
147
173
 
148
174
  ## ⚙️ 配置示例
@@ -202,11 +228,34 @@ parser = CASTParser()
202
228
  result = parser.parse_file('main.c', mode='fast')
203
229
  ```
204
230
 
231
+ ## 📦 发布到 PyPI
232
+
233
+ ### 发布新版本
234
+
235
+ ```bash
236
+ # 安装发布工具
237
+ pip install build twine
238
+
239
+ # 构建包
240
+ python -m build
241
+
242
+ # 上传到 PyPI
243
+ twine upload dist/*
244
+ ```
245
+
246
+ ### 发布到 TestPyPI(测试)
247
+
248
+ ```bash
249
+ # 上传到 TestPyPI
250
+ twine upload --repository testpypi dist/*
251
+ ```
252
+
205
253
  ## 📄 许可证
206
254
 
207
255
  [MIT License](LICENSE)
208
256
 
209
257
  ## 🔗 链接
210
258
 
259
+ - [PyPI 包地址](https://pypi.org/project/vcode-analysis/)
211
260
  - [项目主页](https://gitcode.com/wellchang/code-analysis)
212
261
  - [问题反馈](https://gitcode.com/wellchang/code-analysis/issues)
@@ -5,6 +5,7 @@ from .documentation import DocumentationAnalyzer, DocumentationResult
5
5
  from .architecture import ArchitectureAnalyzer, ArchitectureResult, ModuleInfo, DependencyInfo
6
6
  from .security import SecurityAnalyzer, SecurityResult, SecurityIssue
7
7
  from .directory import DirectoryAnalyzer, DirectoryAnalysisResult, ProjectInfo
8
+ from .context_builder import ContextBuilder, AnalysisContext
8
9
 
9
10
  __all__ = [
10
11
  "CodeReviewAnalyzer",
@@ -21,4 +22,6 @@ __all__ = [
21
22
  "DirectoryAnalyzer",
22
23
  "DirectoryAnalysisResult",
23
24
  "ProjectInfo",
25
+ "ContextBuilder",
26
+ "AnalysisContext",
24
27
  ]
@@ -166,6 +166,16 @@ class ArchitectureAnalyzer:
166
166
  self.modules: list[ModuleInfo] = []
167
167
  self.dependencies: list[DependencyInfo] = []
168
168
 
169
+ def _count_lines(self, content: str) -> int:
170
+ """准确计算代码行数"""
171
+ if not content:
172
+ return 0
173
+ # 如果以换行符结尾,换行符数量就是行数
174
+ # 否则,行数 = 换行符数量 + 1
175
+ if content.endswith('\n'):
176
+ return content.count('\n')
177
+ return content.count('\n') + 1
178
+
169
179
  def _detect_imports(self, content: str, language: str, file_path: str = "") -> list[str]:
170
180
  """检测文件中的导入语句"""
171
181
  imports = []
@@ -349,7 +359,7 @@ class ArchitectureAnalyzer:
349
359
  language=file_info.language,
350
360
  imports=imports,
351
361
  exports=[], # TODO: 实现导出检测
352
- lines=len(content.split('\n')),
362
+ lines=self._count_lines(content),
353
363
  classes=structures.get("classes", 0),
354
364
  functions=structures.get("functions", 0),
355
365
  )
@@ -0,0 +1,307 @@
1
+ """代码审查分析器"""
2
+
3
+ from dataclasses import dataclass
4
+ from typing import Optional, TYPE_CHECKING
5
+ from core.analyzer import Analyzer, FileInfo, AnalysisResult
6
+
7
+ if TYPE_CHECKING:
8
+ from .context_builder import AnalysisContext
9
+
10
+
11
+ @dataclass
12
+ class CodeReviewResult:
13
+ """代码审查结果"""
14
+ file_path: str
15
+ score: int # 1-10, 0 表示分析失败
16
+ issues: list[dict]
17
+ suggestions: list[str]
18
+ summary: str
19
+ success: bool = True
20
+
21
+
22
+ def _add_line_numbers(content: str) -> str:
23
+ """给代码添加行号前缀,方便 LLM 准确定位问题"""
24
+ lines = content.split('\n')
25
+ max_width = len(str(len(lines)))
26
+ numbered_lines = [f"{i+1:>{max_width}}| {line}" for i, line in enumerate(lines)]
27
+ return '\n'.join(numbered_lines)
28
+
29
+
30
+ # 代码审查提示词模板
31
+ CODE_REVIEW_PROMPT = """请审查以下 {language} 代码:
32
+
33
+ 文件: {file_path}
34
+
35
+ ```{language}
36
+ {content}
37
+ ```
38
+
39
+ 请进行代码审查,必须严格按照以下 JSON 格式输出,不要输出任何其他内容:
40
+
41
+ {{"score": 评分1-10, "issues": [{{"type": "问题类型", "severity": "high/medium/low", "line": 行号, "description": "问题描述"}}], "suggestions": ["改进建议"], "summary": "代码评价总结"}}"""
42
+
43
+
44
+ # 带上下文的代码审查提示词模板
45
+ CODE_REVIEW_PROMPT_V2 = """请审查以下 {language} 代码:
46
+
47
+ 文件: {file_path}
48
+
49
+ {context_section}
50
+
51
+ ## 当前文件代码
52
+ ```{language}
53
+ {content}
54
+ ```
55
+
56
+ 请进行代码审查,必须严格按照以下 JSON 格式输出,不要输出任何其他内容:
57
+
58
+ {{"score": 评分1-10, "issues": [{{"type": "问题类型", "severity": "high/medium/low", "line": 行号, "description": "问题描述", "context": "相关上下文说明(可选)"}}], "suggestions": ["改进建议"], "summary": "代码评价总结", "cross_file_issues": ["跨文件问题(可选)"]}}"""
59
+
60
+
61
+ COMMIT_REVIEW_PROMPT = """你是一位代码审查专家。请审查以下 Git 提交的变更。
62
+
63
+ 提交信息: {commit_message}
64
+ 作者: {author}
65
+
66
+ 变更内容:
67
+ {diff}
68
+
69
+ 请分析:
70
+ 1. 变更的目的和影响
71
+ 2. 潜在的问题或风险
72
+ 3. 代码风格和最佳实践
73
+ 4. 改进建议
74
+
75
+ 以 Markdown 格式输出审查报告。"""
76
+
77
+
78
+ class CodeReviewAnalyzer:
79
+ """代码审查分析器"""
80
+
81
+ def __init__(self, analyzer: Analyzer):
82
+ self.analyzer = analyzer
83
+
84
+ def review_file(self, file_info: FileInfo) -> CodeReviewResult:
85
+ """审查单个文件"""
86
+ try:
87
+ # 读取文件内容并添加行号
88
+ content = self.analyzer.read_file_content(file_info)
89
+ numbered_content = _add_line_numbers(content)
90
+
91
+ # 构建提示词
92
+ prompt = CODE_REVIEW_PROMPT.format(
93
+ file_path=file_info.relative_path,
94
+ language=file_info.language,
95
+ content=numbered_content,
96
+ )
97
+
98
+ # 调用 LLM
99
+ response = self.analyzer.llm.simple_chat(prompt)
100
+
101
+ result = AnalysisResult(
102
+ file_path=file_info.relative_path,
103
+ analyzer="code_review",
104
+ success=True,
105
+ content=response,
106
+ )
107
+ except Exception as e:
108
+ result = AnalysisResult(
109
+ file_path=file_info.relative_path,
110
+ analyzer="code_review",
111
+ success=False,
112
+ content="",
113
+ errors=[str(e)],
114
+ )
115
+
116
+ if not result.success:
117
+ return CodeReviewResult(
118
+ file_path=file_info.relative_path,
119
+ score=0,
120
+ issues=[{"type": "error", "severity": "high", "description": result.errors[0]}],
121
+ suggestions=[],
122
+ summary="分析失败",
123
+ success=False,
124
+ )
125
+
126
+ # 解析 JSON 结果
127
+ import json
128
+ try:
129
+ # 尝试从 markdown 代码块中提取 JSON
130
+ content = result.content
131
+ if "```json" in content:
132
+ content = content.split("```json")[1].split("```")[0]
133
+ elif "```" in content:
134
+ content = content.split("```")[1].split("```")[0]
135
+
136
+ data = json.loads(content.strip())
137
+ return CodeReviewResult(
138
+ file_path=file_info.relative_path,
139
+ score=data.get("score", 0),
140
+ issues=data.get("issues", []),
141
+ suggestions=data.get("suggestions", []),
142
+ summary=data.get("summary", ""),
143
+ )
144
+ except json.JSONDecodeError:
145
+ # 如果解析失败,返回原始内容作为总结
146
+ return CodeReviewResult(
147
+ file_path=file_info.relative_path,
148
+ score=0,
149
+ issues=[],
150
+ suggestions=[],
151
+ summary=result.content,
152
+ )
153
+
154
+ def review_commit(self, commit_hash: str) -> AnalysisResult:
155
+ """审查指定提交"""
156
+ git = self.analyzer.git
157
+ if not git:
158
+ return AnalysisResult(
159
+ file_path="",
160
+ analyzer="code_review",
161
+ success=False,
162
+ content="",
163
+ errors=["目标路径不是有效的 Git 仓库"],
164
+ )
165
+
166
+ commit_info = git.get_commit_info(commit_hash)
167
+ diffs = git.get_commit_diff(commit_hash)
168
+
169
+ # 构建差异内容
170
+ diff_content = ""
171
+ for diff in diffs:
172
+ diff_content += f"\n### {diff.file_path}\n"
173
+ diff_content += f"状态: {diff.status} (+{diff.additions}/-{diff.deletions})\n"
174
+ diff_content += f"```diff\n{diff.diff}\n```\n"
175
+
176
+ prompt = COMMIT_REVIEW_PROMPT.format(
177
+ commit_message=commit_info.message,
178
+ author=commit_info.author,
179
+ diff=diff_content,
180
+ )
181
+
182
+ response = self.analyzer.llm.simple_chat(prompt)
183
+
184
+ return AnalysisResult(
185
+ file_path=commit_hash,
186
+ analyzer="code_review",
187
+ success=True,
188
+ content=response,
189
+ metadata={
190
+ "commit_hash": commit_hash,
191
+ "author": commit_info.author,
192
+ "date": commit_info.date.isoformat(),
193
+ "files_changed": commit_info.files_changed,
194
+ },
195
+ )
196
+
197
+ def review_files(self, file_infos: list[FileInfo]) -> list[CodeReviewResult]:
198
+ """审查多个文件"""
199
+ results = []
200
+ for file_info in file_infos:
201
+ result = self.review_file(file_info)
202
+ results.append(result)
203
+ return results
204
+
205
+ def review_file_with_context(
206
+ self,
207
+ file_info: FileInfo,
208
+ context: "AnalysisContext",
209
+ context_builder=None
210
+ ) -> CodeReviewResult:
211
+ """带上下文的文件审查
212
+
213
+ Args:
214
+ file_info: 文件信息
215
+ context: 分析上下文
216
+ context_builder: 上下文构建器(用于格式化)
217
+
218
+ Returns:
219
+ 审查结果
220
+ """
221
+ try:
222
+ # 读取文件内容并添加行号
223
+ content = self.analyzer.read_file_content(file_info)
224
+ numbered_content = _add_line_numbers(content)
225
+
226
+ # 构建上下文部分
227
+ context_section = ""
228
+ if context_builder:
229
+ context_section = context_builder.format_context_for_prompt(
230
+ file_info.relative_path, context
231
+ )
232
+
233
+ # 构建提示词
234
+ prompt = CODE_REVIEW_PROMPT_V2.format(
235
+ file_path=file_info.relative_path,
236
+ language=file_info.language,
237
+ context_section=context_section,
238
+ content=numbered_content,
239
+ )
240
+
241
+ # 调用 LLM
242
+ response = self.analyzer.llm.simple_chat(prompt)
243
+
244
+ result = AnalysisResult(
245
+ file_path=file_info.relative_path,
246
+ analyzer="code_review",
247
+ success=True,
248
+ content=response,
249
+ )
250
+ except Exception as e:
251
+ result = AnalysisResult(
252
+ file_path=file_info.relative_path,
253
+ analyzer="code_review",
254
+ success=False,
255
+ content="",
256
+ errors=[str(e)],
257
+ )
258
+
259
+ if not result.success:
260
+ return CodeReviewResult(
261
+ file_path=file_info.relative_path,
262
+ score=0,
263
+ issues=[{"type": "error", "severity": "high", "description": result.errors[0]}],
264
+ suggestions=[],
265
+ summary="分析失败",
266
+ success=False,
267
+ )
268
+
269
+ # 解析 JSON 结果
270
+ import json
271
+ try:
272
+ # 尝试从 markdown 代码块中提取 JSON
273
+ content = result.content
274
+ if "```json" in content:
275
+ content = content.split("```json")[1].split("```")[0]
276
+ elif "```" in content:
277
+ content = content.split("```")[1].split("```")[0]
278
+
279
+ data = json.loads(content.strip())
280
+
281
+ # 提取跨文件问题并添加到 issues
282
+ issues = data.get("issues", [])
283
+ cross_file = data.get("cross_file_issues", [])
284
+ if cross_file:
285
+ for cf_issue in cross_file:
286
+ issues.append({
287
+ "type": "cross_file",
288
+ "severity": "medium",
289
+ "description": cf_issue,
290
+ })
291
+
292
+ return CodeReviewResult(
293
+ file_path=file_info.relative_path,
294
+ score=data.get("score", 0),
295
+ issues=issues,
296
+ suggestions=data.get("suggestions", []),
297
+ summary=data.get("summary", ""),
298
+ )
299
+ except json.JSONDecodeError:
300
+ # 如果解析失败,返回原始内容作为总结
301
+ return CodeReviewResult(
302
+ file_path=file_info.relative_path,
303
+ score=0,
304
+ issues=[],
305
+ suggestions=[],
306
+ summary=result.content,
307
+ )