diff --git a/.claude/skills/cf-validate/scripts/cf-validate.ps1 b/.claude/skills/cf-validate/scripts/cf-validate.ps1 index 6e903ab6d..58424cc76 100644 --- a/.claude/skills/cf-validate/scripts/cf-validate.ps1 +++ b/.claude/skills/cf-validate/scripts/cf-validate.ps1 @@ -1,4 +1,4 @@ -# cf-validate v1.10 — Validate 1C configuration root structure +# cf-validate v1.11 — Validate 1C configuration root structure # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills [CmdletBinding(PositionalBinding=$false)] param( @@ -103,6 +103,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}$' $identPattern = '^[A-Za-z\u0410-\u042F\u0401\u0430-\u044F\u0451_][A-Za-z0-9\u0410-\u042F\u0401\u0430-\u044F\u0451_]*$' @@ -623,6 +638,28 @@ if ($formRefsChecked -eq 0) { foreach ($err in $formRefErrors) { Report-Error "9. $err" } } +# --- Check 10: тела конфигурации Ext/*.xml в версии Configuration.xml --- +# Конфигурация для платформы — такой же объект, как остальные: Configuration.xml и штампованные тела +# Ext/*.xml (CommandInterface, HomePageWorkArea, Splash, …) загружаются только в одной версии формата +# («Версия формата загружаемого файла … отличается от версии формата ранее загруженных файлов»). +$cfgExtDir = Join-Path $configDir "Ext" +$cfgBodiesOk = 0 +$cfgBodyErrors = 0 +if ($version -and (Test-Path $cfgExtDir -PathType Container)) { + $bodyNames = @(Get-ChildItem $cfgExtDir -Filter "*.xml" -File | ForEach-Object { $_.Name }) + [Array]::Sort($bodyNames, [StringComparer]::Ordinal) + foreach ($bn in $bodyNames) { + $bodyVer = Get-RootVersion (Join-Path $cfgExtDir $bn) + if (-not $bodyVer) { continue } + if ($bodyVer -eq $version) { $cfgBodiesOk++; continue } + $cfgBodyErrors++ + Report-Error "10. Ext/$bn is stamped $bodyVer, Configuration.xml $version — the platform refuses to load parts of one object in different formats" + } +} +if ($cfgBodyErrors -eq 0 -and $cfgBodiesOk -gt 0) { + Report-OK "10. Format version: $cfgBodiesOk stamped Ext part(s) agree with Configuration.xml" +} + # --- Final output --- & $finalize diff --git a/.claude/skills/cf-validate/scripts/cf-validate.py b/.claude/skills/cf-validate/scripts/cf-validate.py index 04c71dfef..c734b040f 100644 --- a/.claude/skills/cf-validate/scripts/cf-validate.py +++ b/.claude/skills/cf-validate/scripts/cf-validate.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# cf-validate v1.10 — Validate 1C configuration XML structure +# cf-validate v1.11 — Validate 1C configuration XML structure # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills """Validates Configuration.xml: root structure, InternalInfo, properties, ChildObjects, languages.""" import sys, os, argparse, re @@ -148,6 +148,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 + + class Reporter: def __init__(self, max_errors, detailed=False): self.errors = 0 @@ -636,6 +652,29 @@ def main(): for err in form_ref_errors: r.error(f'9. {err}') + # --- Check 10: тела конфигурации Ext/*.xml в версии Configuration.xml --- + # Конфигурация для платформы — такой же объект, как остальные: Configuration.xml и штампованные тела + # Ext/*.xml (CommandInterface, HomePageWorkArea, Splash, …) загружаются только в одной версии формата + # («Версия формата загружаемого файла … отличается от версии формата ранее загруженных файлов»). + cfg_ext_dir = os.path.join(config_dir, 'Ext') + cfg_bodies_ok = 0 + cfg_body_errors = 0 + if version and os.path.isdir(cfg_ext_dir): + body_names = sorted(n for n in os.listdir(cfg_ext_dir) + if n.lower().endswith('.xml') and os.path.isfile(os.path.join(cfg_ext_dir, n))) + for bn in body_names: + body_ver = root_version(os.path.join(cfg_ext_dir, bn)) + if not body_ver: + continue + if body_ver == version: + cfg_bodies_ok += 1 + continue + cfg_body_errors += 1 + r.error(f'10. Ext/{bn} is stamped {body_ver}, Configuration.xml {version} ' + '— the platform refuses to load parts of one object in different formats') + if cfg_body_errors == 0 and cfg_bodies_ok > 0: + r.ok(f'10. Format version: {cfg_bodies_ok} stamped Ext part(s) agree with Configuration.xml') + # --- Final output --- r.finalize(out_file) sys.exit(1 if r.errors > 0 else 0) diff --git a/tests/skills/cases/cf-validate/error-version-ext-mismatch.json b/tests/skills/cases/cf-validate/error-version-ext-mismatch.json new file mode 100644 index 000000000..02e1ef5ff --- /dev/null +++ b/tests/skills/cases/cf-validate/error-version-ext-mismatch.json @@ -0,0 +1,8 @@ +{ + "name": "HomePageWorkArea.xml 2.18 при Configuration.xml 2.20 — ошибка: платформа такую конфигурацию не загрузит", + "setup": "fixture:version-ext-mismatch", + "expectError": true, + "noSnapshot": "cf-validate только читает и печатает — эталон зафиксировал бы фикстуру, а не выход проверяемого навыка; проверяется stdout", + "expect": { "stdoutContains": ["[ERROR] 10. Ext/HomePageWorkArea.xml is stamped 2.18, Configuration.xml 2.20"] }, + "skipPlatformVerify": "фикстура намеренно не загружается: Configuration.xml и его тело в разных версиях формата" +} diff --git a/tests/skills/cases/cf-validate/fixtures/version-ext-agree/Configuration.xml b/tests/skills/cases/cf-validate/fixtures/version-ext-agree/Configuration.xml new file mode 100644 index 000000000..5dbd6cb90 --- /dev/null +++ b/tests/skills/cases/cf-validate/fixtures/version-ext-agree/Configuration.xml @@ -0,0 +1,255 @@ + + + + + + 9cd510cd-abfc-11d4-9434-004095e12fc7 + 36197842-3924-4ed9-af58-a000c60e538f + + + 9fcd25a0-4822-11d4-9414-008048da11f9 + 5aee8ff0-4d4a-4bf1-bb50-4b4054bbb288 + + + e3687481-0a87-462c-a166-9f34594f9bba + 075f7faa-ceb1-4098-ac29-a4c11d4dd7a6 + + + 9de14907-ec23-4a07-96f0-85521cb6b53b + ff1dfda3-e856-49eb-afe8-e7f6dce55e16 + + + 51f2d5d8-ea4d-4064-8892-82951750031e + 71e0983f-f59b-439a-954a-7e2494108760 + + + e68182ea-4237-4383-967f-90c1e3370bc7 + 62b34336-f570-44f7-94e9-3016b5237ec9 + + + fb282519-d103-4dd3-bc12-cb271d631dfc + 66dfac93-ffbe-4b12-83cf-9ab0ed080cfa + + + + ПроверкаВерсий + + + ru + ПроверкаВерсий + + + + + Version8_3_27 + ManagedApplication + + PlatformApplication + + Russian + + + + + false + false + false + + + + + + + + + + + + + + + + + + + + + + Biometrics + true + + + Location + false + + + BackgroundLocation + false + + + BluetoothPrinters + false + + + WiFiPrinters + false + + + Contacts + false + + + Calendars + false + + + PushNotifications + false + + + LocalNotifications + false + + + InAppPurchases + false + + + PersonalComputerFileExchange + false + + + Ads + false + + + NumberDialing + false + + + CallProcessing + false + + + CallLog + false + + + AutoSendSMS + false + + + ReceiveSMS + false + + + SMSLog + false + + + Camera + false + + + Microphone + false + + + MusicLibrary + false + + + PictureAndVideoLibraries + false + + + AudioPlaybackAndVibration + false + + + BackgroundAudioPlaybackAndVibration + false + + + InstallPackages + false + + + OSBackup + true + + + ApplicationUsageStatistics + false + + + BarcodeScanning + false + + + BackgroundAudioRecording + false + + + AllFilesAccess + false + + + Videoconferences + false + + + NFC + false + + + DocumentScanning + false + + + SpeechToText + false + + + Geofences + false + + + IncomingShareRequests + false + + + AllIncomingShareRequestsTypesProcessing + false + + + TextToSpeech + false + + + + + + Normal + + + Language.Русский + + + + + + Managed + NotAutoFree + DontUse + DontUse + TaxiEnableVersion8_2 + DontUse + Version8_3_27 + + + + Русский + + + \ No newline at end of file diff --git a/tests/skills/cases/cf-validate/fixtures/version-ext-agree/Ext/ClientApplicationInterface.xml b/tests/skills/cases/cf-validate/fixtures/version-ext-agree/Ext/ClientApplicationInterface.xml new file mode 100644 index 000000000..ff30bfe90 --- /dev/null +++ b/tests/skills/cases/cf-validate/fixtures/version-ext-agree/Ext/ClientApplicationInterface.xml @@ -0,0 +1,18 @@ + + + + + cbab57f2-a0f3-4f0a-89ea-4cb19570ab75 + + + + + b553047f-c9aa-4157-978d-448ecad24248 + + + + + + + + \ No newline at end of file diff --git a/tests/skills/cases/cf-validate/fixtures/version-ext-agree/Ext/HomePageWorkArea.xml b/tests/skills/cases/cf-validate/fixtures/version-ext-agree/Ext/HomePageWorkArea.xml new file mode 100644 index 000000000..7213f1590 --- /dev/null +++ b/tests/skills/cases/cf-validate/fixtures/version-ext-agree/Ext/HomePageWorkArea.xml @@ -0,0 +1,6 @@ + + + TwoColumnsEqualWidth + + + \ No newline at end of file diff --git a/tests/skills/cases/cf-validate/fixtures/version-ext-agree/Languages/Русский.xml b/tests/skills/cases/cf-validate/fixtures/version-ext-agree/Languages/Русский.xml new file mode 100644 index 000000000..dacbaac10 --- /dev/null +++ b/tests/skills/cases/cf-validate/fixtures/version-ext-agree/Languages/Русский.xml @@ -0,0 +1,16 @@ + + + + + Русский + + + ru + Русский + + + + ru + + + \ No newline at end of file diff --git a/tests/skills/cases/cf-validate/fixtures/version-ext-mismatch/Configuration.xml b/tests/skills/cases/cf-validate/fixtures/version-ext-mismatch/Configuration.xml new file mode 100644 index 000000000..5dbd6cb90 --- /dev/null +++ b/tests/skills/cases/cf-validate/fixtures/version-ext-mismatch/Configuration.xml @@ -0,0 +1,255 @@ + + + + + + 9cd510cd-abfc-11d4-9434-004095e12fc7 + 36197842-3924-4ed9-af58-a000c60e538f + + + 9fcd25a0-4822-11d4-9414-008048da11f9 + 5aee8ff0-4d4a-4bf1-bb50-4b4054bbb288 + + + e3687481-0a87-462c-a166-9f34594f9bba + 075f7faa-ceb1-4098-ac29-a4c11d4dd7a6 + + + 9de14907-ec23-4a07-96f0-85521cb6b53b + ff1dfda3-e856-49eb-afe8-e7f6dce55e16 + + + 51f2d5d8-ea4d-4064-8892-82951750031e + 71e0983f-f59b-439a-954a-7e2494108760 + + + e68182ea-4237-4383-967f-90c1e3370bc7 + 62b34336-f570-44f7-94e9-3016b5237ec9 + + + fb282519-d103-4dd3-bc12-cb271d631dfc + 66dfac93-ffbe-4b12-83cf-9ab0ed080cfa + + + + ПроверкаВерсий + + + ru + ПроверкаВерсий + + + + + Version8_3_27 + ManagedApplication + + PlatformApplication + + Russian + + + + + false + false + false + + + + + + + + + + + + + + + + + + + + + + Biometrics + true + + + Location + false + + + BackgroundLocation + false + + + BluetoothPrinters + false + + + WiFiPrinters + false + + + Contacts + false + + + Calendars + false + + + PushNotifications + false + + + LocalNotifications + false + + + InAppPurchases + false + + + PersonalComputerFileExchange + false + + + Ads + false + + + NumberDialing + false + + + CallProcessing + false + + + CallLog + false + + + AutoSendSMS + false + + + ReceiveSMS + false + + + SMSLog + false + + + Camera + false + + + Microphone + false + + + MusicLibrary + false + + + PictureAndVideoLibraries + false + + + AudioPlaybackAndVibration + false + + + BackgroundAudioPlaybackAndVibration + false + + + InstallPackages + false + + + OSBackup + true + + + ApplicationUsageStatistics + false + + + BarcodeScanning + false + + + BackgroundAudioRecording + false + + + AllFilesAccess + false + + + Videoconferences + false + + + NFC + false + + + DocumentScanning + false + + + SpeechToText + false + + + Geofences + false + + + IncomingShareRequests + false + + + AllIncomingShareRequestsTypesProcessing + false + + + TextToSpeech + false + + + + + + Normal + + + Language.Русский + + + + + + Managed + NotAutoFree + DontUse + DontUse + TaxiEnableVersion8_2 + DontUse + Version8_3_27 + + + + Русский + + + \ No newline at end of file diff --git a/tests/skills/cases/cf-validate/fixtures/version-ext-mismatch/Ext/ClientApplicationInterface.xml b/tests/skills/cases/cf-validate/fixtures/version-ext-mismatch/Ext/ClientApplicationInterface.xml new file mode 100644 index 000000000..ff30bfe90 --- /dev/null +++ b/tests/skills/cases/cf-validate/fixtures/version-ext-mismatch/Ext/ClientApplicationInterface.xml @@ -0,0 +1,18 @@ + + + + + cbab57f2-a0f3-4f0a-89ea-4cb19570ab75 + + + + + b553047f-c9aa-4157-978d-448ecad24248 + + + + + + + + \ No newline at end of file diff --git a/tests/skills/cases/cf-validate/fixtures/version-ext-mismatch/Ext/HomePageWorkArea.xml b/tests/skills/cases/cf-validate/fixtures/version-ext-mismatch/Ext/HomePageWorkArea.xml new file mode 100644 index 000000000..9bc35483a --- /dev/null +++ b/tests/skills/cases/cf-validate/fixtures/version-ext-mismatch/Ext/HomePageWorkArea.xml @@ -0,0 +1,6 @@ + + + TwoColumnsEqualWidth + + + \ No newline at end of file diff --git a/tests/skills/cases/cf-validate/fixtures/version-ext-mismatch/Languages/Русский.xml b/tests/skills/cases/cf-validate/fixtures/version-ext-mismatch/Languages/Русский.xml new file mode 100644 index 000000000..dacbaac10 --- /dev/null +++ b/tests/skills/cases/cf-validate/fixtures/version-ext-mismatch/Languages/Русский.xml @@ -0,0 +1,16 @@ + + + + + Русский + + + ru + Русский + + + + ru + + + \ No newline at end of file diff --git a/tests/skills/cases/cf-validate/valid-version-ext-agree.json b/tests/skills/cases/cf-validate/valid-version-ext-agree.json new file mode 100644 index 000000000..fb43e746c --- /dev/null +++ b/tests/skills/cases/cf-validate/valid-version-ext-agree.json @@ -0,0 +1,6 @@ +{ + "name": "Тела конфигурации Ext/*.xml в версии Configuration.xml — чисто", + "setup": "fixture:version-ext-agree", + "noSnapshot": "cf-validate только читает и печатает — эталон зафиксировал бы фикстуру, а не выход проверяемого навыка; проверяется stdout", + "expect": { "stdoutContains": ["=== Validation OK"] } +} diff --git a/tests/skills/check-inline-drift.mjs b/tests/skills/check-inline-drift.mjs index 43c9eedad..99e25150c 100644 --- a/tests/skills/check-inline-drift.mjs +++ b/tests/skills/check-inline-drift.mjs @@ -130,7 +130,7 @@ const FAMILIES = [ { name: 'root_version', py: 'root_version', ps1: 'Get-RootVersion', variants: [ - { id: 'base', authority: 'meta-validate', consumers: ['form-validate'] }, + { id: 'base', authority: 'meta-validate', consumers: ['cf-validate', 'form-validate'] }, ], }, {