This commit is contained in:
Dang Zerong
2026-03-12 14:42:23 +08:00
parent 9ae55407fc
commit 027cf50759
8 changed files with 225 additions and 52 deletions

View File

@@ -41,7 +41,7 @@ class AIReviewer(BaseScanner):
logger.info(f'AI 审查器初始化: {self.provider}/{self.model}')
def scan(self, repo_url: str, commit_id: Optional[str], branch: str) -> Dict[str, Any]:
def scan(self, repo_url: str, commit_id: Optional[str], branch: str, changed_files: Optional[List[str]] = None) -> Dict[str, Any]:
"""
执行代码扫描(实现抽象方法)
@@ -49,16 +49,18 @@ class AIReviewer(BaseScanner):
repo_url: 仓库 URL
commit_id: 提交 ID
branch: 分支名
changed_files: 可选的变更文件列表(来自 PR
Returns:
审查结果
"""
# 调用实际的审查逻辑
return self._do_review(repo_url=repo_url, commit_id=commit_id, branch=branch)
return self._do_review(repo_url=repo_url, commit_id=commit_id, branch=branch, changed_files=changed_files)
def _do_review(self, clone_dir: str = None, repo_url: str = None,
commit_id: str = None, branch: str = None,
language: str = 'python') -> Dict[str, Any]:
language: str = 'python',
changed_files: Optional[List[str]] = None) -> Dict[str, Any]:
"""
执行 AI 代码审查
@@ -68,6 +70,7 @@ class AIReviewer(BaseScanner):
commit_id: 提交 ID
branch: 分支名
language: 编程语言
changed_files: 可选的变更文件列表(来自 PR
Returns:
审查结果
@@ -94,7 +97,7 @@ class AIReviewer(BaseScanner):
}
# 获取要审查的代码文件
files = self._get_code_files(clone_dir, language)
files = self._get_code_files(clone_dir, language, changed_files)
if not files:
return {
@@ -107,7 +110,7 @@ class AIReviewer(BaseScanner):
# 对每个文件进行 AI 审查
all_reviews = []
for file_path in files[:5]: # 限制最多审查 5 个文件
review = self._review_file(file_path, language)
review = self._review_file(file_path, language, clone_dir)
if review:
all_reviews.append(review)
@@ -133,7 +136,7 @@ class AIReviewer(BaseScanner):
'summary': f'AI 审查出错: {str(e)}'
}
def _get_code_files(self, clone_dir: str, language: str) -> List[str]:
def _get_code_files(self, clone_dir: str, language: str, changed_files: Optional[List[str]] = None) -> List[str]:
"""获取代码文件列表"""
import glob
@@ -144,6 +147,18 @@ class AIReviewer(BaseScanner):
}
exts = extensions.get(language, ['.py'])
# 如果提供了变更文件列表,只返回这些文件
if changed_files:
files = []
for changed_file in changed_files:
if any(changed_file.endswith(ext) for ext in exts):
full_path = os.path.join(clone_dir, changed_file)
if os.path.exists(full_path):
files.append(full_path)
return files[:10]
# 否则扫描整个仓库
files = []
for ext in exts:
@@ -157,7 +172,7 @@ class AIReviewer(BaseScanner):
return files[:10] # 最多 10 个文件
def _review_file(self, file_path: str, language: str) -> Optional[Dict[str, Any]]:
def _review_file(self, file_path: str, language: str, clone_dir: str = None) -> Optional[Dict[str, Any]]:
"""审查单个文件"""
try:
with open(file_path, 'r', encoding='utf-8') as f:
@@ -181,9 +196,9 @@ class AIReviewer(BaseScanner):
return None
# 解析响应
filename = os.path.basename(file_path)
rel_path = os.path.relpath(file_path, clone_dir) if (clone_dir and file_path) else file_path
return {
'file': filename,
'file': rel_path,
'path': file_path,
'truncated': truncated,
'review': response
@@ -236,6 +251,7 @@ class AIReviewer(BaseScanner):
logger.warning(f'未知的 AI provider: {self.provider}')
return None
except Exception as e:
print("异常追踪信息:", e.__traceback__)
logger.error(f'AI 调用失败: {str(e)}')
return None