53 lines
2.3 KiB
Python
53 lines
2.3 KiB
Python
#!/usr/bin/env python3
|
|
from pathlib import Path
|
|
import re
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
SKILL = ROOT / "SKILL.md"
|
|
text = SKILL.read_text(encoding="utf-8")
|
|
|
|
assert text.startswith("---\n"), "SKILL.md must start with YAML frontmatter"
|
|
parts = text.split("\n---\n", 1)
|
|
assert len(parts) == 2 and parts[1].strip(), "frontmatter must close and body must be non-empty"
|
|
frontmatter, body = parts
|
|
assert re.search(r"^name:\s*documentation-docusaurus\s*$", frontmatter, re.M), "wrong skill name"
|
|
assert "description:" in frontmatter, "missing description"
|
|
assert len(text) <= 100_000, "SKILL.md exceeds Hermes size limit"
|
|
assert "## Authoritative repository" in body
|
|
assert "## Gitea delivery gate" in body
|
|
assert "references/gitea-docusaurus-delivery.md" in text
|
|
|
|
required = [
|
|
ROOT / "README.md",
|
|
ROOT / "PROVENANCE.md",
|
|
ROOT / "templates/gitea-actions-build.yml",
|
|
ROOT / "references/gitea-docusaurus-delivery.md",
|
|
]
|
|
assert all(path.is_file() for path in required), "required package artifact missing"
|
|
|
|
markdown_files = [SKILL, ROOT / "README.md", ROOT / "PROVENANCE.md", *sorted((ROOT / "references").glob("*.md"))]
|
|
link_pattern = re.compile(r"\[[^]]*\]\(([^)]+)\)")
|
|
missing = []
|
|
for source in markdown_files:
|
|
source_text = source.read_text(encoding="utf-8")
|
|
for target in link_pattern.findall(source_text):
|
|
target = target.split("#", 1)[0]
|
|
if not target or "://" in target or target.startswith(("mailto:", "#", "/")):
|
|
continue
|
|
resolved = (source.parent / target).resolve()
|
|
if ROOT not in resolved.parents and resolved != ROOT:
|
|
missing.append(f"{source.relative_to(ROOT)} -> outside package: {target}")
|
|
elif not resolved.exists():
|
|
missing.append(f"{source.relative_to(ROOT)} -> missing: {target}")
|
|
assert not missing, "broken local links:\n" + "\n".join(missing)
|
|
|
|
reference_names = {path.name for path in (ROOT / "references").glob("*.md")}
|
|
coverage_text = "\n".join(path.read_text(encoding="utf-8") for path in markdown_files)
|
|
unreferenced = sorted(name for name in reference_names if name not in coverage_text.replace(str(ROOT), ""))
|
|
assert not unreferenced, f"unreferenced support files: {unreferenced}"
|
|
|
|
print(
|
|
f"OK skill=documentation-docusaurus chars={len(text)} "
|
|
f"references={len(reference_names)} markdown_files={len(markdown_files)}"
|
|
)
|