mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-10-01 14:35:54 +03:00
feat(cfe-validate): проверка 17 — версия формата согласована внутри объектов расширения
Объекты расширения платформа загружает по тому же правилу, что и объекты конфигурации: дескриптор и его штампованные тела (у заимствованной формы — ещё и вложенный <BaseForm version=…>) только в одной версии формата, иначе «Версия формата загружаемого файла … отличается от версии формата ранее загруженных файлов». Проверено загрузкой расширения на 8.3.27.1859: тело формы или <BaseForm> не в версии дескриптора — отказ; заимствованный объект целиком в 2.18 в расширении 2.20 загружается. Первое — ошибка, второе — предупреждение о неоднородной выгрузке. Так же сверяются Configuration.xml расширения и его Ext/*.xml. Co-Authored-By: Sergei Pleshanov <2357qwr@gmail.com> Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Sergei Pleshanov
Claude Opus 5.5
parent
fbcf65e12d
commit
88eca0b000
@@ -1,4 +1,4 @@
|
||||
# cfe-validate v1.17 — Validate 1C configuration extension structure (CFE)
|
||||
# cfe-validate v1.18 — Validate 1C configuration extension structure (CFE)
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
[CmdletBinding(PositionalBinding=$false)]
|
||||
param(
|
||||
@@ -107,6 +107,21 @@ function Get-FormatRank([string]$ver) {
|
||||
return 0
|
||||
}
|
||||
|
||||
# Штамп версии формата — атрибут version КОРНЕВОГО элемента файла. Копия общего эталона (семья
|
||||
# root_version, авторитет — meta-validate). Корневого: в Form.xml расширения ниже стоит <BaseForm version=…>.
|
||||
function Get-RootVersion([string]$xmlPath) {
|
||||
if (-not (Test-Path -LiteralPath $xmlPath -PathType Leaf)) { return $null }
|
||||
$buf = New-Object byte[] 4096
|
||||
$fs = [System.IO.File]::OpenRead($xmlPath)
|
||||
try { $len = $fs.Read($buf, 0, $buf.Length) } finally { $fs.Dispose() }
|
||||
$head = [System.Text.Encoding]::UTF8.GetString($buf, 0, $len)
|
||||
$m = [regex]::Match($head, '<[A-Za-z_][\w.:-]*(\s[^>]*)?/?>')
|
||||
if (-not $m.Success) { return $null }
|
||||
$v = [regex]::Match($m.Groups[1].Value, '(?:^|\s)version="([^"]*)"')
|
||||
if ($v.Success) { return $v.Groups[1].Value }
|
||||
return $null
|
||||
}
|
||||
|
||||
# --- Reference tables ---
|
||||
# Модули заимствованных объектов: тип → виды модулей. Имя свойства в <xr:PropertyState>
|
||||
# совпадает с базовым именем файла модуля. Копия таблицы есть в cfe-borrow (навыки автономны).
|
||||
@@ -1299,6 +1314,79 @@ if ($versionRank -ge 219 -and $childObjNode) {
|
||||
}
|
||||
}
|
||||
|
||||
# --- Check 17: версия формата согласована внутри объектов расширения; сверка с Configuration.xml ---
|
||||
# Дескриптор объекта и его штампованные тела X/Ext/*.xml, дескриптор формы/макета и его тело (и
|
||||
# Configuration.xml с его Ext/*.xml) платформа загружает только в одной версии формата: «Версия формата
|
||||
# загружаемого файла … отличается от версии формата ранее загруженных файлов». Объект целиком в другой
|
||||
# версии, чем расширение, загружается — это лишь неоднородность выгрузки (типично после мержа веток,
|
||||
# выгруженных разными платформами), поэтому такое расхождение только предупреждение.
|
||||
if ($version) {
|
||||
# Каждый элемент — пара: дескриптор и его версия, известная заранее (у Configuration.xml — своя).
|
||||
$verDescriptors = @($resolvedPath)
|
||||
if ($childObjNode) {
|
||||
foreach ($child in $childObjNode.ChildNodes) {
|
||||
if ($child.NodeType -ne 'Element') { continue }
|
||||
if (-not $childTypeDirMap.ContainsKey($child.LocalName)) { continue }
|
||||
$verObjName = $child.InnerText.Trim()
|
||||
if (-not $verObjName) { continue }
|
||||
$verTypeDir = Join-Path $configDir $childTypeDirMap[$child.LocalName]
|
||||
$verObjFile = Join-Path $verTypeDir "$verObjName.xml"
|
||||
if (-not (Test-Path $verObjFile)) { continue }
|
||||
$verDescriptors += $verObjFile
|
||||
foreach ($sub in @("Forms","Templates")) {
|
||||
$subDir = Join-Path (Join-Path $verTypeDir $verObjName) $sub
|
||||
if (-not (Test-Path $subDir -PathType Container)) { continue }
|
||||
$names = @(Get-ChildItem $subDir -Filter "*.xml" -File | ForEach-Object { $_.Name })
|
||||
[Array]::Sort($names, [StringComparer]::Ordinal)
|
||||
foreach ($n in $names) { $verDescriptors += (Join-Path $subDir $n) }
|
||||
}
|
||||
}
|
||||
}
|
||||
$verRel = { param($p) $p.Substring($configDir.Length).TrimStart('\', '/') -replace '\\', '/' }
|
||||
$verErrors = 0
|
||||
$verBodiesOk = 0
|
||||
$verOff = @()
|
||||
foreach ($desc in $verDescriptors) {
|
||||
if ($script:stopped) { break }
|
||||
$isRoot = ($desc -eq $resolvedPath)
|
||||
$descVer = if ($isRoot) { $version } else { Get-RootVersion $desc }
|
||||
if (-not $descVer) { continue }
|
||||
if (-not $isRoot -and $descVer -ne $version) { $verOff += "$(& $verRel $desc) $descVer" }
|
||||
# Тела Configuration.xml лежат в <корень>/Ext, тела объекта X.xml — в X/Ext.
|
||||
$extDir = if ($isRoot) { Join-Path $configDir "Ext" } else { Join-Path (Join-Path (Split-Path $desc) ([System.IO.Path]::GetFileNameWithoutExtension($desc))) "Ext" }
|
||||
if (-not (Test-Path $extDir -PathType Container)) { continue }
|
||||
$bodyNames = @(Get-ChildItem $extDir -Filter "*.xml" -File | ForEach-Object { $_.Name })
|
||||
[Array]::Sort($bodyNames, [StringComparer]::Ordinal)
|
||||
foreach ($bn in $bodyNames) {
|
||||
$body = Join-Path $extDir $bn
|
||||
$bodyVer = Get-RootVersion $body
|
||||
if (-not $bodyVer) { continue }
|
||||
# У заимствованной формы второй штамп — <BaseForm version=…> внутри тела; платформа сверяет
|
||||
# с дескриптором и его.
|
||||
if ($bn -ceq "Form.xml") {
|
||||
$bodyText = [System.IO.File]::ReadAllText($body, [System.Text.Encoding]::UTF8)
|
||||
$bfm = [regex]::Match($bodyText, '<BaseForm\s[^>]*?version="([^"]*)"')
|
||||
if ($bfm.Success -and $bfm.Groups[1].Value -ne $descVer) {
|
||||
$verErrors++
|
||||
Report-Error "17. $(& $verRel $body) <BaseForm> is stamped $($bfm.Groups[1].Value), its descriptor $(& $verRel $desc) $descVer — the platform refuses to load parts of one object in different formats"
|
||||
if ($script:stopped) { break }
|
||||
}
|
||||
}
|
||||
if ($bodyVer -eq $descVer) { $verBodiesOk++; continue }
|
||||
$verErrors++
|
||||
Report-Error "17. $(& $verRel $body) is stamped $bodyVer, its descriptor $(& $verRel $desc) $descVer — the platform refuses to load parts of one object in different formats"
|
||||
if ($script:stopped) { break }
|
||||
}
|
||||
}
|
||||
if ($verOff.Count -gt 0) {
|
||||
$shown = ($verOff | Select-Object -First 5) -join ", "
|
||||
if ($verOff.Count -gt 5) { $shown += ", … (+$($verOff.Count - 5))" }
|
||||
Report-Warn "17. Format version differs from the extension ($version): $shown — the platform loads it, but the dump is no longer uniform (typical after merging branches dumped by different platforms)"
|
||||
} elseif ($verErrors -eq 0 -and $verBodiesOk -gt 0) {
|
||||
Report-OK "17. Format version: $verBodiesOk stamped part(s) agree with their descriptors and the extension"
|
||||
}
|
||||
}
|
||||
|
||||
# Built-in language keywords in both spellings. The platform accepts either one in any module
|
||||
# (pairs taken from the platform string tables), so a module written in English is ordinary
|
||||
# source, not a broken one: we must read both and emit the spelling we read.
|
||||
|
||||
Reference in New Issue
Block a user