feat(epf-build,epf-dump): полная сборка/разборка EPF·ERF через ibcmd

Если -V8Path указывает на ibcmd.exe — обработки/отчёты собираются и
разбираются автономным сервером (offline, без запуска платформы), иначе
как прежде через 1cv8 DESIGNER.

- epf-build → ibcmd infobase config import <src-dir> --out=<epf> --db-path
- epf-dump  → ibcmd infobase config export --file=<epf> <dir> --db-path
- stub-db-create: при ibcmd создаёт stub-базу ОДНИМ вызовом
  ibcmd infobase create --db-path --create-database [--import=cfg --apply
  --force] вместо трёх стартов 1cv8 (CREATEINFOBASE/Load/Update). --force
  обязателен: иначе apply уходит в интерактивный [y/n] и отменяется.

Только файловые базы (серверные/-Format Plain под ibcmd → чистая ошибка).
1cv8-ветки без изменений. Версии: epf-build/epf-dump 1.1→1.2,
stub-db-create 1.0→1.1.

E2E: dump (.epf→XML), build без ref-типов, build СО ссылочными типами
через auto-stub на ibcmd (валидность подтверждена обратной разборкой),
1cv8-регресс — всё зелёное; оба порта.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Nick Shirokov
2026-06-21 17:09:23 +03:00
co-authored by Claude Opus 4.8
parent 27b9d539e0
commit 3f5065221e
8 changed files with 148 additions and 8 deletions
+24 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
# epf-dump v1.1 — Dump external data processor or report (EPF/ERF) to XML sources
# epf-dump v1.2 — Dump external data processor or report (EPF/ERF) to XML sources
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
import argparse
@@ -90,12 +90,20 @@ def main():
# --- Resolve V8Path ---
v8path = resolve_v8path(args.V8Path)
engine = "ibcmd" if os.path.basename(v8path).lower().startswith("ibcmd") else "1cv8"
# --- Validate database connection ---
if not args.InfoBasePath and (not args.InfoBaseServer or not args.InfoBaseRef):
print("Error: database connection required. Specify -InfoBasePath or -InfoBaseServer/-InfoBaseRef", file=sys.stderr)
print("Dump in an empty database loses reference types (CatalogRef, DocumentRef, etc.) irreversibly.")
sys.exit(1)
if engine == "ibcmd":
if not args.InfoBasePath:
print("Error: ibcmd supports file infobases only (use -InfoBasePath)", file=sys.stderr)
sys.exit(1)
if args.Format == "Plain":
print("Error: ibcmd config export supports hierarchical format only (use -Format Hierarchical or 1cv8)", file=sys.stderr)
sys.exit(1)
# --- Validate input file ---
if not os.path.isfile(args.InputFile):
@@ -111,6 +119,21 @@ def main():
os.makedirs(temp_dir, exist_ok=True)
try:
if engine == "ibcmd":
# --- ibcmd branch: dump EPF/ERF via config export --file ---
arguments = ["infobase", "config", "export", f"--file={args.InputFile}", args.OutputDir, f"--db-path={args.InfoBasePath}"]
print(f"Running: ibcmd {' '.join(arguments)}")
result = subprocess.run([v8path] + arguments, capture_output=True, encoding="utf-8", errors="replace")
if result.returncode == 0:
print(f"External data processor/report dumped successfully to: {args.OutputDir}")
else:
print(f"Error dumping external data processor/report (code: {result.returncode})", file=sys.stderr)
if result.stdout:
print(result.stdout)
if result.stderr:
print(result.stderr, file=sys.stderr)
sys.exit(result.returncode)
# --- Build arguments ---
arguments = ["DESIGNER"]