fix(db-dump-xml,db-load-xml): список объектов задаёт частичную операцию

Список без режима давал молчаливо неверный результат, причём разный. У выгрузки
умолчание Changes игнорировало -Objects и отдавало «изменённое с прошлой
выгрузки». У загрузки на движке 1cv8 умолчание Full игнорировало -Files и
заменяло всю конфигурацию базы, тогда как на ibcmd та же команда выполнялась
частично — одни и те же аргументы вели себя по-разному.

Теперь перечисленные объекты или файлы сами задают частичную операцию. Режим
разрешается до ветвления на движки, поэтому расхождение исчезает по построению;
проверено на стенде: обе ветки дают одинаковый результат.

Заданный вместе со списком -Mode Full или Changes не отбрасывается молча — о нём
сообщает [note]. Список с -Mode UpdateInfo отвергается: это другая операция,
обновление ConfigDumpInfo без выгрузки файлов, и вывод подменил бы её.

Инструкции намеренно не менялись: -Mode Partial остаётся каноничной формой,
а вывод режима — прощающим вводом, который мы не документируем.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Nick Shirokov
2026-08-23 17:43:39 +03:00
co-authored by Claude Opus 5
parent 7c37fe2ac2
commit 989f4c5526
9 changed files with 205 additions and 14 deletions
@@ -1,4 +1,4 @@
# db-dump-xml v1.18 — Dump 1C configuration to XML files
# db-dump-xml v1.19 — Dump 1C configuration to XML files
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
# NB: *nix-раскладку платформы (/opt/1cv8/<ver>/1cv8, без .exe) знает только .py-порт — PS на *nix не исполняется.
<#
@@ -85,8 +85,10 @@ param(
[string]$ConfigDir,
[Parameter(Mandatory=$false)]
[ValidateSet("Full", "Changes", "Partial", "UpdateInfo")]
[string]$Mode = "Changes",
# Пустое значение = режим не задан. Прежнее умолчание Changes подставляется ниже, после
# того как станет видно, перечислены ли объекты.
[ValidateSet("", "Full", "Changes", "Partial", "UpdateInfo")]
[string]$Mode = "",
[Parameter(Mandatory=$false)]
[string]$Objects,
@@ -522,6 +524,20 @@ if ($ObjectsFile) {
ForEach-Object { $_.Trim() } | Where-Object { $_ -and -not $_.StartsWith('#') })
$Objects = (@(@($Objects -split ',' | ForEach-Object { $_.Trim() } | Where-Object { $_ }) + $fromFile) -join ',')
}
# Перечислены объекты — операция частичная. Иначе список молча игнорировался бы: умолчание
# Changes выгружает «изменённое с прошлой выгрузки», а не то, что просили.
if ($Objects) {
if ($Mode -eq "UpdateInfo") {
# Не «шире/уже», а другая операция: обновление ConfigDumpInfo без выгрузки файлов.
Write-Host "Error: -Mode UpdateInfo does not take an object list — it only refreshes ConfigDumpInfo.xml" -ForegroundColor Red
exit 1
}
if ($Mode -eq "Full" -or $Mode -eq "Changes") {
Write-Host "[note] перечислены объекты — выгружаются только они; -Mode $Mode не применён" -ForegroundColor Yellow
}
$Mode = "Partial"
}
if (-not $Mode) { $Mode = "Changes" }
if ($Mode -eq "Partial" -and -not $Objects) {
Write-Host "Error: -Objects or -ObjectsFile required for Partial mode" -ForegroundColor Red
exit 1
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
# db-dump-xml v1.19 — Dump 1C configuration to XML files
# db-dump-xml v1.20 — Dump 1C configuration to XML files
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
import argparse
@@ -499,8 +499,8 @@ def main():
parser.add_argument("-ConfigDir", required=True, help="Directory for configuration dump")
parser.add_argument(
"-Mode",
default="Changes",
choices=["Full", "Changes", "Partial", "UpdateInfo"],
default="",
choices=["", "Full", "Changes", "Partial", "UpdateInfo"],
help="Dump mode (default: Changes)",
)
parser.add_argument("-Objects", default="", help="Comma-separated metadata object names (for Partial mode)")
@@ -563,6 +563,20 @@ def main():
if s.strip() and not s.strip().startswith("#")]
inline = [s.strip() for s in args.Objects.split(",") if s.strip()]
args.Objects = ",".join(inline + from_file)
# Перечислены объекты — операция частичная. Иначе список молча игнорировался бы: умолчание
# Changes выгружает «изменённое с прошлой выгрузки», а не то, что просили.
if args.Objects:
if args.Mode == "UpdateInfo":
# Не «шире/уже», а другая операция: обновление ConfigDumpInfo без выгрузки файлов.
print("Error: -Mode UpdateInfo does not take an object list — it only refreshes "
"ConfigDumpInfo.xml", file=sys.stderr)
sys.exit(1)
if args.Mode in ("Full", "Changes"):
print("[note] перечислены объекты — выгружаются только они; -Mode %s не применён"
% args.Mode)
args.Mode = "Partial"
if not args.Mode:
args.Mode = "Changes"
if args.Mode == "Partial" and not args.Objects:
print("Error: -Objects or -ObjectsFile required for Partial mode", file=sys.stderr)
sys.exit(1)
@@ -1,4 +1,4 @@
# db-load-xml v1.25 — Load 1C configuration from XML files
# db-load-xml v1.26 — Load 1C configuration from XML files
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
# NB: *nix-раскладку платформы (/opt/1cv8/<ver>/1cv8, без .exe) знает только .py-порт — PS на *nix не исполняется.
<#
@@ -85,8 +85,10 @@ param(
[string]$ConfigDir,
[Parameter(Mandatory=$false)]
[ValidateSet("Full", "Partial")]
[string]$Mode = "Full",
# Пустое значение = режим не задан. Прежнее умолчание Full подставляется ниже, после того
# как станет видно, перечислены ли файлы.
[ValidateSet("", "Full", "Partial")]
[string]$Mode = "",
[Parameter(Mandatory=$false)]
[string]$Files,
@@ -593,6 +595,16 @@ if (-not (Test-Path $ConfigDir)) {
exit 1
}
# Перечислены файлы — загрузка частичная. Иначе список молча игнорировался бы, а умолчание Full
# заменило бы всю конфигурацию базы.
if ($Files -or $ListFile) {
if ($Mode -eq "Full") {
Write-Host "[note] перечислены файлы — загружаются только они; -Mode Full не применён" -ForegroundColor Yellow
}
$Mode = "Partial"
}
if (-not $Mode) { $Mode = "Full" }
# --- Validate Partial mode ---
if ($Mode -eq "Partial" -and -not $Files -and -not $ListFile) {
Write-Host "Error: -Files or -ListFile required for Partial mode" -ForegroundColor Red
@@ -612,7 +624,7 @@ try {
}
if ($AllExtensions) {
$arguments = @("infobase", "config", "import", "all-extensions", "$ConfigDir", "--db-path=$InfoBasePath")
} elseif ($Mode -eq "Partial" -or $Files -or $ListFile) {
} elseif ($Mode -eq "Partial") {
# partial: import specific files (relative to ConfigDir)
$fileList = @()
if ($ListFile) {
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
# db-load-xml v1.26 — Load 1C configuration from XML files
# db-load-xml v1.27 — Load 1C configuration from XML files
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
import argparse
@@ -570,8 +570,8 @@ def main():
parser.add_argument("-ConfigDir", required=True, help="Directory with XML configuration sources")
parser.add_argument(
"-Mode",
default="Full",
choices=["Full", "Partial"],
default="",
choices=["", "Full", "Partial"],
help="Load mode (default: Full)",
)
parser.add_argument("-Files", default="", help="Comma-separated relative file paths (for Partial mode)")
@@ -636,6 +636,14 @@ def main():
sys.exit(1)
# --- Validate Partial mode ---
# Перечислены файлы — загрузка частичная. Иначе список молча игнорировался бы, а умолчание
# Full заменило бы всю конфигурацию базы.
if args.Files or args.ListFile:
if args.Mode == "Full":
print("[note] перечислены файлы — загружаются только они; -Mode Full не применён")
args.Mode = "Partial"
if not args.Mode:
args.Mode = "Full"
if args.Mode == "Partial" and not args.Files and not args.ListFile:
print("Error: -Files or -ListFile required for Partial mode", file=sys.stderr)
sys.exit(1)
@@ -647,7 +655,7 @@ def main():
sys.exit(1)
if args.AllExtensions:
arguments = ["infobase", "config", "import", "all-extensions", args.ConfigDir, f"--db-path={args.InfoBasePath}"]
elif args.Mode == "Partial" or args.Files or args.ListFile:
elif args.Mode == "Partial":
# partial: import specific files (relative to ConfigDir)
if args.ListFile:
if not os.path.isfile(args.ListFile):
@@ -0,0 +1,23 @@
{
"name": "Ошибка: список объектов с -Mode UpdateInfo — это другая операция",
"fakePlatform": {
"log": ""
},
"args_extra": [
"-V8Path",
"{fakePlatform}",
"-InfoBasePath",
"{workDir}/ib",
"-ConfigDir",
"{workDir}/out",
"-Objects",
"Справочник.Номенклатура",
"-Mode",
"UpdateInfo"
],
"expectError": true,
"expect": {
"stdoutContains": "UpdateInfo does not take an object list"
},
"noSnapshot": "навык ничего не пишет в рабочий каталог — проверяется, какие ключи ушли платформе"
}
@@ -0,0 +1,25 @@
{
"name": "Перечислены объекты без -Mode: выгрузка частичная, а не инкрементальная",
"fakePlatform": {
"log": ""
},
"args_extra": [
"-V8Path",
"{fakePlatform}",
"-InfoBasePath",
"{workDir}/ib",
"-ConfigDir",
"{workDir}/out",
"-Objects",
"Справочник.Номенклатура"
],
"expectError": true,
"expect": {
"stdoutContains": [
"Executing partial configuration dump...",
"-listFile"
],
"stdoutNotContains": "incremental"
},
"noSnapshot": "навык ничего не пишет в рабочий каталог — проверяется, какие ключи ушли платформе; фейк файлов не выгружает, поэтому постусловие навыка справедливо даёт отказ"
}
@@ -0,0 +1,27 @@
{
"name": "Объекты вместе с -Mode Full: выгружаются только они, режим назван неприменённым",
"fakePlatform": {
"log": ""
},
"args_extra": [
"-V8Path",
"{fakePlatform}",
"-InfoBasePath",
"{workDir}/ib",
"-ConfigDir",
"{workDir}/out",
"-Objects",
"Справочник.Номенклатура",
"-Mode",
"Full"
],
"expectError": true,
"expect": {
"stdoutContains": [
"[note] перечислены объекты",
"-Mode Full не применён",
"Executing partial configuration dump..."
]
},
"noSnapshot": "навык ничего не пишет в рабочий каталог — проверяется, какие ключи ушли платформе; фейк файлов не выгружает, поэтому постусловие навыка справедливо даёт отказ"
}
@@ -0,0 +1,32 @@
{
"name": "Перечислены файлы без -Mode: загрузка частичная, а не полная",
"fakePlatform": {
"log": ""
},
"preRun": [
{
"writeFile": {
"path": "src/Configuration.xml",
"content": "<?xml version=\"1.0\"?><MetaDataObject/>"
}
}
],
"args_extra": [
"-V8Path",
"{fakePlatform}",
"-InfoBasePath",
"{workDir}/ib",
"-ConfigDir",
"{workDir}/src",
"-Files",
"Catalogs/Номенклатура.xml"
],
"expect": {
"stdoutContains": [
"Executing partial configuration load...",
"-partial"
],
"stdoutNotContains": "Executing full configuration load"
},
"noSnapshot": "навык ничего не пишет в рабочий каталог — проверяется, какие ключи ушли платформе"
}
@@ -0,0 +1,34 @@
{
"name": "Файлы вместе с -Mode Full: загружаются только они, режим назван неприменённым",
"fakePlatform": {
"log": ""
},
"preRun": [
{
"writeFile": {
"path": "src/Configuration.xml",
"content": "<?xml version=\"1.0\"?><MetaDataObject/>"
}
}
],
"args_extra": [
"-V8Path",
"{fakePlatform}",
"-InfoBasePath",
"{workDir}/ib",
"-ConfigDir",
"{workDir}/src",
"-Files",
"Catalogs/Номенклатура.xml",
"-Mode",
"Full"
],
"expect": {
"stdoutContains": [
"[note] перечислены файлы",
"-Mode Full не применён",
"Executing partial configuration load..."
]
},
"noSnapshot": "навык ничего не пишет в рабочий каталог — проверяется, какие ключи ушли платформе"
}