diff --git a/CHANGELOG.md b/CHANGELOG.md index 08bc9e8..e235a3d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,13 @@ All notable changes to **export_1c_help** are documented in this file. +## [0.3.3] - 2026-07-23 + +### Fixed + +- `push` no longer deletes user-written wiki pages; only manifest-managed help pages are updated/removed +- Full wipe available explicitly via `--wipe-unmanaged` + ## [0.3.2] - 2026-07-23 ### Fixed diff --git a/README.md b/README.md index 8b70b1e..7c5b9ec 100644 --- a/README.md +++ b/README.md @@ -115,7 +115,8 @@ python3 export_1c_help.py push -c /path/to/config --remote upstream python3 export_1c_help.py push -c /path/to/config ``` -**Канон текста** — HTML в конфигурации. Ручные правки wiki сотрутся при следующем `push` (если нет `--keep-unmanaged`). +**Канон текста справки** — HTML в конфигурации: страницы, попавшие в `manifest.json`, при `push` перезаписываются. +**Пользовательские статьи wiki** (не из выгрузки Help) **сохраняются**. Полная очистка wiki — только с `--wipe-unmanaged`. --- @@ -155,8 +156,10 @@ python3 export_1c_help.py push -c /path/to/config | `--remote` | имя remote для авто-URL (`origin`) | | `--objects-only` | без справки форм | | `--dry-run` | без git push | +| `--wipe-unmanaged` | стереть и пользовательские статьи wiki (по умолчанию они сохраняются) | | `--prev-manifest` | свой предыдущий manifest | | `--config-version` | явная версия | +| `-m` / `--message` | сообщение коммита | --- diff --git a/VERSION b/VERSION index d15723f..1c09c74 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.3.2 +0.3.3 diff --git a/export1c_help/wiki.py b/export1c_help/wiki.py index 9776c11..f792022 100644 --- a/export1c_help/wiki.py +++ b/export1c_help/wiki.py @@ -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(): diff --git a/export_1c_help.py b/export_1c_help.py index 9fa5472..dedfabc 100644 --- a/export_1c_help.py +++ b/export_1c_help.py @@ -89,10 +89,18 @@ def build_parser() -> argparse.ArgumentParser: default=None, help="Промежуточный каталог MD (по умолчанию: out/wiki-md-)", ) + w.add_argument( + "--wipe-unmanaged", + action="store_true", + help=( + "Удалить из wiki все .md/.json/картинки, не только страницы справки " + "(опасно: сотрёт пользовательские статьи)" + ), + ) w.add_argument( "--keep-unmanaged", action="store_true", - help="Не удалять чужие .md в wiki перед копированием", + help=argparse.SUPPRESS, # legacy no-op: preserving user pages is now default ) w.add_argument("-m", "--message", default=None, help="Сообщение коммита wiki") w.add_argument("--branch", default="main") @@ -278,7 +286,7 @@ def cmd_push(args: argparse.Namespace) -> int: work_dir=work, message=message, branch=branch, - keep_unmanaged=args.keep_unmanaged, + wipe_unmanaged=args.wipe_unmanaged, already_prepared=True, ) except WikiPushError as exc: