Files
iAOP/docs/_check_m2_baseline.py
T

90 lines
2.8 KiB
Python
Raw Normal View History

# -*- coding: utf-8 -*-
"""M2 实施基线文档一致性校验(issue #1 辅助脚本)。
校验项:
1. 必备章节齐全(目标/现状盘点/改造清单/里程碑与风险/验收对照/关联);
2. 引用的配置资产路径在仓库中存在(防文档指向缺失文件);
3. 关键验收关键词存在(配置驱动/模板配置台/缓冲/RISK 风险标注)。
"""
from __future__ import annotations
import os
import re
import sys
REPO_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
DOC = os.path.join(REPO_ROOT, "docs", "M2内核平台化改造_实施基线.md")
REQUIRED_SECTIONS = [
"目标与范围",
"现状盘点",
"改造清单",
"里程碑与风险",
"验收对照",
"关联",
]
KEYWORDS = ["配置驱动", "Template Console", "模板配置台", "预留 2 周缓冲", "iAOP-Core 可用"]
# 文档中应引用的内核配置资产(以仓库内路径出现,支持 {a,b} 集合写法)
EXPECTED_ASSETS = [
"core/edge-gateway/config/gateway.example.yaml",
"core/data-bus/config/{kafka,postgres,retention,minio}.template.yaml",
"core/llm-gateway/config/{router,prompts}.template.yaml",
"core/rag-kb/config/kb.template.yaml",
"core/inference-backend/config/backends.template.yaml",
"deploy/k8s/helm/iaop",
"templates/resin/dashboard/cockpit.resin.yaml",
]
def expand_braces(path: str) -> list:
"""展开 {a,b} 集合写法:a/{b,c}.yaml -> [a/b.yaml, a/c.yaml]。"""
m = re.search(r"\{(.+?)\}", path)
if not m:
return [path]
parts = m.group(1).split(",")
prefix, suffix = path.split(m.group(0), 1)
return [prefix + p + suffix for p in parts]
def main() -> int:
with open(DOC, encoding="utf-8") as f:
text = f.read()
errors = []
# 1. 必备章节
for sec in REQUIRED_SECTIONS:
if sec not in text:
errors.append("缺少必备章节: %s" % sec)
# 2. 配置资产引用存在(支持 {a,b} 集合写法:原始形式或展开后任一命中)
for asset in EXPECTED_ASSETS:
candidates = expand_braces(asset)
if asset in text or any(a in text for a in candidates):
for a in candidates:
if not os.path.exists(os.path.join(REPO_ROOT, a)):
errors.append("引用资产不存在: %s" % a)
else:
errors.append("未引用核心资产: %s" % asset)
# 3. 验收关键词
for kw in KEYWORDS:
if kw not in text:
errors.append("缺少验收关键词: %s" % kw)
if errors:
print("FAIL")
for e in errors:
print(" - %s" % e)
return 1
print("PASS — 章节 %d 项、资产引用 %d 项、关键词 %d 项全部通过" %
(len(REQUIRED_SECTIONS), len(EXPECTED_ASSETS), len(KEYWORDS)))
return 0
if __name__ == "__main__":
sys.exit(main())