import argparse
import subprocess
import sys
from pathlib import Path
LOCALES = ("ru", "zh")
DOCS_PREFIX = "docs/"
TRIGGERING = ("M", "D", "R")
REPO = Path(__file__).resolve().parent.parent
def git(*args: str) -> str:
return subprocess.run(
["git", *args], cwd=REPO, check=True, capture_output=True, text=True
).stdout
def family(path: str) -> tuple[str, dict[str, str]]:
relative = path[len(DOCS_PREFIX) :]
head, _, rest = relative.partition("/")
if head in LOCALES:
relative = rest
english = f"{DOCS_PREFIX}{relative}"
return english, {loc: f"{DOCS_PREFIX}{loc}/{relative}" for loc in LOCALES}
def changed_pages(base: str) -> dict[str, str]:
merge_base = git("merge-base", base, "HEAD").strip()
raw = git("diff", "--name-status", "-M", merge_base, "HEAD")
pages: dict[str, str] = {}
for line in raw.splitlines():
fields = line.split("\t")
code = fields[0]
status = code[0]
if status == "R" and code[1:] == "100":
continue
for path in fields[1:]:
if path.startswith(DOCS_PREFIX) and path.endswith(".md"):
pages[path] = status
return pages
def main() -> int:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument(
"--base",
default="origin/main",
help="branch, tag or commit the pull request targets (default: origin/main)",
)
args = parser.parse_args()
pages = changed_pages(args.base)
if not pages:
print("no documentation pages changed")
return 0
errors: list[str] = []
for path, status in sorted(pages.items()):
if status not in TRIGGERING:
continue
english, translations = family(path)
for member in (english, *translations.values()):
if member == path or member in pages:
continue
if not (REPO / member).exists():
continue
errors.append(f"{path} changed, but its counterpart {member} did not")
for error in errors:
print(error, file=sys.stderr)
if errors:
print(
"\nA change to what a page says belongs in every language that page exists in."
"\nIf this edit is confined to one language (spelling, grammar, or a word choice"
"\nthat was already right elsewhere), label the pull request and this job is"
"\nskipped; see .github/workflows/docs.yml for the label name.",
file=sys.stderr,
)
return 1
print(f"checked {len(pages)} changed documentation page(s)")
return 0
if __name__ == "__main__":
raise SystemExit(main())