2"""Create a commit-scoped documentation certification after strict validation."""
4from __future__
import annotations
10from pathlib
import Path
13REPO_ROOT = Path(__file__).resolve().parents[2]
16def run(command: list[str], label: str) ->
None:
18 @brief Run one certification gate and stream its output.
19 @param[in] command Executable and arguments for the gate.
20 @param[in] label Human-readable gate label.
24 print(f
"==> {label}", flush=
True)
25 completed = subprocess.run(command, cwd=REPO_ROOT, check=
False)
26 if completed.returncode != 0:
27 raise RuntimeError(f
"{label} failed with exit code {completed.returncode}.")
32 @brief Return trimmed output from one Git command.
33 @param[in] args Arguments passed after `git`.
34 @return Decoded, trimmed Git stdout.
37 return subprocess.check_output([
"git", *args], cwd=REPO_ROOT, text=
True).strip()
42 @brief Require that HEAD names a clean, commit-scoped source revision.
43 @return Full SHA of the clean HEAD revision.
48 "Documentation certification requires a clean working tree so its result can be "
49 "claimed for one commit. Commit or stash changes, then rerun."
56 @brief Fail certification when Doxygen reports a warning.
60 warning_log = REPO_ROOT /
"logs" /
"doxygen.warnings"
61 warnings = warning_log.read_text(encoding=
"utf-8").strip()
if warning_log.exists()
else ""
64 "Doxygen emitted warnings; documentation cannot be certified.\n" + warnings
70 @brief Write a reproducible certification record for one validated revision.
71 @param[in] sha Full Git revision validated by the certification gates.
72 @param[in] runtime_checked Whether the PETSc/MPI runtime suite was included.
73 @return Path of the generated certificate.
76 certificate = REPO_ROOT /
"logs" / f
"documentation-certificate-{sha}.md"
77 timestamp = dt.datetime.now(dt.timezone.utc).replace(microsecond=0).isoformat()
78 runtime_gate =
"`make check-full`" if runtime_checked
else "not run"
80 "This full certification is authoritative only for the commit named above. "
81 "Any source, configuration, example, or documentation change requires a new certification.\n"
83 else "This structural certification is authoritative only for the commit named above and "
84 "does not certify PETSc/MPI runtime behavior. A pre-push policy may reuse a recent full "
85 "certificate only when it establishes that runtime-relevant files are unchanged.\n"
87 certificate.write_text(
88 "# PICurv Documentation Certification\n\n"
89 f
"- Certified commit: `{sha}`\n"
90 f
"- Certified at (UTC): `{timestamp}`\n"
91 "- Markdown links: passed\n"
92 "- Public-header and implementation comment audit: passed\n"
93 "- PETSc option-ingress manifest audit: passed\n"
94 "- Example/template and configuration regression suite: passed\n"
95 "- Doxygen HTML build: passed with zero warnings\n"
96 f
"- PETSc/MPI runtime validation: {runtime_gate}\n\n"
105 @brief Parse documentation-certification command-line arguments.
106 @param[in] argv Arguments excluding the executable name.
107 @return Parsed command-line namespace.
110 parser = argparse.ArgumentParser(
111 description=
"Validate and certify PICurv documentation for the current clean Git commit."
116 help=
"also run the PETSc/MPI `make check-full` runtime validation gate",
121 help=
"run the gates without writing logs/documentation-certificate-<sha>.md",
123 return parser.parse_args(argv)
126def main(argv: list[str] |
None =
None) -> int:
128 @brief Run the commit-scoped documentation certification workflow.
129 @param[in] argv Optional command-line arguments excluding the executable name.
130 @return Process status code.
133 args =
parse_args(sys.argv[1:]
if argv
is None else argv)
136 run([sys.executable,
"tests/tooling/check_markdown_links.py"],
"Markdown links")
137 run([sys.executable,
"tests/tooling/audit_function_docs.py"],
"function documentation")
138 run([sys.executable,
"tests/tooling/audit_ingress.py"],
"option-ingress manifest")
140 [sys.executable,
"-m",
"pytest",
"-q",
"tests/test_repo_consistency.py",
"tests/test_config_regressions.py"],
141 "example/template and configuration validation",
143 run([
"make",
"--no-print-directory",
"build-docs"],
"Doxygen HTML build")
146 run([
"make",
"--no-print-directory",
"check-full"],
"PETSc/MPI runtime validation")
147 if not args.no_certificate:
149 certification_kind =
"full" if args.runtime
else "structural"
150 print(f
"{certification_kind.capitalize()} documentation certification through commit {sha}: {certificate}")
152 except (RuntimeError, subprocess.CalledProcessError)
as error:
153 print(f
"Documentation certification failed: {error}", file=sys.stderr)
157if __name__ ==
"__main__":
158 raise SystemExit(
main())
None run(list[str] command, str label)
Run one certification gate and stream its output.
None ensure_empty_doxygen_warning_log()
Fail certification when Doxygen reports a warning.
str require_clean_revision()
Require that HEAD names a clean, commit-scoped source revision.
argparse.Namespace parse_args(list[str] argv)
Parse documentation-certification command-line arguments.
int main(list[str]|None argv=None)
Run the commit-scoped documentation certification workflow.
Path write_certificate(str sha, bool runtime_checked)
Write a reproducible certification record for one validated revision.
str git_output(*str args)
Return trimmed output from one Git command.