feat: 引入 Wiki 文档镜像流程 (#1)

This commit is contained in:
QiuSW
2026-08-07 23:57:13 +08:00
parent 1337b5c894
commit b08a919fd7
13 changed files with 859 additions and 92 deletions
+43
View File
@@ -6,6 +6,8 @@ import argparse
import re
from pathlib import Path
from wiki_docs import WikiDocsError, load_config, parse_mirror
ROOT = Path(__file__).resolve().parents[1]
REQUIRED_FILES = (
@@ -14,6 +16,9 @@ REQUIRED_FILES = (
"docs/00-project-profile.md",
"docs/01-workflow.md",
"docs/templates/task-archive.md",
"wiki-docs.json",
"scripts/wiki_docs.py",
"scripts/sync_wiki_docs.py",
".gitea/issue_template/epic.md",
".gitea/issue_template/mvp.md",
".gitea/issue_template/task.md",
@@ -56,6 +61,43 @@ def check_archives(errors: list[str]) -> None:
errors.append(f"{path.name} 没有记录未验证部分")
def check_wiki_mirrors(errors: list[str]) -> None:
"""检查每份本地文档都有显式映射和可追踪的镜像头。"""
try:
config = load_config()
except WikiDocsError as exc:
errors.append(str(exc))
return
mapped_paths = {mapping.path for mapping in config.mappings}
actual_paths = {
path.relative_to(ROOT).as_posix() for path in (ROOT / "docs").rglob("*.md")
}
for path in sorted(actual_paths - mapped_paths):
errors.append(f"docs 中存在未登记的 Wiki 镜像:{path}")
for mapping in config.mappings:
path = ROOT / mapping.path
if not path.is_file():
errors.append(f"缺少 Wiki 镜像:{mapping.path}")
continue
try:
metadata, _ = parse_mirror(path.read_text(encoding="utf-8"))
except (OSError, UnicodeDecodeError, WikiDocsError) as exc:
errors.append(f"Wiki 镜像无效 {mapping.path}:{exc}")
continue
if metadata.get("generated") != "true (请先修改 Gitea Wiki,禁止直接编辑本文件)":
errors.append(f"{mapping.path} 没有只读镜像标记")
if metadata.get("wiki_page") != mapping.page:
errors.append(f"{mapping.path} 的 wiki_page 与映射不一致")
revision = metadata.get("wiki_revision", "")
if re.fullmatch(r"[0-9a-f]{40,64}", revision) is None:
errors.append(f"{mapping.path} 的 wiki_revision 无效")
if not metadata.get("synchronized_at"):
errors.append(f"{mapping.path} 缺少 synchronized_at")
def main() -> int:
parser = argparse.ArgumentParser(description="检查 DevHarness 项目结构")
parser.add_argument(
@@ -69,6 +111,7 @@ def main() -> int:
warnings: list[str] = []
check_required_files(errors)
check_project_profile(errors, warnings, args.strict)
check_wiki_mirrors(errors)
check_archives(errors)
for warning in warnings: