NAC_Blockchain/tools/nac_naming_checker.py

221 lines
8.0 KiB
Python
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/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()