#!/usr/bin/env python3 """ NAC命名规范自动化检查工具 功能: 1. 检查文档中的协议名称大小写 2. 检查GNACS编码定义一致性 3. 检查架构层级命名规范 4. 生成检查报告 使用方法: python3 nac_naming_checker.py [目录路径] 示例: python3 nac_naming_checker.py /home/ubuntu/NAC_Clean_Dev """ import os import re import sys from pathlib import Path from typing import List, Dict, Tuple class NACNamingChecker: def __init__(self, root_dir: str): self.root_dir = Path(root_dir) self.issues = [] # 协议名称规范 self.protocols = { 'cbpp': 'CBPP', 'csnp': 'CSNP', 'nvm': 'NVM', 'acc': 'ACC', 'gnacs': 'GNACS', 'xtzh': 'XTZH', } # GNACS编码规范 self.gnacs_patterns = { 'correct': r'GNACSCode\(\[0u8; 6\]\)', # 48位 = 6字节 'wrong_48': r'GNACSCode\(\[0u8; 48\]\)', # 错误:48字节 'wrong_24': r'GNACSCode\(\[0u8; 24\]\)', # 错误:24字节 } def check_markdown_files(self) -> List[Dict]: """检查Markdown文档中的命名规范""" print("🔍 检查Markdown文档...") md_files = list(self.root_dir.glob('**/*.md')) issues = [] for md_file in md_files: # 跳过node_modules和target目录 if 'node_modules' in str(md_file) or 'target' in str(md_file): continue try: with open(md_file, 'r', encoding='utf-8') as f: content = f.read() # 检查协议名称大小写 for lowercase, uppercase in self.protocols.items(): # 查找小写协议名(排除代码路径) pattern = rf'\b{lowercase}\b(?![/\w])' matches = re.finditer(pattern, content, re.IGNORECASE) for match in matches: matched_text = match.group() if matched_text == lowercase and matched_text != uppercase: line_num = content[:match.start()].count('\n') + 1 issues.append({ 'file': str(md_file.relative_to(self.root_dir)), 'line': line_num, 'type': 'protocol_naming', 'found': matched_text, 'expected': uppercase, 'message': f'协议名称应使用大写:{matched_text} -> {uppercase}' }) except Exception as e: print(f"⚠️ 无法读取文件 {md_file}: {e}") return issues def check_rust_files(self) -> List[Dict]: """检查Rust代码中的命名规范""" print("🔍 检查Rust代码...") rs_files = list(self.root_dir.glob('**/*.rs')) issues = [] for rs_file in rs_files: # 跳过target目录 if 'target' in str(rs_file): continue try: with open(rs_file, 'r', encoding='utf-8') as f: content = f.read() # 检查GNACS编码错误用法 for pattern_name, pattern in self.gnacs_patterns.items(): if pattern_name.startswith('wrong_'): matches = re.finditer(pattern, content) for match in matches: line_num = content[:match.start()].count('\n') + 1 issues.append({ 'file': str(rs_file.relative_to(self.root_dir)), 'line': line_num, 'type': 'gnacs_encoding', 'found': match.group(), 'expected': 'GNACSCode([0u8; 6])', 'message': f'GNACS编码应使用6字节(48位):{match.group()} -> GNACSCode([0u8; 6])' }) except Exception as e: print(f"⚠️ 无法读取文件 {rs_file}: {e}") return issues def generate_report(self, issues: List[Dict]) -> str: """生成检查报告""" report = [] report.append("# NAC命名规范检查报告\n") report.append(f"**检查目录**: {self.root_dir}\n") report.append(f"**检查时间**: {self._get_timestamp()}\n") report.append(f"**发现问题数**: {len(issues)}\n") report.append("\n---\n\n") if not issues: report.append("✅ **未发现命名规范问题!**\n") return ''.join(report) # 按类型分组 issues_by_type = {} for issue in issues: issue_type = issue['type'] if issue_type not in issues_by_type: issues_by_type[issue_type] = [] issues_by_type[issue_type].append(issue) # 生成各类型问题报告 for issue_type, type_issues in issues_by_type.items(): report.append(f"## {self._get_type_name(issue_type)}\n\n") report.append(f"**问题数量**: {len(type_issues)}\n\n") for i, issue in enumerate(type_issues, 1): report.append(f"### 问题 {i}\n\n") report.append(f"- **文件**: `{issue['file']}`\n") report.append(f"- **行号**: {issue['line']}\n") report.append(f"- **发现**: `{issue['found']}`\n") report.append(f"- **应为**: `{issue['expected']}`\n") report.append(f"- **说明**: {issue['message']}\n\n") return ''.join(report) def _get_type_name(self, issue_type: str) -> str: """获取问题类型的中文名称""" type_names = { 'protocol_naming': '协议名称大小写问题', 'gnacs_encoding': 'GNACS编码定义问题', 'architecture_layer': '架构层级命名问题', } return type_names.get(issue_type, issue_type) def _get_timestamp(self) -> str: """获取当前时间戳""" from datetime import datetime return datetime.now().strftime('%Y-%m-%d %H:%M:%S') def run(self) -> Tuple[List[Dict], str]: """运行检查""" print(f"🚀 开始检查NAC命名规范...") print(f"📂 检查目录: {self.root_dir}\n") all_issues = [] # 检查Markdown文档 md_issues = self.check_markdown_files() all_issues.extend(md_issues) print(f" ✅ Markdown文档检查完成,发现 {len(md_issues)} 个问题\n") # 检查Rust代码 rs_issues = self.check_rust_files() all_issues.extend(rs_issues) print(f" ✅ Rust代码检查完成,发现 {len(rs_issues)} 个问题\n") # 生成报告 report = self.generate_report(all_issues) print(f"📊 检查完成,共发现 {len(all_issues)} 个问题") return all_issues, report def main(): if len(sys.argv) < 2: print("使用方法: python3 nac_naming_checker.py [目录路径]") print("示例: python3 nac_naming_checker.py /home/ubuntu/NAC_Clean_Dev") sys.exit(1) root_dir = sys.argv[1] if not os.path.exists(root_dir): print(f"❌ 目录不存在: {root_dir}") sys.exit(1) checker = NACNamingChecker(root_dir) issues, report = checker.run() # 保存报告 report_file = Path(root_dir) / 'NAC_Naming_Check_Report.md' with open(report_file, 'w', encoding='utf-8') as f: f.write(report) print(f"\n📄 报告已保存到: {report_file}") # 返回退出码 sys.exit(0 if len(issues) == 0 else 1) if __name__ == '__main__': main()