Preserve user wiki pages on help export push.
Only manifest-managed help pages are updated or removed; add --wipe-unmanaged for a full clean.
This commit is contained in:
+43
-15
@@ -2,10 +2,15 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import shutil
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
# Always owned by export_1c_help (not user articles).
|
||||
_MANAGED_FIXED = frozenset({"Home.md", "History.md", "_Sidebar.md", "manifest.json"})
|
||||
_IMAGE_SUFFIXES = frozenset({".png", ".jpg", ".jpeg", ".gif", ".bmp", ".webp"})
|
||||
|
||||
|
||||
class WikiPushError(RuntimeError):
|
||||
pass
|
||||
@@ -32,7 +37,7 @@ def prepare_wiki_clone(
|
||||
*,
|
||||
branch: str = "main",
|
||||
) -> Path:
|
||||
"""Clone or reset wiki working tree; return path to existing manifest.json if any."""
|
||||
"""Clone or reset wiki working tree."""
|
||||
work_dir = work_dir.resolve()
|
||||
if work_dir.exists() and (work_dir / ".git").exists():
|
||||
_run(["git", "fetch", "origin"], cwd=work_dir)
|
||||
@@ -57,6 +62,22 @@ def prepare_wiki_clone(
|
||||
return work_dir
|
||||
|
||||
|
||||
def managed_filenames_from_manifest(manifest_path: Path) -> set[str]:
|
||||
"""Filenames previously written by export_1c_help."""
|
||||
names = set(_MANAGED_FIXED)
|
||||
if not manifest_path.is_file():
|
||||
return names
|
||||
try:
|
||||
data = json.loads(manifest_path.read_text(encoding="utf-8"))
|
||||
except (OSError, json.JSONDecodeError):
|
||||
return names
|
||||
for key in ("pages", "deleted_pages"):
|
||||
for item in data.get(key) or []:
|
||||
if isinstance(item, dict) and item.get("filename"):
|
||||
names.add(str(item["filename"]))
|
||||
return names
|
||||
|
||||
|
||||
def push_wiki(
|
||||
content_dir: Path,
|
||||
wiki_url: str,
|
||||
@@ -64,14 +85,14 @@ def push_wiki(
|
||||
work_dir: Path,
|
||||
message: str,
|
||||
branch: str = "main",
|
||||
keep_unmanaged: bool = False,
|
||||
wipe_unmanaged: bool = False,
|
||||
already_prepared: bool = False,
|
||||
) -> None:
|
||||
"""
|
||||
Clone/fetch wiki repo into work_dir, replace managed pages, commit, push.
|
||||
Clone/fetch wiki, update only export-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.
|
||||
User-written wiki pages (not listed in previous manifest.json) are kept
|
||||
unless wipe_unmanaged=True.
|
||||
"""
|
||||
content_dir = content_dir.resolve()
|
||||
work_dir = work_dir.resolve()
|
||||
@@ -79,20 +100,27 @@ def push_wiki(
|
||||
if not already_prepared:
|
||||
prepare_wiki_clone(wiki_url, work_dir, branch=branch)
|
||||
|
||||
if not keep_unmanaged:
|
||||
new_files = {
|
||||
p.name
|
||||
for p in content_dir.iterdir()
|
||||
if p.is_file() and p.name != ".git"
|
||||
}
|
||||
prev_managed = managed_filenames_from_manifest(work_dir / "manifest.json")
|
||||
|
||||
if wipe_unmanaged:
|
||||
for path in work_dir.iterdir():
|
||||
if path.name == ".git":
|
||||
continue
|
||||
if path.is_file() and path.suffix.lower() in {".md", ".json"}:
|
||||
if not path.is_file():
|
||||
continue
|
||||
suf = path.suffix.lower()
|
||||
if suf in {".md", ".json"} or suf in _IMAGE_SUFFIXES:
|
||||
path.unlink()
|
||||
elif path.is_file() and path.suffix.lower() in {
|
||||
".png",
|
||||
".jpg",
|
||||
".jpeg",
|
||||
".gif",
|
||||
".bmp",
|
||||
".webp",
|
||||
}:
|
||||
else:
|
||||
# Drop help pages that disappeared from the configuration export.
|
||||
for name in sorted(prev_managed - new_files):
|
||||
path = work_dir / name
|
||||
if path.is_file():
|
||||
path.unlink()
|
||||
|
||||
for src in content_dir.iterdir():
|
||||
|
||||
Reference in New Issue
Block a user