(args: argparse.Namespace)
| 207 | |
| 208 | |
| 209 | def render_run(args: argparse.Namespace) -> int: |
| 210 | mandoc_path = os.path.expanduser(args.mandoc or config.MANDOC_PATH) |
| 211 | corpus = [Path(p).expanduser() for p in args.paths] |
| 212 | if not corpus: |
| 213 | corpus = _read_corpus(Path(args.corpus)) |
| 214 | corpus = [p if p.is_absolute() else REPO_ROOT / p for p in corpus] |
| 215 | |
| 216 | timestamp = datetime.now(UTC).strftime("%Y%m%d-%H%M%S") |
| 217 | label = re.sub(r"[^A-Za-z0-9_.-]+", "-", args.label).strip("-") or "render" |
| 218 | run_dir = Path(args.output or DEFAULT_RUNS_DIR / f"{timestamp}-{label}") |
| 219 | for subdir in ("markdown", "html", "metrics"): |
| 220 | (run_dir / subdir).mkdir(parents=True, exist_ok=True) |
| 221 | |
| 222 | pages: list[dict[str, Any]] = [] |
| 223 | failures: list[dict[str, str]] = [] |
| 224 | for manpage in corpus: |
| 225 | rel_path = _repo_relative(manpage) |
| 226 | print(f"rendering {rel_path}") |
| 227 | if not manpage.is_file(): |
| 228 | failures.append({"path": rel_path, "error": "file not found"}) |
| 229 | continue |
| 230 | try: |
| 231 | page = _render_page(mandoc_path, manpage) |
| 232 | except Exception as exc: # noqa: BLE001 - report per-page render failures. |
| 233 | failures.append({"path": rel_path, "error": str(exc)}) |
| 234 | continue |
| 235 | (run_dir / "markdown" / f"{page.stem}.md").write_text(page.markdown) |
| 236 | (run_dir / "html" / f"{page.stem}.html").write_text(page.html) |
| 237 | _write_json(run_dir / "metrics" / f"{page.stem}.json", page.metrics) |
| 238 | pages.append( |
| 239 | { |
| 240 | "path": page.path, |
| 241 | "stem": page.stem, |
| 242 | "metrics": page.metrics, |
| 243 | } |
| 244 | ) |
| 245 | |
| 246 | summary = { |
| 247 | "label": args.label, |
| 248 | "timestamp": datetime.now(UTC).isoformat(), |
| 249 | "mandoc": mandoc_path, |
| 250 | "git": _git_metadata(), |
| 251 | "corpus": [_repo_relative(path) for path in corpus], |
| 252 | "page_count": len(pages), |
| 253 | "failure_count": len(failures), |
| 254 | "failures": failures, |
| 255 | "pages": pages, |
| 256 | } |
| 257 | _write_json(run_dir / "summary.json", summary) |
| 258 | print(f"\nrun directory: {run_dir}") |
| 259 | print(f"rendered pages: {len(pages)}") |
| 260 | print(f"failures: {len(failures)}") |
| 261 | return 1 if failures and args.fail_on_failure else 0 |
| 262 | |
| 263 | |
| 264 | def _suspicious_changes( |
nothing calls this directly
no test coverage detected