Support any 1C config dump and auto wiki URL from its git remote.
Add info command, -c/--config, derived repo.wiki.git target, and README for submodule/root workflows.
This commit is contained in:
+15
-30
@@ -2,45 +2,30 @@
|
||||
|
||||
All notable changes to **export_1c_help** are documented in this file.
|
||||
|
||||
## [0.3.0] - 2026-07-23
|
||||
|
||||
### Added
|
||||
|
||||
- Export help from **any** 1C configuration dump (`-c` / `--config` or `-s` / `--src`)
|
||||
- Auto wiki URL from the configuration git repo: `repo.git` → `repo.wiki.git` (Gitea/GitLab)
|
||||
- Explicit `--wiki-url` still supported (any target wiki)
|
||||
- `info` subcommand: src, version, git remote, derived wiki URL
|
||||
- Per-config default output dirs: `out/wiki-md-<slug>`, `out/wiki_clone-<slug>`
|
||||
- README: connect any submodule / root project to its wiki and run export
|
||||
|
||||
## [0.2.0] - 2026-07-23
|
||||
|
||||
### Added
|
||||
|
||||
- Configuration version on each export (`VERSION` / `Configuration.xml`)
|
||||
- Per-page lifecycle in wiki footer and `manifest.json`:
|
||||
- `created_in` — версия конфигурации, в которой страница впервые попала в wiki
|
||||
- `edited_in` — версия, в которой содержимое справки изменилось
|
||||
- `deleted_in` — версия, в которой страница исчезла из `src`
|
||||
- `History.md` — сводка выгрузки и накопительный список удалённых страниц
|
||||
- `push` читает предыдущий `manifest.json` из wiki перед пересборкой
|
||||
- Per-page lifecycle: `created_in` / `edited_in` / `deleted_in`
|
||||
- `History.md`, `push` reads previous `manifest.json` from wiki
|
||||
- CLI: `--prev-manifest`, `--config-version`
|
||||
|
||||
### Changed
|
||||
|
||||
- Home / Sidebar показывают версию конфигурации и ссылку на History
|
||||
|
||||
## [0.1.0] - 2026-07-23
|
||||
|
||||
### Status
|
||||
|
||||
**In development.** Full dump of configuration Help to Gitea wiki.
|
||||
|
||||
### Added
|
||||
|
||||
- Discovery of `**/Ext/Help/ru.html` in a 1C configuration `src/` tree (incl. nested `Subsystems`)
|
||||
- HTML → Markdown converter (stdlib only): headings, lists, bold/italic, links
|
||||
- Rewrite of 1C help links (`Catalog.X/Help`, `….Form.Y/Help`) to Gitea `[[wiki]]` links
|
||||
- Unique wiki page titles (H1 / synonym / meta key) with collision suffixes
|
||||
- Gitea-compatible **percent-encoded** filenames for Cyrillic titles
|
||||
- `Home.md` index and `_Sidebar.md` navigation
|
||||
- `manifest.json` (meta_key → title mapping)
|
||||
- CLI: `convert`, `push` (clone/commit/push wiki git repo)
|
||||
- Option `--objects-only` to skip form-level help
|
||||
|
||||
### Fixed
|
||||
|
||||
- Nested subsystem help paths (`Subsystems/A/Subsystems/B/…`) no longer collapse to the parent meta key
|
||||
- Unicode wiki filenames replaced with percent-encoded slugs (Gitea UI returned HTTP 500)
|
||||
Initial release: Help HTML → Markdown, Gitea wiki push, percent-encoded Cyrillic filenames.
|
||||
|
||||
[0.3.0]: https://git.p7net.ru/tools/export_1c_help/releases/tag/v0.3.0
|
||||
[0.2.0]: https://git.p7net.ru/tools/export_1c_help/releases/tag/v0.2.0
|
||||
[0.1.0]: https://git.p7net.ru/tools/export_1c_help/releases/tag/v0.1.0
|
||||
|
||||
@@ -1,108 +1,187 @@
|
||||
# export_1c_help
|
||||
|
||||
**Версия:** см. [`VERSION`](VERSION) (текущая: **0.2.0**) · [CHANGELOG](CHANGELOG.md)
|
||||
**Версия:** см. [`VERSION`](VERSION) (текущая: **0.3.0**) · [CHANGELOG](CHANGELOG.md)
|
||||
**Лицензия:** [MIT](LICENSE)
|
||||
|
||||
Выгрузка встроенной справки конфигурации 1С (`**/Ext/Help/ru.html`) в Markdown и публикация в [Gitea Wiki](https://docs.gitea.com/usage/wiki).
|
||||
Выгрузка встроенной справки **любой** конфигурации 1С (`**/Ext/Help/ru.html`) в Markdown и публикация в wiki git-репозитория (Gitea / GitLab: `*.wiki.git`).
|
||||
|
||||
Зависимости: **Python 3.10+**, только стандартная библиотека.
|
||||
|
||||
---
|
||||
|
||||
## Порядок обновления wiki (после доработки справки в конфигурации)
|
||||
## Подключение произвольной конфигурации к wiki
|
||||
|
||||
Инструмент **всегда** пересобирает wiki из всего `src/` (инкрементального патча нет). Частичная правка Help в конфигураторе → полная перевыгрузка `src` → полный `push`.
|
||||
Инструмент не привязан к `crm3-26`. Источник — каталог выгрузки конфигурации (подмодуль или корневой git-проект). Цель — wiki **этого** репозитория либо любой другой `*.wiki.git`.
|
||||
|
||||
1. Доработать справку в конфигураторе (нужные объекты/формы).
|
||||
2. Выгрузить конфигурацию в git (`crm3-26/`) и закоммитить/запушить, как обычно.
|
||||
3. В монорепо: `git pull` (актуальный `crm3-26/src`, в т.ч. `VERSION` / `Configuration.xml`).
|
||||
4. Синхронизировать wiki:
|
||||
### 1. Подготовка репозитория конфигурации
|
||||
|
||||
```bash
|
||||
cd tools/export_1c_help
|
||||
python3 export_1c_help.py push \
|
||||
-s ../../crm3-26/src \
|
||||
--wiki-url https://git.p7net.ru/1c/crm3_26.wiki.git \
|
||||
-m "sync help after config update"
|
||||
1. Конфигурация лежит в git (отдельный репозиторий или submodule), типичная структура:
|
||||
|
||||
```text
|
||||
<config-root>/
|
||||
VERSION # опционально
|
||||
src/
|
||||
Configuration.xml
|
||||
Catalogs/…/Ext/Help/ru.html
|
||||
…
|
||||
```
|
||||
|
||||
Перед записью можно проверить без push:
|
||||
2. На сервере (Gitea / GitLab) у репозитория конфигурации **включена Wiki**.
|
||||
3. Убедитесь, что у вас есть права **push** в wiki (`…/repo.wiki.git`).
|
||||
Первый push создаст/обновит страницы; на Gitea wiki должна быть уже инициализирована (хотя бы пустая/одна страница через UI, если сервер так требует).
|
||||
|
||||
Проверка путей и URL:
|
||||
|
||||
```bash
|
||||
cd tools/export_1c_help # или путь к клону export_1c_help
|
||||
|
||||
# подмодуль в монорепо
|
||||
python3 export_1c_help.py info -c ../../crm3-26
|
||||
|
||||
# корневой клон конфигурации
|
||||
python3 export_1c_help.py info -c /path/to/my_config
|
||||
|
||||
# только src
|
||||
python3 export_1c_help.py info -s /path/to/my_config/src
|
||||
```
|
||||
|
||||
Пример вывода:
|
||||
|
||||
```text
|
||||
config_root: …/crm3-26
|
||||
src: …/crm3-26/src
|
||||
config_version: 3.1.36.33
|
||||
git_remote(origin): https://git.p7net.ru/1c/crm3_26.git
|
||||
wiki_url: https://git.p7net.ru/1c/crm3_26.wiki.git
|
||||
```
|
||||
|
||||
Правило авто-URL: `https://host/org/repo.git` → `https://host/org/repo.wiki.git`
|
||||
(аналогично для `git@host:org/repo.git`).
|
||||
|
||||
### 2. Первая выгрузка в wiki репозитория конфигурации
|
||||
|
||||
Без `--wiki-url` цель берётся из `origin` git-репозитория, которому принадлежит `-c` / `-s`:
|
||||
|
||||
```bash
|
||||
# подмодуль
|
||||
python3 export_1c_help.py push -c ../../crm3-26
|
||||
|
||||
# любой другой корень / submodule
|
||||
python3 export_1c_help.py push -c /path/to/other_config
|
||||
|
||||
# dry-run (только сборка MD, без push)
|
||||
python3 export_1c_help.py push -c ../../crm3-26 --dry-run
|
||||
```
|
||||
|
||||
Промежуточные каталоги по умолчанию (чтобы не смешивать конфигурации):
|
||||
|
||||
- `out/wiki-md-<имя-корня>/`
|
||||
- `out/wiki_clone-<имя-корня>/`
|
||||
|
||||
### 3. Выгрузка в произвольный wiki
|
||||
|
||||
Если wiki не у того же репозитория (или remote не определяется):
|
||||
|
||||
```bash
|
||||
python3 export_1c_help.py push \
|
||||
-s ../../crm3-26/src \
|
||||
--wiki-url https://git.p7net.ru/1c/crm3_26.wiki.git \
|
||||
--dry-run
|
||||
-c /path/to/config \
|
||||
--wiki-url https://git.example/org/docs.wiki.git
|
||||
```
|
||||
|
||||
**Канон текста** — HTML в конфигурации. Ручные правки страниц в wiki сотрутся при следующем `push` (если не указан `--keep-unmanaged`).
|
||||
Можно указать и URL кода — он будет преобразован в `.wiki.git`:
|
||||
|
||||
```bash
|
||||
python3 export_1c_help.py push \
|
||||
-c /path/to/config \
|
||||
--wiki-url https://git.example/org/docs.git
|
||||
```
|
||||
|
||||
Другой remote (не `origin`):
|
||||
|
||||
```bash
|
||||
python3 export_1c_help.py push -c /path/to/config --remote upstream
|
||||
```
|
||||
|
||||
### 4. Обновление после доработки справки в конфигураторе
|
||||
|
||||
Инструмент **всегда** пересобирает wiki из всего `src/` (инкремента нет).
|
||||
|
||||
1. Доработать Help в конфигураторе.
|
||||
2. Выгрузить конфигурацию в её git-репозиторий (`git commit` / `push`).
|
||||
3. Обновить рабочую копию (`git pull` / `git submodule update`).
|
||||
4. Снова:
|
||||
|
||||
```bash
|
||||
python3 export_1c_help.py push -c /path/to/config
|
||||
```
|
||||
|
||||
**Канон текста** — HTML в конфигурации. Ручные правки wiki сотрутся при следующем `push` (если нет `--keep-unmanaged`).
|
||||
|
||||
---
|
||||
|
||||
## Версии конфигурации на страницах
|
||||
|
||||
| Где | Что фиксируется |
|
||||
|-----|-----------------|
|
||||
| Где | Что |
|
||||
|-----|-----|
|
||||
| `Home.md` | версия конфигурации **этой** выгрузки |
|
||||
| подвал каждой страницы | версия выгрузки; **создана в** / **изменена в** |
|
||||
| `History.md` | сводка +/−/~ и накопительный список **удалённых** (`deleted_in`) |
|
||||
| `manifest.json` | те же поля + `content_hash`, история `exports[]` |
|
||||
| подвал страницы | версия выгрузки; **создана в** / **изменена в** |
|
||||
| `History.md` | сводка +/−/~ и удалённые (`deleted_in`) |
|
||||
| `manifest.json` | lifecycle + `content_hash` + `exports[]` |
|
||||
|
||||
Версия берётся из `<config>/VERSION` или `<Version>` в `Configuration.xml` (можно переопределить `--config-version`).
|
||||
Версия: `<config>/VERSION` или `<Version>` в `Configuration.xml` (`--config-version` перекрывает).
|
||||
|
||||
Жизненный цикл считается относительно предыдущего `manifest.json` в wiki (при `push` подтягивается автоматически).
|
||||
|
||||
---
|
||||
|
||||
## Быстрый старт
|
||||
|
||||
```bash
|
||||
cd tools/export_1c_help
|
||||
|
||||
python3 export_1c_help.py convert \
|
||||
-s ../../crm3-26/src \
|
||||
-o ./out/wiki-md \
|
||||
--clean
|
||||
|
||||
python3 export_1c_help.py push \
|
||||
-s ../../crm3-26/src \
|
||||
--wiki-url https://git.p7net.ru/1c/crm3_26.wiki.git
|
||||
```
|
||||
|
||||
```bash
|
||||
python3 export_1c_help.py --version
|
||||
```
|
||||
При `push` предыдущий `manifest.json` читается из целевой wiki автоматически.
|
||||
|
||||
---
|
||||
|
||||
## Команды
|
||||
|
||||
### `convert`
|
||||
| Команда | Назначение |
|
||||
|---------|------------|
|
||||
| `info` | пути, версия, remote, wiki URL |
|
||||
| `convert` | только Markdown на диск |
|
||||
| `push` | convert + commit/push в wiki |
|
||||
|
||||
Общие параметры источника (взаимоисключающие):
|
||||
|
||||
| Параметр | Описание |
|
||||
|----------|----------|
|
||||
| `-s` / `--src` | каталог `src` выгрузки конфигурации |
|
||||
| `-o` / `--out` | каталог результата |
|
||||
| `-c` / `--config` | корень конфигурации (`…/crm3-26`) **или** её `src/` |
|
||||
| `-s` / `--src` | явно каталог `src` |
|
||||
|
||||
| Параметр | Описание |
|
||||
|----------|----------|
|
||||
| `--wiki-url` | явный wiki (иначе из git remote конфигурации) |
|
||||
| `--remote` | имя remote для авто-URL (`origin`) |
|
||||
| `--objects-only` | без справки форм |
|
||||
| `--keep-empty` | не пропускать почти пустые страницы |
|
||||
| `--clean` | очистить `--out` перед записью |
|
||||
| `--prev-manifest` | предыдущий `manifest.json` (lifecycle) |
|
||||
| `--config-version` | явная версия конфигурации |
|
||||
|
||||
### `push`
|
||||
|
||||
`prepare wiki` → `convert` (с `manifest.json` из wiki) → `git commit` / `push`.
|
||||
|
||||
| Параметр | Описание |
|
||||
|----------|----------|
|
||||
| `--wiki-url` | URL `*.wiki.git` |
|
||||
| `--dry-run` | только convert |
|
||||
| `--keep-unmanaged` | не удалять чужие `.md` |
|
||||
| `-m` / `--message` | сообщение коммита |
|
||||
| `--dry-run` | без git push |
|
||||
| `--prev-manifest` | свой предыдущий manifest |
|
||||
| `--config-version` | явная версия |
|
||||
|
||||
---
|
||||
|
||||
## Репозиторий
|
||||
## Примеры для монорепозитория миграции
|
||||
|
||||
- путь: `tools/export_1c_help/`
|
||||
```bash
|
||||
# целевая crm3-26 → её wiki
|
||||
python3 export_1c_help.py push -c ../../crm3-26
|
||||
|
||||
# исходная crm3-dev → её wiki (если wiki включена у crm3_old)
|
||||
python3 export_1c_help.py push -c ../../crm3-dev
|
||||
|
||||
# расширение — только если в выгрузке есть Ext/Help
|
||||
python3 export_1c_help.py info -c ../../crm3-26.rhana
|
||||
```
|
||||
|
||||
Только локальная конвертация:
|
||||
|
||||
```bash
|
||||
python3 export_1c_help.py convert -c ../../crm3-26 -o ./out/wiki-md-crm3-26 --clean
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Репозиторий инструмента
|
||||
|
||||
- путь в монорепо: `tools/export_1c_help/`
|
||||
- remote: https://git.p7net.ru/tools/export_1c_help.git
|
||||
|
||||
@@ -0,0 +1,137 @@
|
||||
"""Resolve configuration paths and Gitea/GitLab wiki clone URLs."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
class ResolveError(ValueError):
|
||||
pass
|
||||
|
||||
|
||||
def resolve_src_root(config_or_src: Path) -> Path:
|
||||
"""
|
||||
Accept configuration root (…/crm3-26) or its src/ dump.
|
||||
|
||||
Returns absolute path to the directory that contains Catalogs/, Documents/, …
|
||||
"""
|
||||
path = Path(config_or_src).expanduser().resolve()
|
||||
if not path.exists():
|
||||
raise ResolveError(f"path does not exist: {path}")
|
||||
|
||||
if path.is_file():
|
||||
raise ResolveError(f"expected directory, got file: {path}")
|
||||
|
||||
if _looks_like_src(path):
|
||||
return path
|
||||
|
||||
src = path / "src"
|
||||
if src.is_dir() and _looks_like_src(src):
|
||||
return src.resolve()
|
||||
|
||||
raise ResolveError(
|
||||
f"not a 1C configuration dump: {path} "
|
||||
"(need …/src with Catalogs|Documents|Configuration.xml, or the src itself)"
|
||||
)
|
||||
|
||||
|
||||
def resolve_config_root(config_or_src: Path) -> Path:
|
||||
"""Configuration root (parent of src when applicable)."""
|
||||
src = resolve_src_root(config_or_src)
|
||||
if src.name == "src":
|
||||
return src.parent
|
||||
return src
|
||||
|
||||
|
||||
def _looks_like_src(path: Path) -> bool:
|
||||
if (path / "Configuration.xml").is_file():
|
||||
return True
|
||||
markers = ("Catalogs", "Documents", "DataProcessors", "Reports", "CommonModules")
|
||||
return any((path / name).is_dir() for name in markers)
|
||||
|
||||
|
||||
def git_toplevel(path: Path) -> Path | None:
|
||||
"""Nearest git work tree containing path (submodule or root project)."""
|
||||
path = Path(path).resolve()
|
||||
try:
|
||||
proc = subprocess.run(
|
||||
["git", "-C", str(path), "rev-parse", "--show-toplevel"],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
check=False,
|
||||
)
|
||||
except OSError:
|
||||
return None
|
||||
if proc.returncode != 0:
|
||||
return None
|
||||
top = proc.stdout.strip()
|
||||
return Path(top) if top else None
|
||||
|
||||
|
||||
def git_remote_url(path: Path, *, remote: str = "origin") -> str | None:
|
||||
"""Clone URL of `remote` for the git repo that owns path."""
|
||||
top = git_toplevel(path)
|
||||
if top is None:
|
||||
return None
|
||||
try:
|
||||
proc = subprocess.run(
|
||||
["git", "-C", str(top), "remote", "get-url", remote],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
check=False,
|
||||
)
|
||||
except OSError:
|
||||
return None
|
||||
if proc.returncode != 0:
|
||||
return None
|
||||
url = proc.stdout.strip()
|
||||
return url or None
|
||||
|
||||
|
||||
def to_wiki_clone_url(repo_url: str) -> str:
|
||||
"""
|
||||
Map configuration repository URL → wiki git URL.
|
||||
|
||||
Gitea / GitLab: https://host/org/repo.git → https://host/org/repo.wiki.git
|
||||
git@host:org/repo.git → git@host:org/repo.wiki.git
|
||||
"""
|
||||
url = repo_url.strip().rstrip("/")
|
||||
if not url:
|
||||
raise ResolveError("empty repository URL")
|
||||
|
||||
if url.endswith(".wiki.git"):
|
||||
return url
|
||||
|
||||
if url.endswith(".git"):
|
||||
return url[: -len(".git")] + ".wiki.git"
|
||||
|
||||
return url + ".wiki.git"
|
||||
|
||||
|
||||
def resolve_wiki_url(
|
||||
config_or_src: Path,
|
||||
*,
|
||||
wiki_url: str | None = None,
|
||||
remote: str = "origin",
|
||||
) -> str:
|
||||
"""Explicit --wiki-url, or derive from git remote of the configuration repo."""
|
||||
if wiki_url:
|
||||
return to_wiki_clone_url(wiki_url)
|
||||
|
||||
root = resolve_config_root(config_or_src)
|
||||
repo = git_remote_url(root, remote=remote)
|
||||
if not repo:
|
||||
raise ResolveError(
|
||||
f"cannot detect git remote '{remote}' for {root}; "
|
||||
"pass --wiki-url explicitly (…/repo.wiki.git)"
|
||||
)
|
||||
return to_wiki_clone_url(repo)
|
||||
|
||||
|
||||
def slug_for_path(path: Path) -> str:
|
||||
"""Short filesystem-safe slug from config root name."""
|
||||
name = resolve_config_root(path).name
|
||||
slug = re.sub(r"[^\w.\-]+", "-", name, flags=re.UNICODE).strip("-")
|
||||
return slug or "config"
|
||||
+119
-23
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
"""CLI: export 1C Help (ru.html) to Markdown / Gitea wiki."""
|
||||
"""CLI: export 1C Help (ru.html) to Markdown / Gitea/GitLab wiki."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
@@ -12,8 +12,20 @@ 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.config_version import ( # noqa: E402
|
||||
read_config_name,
|
||||
read_config_version,
|
||||
)
|
||||
from export1c_help.export import export_help # noqa: E402
|
||||
from export1c_help.resolve import ( # noqa: E402
|
||||
ResolveError,
|
||||
git_remote_url,
|
||||
git_toplevel,
|
||||
resolve_config_root,
|
||||
resolve_src_root,
|
||||
resolve_wiki_url,
|
||||
slug_for_path,
|
||||
)
|
||||
from export1c_help.wiki import WikiPushError, prepare_wiki_clone, push_wiki # noqa: E402
|
||||
|
||||
|
||||
@@ -21,7 +33,7 @@ def build_parser() -> argparse.ArgumentParser:
|
||||
p = argparse.ArgumentParser(
|
||||
prog="export_1c_help",
|
||||
description=(
|
||||
f"Выгрузка встроенной справки 1С (Ext/Help/ru.html) в Markdown / Gitea wiki. "
|
||||
f"Выгрузка встроенной справки любой конфигурации 1С в Markdown / wiki. "
|
||||
f"v{__version__} ({__status__})."
|
||||
),
|
||||
)
|
||||
@@ -29,29 +41,53 @@ def build_parser() -> argparse.ArgumentParser:
|
||||
|
||||
sub = p.add_subparsers(dest="cmd", required=True)
|
||||
|
||||
i = sub.add_parser(
|
||||
"info",
|
||||
help="Показать src, версию, git remote и wiki URL для конфигурации",
|
||||
)
|
||||
_add_config_path_args(i)
|
||||
i.add_argument("--remote", default="origin", help="Git remote (по умолчанию origin)")
|
||||
i.add_argument(
|
||||
"--wiki-url",
|
||||
default=None,
|
||||
help="Явный wiki URL (иначе из remote конфигурации)",
|
||||
)
|
||||
i.set_defaults(func=cmd_info)
|
||||
|
||||
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)")
|
||||
w = sub.add_parser(
|
||||
"push",
|
||||
help="convert + push в wiki (явный --wiki-url или wiki репозитория конфигурации)",
|
||||
)
|
||||
_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",
|
||||
default=None,
|
||||
help=(
|
||||
"URL wiki-репозитория (…/repo.wiki.git). "
|
||||
"Если не задан — берётся из git remote конфигурации (…/repo.git → …/repo.wiki.git)"
|
||||
),
|
||||
)
|
||||
w.add_argument(
|
||||
"--remote",
|
||||
default="origin",
|
||||
help="Git remote конфигурации для авто-wiki URL (по умолчанию origin)",
|
||||
)
|
||||
w.add_argument(
|
||||
"--work-dir",
|
||||
type=Path,
|
||||
default=None,
|
||||
help="Локальный clone wiki (по умолчанию: <out-parent>/wiki_clone)",
|
||||
help="Локальный clone wiki (по умолчанию: out/wiki_clone-<slug>)",
|
||||
)
|
||||
w.add_argument(
|
||||
"-o",
|
||||
"--out",
|
||||
type=Path,
|
||||
default=None,
|
||||
help="Промежуточный каталог MD (по умолчанию: ./out/wiki-md)",
|
||||
help="Промежуточный каталог MD (по умолчанию: out/wiki-md-<slug>)",
|
||||
)
|
||||
w.add_argument(
|
||||
"--keep-unmanaged",
|
||||
@@ -66,14 +102,25 @@ def build_parser() -> argparse.ArgumentParser:
|
||||
return p
|
||||
|
||||
|
||||
def _add_convert_args(p: argparse.ArgumentParser, *, require_out: bool = True) -> None:
|
||||
p.add_argument(
|
||||
def _add_config_path_args(p: argparse.ArgumentParser) -> argparse._MutuallyExclusiveGroup:
|
||||
g = p.add_mutually_exclusive_group(required=True)
|
||||
g.add_argument(
|
||||
"-c",
|
||||
"--config",
|
||||
type=Path,
|
||||
help="Корень выгрузки конфигурации (каталог с src/) или сам src/",
|
||||
)
|
||||
g.add_argument(
|
||||
"-s",
|
||||
"--src",
|
||||
type=Path,
|
||||
required=True,
|
||||
help="Каталог src выгрузки конфигурации (…/crm3-26/src)",
|
||||
help="Каталог src выгрузки (эквивалент -c …/src)",
|
||||
)
|
||||
return g
|
||||
|
||||
|
||||
def _add_convert_args(p: argparse.ArgumentParser, *, require_out: bool = True) -> None:
|
||||
_add_config_path_args(p)
|
||||
if require_out:
|
||||
p.add_argument(
|
||||
"-o",
|
||||
@@ -111,6 +158,14 @@ def _add_convert_args(p: argparse.ArgumentParser, *, require_out: bool = True) -
|
||||
)
|
||||
|
||||
|
||||
def _config_input(args: argparse.Namespace) -> Path:
|
||||
return args.config if getattr(args, "config", None) else args.src
|
||||
|
||||
|
||||
def _resolve_src(args: argparse.Namespace) -> Path:
|
||||
return resolve_src_root(_config_input(args))
|
||||
|
||||
|
||||
def _print_stats(stats, dest: Path) -> None:
|
||||
print(
|
||||
f"OK: config={stats.config_version} "
|
||||
@@ -122,14 +177,42 @@ def _print_stats(stats, dest: Path) -> None:
|
||||
)
|
||||
|
||||
|
||||
def cmd_info(args: argparse.Namespace) -> int:
|
||||
try:
|
||||
src = _resolve_src(args)
|
||||
root = resolve_config_root(src)
|
||||
wiki = resolve_wiki_url(src, wiki_url=args.wiki_url, remote=args.remote)
|
||||
except ResolveError as exc:
|
||||
print(f"error: {exc}", file=sys.stderr)
|
||||
return 1
|
||||
|
||||
top = git_toplevel(root)
|
||||
remote_url = git_remote_url(root, remote=args.remote)
|
||||
print(f"config_root: {root}")
|
||||
print(f"src: {src}")
|
||||
print(f"config_name: {read_config_name(src) or '—'}")
|
||||
print(f"config_version: {read_config_version(src)}")
|
||||
print(f"git_toplevel: {top or '—'}")
|
||||
print(f"git_remote({args.remote}): {remote_url or '—'}")
|
||||
print(f"wiki_url: {wiki}")
|
||||
print(f"slug: {slug_for_path(src)}")
|
||||
return 0
|
||||
|
||||
|
||||
def cmd_convert(args: argparse.Namespace) -> int:
|
||||
try:
|
||||
src = _resolve_src(args)
|
||||
except ResolveError as exc:
|
||||
print(f"error: {exc}", file=sys.stderr)
|
||||
return 1
|
||||
|
||||
stats = export_help(
|
||||
args.src,
|
||||
src,
|
||||
args.out,
|
||||
include_forms=not args.objects_only,
|
||||
skip_empty=not args.keep_empty,
|
||||
clean=args.clean,
|
||||
source_label=args.source_label,
|
||||
source_label=args.source_label or str(src),
|
||||
prev_manifest_path=args.prev_manifest,
|
||||
config_version=args.config_version,
|
||||
)
|
||||
@@ -138,27 +221,40 @@ def cmd_convert(args: argparse.Namespace) -> int:
|
||||
|
||||
|
||||
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")
|
||||
try:
|
||||
src = _resolve_src(args)
|
||||
wiki_url = resolve_wiki_url(
|
||||
src, wiki_url=args.wiki_url, remote=args.remote
|
||||
)
|
||||
except ResolveError as exc:
|
||||
print(f"error: {exc}", file=sys.stderr)
|
||||
return 1
|
||||
|
||||
slug = slug_for_path(src)
|
||||
out = args.out or (TOOL_ROOT / "out" / f"wiki-md-{slug}")
|
||||
work = args.work_dir or (TOOL_ROOT / "out" / f"wiki_clone-{slug}")
|
||||
branch = args.branch
|
||||
|
||||
print(f"wiki_url: {wiki_url}")
|
||||
print(f"src: {src}")
|
||||
|
||||
try:
|
||||
prepare_wiki_clone(args.wiki_url, work, branch=branch)
|
||||
prepare_wiki_clone(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)
|
||||
cfg = args.config_version or read_config_version(src)
|
||||
|
||||
stats = export_help(
|
||||
args.src,
|
||||
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,
|
||||
source_label=args.source_label or str(src),
|
||||
prev_manifest_path=prev if Path(prev).is_file() else None,
|
||||
config_version=cfg,
|
||||
)
|
||||
print(
|
||||
@@ -178,7 +274,7 @@ def cmd_push(args: argparse.Namespace) -> int:
|
||||
try:
|
||||
push_wiki(
|
||||
out,
|
||||
args.wiki_url,
|
||||
wiki_url,
|
||||
work_dir=work,
|
||||
message=message,
|
||||
branch=branch,
|
||||
@@ -188,7 +284,7 @@ def cmd_push(args: argparse.Namespace) -> int:
|
||||
except WikiPushError as exc:
|
||||
print(f"push failed:\n{exc}", file=sys.stderr)
|
||||
return 1
|
||||
print(f"OK: pushed → {args.wiki_url}")
|
||||
print(f"OK: pushed → {wiki_url}")
|
||||
return 0
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user