开发code-quality
This commit is contained in:
@@ -0,0 +1,193 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
自动完成检查 Hook
|
||||
拦截任务结束,执行代码质量检查
|
||||
"""
|
||||
import json
|
||||
import sys
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
# 导入模块
|
||||
sys.path.insert(0, str(Path(__file__).parent))
|
||||
from requirements_tracker import generate_requirement_checklist, save_checklist
|
||||
from code_analyzer import analyze_code_quality, calculate_completeness_score
|
||||
from notification_sender import notify_check_result
|
||||
|
||||
|
||||
def load_iteration_tracker(project_root):
|
||||
"""加载迭代计数器"""
|
||||
tracker_file = Path(project_root) / '.claude' / 'iteration-tracker.json'
|
||||
|
||||
if tracker_file.exists():
|
||||
with open(tracker_file, 'r', encoding='utf-8') as f:
|
||||
return json.load(f)
|
||||
|
||||
return {}
|
||||
|
||||
|
||||
def update_iteration_count(project_root, task_id, increment=True):
|
||||
"""更新迭代计数"""
|
||||
tracker = load_iteration_tracker(project_root)
|
||||
|
||||
if task_id not in tracker:
|
||||
tracker[task_id] = 0
|
||||
|
||||
if increment:
|
||||
tracker[task_id] += 1
|
||||
|
||||
# 保存
|
||||
tracker_file = Path(project_root) / '.claude' / 'iteration-tracker.json'
|
||||
tracker_file.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
with open(tracker_file, 'w', encoding='utf-8') as f:
|
||||
json.dump(tracker, f, ensure_ascii=False, indent=2)
|
||||
|
||||
return tracker[task_id]
|
||||
|
||||
|
||||
def reset_iteration_count(project_root, task_id):
|
||||
"""重置迭代计数(任务完成时)"""
|
||||
return update_iteration_count(project_root, task_id, increment=False)
|
||||
|
||||
|
||||
def generate_fix_requirements(issues, requirements_checklist):
|
||||
"""生成修复要求"""
|
||||
fix_requirements = []
|
||||
|
||||
# 从代码问题生成修复要求
|
||||
if issues['todo']:
|
||||
fix_requirements.append(f"- 处理 {len(issues['todo'])} 个 TODO/FIXME 项")
|
||||
|
||||
if issues['empty_functions']:
|
||||
fix_requirements.append(f"- 实现以下空函数: {', '.join([f'{i[\"file\"]}:{i[\"line\"]}' for i in issues['empty_functions'][:3]])}")
|
||||
|
||||
if issues['placeholders']:
|
||||
fix_requirements.append(f"- 移除或实现占位符代码 ({len(issues['placeholders'])} 处)")
|
||||
|
||||
if issues['commented_code']:
|
||||
fix_requirements.append(f"- 清理或取消注释代码 ({len(issues['commented_code'])} 处)")
|
||||
|
||||
# 从需求清单生成修复要求
|
||||
unverified = [r for r in requirements_checklist.get('requirements', []) if not r.get('verified', False)]
|
||||
if unverified:
|
||||
fix_requirements.append(f"- 验证以下需求已完成:\n " + "\n ".join([f"{i+1}. {r['description']}" for i, r in enumerate(unverified[:5])]))
|
||||
|
||||
return "\n".join(fix_requirements) if fix_requirements else "未发现明显问题,建议人工审查"
|
||||
|
||||
|
||||
def perform_quick_check(project_root, task_id, conversation_context=''):
|
||||
"""执行快速检查"""
|
||||
# 1. 生成需求检查清单
|
||||
requirements_checklist = generate_requirement_checklist(project_root, conversation_context)
|
||||
save_checklist(requirements_checklist, task_id, project_root)
|
||||
|
||||
# 2. 代码质量分析
|
||||
analysis_result = analyze_code_quality(project_root)
|
||||
score = analysis_result['score']
|
||||
issues = analysis_result['issues']
|
||||
|
||||
# 3. 检查逻辑
|
||||
passed = score >= 80
|
||||
critical_issues = len(issues['empty_functions']) + len(issues['placeholders'])
|
||||
|
||||
# 4. 获取迭代计数
|
||||
iteration_count = load_iteration_tracker(project_root).get(task_id, 0)
|
||||
requires_review = iteration_count >= 3
|
||||
|
||||
# 5. 生成结果
|
||||
result = {
|
||||
'passed': passed,
|
||||
'score': score,
|
||||
'iteration_count': iteration_count,
|
||||
'requires_review': requires_review,
|
||||
'issues': analysis_result['summary'],
|
||||
'total_issues': analysis_result['total_issues']
|
||||
}
|
||||
|
||||
# 6. 决定是否阻止完成
|
||||
if not passed and not requires_review:
|
||||
# 增加迭代计数
|
||||
new_count = update_iteration_count(project_root, task_id)
|
||||
result['iteration_count'] = new_count
|
||||
|
||||
# 生成修复要求
|
||||
fix_requirements = generate_fix_requirements(issues, requirements_checklist)
|
||||
result['fix_requirements'] = fix_requirements
|
||||
result['block_completion'] = True
|
||||
result['message'] = f'代码质量检查未通过 (评分: {score}/100,迭代: {new_count}/3)'
|
||||
|
||||
elif requires_review:
|
||||
result['block_completion'] = True
|
||||
result['message'] = f'已达最大迭代次数 ({iteration_count}/3),需要深度审查'
|
||||
result['trigger_review_agent'] = True
|
||||
|
||||
else:
|
||||
# 通过,重置计数
|
||||
reset_iteration_count(project_root, task_id)
|
||||
result['block_completion'] = False
|
||||
result['message'] = f'代码质量检查通过 (评分: {score}/100)'
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def main():
|
||||
"""主函数"""
|
||||
try:
|
||||
# 加载输入
|
||||
input_data = json.load(sys.stdin)
|
||||
except json.JSONDecodeError:
|
||||
input_data = {}
|
||||
|
||||
# 获取参数
|
||||
project_root = input_data.get('projectRoot', os.getcwd())
|
||||
task_id = input_data.get('taskId', 'default')
|
||||
conversation_context = input_data.get('conversationContext', '')
|
||||
|
||||
# 执行快速检查
|
||||
check_result = perform_quick_check(project_root, task_id, conversation_context)
|
||||
|
||||
# 发送通知(异步,不阻塞)
|
||||
if check_result.get('passed') or check_result.get('requires_review'):
|
||||
try:
|
||||
notify_check_result(check_result)
|
||||
except Exception:
|
||||
pass # 通知失败不影响主流程
|
||||
|
||||
# 显示终端信息
|
||||
if not check_result.get('passed'):
|
||||
print(f"\n{'='*60}", file=sys.stderr)
|
||||
print(f"⚠️ 代码质量检查未通过", file=sys.stderr)
|
||||
print(f"{'='*60}", file=sys.stderr)
|
||||
print(f"评分: {check_result['score']}/100", file=sys.stderr)
|
||||
print(f"迭代次数: {check_result['iteration_count']}/3", file=sys.stderr)
|
||||
print(f"\n发现的问题:", file=sys.stderr)
|
||||
for key, count in check_result['issues'].items():
|
||||
if count > 0:
|
||||
print(f" - {key}: {count}", file=sys.stderr)
|
||||
print(f"\n修复要求:", file=sys.stderr)
|
||||
print(check_result.get('fix_requirements', ''), file=sys.stderr)
|
||||
print(f"{'='*60}\n", file=sys.stderr)
|
||||
|
||||
# 构造 Hook 输出
|
||||
output = {
|
||||
'hookSpecificOutput': {
|
||||
'hookEventName': 'TaskEnd',
|
||||
'blockCompletion': check_result.get('block_completion', False),
|
||||
'additionalContext': check_result.get('fix_requirements', ''),
|
||||
'triggerReviewAgent': check_result.get('trigger_review_agent', False),
|
||||
'checkResult': check_result
|
||||
}
|
||||
}
|
||||
|
||||
# 如果通过,添加成功消息
|
||||
if check_result.get('passed'):
|
||||
output['hookSpecificOutput']['message'] = f"✅ 代码质量检查通过 (评分: {check_result['score']}/100)"
|
||||
|
||||
# 输出 JSON
|
||||
print(json.dumps(output, ensure_ascii=False))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Reference in New Issue
Block a user