feat(epf-build): auto-create stub database for EPF/ERF with reference types

Add stub-db-create script (.ps1/.py) that scans EPF XML sources for
reference types (CatalogRef, DocumentRef, EnumRef, etc.) and generates
a minimal 1C configuration with metadata stubs. Supports 14 metadata
types including registers, charts, defined types.

epf-build/erf-build: if no database specified, auto-create stub DB
with matching metadata, build EPF, then cleanup temp DB.

epf-dump/erf-dump: if no database specified, create empty DB with
warning that reference types will be converted to strings.

SKILL.md updated: prefer real database from .v8-project.json first,
fall back to auto-created stub only when unavailable.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Nick Shirokov
2026-03-07 18:27:38 +03:00
parent 0a1f8888dc
commit f01f9d6ae8
10 changed files with 2261 additions and 52 deletions
+11 -12
View File
@@ -25,14 +25,17 @@ allowed-tools:
| SrcDir | нет | `src` | Каталог исходников |
| OutDir | нет | `build` | Каталог для результата |
## Параметры подключения
## Параметры подключения (опционально)
Предпочтительно использовать конкретную базу — это надёжнее и не требует создания временной базы.
1. Прочитай `.v8-project.json` из корня проекта. Возьми `v8path` и разреши базу:
2. Если пользователь указал параметры подключения (путь, сервер) — используй напрямую
3. Если указал базу по имени — ищи по id / alias / name в `.v8-project.json`
4. Если не указал — сопоставь текущую ветку Git с `databases[].branches`
5. Если ветка не совпала — используй `default`
6. Если `.v8-project.json` нет или база не найдена — не указывай параметры подключения: скрипт автоматически создаст временную базу. Для EPF со ссылочными типами (CatalogRef, DocumentRef и т.д.) генерируются заглушки метаданных. Временная база удаляется после сборки.
Прочитай `.v8-project.json` из корня проекта. Возьми `v8path` (путь к платформе) и разреши базу для сборки:
1. Если пользователь указал параметры подключения (путь, сервер) — используй напрямую
2. Если указал базу по имени — ищи по id / alias / name в `.v8-project.json`
3. Если не указал — сопоставь текущую ветку Git с `databases[].branches`
4. Если ветка не совпала — используй `default`
5. Если `.v8-project.json` нет или баз нет — создай пустую ИБ в `./base`
Если `v8path` не задан — автоопределение: `Get-ChildItem "C:\Program Files\1cv8\*\bin\1cv8.exe" | Sort -Desc | Select -First 1`
Если использованная база не зарегистрирована — после выполнения предложи добавить через `/db-list add`.
@@ -55,7 +58,7 @@ powershell.exe -NoProfile -File .claude/skills/epf-build/scripts/epf-build.ps1 <
| `-SourceFile <путь>` | да | Путь к корневому XML-файлу исходников |
| `-OutputFile <путь>` | да | Путь к выходному EPF/ERF-файлу |
> `*` — нужен либо `-InfoBasePath`, либо пара `-InfoBaseServer` + `-InfoBaseRef`
> `*` — опционально. Если не указано — автоматически создаётся временная база со заглушками метаданных
## Коды возврата
@@ -64,10 +67,6 @@ powershell.exe -NoProfile -File .claude/skills/epf-build/scripts/epf-build.ps1 <
| 0 | Успешная сборка |
| 1 | Ошибка (см. лог) |
## Ссылочные типы
Если обработка использует ссылочные типы конфигурации (`CatalogRef.XXX`, `DocumentRef.XXX`) — сборка в пустой базе упадёт с ошибкой XDTO. Зарегистрируй базу с целевой конфигурацией через `/db-list add`.
## Примеры
```powershell
+17 -3
View File
@@ -87,10 +87,21 @@ if (-not (Test-Path $V8Path)) {
exit 1
}
# --- Validate connection ---
# --- Auto-create stub database if no connection specified ---
$autoCreatedBase = $null
if (-not $InfoBasePath -and (-not $InfoBaseServer -or -not $InfoBaseRef)) {
Write-Host "Error: specify -InfoBasePath or -InfoBaseServer + -InfoBaseRef" -ForegroundColor Red
exit 1
$sourceDir = Split-Path $SourceFile -Parent
$autoBasePath = Join-Path $env:TEMP "epf_stub_db_$(Get-Random)"
$stubScript = Join-Path $PSScriptRoot "stub-db-create.ps1"
Write-Host "No database specified. Creating temporary stub database..."
$stubArgs = "-SourceDir `"$sourceDir`" -V8Path `"$V8Path`" -TempBasePath `"$autoBasePath`""
$stubProc = Start-Process -FilePath "powershell.exe" -ArgumentList "-NoProfile -File `"$stubScript`" $stubArgs" -NoNewWindow -Wait -PassThru
if ($stubProc.ExitCode -ne 0) {
Write-Host "Error: failed to create stub database" -ForegroundColor Red
exit 1
}
$InfoBasePath = $autoBasePath
$autoCreatedBase = $autoBasePath
}
# --- Validate source file ---
@@ -156,4 +167,7 @@ try {
if (Test-Path $tempDir) {
Remove-Item -Path $tempDir -Recurse -Force -ErrorAction SilentlyContinue
}
if ($autoCreatedBase -and (Test-Path $autoCreatedBase)) {
Remove-Item -Path $autoCreatedBase -Recurse -Force -ErrorAction SilentlyContinue
}
}
+17 -3
View File
@@ -52,10 +52,22 @@ def main():
# --- Resolve V8Path ---
v8path = resolve_v8path(args.V8Path)
# --- Validate connection ---
# --- Auto-create stub database if no connection specified ---
auto_created_base = None
if not args.InfoBasePath and (not args.InfoBaseServer or not args.InfoBaseRef):
print("Error: specify -InfoBasePath or -InfoBaseServer + -InfoBaseRef", file=sys.stderr)
sys.exit(1)
source_dir = os.path.dirname(os.path.abspath(args.SourceFile))
auto_base_path = os.path.join(tempfile.gettempdir(), f"epf_stub_db_{random.randint(0, 999999)}")
stub_script = os.path.join(os.path.dirname(os.path.abspath(__file__)), "stub-db-create.py")
print("No database specified. Creating temporary stub database...")
result = subprocess.run(
[sys.executable, stub_script, "-SourceDir", source_dir, "-V8Path", v8path, "-TempBasePath", auto_base_path],
capture_output=False,
)
if result.returncode != 0:
print("Error: failed to create stub database", file=sys.stderr)
sys.exit(1)
args.InfoBasePath = auto_base_path
auto_created_base = auto_base_path
# --- Validate source file ---
if not os.path.isfile(args.SourceFile):
@@ -123,6 +135,8 @@ def main():
finally:
if os.path.exists(temp_dir):
shutil.rmtree(temp_dir, ignore_errors=True)
if auto_created_base and os.path.exists(auto_created_base):
shutil.rmtree(auto_created_base, ignore_errors=True)
if __name__ == "__main__":
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+11 -8
View File
@@ -24,14 +24,17 @@ allowed-tools:
| EpfFile | да | — | Путь к EPF-файлу |
| OutDir | нет | `src` | Каталог для выгрузки исходников |
## Параметры подключения
## Параметры подключения (опционально)
Предпочтительно использовать конкретную базу — это надёжнее и не требует создания временной базы.
1. Прочитай `.v8-project.json` из корня проекта. Возьми `v8path` и разреши базу:
2. Если пользователь указал параметры подключения (путь, сервер) — используй напрямую
3. Если указал базу по имени — ищи по id / alias / name в `.v8-project.json`
4. Если не указал — сопоставь текущую ветку Git с `databases[].branches`
5. Если ветка не совпала — используй `default`
6. Если `.v8-project.json` нет или база не найдена — не указывай параметры подключения: скрипт автоматически создаст временную пустую базу. **Важно:** в пустой базе ссылочные типы (CatalogRef, DocumentRef и т.д.) сбрасываются в строки. Для сохранения типов нужна реальная база с конфигурацией. Предупреди пользователя об этом.
Прочитай `.v8-project.json` из корня проекта. Возьми `v8path` (путь к платформе) и разреши базу:
1. Если пользователь указал параметры подключения (путь, сервер) — используй напрямую
2. Если указал базу по имени — ищи по id / alias / name в `.v8-project.json`
3. Если не указал — сопоставь текущую ветку Git с `databases[].branches`
4. Если ветка не совпала — используй `default`
5. Если `.v8-project.json` нет или баз нет — создай пустую ИБ в `./base`
Если `v8path` не задан — автоопределение: `Get-ChildItem "C:\Program Files\1cv8\*\bin\1cv8.exe" | Sort -Desc | Select -First 1`
Если использованная база не зарегистрирована — после выполнения предложи добавить через `/db-list add`.
@@ -55,7 +58,7 @@ powershell.exe -NoProfile -File .claude/skills/epf-dump/scripts/epf-dump.ps1 <п
| `-OutputDir <путь>` | да | Каталог для выгрузки исходников |
| `-Format <формат>` | нет | `Hierarchical` (по умолч.) / `Plain` |
> `*` — нужен либо `-InfoBasePath`, либо пара `-InfoBaseServer` + `-InfoBaseRef`
> `*` — опционально. Если не указано — автоматически создаётся временная пустая база. Ссылочные типы при этом сбрасываются в строки
## Коды возврата
+16 -3
View File
@@ -94,10 +94,20 @@ if (-not (Test-Path $V8Path)) {
exit 1
}
# --- Validate connection ---
# --- Auto-create empty database if no connection specified ---
$autoCreatedBase = $null
if (-not $InfoBasePath -and (-not $InfoBaseServer -or -not $InfoBaseRef)) {
Write-Host "Error: specify -InfoBasePath or -InfoBaseServer + -InfoBaseRef" -ForegroundColor Red
exit 1
$autoBasePath = Join-Path $env:TEMP "epf_dump_db_$(Get-Random)"
Write-Host "No database specified. Creating temporary empty database..."
Write-Host "WARNING: Reference types (CatalogRef, DocumentRef, etc.) will be lost - converted to strings. Use a real database to preserve types." -ForegroundColor Yellow
$createArgs = "CREATEINFOBASE File=`"$autoBasePath`" /DisableStartupDialogs"
$createProc = Start-Process -FilePath $V8Path -ArgumentList $createArgs -NoNewWindow -Wait -PassThru
if ($createProc.ExitCode -ne 0) {
Write-Host "Error: failed to create temporary database" -ForegroundColor Red
exit 1
}
$InfoBasePath = $autoBasePath
$autoCreatedBase = $autoBasePath
}
# --- Validate input file ---
@@ -163,4 +173,7 @@ try {
if (Test-Path $tempDir) {
Remove-Item -Path $tempDir -Recurse -Force -ErrorAction SilentlyContinue
}
if ($autoCreatedBase -and (Test-Path $autoCreatedBase)) {
Remove-Item -Path $autoCreatedBase -Recurse -Force -ErrorAction SilentlyContinue
}
}
+16 -3
View File
@@ -58,10 +58,21 @@ def main():
# --- Resolve V8Path ---
v8path = resolve_v8path(args.V8Path)
# --- Validate connection ---
# --- Auto-create empty database if no connection specified ---
auto_created_base = None
if not args.InfoBasePath and (not args.InfoBaseServer or not args.InfoBaseRef):
print("Error: specify -InfoBasePath or -InfoBaseServer + -InfoBaseRef", file=sys.stderr)
sys.exit(1)
auto_base_path = os.path.join(tempfile.gettempdir(), f"epf_dump_db_{random.randint(0, 999999)}")
print("No database specified. Creating temporary empty database...")
print("WARNING: Reference types (CatalogRef, DocumentRef, etc.) will be lost - converted to strings. Use a real database to preserve types.")
result = subprocess.run(
[v8path, "CREATEINFOBASE", f'File={auto_base_path}', "/DisableStartupDialogs"],
capture_output=True, text=True,
)
if result.returncode != 0:
print("Error: failed to create temporary database", file=sys.stderr)
sys.exit(1)
args.InfoBasePath = auto_base_path
auto_created_base = auto_base_path
# --- Validate input file ---
if not os.path.isfile(args.InputFile):
@@ -129,6 +140,8 @@ def main():
finally:
if os.path.exists(temp_dir):
shutil.rmtree(temp_dir, ignore_errors=True)
if auto_created_base and os.path.exists(auto_created_base):
shutil.rmtree(auto_created_base, ignore_errors=True)
if __name__ == "__main__":
+11 -12
View File
@@ -25,14 +25,17 @@ allowed-tools:
| SrcDir | нет | `src` | Каталог исходников |
| OutDir | нет | `build` | Каталог для результата |
## Параметры подключения
## Параметры подключения (опционально)
Предпочтительно использовать конкретную базу — это надёжнее и не требует создания временной базы.
1. Прочитай `.v8-project.json` из корня проекта. Возьми `v8path` и разреши базу:
2. Если пользователь указал параметры подключения (путь, сервер) — используй напрямую
3. Если указал базу по имени — ищи по id / alias / name в `.v8-project.json`
4. Если не указал — сопоставь текущую ветку Git с `databases[].branches`
5. Если ветка не совпала — используй `default`
6. Если `.v8-project.json` нет или база не найдена — не указывай параметры подключения: скрипт автоматически создаст временную базу. Для ERF со ссылочными типами (CatalogRef, DocumentRef и т.д.) генерируются заглушки метаданных. Временная база удаляется после сборки.
Прочитай `.v8-project.json` из корня проекта. Возьми `v8path` (путь к платформе) и разреши базу для сборки:
1. Если пользователь указал параметры подключения (путь, сервер) — используй напрямую
2. Если указал базу по имени — ищи по id / alias / name в `.v8-project.json`
3. Если не указал — сопоставь текущую ветку Git с `databases[].branches`
4. Если ветка не совпала — используй `default`
5. Если `.v8-project.json` нет или баз нет — создай пустую ИБ в `./base`
Если `v8path` не задан — автоопределение: `Get-ChildItem "C:\Program Files\1cv8\*\bin\1cv8.exe" | Sort -Desc | Select -First 1`
Если использованная база не зарегистрирована — после выполнения предложи добавить через `/db-list add`.
@@ -57,7 +60,7 @@ powershell.exe -NoProfile -File .claude/skills/epf-build/scripts/epf-build.ps1 <
| `-SourceFile <путь>` | да | Путь к корневому XML-файлу исходников |
| `-OutputFile <путь>` | да | Путь к выходному ERF-файлу |
> `*` — нужен либо `-InfoBasePath`, либо пара `-InfoBaseServer` + `-InfoBaseRef`
> `*` — опционально. Если не указано — автоматически создаётся временная база со заглушками метаданных
## Коды возврата
@@ -66,10 +69,6 @@ powershell.exe -NoProfile -File .claude/skills/epf-build/scripts/epf-build.ps1 <
| 0 | Успешная сборка |
| 1 | Ошибка (см. лог) |
## Ссылочные типы
Если отчёт использует ссылочные типы конфигурации (`CatalogRef.XXX`, `DocumentRef.XXX`) — сборка в пустой базе упадёт с ошибкой XDTO. Зарегистрируй базу с целевой конфигурацией через `/db-list add`.
## Примеры
```powershell
+11 -8
View File
@@ -24,14 +24,17 @@ allowed-tools:
| ErfFile | да | — | Путь к ERF-файлу |
| OutDir | нет | `src` | Каталог для выгрузки исходников |
## Параметры подключения
## Параметры подключения (опционально)
Предпочтительно использовать конкретную базу — это надёжнее и не требует создания временной базы.
1. Прочитай `.v8-project.json` из корня проекта. Возьми `v8path` и разреши базу:
2. Если пользователь указал параметры подключения (путь, сервер) — используй напрямую
3. Если указал базу по имени — ищи по id / alias / name в `.v8-project.json`
4. Если не указал — сопоставь текущую ветку Git с `databases[].branches`
5. Если ветка не совпала — используй `default`
6. Если `.v8-project.json` нет или база не найдена — не указывай параметры подключения: скрипт автоматически создаст временную пустую базу. **Важно:** в пустой базе ссылочные типы (CatalogRef, DocumentRef и т.д.) сбрасываются в строки. Для сохранения типов нужна реальная база с конфигурацией. Предупреди пользователя об этом.
Прочитай `.v8-project.json` из корня проекта. Возьми `v8path` (путь к платформе) и разреши базу:
1. Если пользователь указал параметры подключения (путь, сервер) — используй напрямую
2. Если указал базу по имени — ищи по id / alias / name в `.v8-project.json`
3. Если не указал — сопоставь текущую ветку Git с `databases[].branches`
4. Если ветка не совпала — используй `default`
5. Если `.v8-project.json` нет или баз нет — создай пустую ИБ в `./base`
Если `v8path` не задан — автоопределение: `Get-ChildItem "C:\Program Files\1cv8\*\bin\1cv8.exe" | Sort -Desc | Select -First 1`
Если использованная база не зарегистрирована — после выполнения предложи добавить через `/db-list add`.
@@ -57,7 +60,7 @@ powershell.exe -NoProfile -File .claude/skills/epf-dump/scripts/epf-dump.ps1 <п
| `-OutputDir <путь>` | да | Каталог для выгрузки исходников |
| `-Format <формат>` | нет | `Hierarchical` (по умолч.) / `Plain` |
> `*` — нужен либо `-InfoBasePath`, либо пара `-InfoBaseServer` + `-InfoBaseRef`
> `*` — опционально. Если не указано — автоматически создаётся временная пустая база
## Коды возврата