#!/usr/bin/env python3 """ 代码分析器 扫描代码文件,检测常见问题 """ import json import sys import os import re from pathlib import Path def analyze_file(file_path): """分析单个代码文件""" issues = [] try: with open(file_path, 'r', encoding='utf-8', errors='ignore') as f: content = f.read() lines = content.split('\n') # 检测模式 patterns = { 'TODO': r'TODO|FIXME|XXX|HACK', 'empty_function': r'def\s+\w+\s*\([^)]*\)\s*:\s*(pass|#\s*.*|.{0})', 'empty_method': r'(def|async\s+def)\s+\w+\s*\([^)]*\)\s*:\s*(pass|.{0})', 'commented_code': r'^\s*#.*=[^#\n]|^\s*#.*\([^)]*\)', 'placeholder': r'(NotImplementedError|raise\s+NotImplemented|pass\s*#.*placeholder)', 'debug_print': r'print\([^)]*\)|console\.log\([^)]*\)', } for line_num, line in enumerate(lines, 1): for issue_type, pattern in patterns.items(): if re.search(pattern, line, re.IGNORECASE): issues.append({ 'type': issue_type, 'line': line_num, 'content': line.strip(), 'file': str(file_path) }) except Exception as e: issues.append({ 'type': 'read_error', 'message': str(e), 'file': str(file_path) }) return issues def detect_project_changes(project_root): """检测项目中的代码变更""" import subprocess try: # 获取 Git 变更的文件 result = subprocess.run( ['git', 'diff', '--name-only', 'HEAD'], cwd=project_root, capture_output=True, text=True, timeout=5 ) if result.returncode == 0: changed_files = result.stdout.strip().split('\n') changed_files = [f for f in changed_files if f] # 过滤代码文件 code_extensions = {'.py', '.js', '.ts', '.jsx', '.tsx', '.java', '.go', '.rs', '.c', '.cpp', '.h'} code_files = [ Path(project_root) / f for f in changed_files if Path(f).suffix.lower() in code_extensions ] return code_files except Exception: pass # 如果 Git 不可用,扫描所有代码文件 code_extensions = {'.py', '.js', '.ts', '.jsx', '.tsx', '.java', '.go', '.rs', '.c', '.cpp', '.h'} project_path = Path(project_root) code_files = [] for ext in code_extensions: code_files.extend(project_path.rglob(f'*{ext}')) return code_files def analyze_code_quality(project_root): """分析代码质量""" all_issues = { 'todo': [], 'empty_functions': [], 'commented_code': [], 'placeholders': [], 'debug_statements': [], 'other': [] } # 获取需要分析的文件 files_to_analyze = detect_project_changes(project_root) for file_path in files_to_analyze: if not file_path.exists(): continue issues = analyze_file(file_path) for issue in issues: issue_type = issue['type'] if issue_type == 'TODO': all_issues['todo'].append(issue) elif 'empty' in issue_type: all_issues['empty_functions'].append(issue) elif issue_type == 'commented_code': all_issues['commented_code'].append(issue) elif issue_type == 'placeholder': all_issues['placeholders'].append(issue) elif issue_type == 'debug_print': all_issues['debug_statements'].append(issue) else: all_issues['other'].append(issue) return all_issues def calculate_completeness_score(issues): """计算完整度评分""" total_issues = sum(len(v) for v in issues.values()) # 严重问题权重 critical_issues = len(issues['empty_functions']) + len(issues['placeholders']) minor_issues = len(issues['todo']) + len(issues['commented_code']) + len(issues['debug_statements']) # 计算分数(0-100) score = 100 - (critical_issues * 15) - (minor_issues * 5) return max(0, min(100, score)) def main(): """主函数""" # 从命令行参数或 stdin 获取项目路径 if len(sys.argv) > 1: project_root = sys.argv[1] else: project_root = os.getcwd() # 执行分析 issues = analyze_code_quality(project_root) score = calculate_completeness_score(issues) # 输出结果 result = { 'score': score, 'issues': issues, 'total_issues': sum(len(v) for v in issues.values()), 'summary': { 'todo_count': len(issues['todo']), 'empty_functions_count': len(issues['empty_functions']), 'commented_code_count': len(issues['commented_code']), 'placeholder_count': len(issues['placeholders']), 'debug_statements_count': len(issues['debug_statements']) } } print(json.dumps(result, ensure_ascii=False, indent=2)) if __name__ == '__main__': main()