fix(xdto-compile): версия формата из Configuration.xml вместо хардкода 2.17

Раундтрип по 1173 пакетам XDTO трёх конфигураций дал 760 совпадений и 413
расхождений — все ровно по две строки и все на УТ: штамп версии. Оригинал
2.20, наш вывод 2.17. Содержательных расхождений нет ни одного.

xdto-compile единственный из навыков, пишущих XML внутрь конфигурации, не
определял версию формата. Причина не в XDTO: волна авто-детекта прошла
2026-04-06 (d1550864) и накрыла существовавшие тогда навыки, а xdto-compile
появился 2026-07-25 — соглашение к нему просто не применили.

Добавлен Detect-FormatVersion / detect_format_version — дословная копия из
остальных навыков (включая сегодняшнюю правку про символы вместо байтов),
разрешение пути на вызывающей стороне.

Аудит остальных навыков: литеральный хардкод остался только в epf-init и
erf-init (автономные обработки, конфигурации рядом нет — дефолт законен) и в
тестовой заглушке stub-db-create.ps1.

Проверка: XDTO 1173/1173 без расхождений (было 760), сюита xdto 43/43 на
обоих портах.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Nick Shirokov
2026-08-02 16:21:22 +03:00
co-authored by Claude Opus 5
parent fae22435d4
commit f552def817
2 changed files with 51 additions and 4 deletions
@@ -1,4 +1,4 @@
# xdto-compile v1.1 — Build a 1C XDTO package from an XML Schema (XSD) # xdto-compile v1.2 — Build a 1C XDTO package from an XML Schema (XSD)
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
param( param(
[Parameter(Mandatory=$true, ParameterSetName='File')] [Parameter(Mandatory=$true, ParameterSetName='File')]
@@ -41,6 +41,27 @@ $V8_NS = "http://v8.1c.ru/8.1/data/core"
# read-only configs unless allowed. Trigger = bin present; reaction from # read-only configs unless allowed. Trigger = bin present; reaction from
# .v8-project.json editingAllowedCheck (deny|warn|off, default deny). Never # .v8-project.json editingAllowedCheck (deny|warn|off, default deny). Never
# throws — guard errors degrade to allow. # throws — guard errors degrade to allow.
# Версия формата выгрузки — из Configuration.xml проекта (климб вверх от каталога исходников).
# Её задаёт платформа выгрузки: 8.3.20-8.3.24 → 2.17, 8.3.25 → 2.18, 8.3.26 → 2.19, 8.3.27 → 2.20.
# Раньше здесь стоял хардкод 2.17, и на проекте 2.20 пакет расходился с выгрузкой платформы.
function Detect-FormatVersion([string]$dir) {
$d = $dir
while ($d) {
$cfgPath = Join-Path $d "Configuration.xml"
if (Test-Path $cfgPath) {
$cfgText = [System.IO.File]::ReadAllText($cfgPath, [System.Text.Encoding]::UTF8)
# Длину среза берём по СТРОКЕ, а не по размеру файла: размер в БАЙТАХ, Substring считает
# СИМВОЛЫ, и на кириллице байт больше — короткий Configuration.xml ронял навык исключением.
$head = $cfgText.Substring(0, [Math]::Min(2000, $cfgText.Length))
if ($head -match '<MetaDataObject[^>]+version="(\d+\.\d+)"') { return $Matches[1] }
}
$parent = Split-Path $d -Parent
if ($parent -eq $d) { break }
$d = $parent
}
return "2.17"
}
function Get-RootUuid([string]$xmlPath) { function Get-RootUuid([string]$xmlPath) {
if (-not (Test-Path $xmlPath)) { return $null } if (-not (Test-Path $xmlPath)) { return $null }
try { try {
@@ -811,6 +832,8 @@ if ($Name -match '^\d') { $Name = "_$Name" }
Assert-EditAllowed $OutputDir Assert-EditAllowed $OutputDir
$script:formatVersion = Detect-FormatVersion $OutputDir
$pkgRoot = Join-Path $OutputDir "XDTOPackages" $pkgRoot = Join-Path $OutputDir "XDTOPackages"
$pkgDir = Join-Path $pkgRoot $Name $pkgDir = Join-Path $pkgRoot $Name
$extDir = Join-Path $pkgDir "Ext" $extDir = Join-Path $pkgDir "Ext"
@@ -843,7 +866,7 @@ $uuid = [guid]::NewGuid().ToString()
$md = New-Object System.Text.StringBuilder $md = New-Object System.Text.StringBuilder
function M([string]$s) { [void]$md.Append($s); [void]$md.Append("`r`n") } function M([string]$s) { [void]$md.Append($s); [void]$md.Append("`r`n") }
M '<?xml version="1.0" encoding="UTF-8"?>' M '<?xml version="1.0" encoding="UTF-8"?>'
M '<MetaDataObject xmlns="http://v8.1c.ru/8.3/MDClasses" xmlns:app="http://v8.1c.ru/8.2/managed-application/core" xmlns:cfg="http://v8.1c.ru/8.1/data/enterprise/current-config" xmlns:cmi="http://v8.1c.ru/8.2/managed-application/cmi" xmlns:ent="http://v8.1c.ru/8.1/data/enterprise" xmlns:lf="http://v8.1c.ru/8.2/managed-application/logform" xmlns:style="http://v8.1c.ru/8.1/data/ui/style" xmlns:sys="http://v8.1c.ru/8.1/data/ui/fonts/system" xmlns:v8="http://v8.1c.ru/8.1/data/core" xmlns:v8ui="http://v8.1c.ru/8.1/data/ui" xmlns:web="http://v8.1c.ru/8.1/data/ui/colors/web" xmlns:win="http://v8.1c.ru/8.1/data/ui/colors/windows" xmlns:xen="http://v8.1c.ru/8.3/xcf/enums" xmlns:xpr="http://v8.1c.ru/8.3/xcf/predef" xmlns:xr="http://v8.1c.ru/8.3/xcf/readable" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.17">' M ("<MetaDataObject xmlns=`"http://v8.1c.ru/8.3/MDClasses`" xmlns:app=`"http://v8.1c.ru/8.2/managed-application/core`" xmlns:cfg=`"http://v8.1c.ru/8.1/data/enterprise/current-config`" xmlns:cmi=`"http://v8.1c.ru/8.2/managed-application/cmi`" xmlns:ent=`"http://v8.1c.ru/8.1/data/enterprise`" xmlns:lf=`"http://v8.1c.ru/8.2/managed-application/logform`" xmlns:style=`"http://v8.1c.ru/8.1/data/ui/style`" xmlns:sys=`"http://v8.1c.ru/8.1/data/ui/fonts/system`" xmlns:v8=`"http://v8.1c.ru/8.1/data/core`" xmlns:v8ui=`"http://v8.1c.ru/8.1/data/ui`" xmlns:web=`"http://v8.1c.ru/8.1/data/ui/colors/web`" xmlns:win=`"http://v8.1c.ru/8.1/data/ui/colors/windows`" xmlns:xen=`"http://v8.1c.ru/8.3/xcf/enums`" xmlns:xpr=`"http://v8.1c.ru/8.3/xcf/predef`" xmlns:xr=`"http://v8.1c.ru/8.3/xcf/readable`" xmlns:xs=`"http://www.w3.org/2001/XMLSchema`" xmlns:xsi=`"http://www.w3.org/2001/XMLSchema-instance`" version=`"$script:formatVersion`">")
M "`t<XDTOPackage uuid=`"$uuid`">" M "`t<XDTOPackage uuid=`"$uuid`">"
M "`t`t<Properties>" M "`t`t<Properties>"
M "`t`t`t<Name>$(EscText $Name)</Name>" M "`t`t`t<Name>$(EscText $Name)</Name>"
@@ -1,4 +1,4 @@
# xdto-compile v1.1 — Build a 1C XDTO package from an XML Schema (XSD) (Python port) # xdto-compile v1.2 — Build a 1C XDTO package from an XML Schema (XSD) (Python port)
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
import argparse import argparse
import json import json
@@ -98,6 +98,28 @@ def is_external_object_root(xml_path):
return False return False
def detect_format_version(d):
"""Версия формата выгрузки — из Configuration.xml проекта (климб вверх от каталога исходников).
Её задаёт платформа выгрузки: 8.3.20-8.3.24 -> 2.17, 8.3.25 -> 2.18, 8.3.26 -> 2.19,
8.3.27 -> 2.20. Раньше здесь стоял хардкод 2.17, и на проекте 2.20 пакет расходился с выгрузкой.
Тело — точная копия из остальных навыков (разрешение пути делает вызывающая сторона).
"""
while d:
cfg_path = os.path.join(d, "Configuration.xml")
if os.path.isfile(cfg_path):
with open(cfg_path, "r", encoding="utf-8-sig") as f:
head = f.read(2000)
m = re.search(r'<MetaDataObject[^>]+version="(\d+\.\d+)"', head)
if m:
return m.group(1)
parent = os.path.dirname(d)
if parent == d:
break
d = parent
return "2.17"
def assert_edit_allowed(target_path): def assert_edit_allowed(target_path):
d = os.path.abspath(target_path) d = os.path.abspath(target_path)
for _ in range(20): for _ in range(20):
@@ -837,6 +859,8 @@ if re.match(r"^\d", name):
assert_edit_allowed(args.OutputDir) assert_edit_allowed(args.OutputDir)
format_version = detect_format_version(os.path.abspath(args.OutputDir))
pkg_root = os.path.join(args.OutputDir, "XDTOPackages") pkg_root = os.path.join(args.OutputDir, "XDTOPackages")
pkg_dir = os.path.join(pkg_root, name) pkg_dir = os.path.join(pkg_root, name)
ext_dir = os.path.join(pkg_dir, "Ext") ext_dir = os.path.join(pkg_dir, "Ext")
@@ -871,7 +895,7 @@ md_lines = [
'xmlns:web="http://v8.1c.ru/8.1/data/ui/colors/web" xmlns:win="http://v8.1c.ru/8.1/data/ui/colors/windows" ' 'xmlns:web="http://v8.1c.ru/8.1/data/ui/colors/web" xmlns:win="http://v8.1c.ru/8.1/data/ui/colors/windows" '
'xmlns:xen="http://v8.1c.ru/8.3/xcf/enums" xmlns:xpr="http://v8.1c.ru/8.3/xcf/predef" ' 'xmlns:xen="http://v8.1c.ru/8.3/xcf/enums" xmlns:xpr="http://v8.1c.ru/8.3/xcf/predef" '
'xmlns:xr="http://v8.1c.ru/8.3/xcf/readable" xmlns:xs="http://www.w3.org/2001/XMLSchema" ' 'xmlns:xr="http://v8.1c.ru/8.3/xcf/readable" xmlns:xs="http://www.w3.org/2001/XMLSchema" '
'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.17">', f'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="{format_version}">',
f'\t<XDTOPackage uuid="{uuid.uuid4()}">', f'\t<XDTOPackage uuid="{uuid.uuid4()}">',
"\t\t<Properties>", "\t\t<Properties>",
f"\t\t\t<Name>{esc_text(name)}</Name>", f"\t\t\t<Name>{esc_text(name)}</Name>",