Skip to content

Commit cd4e453

Browse files
committed
build(scripts): add docs-commit workflow and remove headers
1 parent 7419653 commit cd4e453

2 files changed

Lines changed: 60 additions & 6 deletions

File tree

Justfile

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,10 @@ docs: _require-uv
5757
uv run --extra docs python scripts/document_rules.py
5858
uv run --extra docs sphinx-build -ab html docs html
5959

60-
# check source headers
61-
headers: _require-uv
62-
uv run --extra dev python scripts/check_copyright.py
60+
# regenerate rule docs, commit generated changes, and build the docs
61+
docs-commit: _require-uv
62+
uv run --extra docs python scripts/document_rules.py --commit
63+
uv run --extra docs sphinx-build -ab html docs html
6364

6465
# clean build artifacts and caches
6566
clean:
@@ -75,7 +76,7 @@ spell: _require-uv
7576
uv run --extra dev codespell
7677

7778
# run all quality checks
78-
check: lint coverage typecheck spell headers
79+
check: lint coverage typecheck spell
7980

8081
# run the main local workflow
8182
all: install test lint docs

scripts/document_rules.py

Lines changed: 55 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,22 @@
1010
import inspect
1111
import re
1212
import shutil
13+
import subprocess
1314
from collections.abc import Callable, Iterable, Sequence
1415
from dataclasses import dataclass
1516
from pathlib import Path
1617
from textwrap import dedent, indent
1718
from typing import TypeVar
1819

20+
from interfacy import Interfacy
1921
from jinja2 import Template
2022

2123
from rattle.config import BUILTIN_RULE_COLLECTIONS, find_rules
2224
from rattle.ftypes import Invalid, QualifiedRule, Valid
2325
from rattle.rule import LintRule, RuleReference, RuleSetting
2426

25-
DOCS_DIR = Path(__file__).parent.parent / "docs"
27+
PROJECT_ROOT = Path(__file__).parent.parent
28+
DOCS_DIR = PROJECT_ROOT / "docs"
2629
RULES_INDEX_DOC = DOCS_DIR / "guide" / "builtins.md"
2730
RULES_CATEGORY_DIR = DOCS_DIR / "guide" / "rule-collections"
2831
RULES_DETAIL_DIR = DOCS_DIR / "guide" / "rules"
@@ -534,12 +537,62 @@ def render_rule_details(rules: Iterable[RuleDoc]) -> None:
534537
(RULES_DETAIL_DIR / f"{rule.slug}.md").write_text(rendered.rstrip() + "\n")
535538

536539

537-
def main() -> None:
540+
def generated_paths() -> tuple[Path, ...]:
541+
return (RULES_INDEX_DOC, RULES_CATEGORY_DIR, RULES_DETAIL_DIR)
542+
543+
544+
def git_path(path: Path) -> str:
545+
return path.relative_to(PROJECT_ROOT).as_posix()
546+
547+
548+
def git_executable() -> str:
549+
git = shutil.which("git")
550+
if git is None:
551+
raise RuntimeError("git executable not found")
552+
return git
553+
554+
555+
def commit_generated_docs(message: str) -> None:
556+
git = git_executable()
557+
paths = [git_path(path) for path in generated_paths()]
558+
subprocess.run([git, "add", "--", *paths], cwd=PROJECT_ROOT, check=True) # noqa: S603
559+
diff = subprocess.run( # noqa: S603
560+
[git, "diff", "--cached", "--quiet", "--", *paths],
561+
cwd=PROJECT_ROOT,
562+
check=False,
563+
)
564+
if diff.returncode == 0:
565+
return
566+
if diff.returncode != 1:
567+
raise subprocess.CalledProcessError(diff.returncode, diff.args)
568+
569+
subprocess.run( # noqa: S603
570+
[git, "commit", "-m", message, "--", *paths], cwd=PROJECT_ROOT, check=True
571+
)
572+
573+
574+
def generate_rule_docs(
575+
*,
576+
commit: bool = False,
577+
message: str = "docs: regenerate rule documentation",
578+
) -> None:
579+
"""Generate rule documentation.
580+
581+
Args:
582+
commit: Commit generated documentation changes with a Conventional Commit message.
583+
message: Commit message to use when commit is enabled.
584+
"""
538585
categories = build_categories()
539586
render_rule_categories(categories)
540587
render_rule_details(rule for category in categories for rule in category.rules)
541588
rendered = INDEX_TPL.render(categories=categories)
542589
RULES_INDEX_DOC.write_text(rendered.rstrip() + "\n")
590+
if commit:
591+
commit_generated_docs(message)
592+
593+
594+
def main(args: list[str] | None = None, *, sys_exit_enabled: bool = True) -> object:
595+
return Interfacy(sys_exit_enabled=sys_exit_enabled).run(generate_rule_docs, args=args)
543596

544597

545598
if __name__ == "__main__":

0 commit comments

Comments
 (0)