mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-09-28 21:15:54 +03:00
feat(epf-validate): проверка 11 — версия формата согласована внутри объектов обработки
Корень обработки и его штампованные тела (Ext/Help.xml), дескриптор формы или макета и его тело платформа загружает только в одной версии формата — иначе сборка отменяется с «Версия формата загружаемого файла … отличается от версии формата ранее загруженных файлов». Проверено сборкой на 8.3.27.1859: тело формы или справка не в версии своего дескриптора — отказ; форма целиком в 2.18 внутри обработки 2.20 собирается. Первое — ошибка, второе — предупреждение о неоднородных исходниках. Работает и для внешних отчётов (erf-validate). 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
14d010f4c2
commit
fbcf65e12d
@@ -1,4 +1,4 @@
|
||||
# epf-validate v1.7 — Validate 1C external data processor / report structure
|
||||
# epf-validate v1.8 — Validate 1C external data processor / report structure
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
# Works for both EPF (ExternalDataProcessor) and ERF (ExternalReport) — auto-detects
|
||||
[CmdletBinding(PositionalBinding=$false)]
|
||||
@@ -125,6 +125,21 @@ function Get-FormatRank([string]$ver) {
|
||||
return 0
|
||||
}
|
||||
|
||||
# Штамп версии формата — атрибут version КОРНЕВОГО элемента файла. Копия общего эталона (семья
|
||||
# root_version, авторитет — meta-validate).
|
||||
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 ---
|
||||
|
||||
$guidPattern = '^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$'
|
||||
@@ -862,6 +877,54 @@ if ($check10Ok) {
|
||||
}
|
||||
}
|
||||
|
||||
# --- Check 11: версия формата согласована внутри объектов обработки; сверка с корнем ---
|
||||
# Корень обработки и его штампованные тела (Ext/Help.xml), дескриптор формы/макета и его тело платформа
|
||||
# загружает только в одной версии: «Версия формата загружаемого файла … отличается от версии формата
|
||||
# ранее загруженных файлов» — сборка отменяется. Форма или макет целиком в другой версии, чем корень,
|
||||
# собирается — это лишь неоднородность исходников (типично после мержа веток, выгруженных разными
|
||||
# платформами), поэтому такое расхождение только предупреждение.
|
||||
if ($version) {
|
||||
$verObjDir = Join-Path $srcDir ([System.IO.Path]::GetFileNameWithoutExtension($resolvedPath))
|
||||
$verDescriptors = @($resolvedPath)
|
||||
foreach ($sub in @("Forms","Templates")) {
|
||||
$subDir = Join-Path $verObjDir $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($srcDir.Length).TrimStart('\', '/') -replace '\\', '/' }
|
||||
$verErrors = 0
|
||||
$verBodiesOk = 0
|
||||
$verOff = @()
|
||||
foreach ($desc in $verDescriptors) {
|
||||
if ($script:stopped) { break }
|
||||
$descVer = if ($desc -eq $resolvedPath) { $version } else { Get-RootVersion $desc }
|
||||
if (-not $descVer) { continue }
|
||||
if ($desc -ne $resolvedPath -and $descVer -ne $version) { $verOff += "$(& $verRel $desc) $descVer" }
|
||||
$extDir = 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 }
|
||||
if ($bodyVer -eq $descVer) { $verBodiesOk++; continue }
|
||||
$verErrors++
|
||||
Report-Error "11. $(& $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 "11. Format version differs from the processor root ($version): $shown — the platform builds it, but the sources are no longer uniform (typical after merging branches dumped by different platforms)"
|
||||
} elseif ($verErrors -eq 0 -and $verBodiesOk -gt 0) {
|
||||
Report-OK "11. Format version: $verBodiesOk stamped part(s) agree with their descriptors and the root"
|
||||
}
|
||||
}
|
||||
|
||||
# --- Final output ---
|
||||
|
||||
& $finalize
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# epf-validate v1.7 — Validate 1C external data processor / report structure
|
||||
# epf-validate v1.8 — Validate 1C external data processor / report structure
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
# Works for both EPF (ExternalDataProcessor) and ERF (ExternalReport) — auto-detects
|
||||
|
||||
@@ -75,6 +75,22 @@ def format_rank(ver):
|
||||
return int(m.group(1)) * 100 + int(m.group(2)) if m else 0
|
||||
|
||||
|
||||
# Штамп версии формата — атрибут version КОРНЕВОГО элемента файла. Копия общего эталона (семья
|
||||
# root_version, авторитет — meta-validate).
|
||||
def root_version(xml_path):
|
||||
if not os.path.isfile(xml_path):
|
||||
return None
|
||||
with open(xml_path, "rb") as f:
|
||||
head = f.read(4096).decode("utf-8", errors="ignore")
|
||||
m = re.search(r'<[A-Za-z_][\w.:-]*(\s[^>]*)?/?>', head)
|
||||
if not m:
|
||||
return None
|
||||
v = re.search(r'(?:^|\s)version="([^"]*)"', m.group(1) or "")
|
||||
if v:
|
||||
return v.group(1)
|
||||
return None
|
||||
|
||||
|
||||
def localname(el):
|
||||
return etree.QName(el.tag).localname
|
||||
|
||||
@@ -749,6 +765,65 @@ def main():
|
||||
else:
|
||||
pass # no form descriptors to check
|
||||
|
||||
# --- Check 11: версия формата согласована внутри объектов обработки; сверка с корнем ---
|
||||
# Корень обработки и его штампованные тела (Ext/Help.xml), дескриптор формы/макета и его тело платформа
|
||||
# загружает только в одной версии: «Версия формата загружаемого файла … отличается от версии формата
|
||||
# ранее загруженных файлов» — сборка отменяется. Форма или макет целиком в другой версии, чем корень,
|
||||
# собирается — это лишь неоднородность исходников (типично после мержа веток, выгруженных разными
|
||||
# платформами), поэтому такое расхождение только предупреждение.
|
||||
if version:
|
||||
ver_obj_dir = os.path.join(src_dir, os.path.splitext(os.path.basename(resolved_path))[0])
|
||||
ver_descriptors = [resolved_path]
|
||||
for sub in ("Forms", "Templates"):
|
||||
sub_dir = os.path.join(ver_obj_dir, sub)
|
||||
if not os.path.isdir(sub_dir):
|
||||
continue
|
||||
names = sorted(n for n in os.listdir(sub_dir)
|
||||
if n.lower().endswith(".xml") and os.path.isfile(os.path.join(sub_dir, n)))
|
||||
for n in names:
|
||||
ver_descriptors.append(os.path.join(sub_dir, n))
|
||||
|
||||
def ver_rel(p):
|
||||
return p[len(src_dir):].lstrip("\\/").replace("\\", "/")
|
||||
|
||||
ver_errors = 0
|
||||
ver_bodies_ok = 0
|
||||
ver_off = []
|
||||
for desc in ver_descriptors:
|
||||
if stopped:
|
||||
break
|
||||
desc_ver = version if desc == resolved_path else root_version(desc)
|
||||
if not desc_ver:
|
||||
continue
|
||||
if desc != resolved_path and desc_ver != version:
|
||||
ver_off.append(f"{ver_rel(desc)} {desc_ver}")
|
||||
ext_dir = os.path.join(os.path.dirname(desc), os.path.splitext(os.path.basename(desc))[0], "Ext")
|
||||
if not os.path.isdir(ext_dir):
|
||||
continue
|
||||
body_names = sorted(n for n in os.listdir(ext_dir)
|
||||
if n.lower().endswith(".xml") and os.path.isfile(os.path.join(ext_dir, n)))
|
||||
for bn in body_names:
|
||||
body = os.path.join(ext_dir, bn)
|
||||
body_ver = root_version(body)
|
||||
if not body_ver:
|
||||
continue
|
||||
if body_ver == desc_ver:
|
||||
ver_bodies_ok += 1
|
||||
continue
|
||||
ver_errors += 1
|
||||
report_error(f"11. {ver_rel(body)} is stamped {body_ver}, its descriptor {ver_rel(desc)} {desc_ver} "
|
||||
"— the platform refuses to load parts of one object in different formats")
|
||||
if stopped:
|
||||
break
|
||||
if ver_off:
|
||||
shown = ", ".join(ver_off[:5])
|
||||
if len(ver_off) > 5:
|
||||
shown += f", … (+{len(ver_off) - 5})"
|
||||
report_warn(f"11. Format version differs from the processor root ({version}): {shown} — the platform builds it, "
|
||||
"but the sources are no longer uniform (typical after merging branches dumped by different platforms)")
|
||||
elif ver_errors == 0 and ver_bodies_ok > 0:
|
||||
report_ok(f"11. Format version: {ver_bodies_ok} stamped part(s) agree with their descriptors and the root")
|
||||
|
||||
# --- Final output ---
|
||||
finalize()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user