#!/usr/bin/env python3 """CLI: export 1C Help (ru.html) to Markdown / Gitea wiki.""" from __future__ import annotations import argparse import sys from pathlib import Path TOOL_ROOT = Path(__file__).resolve().parent if str(TOOL_ROOT) not in sys.path: sys.path.insert(0, str(TOOL_ROOT)) from export1c_help import __status__, __version__ # noqa: E402 from export1c_help.config_version import read_config_version # noqa: E402 from export1c_help.export import export_help # noqa: E402 from export1c_help.wiki import WikiPushError, prepare_wiki_clone, push_wiki # noqa: E402 def build_parser() -> argparse.ArgumentParser: p = argparse.ArgumentParser( prog="export_1c_help", description=( f"Выгрузка встроенной справки 1С (Ext/Help/ru.html) в Markdown / Gitea wiki. " f"v{__version__} ({__status__})." ), ) p.add_argument("--version", action="version", version=f"%(prog)s {__version__}") sub = p.add_subparsers(dest="cmd", required=True) c = sub.add_parser("convert", help="Конвертация Help → Markdown в каталог") _add_convert_args(c) c.set_defaults(func=cmd_convert) w = sub.add_parser("push", help="convert + push в Gitea wiki (.wiki.git)") _add_convert_args(w, require_out=False) w.add_argument( "--wiki-url", required=True, help="URL wiki-репозитория, напр. https://git.p7net.ru/1c/crm3_26.wiki.git", ) w.add_argument( "--work-dir", type=Path, default=None, help="Локальный clone wiki (по умолчанию: /wiki_clone)", ) w.add_argument( "-o", "--out", type=Path, default=None, help="Промежуточный каталог MD (по умолчанию: ./out/wiki-md)", ) w.add_argument( "--keep-unmanaged", action="store_true", help="Не удалять чужие .md в wiki перед копированием", ) w.add_argument("-m", "--message", default=None, help="Сообщение коммита wiki") w.add_argument("--branch", default="main") w.add_argument("--dry-run", action="store_true", help="Только convert, без git push") w.set_defaults(func=cmd_push) return p def _add_convert_args(p: argparse.ArgumentParser, *, require_out: bool = True) -> None: p.add_argument( "-s", "--src", type=Path, required=True, help="Каталог src выгрузки конфигурации (…/crm3-26/src)", ) if require_out: p.add_argument( "-o", "--out", type=Path, required=True, help="Каталог результата (wiki working tree)", ) p.add_argument( "--objects-only", action="store_true", help="Только справка объектов (без Forms/*/Ext/Help)", ) p.add_argument( "--keep-empty", action="store_true", help="Не пропускать почти пустые страницы", ) p.add_argument( "--clean", action="store_true", help="Очистить --out перед записью (кроме .git)", ) p.add_argument("--source-label", default=None, help="Подпись источника в Home.md") p.add_argument( "--prev-manifest", type=Path, default=None, help="Предыдущий manifest.json (жизненный цикл страниц)", ) p.add_argument( "--config-version", default=None, help="Версия конфигурации (иначе VERSION / Configuration.xml)", ) def _print_stats(stats, dest: Path) -> None: print( f"OK: config={stats.config_version} " f"written={stats.pages_written} " f"+{stats.created_count}/~{stats.edited_count}/={stats.unchanged_count}/−{stats.deleted_count} " f"skipped_empty={stats.pages_skipped_empty} " f"total={stats.pages_total} " f"images={stats.images_copied} → {dest}" ) def cmd_convert(args: argparse.Namespace) -> int: stats = export_help( args.src, args.out, include_forms=not args.objects_only, skip_empty=not args.keep_empty, clean=args.clean, source_label=args.source_label, prev_manifest_path=args.prev_manifest, config_version=args.config_version, ) _print_stats(stats, args.out) return 0 def cmd_push(args: argparse.Namespace) -> int: out = args.out or (TOOL_ROOT / "out" / "wiki-md") work = args.work_dir or (out.parent / "wiki_clone") branch = args.branch try: prepare_wiki_clone(args.wiki_url, work, branch=branch) except WikiPushError as exc: print(f"wiki prepare failed:\n{exc}", file=sys.stderr) return 1 prev = args.prev_manifest or (work / "manifest.json") cfg = args.config_version or read_config_version(args.src) stats = export_help( args.src, out, include_forms=not args.objects_only, skip_empty=not args.keep_empty, clean=True, source_label=args.source_label or str(args.src), prev_manifest_path=prev if prev.is_file() else None, config_version=cfg, ) print( f"convert: config={stats.config_version} " f"written={stats.pages_written} " f"+{stats.created_count}/~{stats.edited_count}/={stats.unchanged_count}/−{stats.deleted_count} " f"→ {out}" ) if args.dry_run: print("dry-run: push skipped") return 0 message = args.message or ( f"export_1c_help v{__version__}: sync help cfg {stats.config_version} " f"({stats.pages_written} pages, +{stats.created_count}/~{stats.edited_count}/−{stats.deleted_count})" ) try: push_wiki( out, args.wiki_url, work_dir=work, message=message, branch=branch, keep_unmanaged=args.keep_unmanaged, already_prepared=True, ) except WikiPushError as exc: print(f"push failed:\n{exc}", file=sys.stderr) return 1 print(f"OK: pushed → {args.wiki_url}") return 0 def main(argv: list[str] | None = None) -> int: parser = build_parser() args = parser.parse_args(argv) return args.func(args) if __name__ == "__main__": raise SystemExit(main())