ecddcef586
Record created/edited/deleted-in versions per page; add History.md and update workflow docs.
116 lines
3.1 KiB
Python
116 lines
3.1 KiB
Python
"""Push generated wiki tree into a Gitea wiki git repository."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import shutil
|
|
import subprocess
|
|
from pathlib import Path
|
|
|
|
|
|
class WikiPushError(RuntimeError):
|
|
pass
|
|
|
|
|
|
def _run(cmd: list[str], *, cwd: Path) -> str:
|
|
proc = subprocess.run(
|
|
cmd,
|
|
cwd=cwd,
|
|
capture_output=True,
|
|
text=True,
|
|
check=False,
|
|
)
|
|
if proc.returncode != 0:
|
|
raise WikiPushError(
|
|
f"$ {' '.join(cmd)}\n{proc.stdout}\n{proc.stderr}".strip()
|
|
)
|
|
return proc.stdout
|
|
|
|
|
|
def prepare_wiki_clone(
|
|
wiki_url: str,
|
|
work_dir: Path,
|
|
*,
|
|
branch: str = "main",
|
|
) -> Path:
|
|
"""Clone or reset wiki working tree; return path to existing manifest.json if any."""
|
|
work_dir = work_dir.resolve()
|
|
if work_dir.exists() and (work_dir / ".git").exists():
|
|
_run(["git", "fetch", "origin"], cwd=work_dir)
|
|
_run(["git", "checkout", branch], cwd=work_dir)
|
|
_run(["git", "reset", "--hard", f"origin/{branch}"], cwd=work_dir)
|
|
else:
|
|
if work_dir.exists():
|
|
shutil.rmtree(work_dir)
|
|
work_dir.parent.mkdir(parents=True, exist_ok=True)
|
|
_run(
|
|
[
|
|
"git",
|
|
"clone",
|
|
"--branch",
|
|
branch,
|
|
"--single-branch",
|
|
wiki_url,
|
|
str(work_dir),
|
|
],
|
|
cwd=work_dir.parent,
|
|
)
|
|
return work_dir
|
|
|
|
|
|
def push_wiki(
|
|
content_dir: Path,
|
|
wiki_url: str,
|
|
*,
|
|
work_dir: Path,
|
|
message: str,
|
|
branch: str = "main",
|
|
keep_unmanaged: bool = False,
|
|
already_prepared: bool = False,
|
|
) -> None:
|
|
"""
|
|
Clone/fetch wiki repo into work_dir, replace managed pages, commit, push.
|
|
|
|
Managed pages = all files from content_dir (md/json/images).
|
|
If keep_unmanaged=False, removes other .md/.json/images before copy.
|
|
"""
|
|
content_dir = content_dir.resolve()
|
|
work_dir = work_dir.resolve()
|
|
|
|
if not already_prepared:
|
|
prepare_wiki_clone(wiki_url, work_dir, branch=branch)
|
|
|
|
if not keep_unmanaged:
|
|
for path in work_dir.iterdir():
|
|
if path.name == ".git":
|
|
continue
|
|
if path.is_file() and path.suffix.lower() in {".md", ".json"}:
|
|
path.unlink()
|
|
elif path.is_file() and path.suffix.lower() in {
|
|
".png",
|
|
".jpg",
|
|
".jpeg",
|
|
".gif",
|
|
".bmp",
|
|
".webp",
|
|
}:
|
|
path.unlink()
|
|
|
|
for src in content_dir.iterdir():
|
|
if src.name == ".git":
|
|
continue
|
|
dst = work_dir / src.name
|
|
if src.is_dir():
|
|
if dst.exists():
|
|
shutil.rmtree(dst)
|
|
shutil.copytree(src, dst)
|
|
else:
|
|
shutil.copy2(src, dst)
|
|
|
|
_run(["git", "add", "-A"], cwd=work_dir)
|
|
status = _run(["git", "status", "--porcelain"], cwd=work_dir)
|
|
if not status.strip():
|
|
return
|
|
|
|
_run(["git", "commit", "-m", message], cwd=work_dir)
|
|
_run(["git", "push", "origin", f"HEAD:{branch}"], cwd=work_dir)
|