mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-09-25 19:45:53 +03:00
fix(db-dump-xml): Changes без тихой полной перевыгрузки, инкремент в ibcmd
- -update без -force: при другой версии формата — отказ с подсказкой про -Mode Full, а не молчаливая перезапись всего дерева в новом формате. - Первая выгрузка режимом по умолчанию: в каталог без выгрузки (пусто, только .git/README) — полностью; выгрузка без ConfigDumpInfo.xml — ошибка. - ibcmd: Changes через --sync; Full в непустой каталог — через временный каталог и копирование поверх, как пишет конфигуратор; ошибка копирования даёт код 1. UpdateInfo с -AllExtensions отвергается, а не выгружает всё. - py-порт печатает вывод ibcmd, как PS. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ANXwbMUhuRFSCsq2RgmTTm
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
ce7238792e
commit
f98e7e9e81
@@ -66,13 +66,17 @@ powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/db-dump-xml.ps1" <
|
|||||||
|
|
||||||
| Режим | Описание |
|
| Режим | Описание |
|
||||||
|-------|----------|
|
|-------|----------|
|
||||||
| `Full` | Полная выгрузка — все объекты конфигурации |
|
| `Full` | Полная выгрузка — все объекты конфигурации. Пишет поверх каталога: файлы, которых нет в конфигурации, остаются |
|
||||||
| `Changes` | Инкрементальная — только изменённые с последней выгрузки (использует ConfigDumpInfo.xml) |
|
| `Changes` | Инкрементальная — только изменённые с последней выгрузки (по `ConfigDumpInfo.xml`). Если выгрузки в каталоге ещё нет (пусто или только `.git`, README), выгружает полностью |
|
||||||
| `Partial` | Частичная — выбранные объекты из параметра `-Objects` |
|
| `Partial` | Частичная — выбранные объекты из параметра `-Objects` |
|
||||||
| `UpdateInfo` | Обновить только ConfigDumpInfo.xml без выгрузки файлов |
|
| `UpdateInfo` | Обновить только ConfigDumpInfo.xml без выгрузки файлов |
|
||||||
|
|
||||||
> Если пользователь просит выгрузить конкретные объекты — используй `-Mode Partial` с `-Objects`.
|
> Если пользователь просит выгрузить конкретные объекты — используй `-Mode Partial` с `-Objects`.
|
||||||
|
|
||||||
|
`Changes` отказывает, если в каталоге есть выгрузка без `ConfigDumpInfo.xml` или каталог выгружен
|
||||||
|
в другой версии формата (другой платформой). `-Mode Full` в таком случае перевыгрузит всё дерево,
|
||||||
|
и изменятся все файлы, поэтому решение о полной выгрузке оставь пользователю.
|
||||||
|
|
||||||
## Примеры
|
## Примеры
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# db-dump-xml v1.22 — Dump 1C configuration to XML files
|
# db-dump-xml v1.23 — Dump 1C configuration to XML files
|
||||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||||
# NB: *nix-раскладку платформы (/opt/1cv8/<ver>/1cv8, без .exe) знает только .py-порт — PS на *nix не исполняется.
|
# NB: *nix-раскладку платформы (/opt/1cv8/<ver>/1cv8, без .exe) знает только .py-порт — PS на *nix не исполняется.
|
||||||
<#
|
<#
|
||||||
@@ -8,7 +8,7 @@
|
|||||||
.DESCRIPTION
|
.DESCRIPTION
|
||||||
Выполняет выгрузку конфигурации 1С в файлы в четырёх режимах:
|
Выполняет выгрузку конфигурации 1С в файлы в четырёх режимах:
|
||||||
- Full: полная выгрузка всей конфигурации
|
- Full: полная выгрузка всей конфигурации
|
||||||
- Changes: инкрементальная выгрузка изменённых объектов
|
- Changes: инкрементальная выгрузка изменённых объектов (в пустой каталог — полная)
|
||||||
- Partial: выгрузка конкретных объектов из списка
|
- Partial: выгрузка конкретных объектов из списка
|
||||||
- UpdateInfo: обновление только ConfigDumpInfo.xml
|
- UpdateInfo: обновление только ConfigDumpInfo.xml
|
||||||
|
|
||||||
@@ -519,6 +519,32 @@ function Test-DirNonEmpty {
|
|||||||
return (Test-Path $Path -PathType Container) -and ([bool](Get-ChildItem -LiteralPath $Path -Force -ErrorAction SilentlyContinue | Select-Object -First 1))
|
return (Test-Path $Path -PathType Container) -and ([bool](Get-ChildItem -LiteralPath $Path -Force -ErrorAction SilentlyContinue | Select-Object -First 1))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function Copy-TreeOver {
|
||||||
|
# Скопировать дерево поверх каталога: файлы заменяются, лишнее в приёмнике остаётся —
|
||||||
|
# так пишет полную выгрузку конфигуратор (устаревшие объекты, .git и прочее не трогает).
|
||||||
|
# Через .NET: исключение на первой же ошибке (а не пропуск файла с продолжением), и без
|
||||||
|
# накладных расходов командлетов на десятках тысяч файлов. Пустые каталоги не переносятся.
|
||||||
|
param([string]$From, [string]$To)
|
||||||
|
$root = [System.IO.Path]::GetFullPath($From).TrimEnd('\')
|
||||||
|
$dest = (Resolve-Path -LiteralPath $To).ProviderPath
|
||||||
|
foreach ($f in [System.IO.Directory]::EnumerateFiles($root, '*', [System.IO.SearchOption]::AllDirectories)) {
|
||||||
|
$dst = [System.IO.Path]::Combine($dest, $f.Substring($root.Length + 1))
|
||||||
|
[void][System.IO.Directory]::CreateDirectory([System.IO.Path]::GetDirectoryName($dst))
|
||||||
|
[System.IO.File]::Copy($f, $dst, $true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function Write-FormatMismatchHint {
|
||||||
|
# Отказ инкрементальной выгрузки из-за версии формата: каталог выгружен другой платформой.
|
||||||
|
# Тексты: 1cv8 — «версия формата платформы отличается от версии формата выгрузки»,
|
||||||
|
# ibcmd — «Версия формат выгрузки и платформы не совпадают».
|
||||||
|
param([string]$Text)
|
||||||
|
if ($Text -match 'верси\S* формат\S* .{0,40}(отличается|не совпадают)') {
|
||||||
|
Write-Host "[подсказка] Каталог выгружен в другой версии формата. -Mode Full перевыгрузит конфигурацию" -ForegroundColor Yellow
|
||||||
|
Write-Host " целиком в формате текущей платформы — изменятся все файлы каталога." -ForegroundColor Yellow
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$engine = if ((Split-Path $V8Path -Leaf) -match '^ibcmd') { "ibcmd" } else { "1cv8" }
|
$engine = if ((Split-Path $V8Path -Leaf) -match '^ibcmd') { "ibcmd" } else { "1cv8" }
|
||||||
|
|
||||||
# --- Resolve additional arguments for the selected engine ---
|
# --- Resolve additional arguments for the selected engine ---
|
||||||
@@ -567,6 +593,26 @@ if ($Mode -eq "Partial" -and -not $Objects) {
|
|||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# --- Changes: инкремент ведётся от файла версий прошлой выгрузки ---
|
||||||
|
# Без ConfigDumpInfo.xml платформа инкремент отвергает. Выгрузки в каталоге ещё нет (пусто или
|
||||||
|
# только .git, README и т.п.) — первая выгрузка, она полная. Выгрузка есть, а файла версий нет —
|
||||||
|
# не трогаем: полная выгрузка перепишет её целиком, и это решение пользователя. У -AllExtensions
|
||||||
|
# файлы версий лежат в подкаталогах расширений — их проверяет платформа.
|
||||||
|
if ($Mode -eq "Changes") {
|
||||||
|
$firstDump = if ($AllExtensions) { -not (Test-DirNonEmpty $ConfigDir) } else {
|
||||||
|
-not (Test-Path -LiteralPath (Join-Path $ConfigDir "ConfigDumpInfo.xml")) -and
|
||||||
|
-not (Test-Path -LiteralPath (Join-Path $ConfigDir "Configuration.xml"))
|
||||||
|
}
|
||||||
|
if ($firstDump) {
|
||||||
|
Write-Host "[note] выгрузки в каталоге ещё нет — первая выгрузка выполняется полностью" -ForegroundColor Yellow
|
||||||
|
$Mode = "Full"
|
||||||
|
} elseif (-not $AllExtensions -and -not (Test-Path -LiteralPath (Join-Path $ConfigDir "ConfigDumpInfo.xml"))) {
|
||||||
|
Write-Host "Error: no ConfigDumpInfo.xml in $ConfigDir — incremental dump (Changes) is impossible" -ForegroundColor Red
|
||||||
|
Write-Host " -Mode Full выгрузит конфигурацию целиком поверх каталога." -ForegroundColor Yellow
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
# --- Create output dir if needed ---
|
# --- Create output dir if needed ---
|
||||||
if (-not (Test-Path $ConfigDir)) {
|
if (-not (Test-Path $ConfigDir)) {
|
||||||
New-Item -ItemType Directory -Path $ConfigDir -Force | Out-Null
|
New-Item -ItemType Directory -Path $ConfigDir -Force | Out-Null
|
||||||
@@ -584,11 +630,23 @@ try {
|
|||||||
Write-Host "Error: ibcmd config export supports hierarchical format only (use -Format Hierarchical or 1cv8)" -ForegroundColor Red
|
Write-Host "Error: ibcmd config export supports hierarchical format only (use -Format Hierarchical or 1cv8)" -ForegroundColor Red
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
if ($AllExtensions) {
|
# Полный экспорт ibcmd в непустой каталог отказывает («Каталог не пуст»), а конфигуратор
|
||||||
$arguments = @("infobase", "config", "export", "all-extensions", "$ConfigDir", "--db-path=$InfoBasePath")
|
# пишет поверх. Чтобы движки вели себя одинаково, такой экспорт идёт во временный каталог
|
||||||
} elseif ($Mode -eq "UpdateInfo") {
|
# и копируется поверх ConfigDir.
|
||||||
|
if ($AllExtensions -and $Mode -eq "Changes") {
|
||||||
|
Write-Host "[note] ibcmd выгружает все расширения только полностью" -ForegroundColor Yellow
|
||||||
|
}
|
||||||
|
$overlay = ($Mode -ne "Partial") -and ($AllExtensions -or $Mode -eq "Full") -and (Test-DirNonEmpty $ConfigDir)
|
||||||
|
$outDir = if ($overlay) { Join-Path $tempDir "export" } else { $ConfigDir }
|
||||||
|
$dataDir = Join-Path $tempDir "data"
|
||||||
|
New-Item -ItemType Directory -Path $dataDir -Force | Out-Null
|
||||||
|
if ($Mode -eq "UpdateInfo") {
|
||||||
|
# Раньше развилки по -AllExtensions: иначе вместо обновления файла версий ушла бы
|
||||||
|
# полная выгрузка всех расширений.
|
||||||
Write-Host "Error: ibcmd config export does not support Mode UpdateInfo; use 1cv8" -ForegroundColor Red
|
Write-Host "Error: ibcmd config export does not support Mode UpdateInfo; use 1cv8" -ForegroundColor Red
|
||||||
exit 1
|
exit 1
|
||||||
|
} elseif ($AllExtensions) {
|
||||||
|
$arguments = @("infobase", "config", "export", "all-extensions", "$outDir", "--db-path=$InfoBasePath")
|
||||||
} elseif ($Mode -eq "Partial") {
|
} elseif ($Mode -eq "Partial") {
|
||||||
$objList = @($Objects -split ',' | ForEach-Object { $_.Trim() } | Where-Object { $_ })
|
$objList = @($Objects -split ',' | ForEach-Object { $_.Trim() } | Where-Object { $_ })
|
||||||
$arguments = @("infobase", "config", "export", "objects") + $objList
|
$arguments = @("infobase", "config", "export", "objects") + $objList
|
||||||
@@ -597,26 +655,36 @@ try {
|
|||||||
} else {
|
} else {
|
||||||
$arguments = @("infobase", "config", "export", "--db-path=$InfoBasePath")
|
$arguments = @("infobase", "config", "export", "--db-path=$InfoBasePath")
|
||||||
if ($Extension) { $arguments += "--extension=$Extension" }
|
if ($Extension) { $arguments += "--extension=$Extension" }
|
||||||
$arguments += "$ConfigDir"
|
# Инкремент — --sync; без --force: при другой версии формата ibcmd честно отказывает.
|
||||||
|
if ($Mode -eq "Changes") { $arguments += "--sync" }
|
||||||
|
$arguments += "$outDir"
|
||||||
}
|
}
|
||||||
if ($UserName) { $arguments += "--user=$UserName" }
|
if ($UserName) { $arguments += "--user=$UserName" }
|
||||||
if ($Password) { $arguments += "--password=$Password" }
|
if ($Password) { $arguments += "--password=$Password" }
|
||||||
$arguments += "--data=$tempDir"
|
$arguments += "--data=$dataDir"
|
||||||
$arguments += $extraArgs
|
$arguments += $extraArgs
|
||||||
Write-Host "Running: ibcmd $(Protect-Secrets ((Format-ArgsForDisplay $arguments $engine) -join ' ') @($Password, $UserName))"
|
Write-Host "Running: ibcmd $(Protect-Secrets ((Format-ArgsForDisplay $arguments $engine) -join ' ') @($Password, $UserName))"
|
||||||
$__ib = Invoke-PlatformProcess $V8Path $arguments
|
$__ib = Invoke-PlatformProcess $V8Path $arguments
|
||||||
$output = $__ib.Output
|
$output = $__ib.Output
|
||||||
$exitCode = $__ib.ExitCode
|
$exitCode = $__ib.ExitCode
|
||||||
$outMissing = ($exitCode -eq 0) -and -not (Test-DirNonEmpty $ConfigDir)
|
$outMissing = ($exitCode -eq 0) -and -not (Test-DirNonEmpty $outDir)
|
||||||
if ($outMissing) { $exitCode = 1 }
|
if ($outMissing) { $exitCode = 1 }
|
||||||
|
$copyError = $null
|
||||||
|
if ($exitCode -eq 0 -and $overlay) {
|
||||||
|
try { Copy-TreeOver $outDir $ConfigDir } catch { $copyError = $_.Exception.Message; $exitCode = 1 }
|
||||||
|
}
|
||||||
if ($exitCode -eq 0) {
|
if ($exitCode -eq 0) {
|
||||||
Write-Host "Configuration exported successfully to: $ConfigDir" -ForegroundColor Green
|
Write-Host "Configuration exported successfully to: $ConfigDir" -ForegroundColor Green
|
||||||
|
} elseif ($copyError) {
|
||||||
|
Write-Host "Error: export succeeded, but copying it over $ConfigDir failed: $copyError" -ForegroundColor Red
|
||||||
|
Write-Host " Каталог мог остаться частично обновлённым — повторите выгрузку." -ForegroundColor Yellow
|
||||||
} elseif ($outMissing) {
|
} elseif ($outMissing) {
|
||||||
Write-Host "Error: exit code 0 but no files under $ConfigDir — configuration was not exported" -ForegroundColor Red
|
Write-Host "Error: exit code 0 but no files under $ConfigDir — configuration was not exported" -ForegroundColor Red
|
||||||
} else {
|
} else {
|
||||||
Write-Host "Error exporting configuration (code: $exitCode)" -ForegroundColor Red
|
Write-Host "Error exporting configuration (code: $exitCode)" -ForegroundColor Red
|
||||||
}
|
}
|
||||||
Write-PlatformOutput $output
|
Write-PlatformOutput $output
|
||||||
|
if ($exitCode -ne 0) { Write-FormatMismatchHint $output }
|
||||||
exit $exitCode
|
exit $exitCode
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -647,8 +715,8 @@ try {
|
|||||||
}
|
}
|
||||||
"Changes" {
|
"Changes" {
|
||||||
Write-Host "Executing incremental configuration dump..."
|
Write-Host "Executing incremental configuration dump..."
|
||||||
|
# Без -force: с ним при другой версии формата платформа молча выгружает всё заново.
|
||||||
$arguments += "-update"
|
$arguments += "-update"
|
||||||
$arguments += "-force"
|
|
||||||
}
|
}
|
||||||
"Partial" {
|
"Partial" {
|
||||||
Write-Host "Executing partial configuration dump..."
|
Write-Host "Executing partial configuration dump..."
|
||||||
@@ -699,6 +767,7 @@ try {
|
|||||||
Write-Host "Error dumping configuration (code: $exitCode)" -ForegroundColor Red
|
Write-Host "Error dumping configuration (code: $exitCode)" -ForegroundColor Red
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$logContent = $null
|
||||||
if (Test-Path $outFile) {
|
if (Test-Path $outFile) {
|
||||||
$logContent = Get-Content $outFile -Raw -ErrorAction SilentlyContinue
|
$logContent = Get-Content $outFile -Raw -ErrorAction SilentlyContinue
|
||||||
if ($logContent) {
|
if ($logContent) {
|
||||||
@@ -708,6 +777,7 @@ try {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Write-PlatformOutput $__v8.Output
|
Write-PlatformOutput $__v8.Output
|
||||||
|
if ($exitCode -ne 0) { Write-FormatMismatchHint "$logContent`n$($__v8.Output)" }
|
||||||
|
|
||||||
exit $exitCode
|
exit $exitCode
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# db-dump-xml v1.22 — Dump 1C configuration to XML files
|
# db-dump-xml v1.23 — Dump 1C configuration to XML files
|
||||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
@@ -494,6 +494,27 @@ def dir_nonempty(path):
|
|||||||
return os.path.isdir(path) and any(os.scandir(path))
|
return os.path.isdir(path) and any(os.scandir(path))
|
||||||
|
|
||||||
|
|
||||||
|
def copy_tree_over(src, dst):
|
||||||
|
"""Скопировать дерево поверх каталога: файлы заменяются, лишнее в приёмнике остаётся —
|
||||||
|
так пишет полную выгрузку конфигуратор (устаревшие объекты, .git и прочее не трогает).
|
||||||
|
Исключение на первой же ошибке. Пустые каталоги не переносятся."""
|
||||||
|
for base, _dirs, files in os.walk(src):
|
||||||
|
rel = os.path.relpath(base, src)
|
||||||
|
target = dst if rel == "." else os.path.join(dst, rel)
|
||||||
|
for name in files:
|
||||||
|
os.makedirs(target, exist_ok=True)
|
||||||
|
shutil.copy2(os.path.join(base, name), os.path.join(target, name))
|
||||||
|
|
||||||
|
|
||||||
|
def print_format_mismatch_hint(text):
|
||||||
|
"""Отказ инкрементальной выгрузки из-за версии формата: каталог выгружен другой платформой.
|
||||||
|
Тексты: 1cv8 — «версия формата платформы отличается от версии формата выгрузки»,
|
||||||
|
ibcmd — «Версия формат выгрузки и платформы не совпадают»."""
|
||||||
|
if re.search(r"верси\S* формат\S* .{0,40}(отличается|не совпадают)", text or "", re.IGNORECASE):
|
||||||
|
print("[подсказка] Каталог выгружен в другой версии формата. -Mode Full перевыгрузит конфигурацию")
|
||||||
|
print(" целиком в формате текущей платформы — изменятся все файлы каталога.")
|
||||||
|
|
||||||
|
|
||||||
def _redact(text, *secrets):
|
def _redact(text, *secrets):
|
||||||
"""Redact literal secret values (password, user) from a display string —
|
"""Redact literal secret values (password, user) from a display string —
|
||||||
precise, never touches lookalike paths."""
|
precise, never touches lookalike paths."""
|
||||||
@@ -604,6 +625,25 @@ def main():
|
|||||||
print("Error: -Objects or -ObjectsFile required for Partial mode")
|
print("Error: -Objects or -ObjectsFile required for Partial mode")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
# --- Changes: инкремент ведётся от файла версий прошлой выгрузки ---
|
||||||
|
# Без ConfigDumpInfo.xml платформа инкремент отвергает. Пустой каталог — первая выгрузка, она
|
||||||
|
# полная. Непустой без файла версий не трогаем: полная выгрузка перепишет его целиком, и это
|
||||||
|
# решение пользователя. У -AllExtensions файлы версий лежат в подкаталогах расширений — их
|
||||||
|
# проверяет платформа.
|
||||||
|
if args.Mode == "Changes":
|
||||||
|
if args.AllExtensions:
|
||||||
|
first_dump = not dir_nonempty(args.ConfigDir)
|
||||||
|
else:
|
||||||
|
first_dump = (not os.path.exists(os.path.join(args.ConfigDir, "ConfigDumpInfo.xml"))
|
||||||
|
and not os.path.exists(os.path.join(args.ConfigDir, "Configuration.xml")))
|
||||||
|
if first_dump:
|
||||||
|
print("[note] выгрузки в каталоге ещё нет — первая выгрузка выполняется полностью")
|
||||||
|
args.Mode = "Full"
|
||||||
|
elif not args.AllExtensions and not os.path.exists(os.path.join(args.ConfigDir, "ConfigDumpInfo.xml")):
|
||||||
|
print(f"Error: no ConfigDumpInfo.xml in {args.ConfigDir} — incremental dump (Changes) is impossible")
|
||||||
|
print(" -Mode Full выгрузит конфигурацию целиком поверх каталога.")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
# --- Create output dir if needed ---
|
# --- Create output dir if needed ---
|
||||||
if not os.path.exists(args.ConfigDir):
|
if not os.path.exists(args.ConfigDir):
|
||||||
os.makedirs(args.ConfigDir, exist_ok=True)
|
os.makedirs(args.ConfigDir, exist_ok=True)
|
||||||
@@ -614,11 +654,25 @@ def main():
|
|||||||
if args.Format == "Plain":
|
if args.Format == "Plain":
|
||||||
print("Error: ibcmd config export supports hierarchical format only (use -Format Hierarchical or 1cv8)")
|
print("Error: ibcmd config export supports hierarchical format only (use -Format Hierarchical or 1cv8)")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
if args.AllExtensions:
|
# Полный экспорт ibcmd в непустой каталог отказывает («Каталог не пуст»), а конфигуратор
|
||||||
arguments = ["infobase", "config", "export", "all-extensions", args.ConfigDir, f"--db-path={args.InfoBasePath}"]
|
# пишет поверх. Чтобы движки вели себя одинаково, такой экспорт идёт во временный каталог
|
||||||
elif args.Mode == "UpdateInfo":
|
# и копируется поверх ConfigDir.
|
||||||
|
if args.AllExtensions and args.Mode == "Changes":
|
||||||
|
print("[note] ibcmd выгружает все расширения только полностью")
|
||||||
|
overlay = (args.Mode != "Partial" and (args.AllExtensions or args.Mode == "Full")
|
||||||
|
and dir_nonempty(args.ConfigDir))
|
||||||
|
out_dir = args.ConfigDir
|
||||||
|
if overlay:
|
||||||
|
export_tmp = tempfile.mkdtemp(prefix="ibcmd_export_")
|
||||||
|
atexit.register(shutil.rmtree, export_tmp, ignore_errors=True)
|
||||||
|
out_dir = os.path.join(export_tmp, "export")
|
||||||
|
if args.Mode == "UpdateInfo":
|
||||||
|
# Раньше развилки по -AllExtensions: иначе вместо обновления файла версий ушла бы
|
||||||
|
# полная выгрузка всех расширений.
|
||||||
print("Error: ibcmd config export does not support Mode UpdateInfo; use 1cv8")
|
print("Error: ibcmd config export does not support Mode UpdateInfo; use 1cv8")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
elif args.AllExtensions:
|
||||||
|
arguments = ["infobase", "config", "export", "all-extensions", out_dir, f"--db-path={args.InfoBasePath}"]
|
||||||
elif args.Mode == "Partial":
|
elif args.Mode == "Partial":
|
||||||
obj_list = [o.strip() for o in args.Objects.split(",") if o.strip()]
|
obj_list = [o.strip() for o in args.Objects.split(",") if o.strip()]
|
||||||
arguments = ["infobase", "config", "export", "objects"] + obj_list
|
arguments = ["infobase", "config", "export", "objects"] + obj_list
|
||||||
@@ -629,7 +683,10 @@ def main():
|
|||||||
arguments = ["infobase", "config", "export", f"--db-path={args.InfoBasePath}"]
|
arguments = ["infobase", "config", "export", f"--db-path={args.InfoBasePath}"]
|
||||||
if args.Extension:
|
if args.Extension:
|
||||||
arguments.append(f"--extension={args.Extension}")
|
arguments.append(f"--extension={args.Extension}")
|
||||||
arguments.append(args.ConfigDir)
|
# Инкремент — --sync; без --force: при другой версии формата ibcmd честно отказывает.
|
||||||
|
if args.Mode == "Changes":
|
||||||
|
arguments.append("--sync")
|
||||||
|
arguments.append(out_dir)
|
||||||
ib_data = tempfile.mkdtemp(prefix="ibcmd_data_")
|
ib_data = tempfile.mkdtemp(prefix="ibcmd_data_")
|
||||||
atexit.register(shutil.rmtree, ib_data, ignore_errors=True)
|
atexit.register(shutil.rmtree, ib_data, ignore_errors=True)
|
||||||
if args.UserName:
|
if args.UserName:
|
||||||
@@ -641,15 +698,28 @@ def main():
|
|||||||
print(f"Running: ibcmd {_redact(' '.join(format_args_for_display(arguments, engine)), args.Password, args.UserName)}")
|
print(f"Running: ibcmd {_redact(' '.join(format_args_for_display(arguments, engine)), args.Password, args.UserName)}")
|
||||||
result = run_ibcmd([v8path] + arguments, bool(args.UserName))
|
result = run_ibcmd([v8path] + arguments, bool(args.UserName))
|
||||||
exit_code = result.returncode
|
exit_code = result.returncode
|
||||||
out_missing = exit_code == 0 and not dir_nonempty(args.ConfigDir)
|
out_missing = exit_code == 0 and not dir_nonempty(out_dir)
|
||||||
if out_missing:
|
if out_missing:
|
||||||
exit_code = 1
|
exit_code = 1
|
||||||
|
copy_error = None
|
||||||
|
if exit_code == 0 and overlay:
|
||||||
|
try:
|
||||||
|
copy_tree_over(out_dir, args.ConfigDir)
|
||||||
|
except OSError as e:
|
||||||
|
copy_error = str(e)
|
||||||
|
exit_code = 1
|
||||||
if exit_code == 0:
|
if exit_code == 0:
|
||||||
print(f"Configuration exported successfully to: {args.ConfigDir}")
|
print(f"Configuration exported successfully to: {args.ConfigDir}")
|
||||||
|
elif copy_error:
|
||||||
|
print(f"Error: export succeeded, but copying it over {args.ConfigDir} failed: {copy_error}")
|
||||||
|
print(" Каталог мог остаться частично обновлённым — повторите выгрузку.")
|
||||||
elif out_missing:
|
elif out_missing:
|
||||||
print(f"Error: exit code 0 but no files under {args.ConfigDir} — configuration was not exported")
|
print(f"Error: exit code 0 but no files under {args.ConfigDir} — configuration was not exported")
|
||||||
else:
|
else:
|
||||||
print(f"Error exporting configuration (code: {exit_code})")
|
print(f"Error exporting configuration (code: {exit_code})")
|
||||||
|
print_platform_output(result)
|
||||||
|
if exit_code != 0:
|
||||||
|
print_format_mismatch_hint((result.stdout or "") + (result.stderr or ""))
|
||||||
sys.exit(exit_code)
|
sys.exit(exit_code)
|
||||||
|
|
||||||
# --- Temp dir ---
|
# --- Temp dir ---
|
||||||
@@ -682,8 +752,8 @@ def main():
|
|||||||
print("Executing full configuration dump...")
|
print("Executing full configuration dump...")
|
||||||
elif args.Mode == "Changes":
|
elif args.Mode == "Changes":
|
||||||
print("Executing incremental configuration dump...")
|
print("Executing incremental configuration dump...")
|
||||||
|
# Без -force: с ним при другой версии формата платформа молча выгружает всё заново.
|
||||||
arguments.append("-update")
|
arguments.append("-update")
|
||||||
arguments.append("-force")
|
|
||||||
elif args.Mode == "Partial":
|
elif args.Mode == "Partial":
|
||||||
print("Executing partial configuration dump...")
|
print("Executing partial configuration dump...")
|
||||||
object_list = [obj.strip() for obj in args.Objects.split(",") if obj.strip()]
|
object_list = [obj.strip() for obj in args.Objects.split(",") if obj.strip()]
|
||||||
@@ -730,6 +800,7 @@ def main():
|
|||||||
else:
|
else:
|
||||||
print(f"Error dumping configuration (code: {exit_code})")
|
print(f"Error dumping configuration (code: {exit_code})")
|
||||||
|
|
||||||
|
log_content = ""
|
||||||
if os.path.isfile(out_file):
|
if os.path.isfile(out_file):
|
||||||
try:
|
try:
|
||||||
with open(out_file, "r", encoding="utf-8-sig") as f:
|
with open(out_file, "r", encoding="utf-8-sig") as f:
|
||||||
@@ -742,6 +813,8 @@ def main():
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
print_platform_output(result)
|
print_platform_output(result)
|
||||||
|
if exit_code != 0:
|
||||||
|
print_format_mismatch_hint(log_content + "\n" + (result.stdout or "") + (result.stderr or ""))
|
||||||
sys.exit(exit_code)
|
sys.exit(exit_code)
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"name": "Changes в пустой каталог: первая выгрузка выполняется полностью",
|
||||||
|
"fakePlatform": {
|
||||||
|
"log": ""
|
||||||
|
},
|
||||||
|
"args_extra": [
|
||||||
|
"-V8Path",
|
||||||
|
"{fakePlatform}",
|
||||||
|
"-InfoBasePath",
|
||||||
|
"{workDir}/ib",
|
||||||
|
"-ConfigDir",
|
||||||
|
"{workDir}/out"
|
||||||
|
],
|
||||||
|
"expectError": true,
|
||||||
|
"expect": {
|
||||||
|
"stdoutContains": [
|
||||||
|
"[note] выгрузки в каталоге ещё нет — первая выгрузка выполняется полностью",
|
||||||
|
"Executing full configuration dump..."
|
||||||
|
],
|
||||||
|
"stdoutNotContains": "-update"
|
||||||
|
},
|
||||||
|
"noSnapshot": "проверяется, какие ключи ушли платформе; фейк файлов не выгружает, поэтому постусловие навыка справедливо даёт отказ"
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
{
|
||||||
|
"name": "Changes в каталог без выгрузки (только служебные файлы репозитория): первая выгрузка полная",
|
||||||
|
"fakePlatform": {
|
||||||
|
"log": ""
|
||||||
|
},
|
||||||
|
"preRun": [
|
||||||
|
{
|
||||||
|
"writeFile": {
|
||||||
|
"path": "out/.gitignore",
|
||||||
|
"content": "*.log\n"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"args_extra": [
|
||||||
|
"-V8Path",
|
||||||
|
"{fakePlatform}",
|
||||||
|
"-InfoBasePath",
|
||||||
|
"{workDir}/ib",
|
||||||
|
"-ConfigDir",
|
||||||
|
"{workDir}/out",
|
||||||
|
"-Mode",
|
||||||
|
"Changes"
|
||||||
|
],
|
||||||
|
"expect": {
|
||||||
|
"stdoutContains": [
|
||||||
|
"[note] выгрузки в каталоге ещё нет — первая выгрузка выполняется полностью",
|
||||||
|
"Executing full configuration dump..."
|
||||||
|
],
|
||||||
|
"stdoutNotContains": "-update"
|
||||||
|
},
|
||||||
|
"noSnapshot": "проверяется командная строка платформы; каталог выгрузки — фикстура кейса"
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
{
|
||||||
|
"name": "Changes по прошлой выгрузке: -update без -force",
|
||||||
|
"fakePlatform": {
|
||||||
|
"log": ""
|
||||||
|
},
|
||||||
|
"preRun": [
|
||||||
|
{
|
||||||
|
"writeFile": {
|
||||||
|
"path": "out/ConfigDumpInfo.xml",
|
||||||
|
"content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?><ConfigDumpInfo format=\"Hierarchical\" version=\"2.17\"/>"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"args_extra": [
|
||||||
|
"-V8Path",
|
||||||
|
"{fakePlatform}",
|
||||||
|
"-InfoBasePath",
|
||||||
|
"{workDir}/ib",
|
||||||
|
"-ConfigDir",
|
||||||
|
"{workDir}/out",
|
||||||
|
"-Mode",
|
||||||
|
"Changes"
|
||||||
|
],
|
||||||
|
"expect": {
|
||||||
|
"stdoutContains": [
|
||||||
|
"Executing incremental configuration dump...",
|
||||||
|
"-update"
|
||||||
|
],
|
||||||
|
"stdoutNotContains": "-force"
|
||||||
|
},
|
||||||
|
"noSnapshot": "проверяется командная строка платформы; каталог выгрузки — фикстура кейса"
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
{
|
||||||
|
"name": "Ошибка: Changes в непустой каталог без ConfigDumpInfo.xml",
|
||||||
|
"fakePlatform": {
|
||||||
|
"log": ""
|
||||||
|
},
|
||||||
|
"preRun": [
|
||||||
|
{
|
||||||
|
"writeFile": {
|
||||||
|
"path": "out/Configuration.xml",
|
||||||
|
"content": "<?xml version=\"1.0\"?><MetaDataObject/>"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"args_extra": [
|
||||||
|
"-V8Path",
|
||||||
|
"{fakePlatform}",
|
||||||
|
"-InfoBasePath",
|
||||||
|
"{workDir}/ib",
|
||||||
|
"-ConfigDir",
|
||||||
|
"{workDir}/out",
|
||||||
|
"-Mode",
|
||||||
|
"Changes"
|
||||||
|
],
|
||||||
|
"expectError": true,
|
||||||
|
"expect": {
|
||||||
|
"stdoutContains": [
|
||||||
|
"no ConfigDumpInfo.xml",
|
||||||
|
"-Mode Full выгрузит конфигурацию целиком поверх каталога."
|
||||||
|
],
|
||||||
|
"stdoutNotContains": "Running:"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
{
|
||||||
|
"name": "Ошибка: ibcmd не умеет UpdateInfo — и с -AllExtensions не подменяет его полной выгрузкой (fake platform)",
|
||||||
|
"preRun": [
|
||||||
|
{
|
||||||
|
"writeFile": {
|
||||||
|
"path": "ibcmd.cmd",
|
||||||
|
"content": "@echo off\r\necho ARGS: %*\r\nexit /b 0\r\n"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"writeFile": {
|
||||||
|
"path": "ib/1Cv8.1CD",
|
||||||
|
"content": "stub"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"writeFile": {
|
||||||
|
"path": "out/РасшА/ConfigDumpInfo.xml",
|
||||||
|
"content": "<ConfigDumpInfo/>"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"args_extra": [
|
||||||
|
"-V8Path",
|
||||||
|
"{workDir}\\ibcmd.cmd",
|
||||||
|
"-InfoBasePath",
|
||||||
|
"{workDir}\\ib",
|
||||||
|
"-UserName",
|
||||||
|
"Admin",
|
||||||
|
"-ConfigDir",
|
||||||
|
"{workDir}\\out",
|
||||||
|
"-Mode",
|
||||||
|
"UpdateInfo",
|
||||||
|
"-AllExtensions"
|
||||||
|
],
|
||||||
|
"expectError": true,
|
||||||
|
"expect": {
|
||||||
|
"stdoutContains": "ibcmd config export does not support Mode UpdateInfo",
|
||||||
|
"stdoutNotContains": "ARGS:"
|
||||||
|
},
|
||||||
|
"osOnly": "win32"
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
{
|
||||||
|
"name": "Отказ инкремента из-за версии формата: подсказка про полную перевыгрузку",
|
||||||
|
"fakePlatform": {
|
||||||
|
"log": "\ufeffОбновление XML выгрузки невозможно: версия формата платформы отличается от версии формата выгрузки.\r\nДля синхронизации необходимо выполнить полную выгрузку.\r\n",
|
||||||
|
"exit": 101
|
||||||
|
},
|
||||||
|
"preRun": [
|
||||||
|
{
|
||||||
|
"writeFile": {
|
||||||
|
"path": "out/ConfigDumpInfo.xml",
|
||||||
|
"content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?><ConfigDumpInfo format=\"Hierarchical\" version=\"2.16\"/>"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"args_extra": [
|
||||||
|
"-V8Path",
|
||||||
|
"{fakePlatform}",
|
||||||
|
"-InfoBasePath",
|
||||||
|
"{workDir}/ib",
|
||||||
|
"-ConfigDir",
|
||||||
|
"{workDir}/out",
|
||||||
|
"-Mode",
|
||||||
|
"Changes"
|
||||||
|
],
|
||||||
|
"expectError": true,
|
||||||
|
"expect": {
|
||||||
|
"stdoutContains": [
|
||||||
|
"Error dumping configuration (code: 101)",
|
||||||
|
"[подсказка] Каталог выгружен в другой версии формата."
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
{
|
||||||
|
"name": "ibcmd: Changes — инкремент через --sync, без --force (fake platform)",
|
||||||
|
"preRun": [
|
||||||
|
{
|
||||||
|
"writeFile": {
|
||||||
|
"path": "ibcmd.cmd",
|
||||||
|
"content": "@echo off\r\necho ARGS: %*\r\nexit /b 0\r\n"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"writeFile": {
|
||||||
|
"path": "ib/1Cv8.1CD",
|
||||||
|
"content": "stub"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"writeFile": {
|
||||||
|
"path": "out/ConfigDumpInfo.xml",
|
||||||
|
"content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?><ConfigDumpInfo format=\"Hierarchical\" version=\"2.17\"/>"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"args_extra": [
|
||||||
|
"-V8Path",
|
||||||
|
"{workDir}\\ibcmd.cmd",
|
||||||
|
"-InfoBasePath",
|
||||||
|
"{workDir}\\ib",
|
||||||
|
"-UserName",
|
||||||
|
"Admin",
|
||||||
|
"-ConfigDir",
|
||||||
|
"{workDir}\\out",
|
||||||
|
"-Mode",
|
||||||
|
"Changes"
|
||||||
|
],
|
||||||
|
"expect": {
|
||||||
|
"stdoutContains": [
|
||||||
|
"ARGS: infobase config export",
|
||||||
|
"--sync"
|
||||||
|
],
|
||||||
|
"stdoutNotContains": "--force"
|
||||||
|
},
|
||||||
|
"noSnapshot": "проверяется командная строка в stdout; каталог выгрузки — фикстура кейса",
|
||||||
|
"osOnly": "win32"
|
||||||
|
}
|
||||||
@@ -54,6 +54,17 @@ export const steps = [
|
|||||||
script: 'db-dump-xml/scripts/db-dump-xml',
|
script: 'db-dump-xml/scripts/db-dump-xml',
|
||||||
args: { '-V8Path': '{v8path}', '-InfoBasePath': '{workDir}/testdb', '-ConfigDir': '{workDir}/dumpA', '-Mode': 'Changes' },
|
args: { '-V8Path': '{v8path}', '-InfoBasePath': '{workDir}/testdb', '-ConfigDir': '{workDir}/dumpA', '-Mode': 'Changes' },
|
||||||
},
|
},
|
||||||
|
// ── 3b. Changes into a FRESH dir → no ConfigDumpInfo yet, so the first dump must be full ──
|
||||||
|
{
|
||||||
|
name: 'db-dump-xml: Changes в пустой каталог (первая выгрузка)',
|
||||||
|
script: 'db-dump-xml/scripts/db-dump-xml',
|
||||||
|
args: { '-V8Path': '{v8path}', '-InfoBasePath': '{workDir}/testdb', '-ConfigDir': '{workDir}/dumpC', '-Mode': 'Changes' },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'assert: первая выгрузка записала ConfigDumpInfo.xml',
|
||||||
|
assertContains: '{workDir}/dumpC/ConfigDumpInfo.xml',
|
||||||
|
expect: 'ConfigDumpInfo',
|
||||||
|
},
|
||||||
// ── 4. UpdateInfo into a FRESH dir → proves the mode alone yields non-empty output ──
|
// ── 4. UpdateInfo into a FRESH dir → proves the mode alone yields non-empty output ──
|
||||||
{
|
{
|
||||||
name: 'db-dump-xml: UpdateInfo',
|
name: 'db-dump-xml: UpdateInfo',
|
||||||
|
|||||||
@@ -0,0 +1,101 @@
|
|||||||
|
// platform-dump-sync.test.mjs — db-dump-xml Changes/Full поверх существующей выгрузки, оба движка.
|
||||||
|
// Changes должен быть инкрементом от ConfigDumpInfo.xml (1cv8 -update, ibcmd --sync), а Full в
|
||||||
|
// непустой каталог — писать поверх и не трогать лишнее, как конфигуратор (ibcmd сам в непустой
|
||||||
|
// каталог не выгружает). Изменение доставляется в базу загрузкой частями и проверяется маркером.
|
||||||
|
|
||||||
|
export const name = 'Выгрузка поверх существующей: Changes и Full (оба движка)';
|
||||||
|
export const setup = 'none';
|
||||||
|
export const requiresPlatform = true;
|
||||||
|
export const engines = ['1cv8', 'ibcmd'];
|
||||||
|
|
||||||
|
export const steps = [
|
||||||
|
// ── 1. Минимальная база ──
|
||||||
|
{
|
||||||
|
name: 'cf-init: пустая конфигурация',
|
||||||
|
script: 'cf-init/scripts/cf-init',
|
||||||
|
args: { '-Name': 'ВыгрузкаПоверх', '-OutputDir': '{workDir}/config' },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'meta-compile: Справочник Товары',
|
||||||
|
script: 'meta-compile/scripts/meta-compile',
|
||||||
|
input: { type: 'Catalog', name: 'Товары', codeLength: 9, descriptionLength: 100 },
|
||||||
|
args: { '-JsonPath': '{inputFile}', '-OutputDir': '{workDir}/config' },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'cf-edit: регистрация справочника',
|
||||||
|
script: 'cf-edit/scripts/cf-edit',
|
||||||
|
input: [{ operation: 'add-childObject', value: 'Catalog.Товары' }],
|
||||||
|
args: { '-ConfigPath': '{workDir}/config', '-DefinitionFile': '{inputFile}' },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'db-create: файловая ИБ',
|
||||||
|
script: 'db-create/scripts/db-create',
|
||||||
|
args: { '-V8Path': '{v8path}', '-InfoBasePath': '{workDir}/testdb' },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'db-load-xml: загрузка конфигурации (Full)',
|
||||||
|
script: 'db-load-xml/scripts/db-load-xml',
|
||||||
|
args: { '-V8Path': '{v8path}', '-InfoBasePath': '{workDir}/testdb', '-ConfigDir': '{workDir}/config' },
|
||||||
|
},
|
||||||
|
|
||||||
|
// ── 2. Первая выгрузка режимом по умолчанию (Changes) в несуществующий каталог → полная ──
|
||||||
|
{
|
||||||
|
name: 'db-dump-xml: первая выгрузка без -Mode',
|
||||||
|
script: 'db-dump-xml/scripts/db-dump-xml',
|
||||||
|
args: { '-V8Path': '{v8path}', '-InfoBasePath': '{workDir}/testdb', '-ConfigDir': '{workDir}/dump' },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'assert: выгрузка содержит ConfigDumpInfo.xml',
|
||||||
|
assertContains: '{workDir}/dump/ConfigDumpInfo.xml',
|
||||||
|
expect: 'ConfigDumpInfo',
|
||||||
|
},
|
||||||
|
|
||||||
|
// ── 3. Изменение в базе → Changes поверх выгрузки ──
|
||||||
|
{
|
||||||
|
name: 'editFile: маркер в Comment справочника',
|
||||||
|
editFile: '{workDir}/config/Catalogs/Товары.xml',
|
||||||
|
replace: '<Comment/>',
|
||||||
|
with: '<Comment>syncMARK</Comment>',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'db-load-xml: частичная загрузка Товары',
|
||||||
|
script: 'db-load-xml/scripts/db-load-xml',
|
||||||
|
args: {
|
||||||
|
'-V8Path': '{v8path}', '-InfoBasePath': '{workDir}/testdb',
|
||||||
|
'-ConfigDir': '{workDir}/config', '-Files': 'Catalogs/Товары.xml',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'db-dump-xml: Changes поверх выгрузки',
|
||||||
|
script: 'db-dump-xml/scripts/db-dump-xml',
|
||||||
|
args: { '-V8Path': '{v8path}', '-InfoBasePath': '{workDir}/testdb', '-ConfigDir': '{workDir}/dump', '-Mode': 'Changes' },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'assert: Changes выгрузил изменение',
|
||||||
|
assertContains: '{workDir}/dump/Catalogs/Товары.xml',
|
||||||
|
expect: 'syncMARK',
|
||||||
|
},
|
||||||
|
|
||||||
|
// ── 4. Full в непустой каталог: пишет поверх, лишнее остаётся ──
|
||||||
|
{
|
||||||
|
name: 'meta-compile: посторонний объект в каталоге выгрузки',
|
||||||
|
script: 'meta-compile/scripts/meta-compile',
|
||||||
|
input: { type: 'Catalog', name: 'Посторонний' },
|
||||||
|
args: { '-JsonPath': '{inputFile}', '-OutputDir': '{workDir}/dump' },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'db-dump-xml: Full в непустой каталог',
|
||||||
|
script: 'db-dump-xml/scripts/db-dump-xml',
|
||||||
|
args: { '-V8Path': '{v8path}', '-InfoBasePath': '{workDir}/testdb', '-ConfigDir': '{workDir}/dump', '-Mode': 'Full' },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'assert: Full выгрузил конфигурацию',
|
||||||
|
assertContains: '{workDir}/dump/Catalogs/Товары.xml',
|
||||||
|
expect: 'syncMARK',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'assert: посторонний объект не удалён',
|
||||||
|
assertContains: '{workDir}/dump/Catalogs/Посторонний.xml',
|
||||||
|
expect: 'Посторонний',
|
||||||
|
},
|
||||||
|
];
|
||||||
Reference in New Issue
Block a user