From 06bdee3e254338c5033a1d55325f8f2820637ed8 Mon Sep 17 00:00:00 2001 From: Nick Shirokov Date: Sat, 5 Sep 2026 19:10:58 +0300 Subject: [PATCH] =?UTF-8?q?fix(epf-build):=20=D0=BF=D1=80=D0=BE=D0=B2?= =?UTF-8?q?=D0=B5=D1=80=D0=BA=D0=B0=20=D0=B8=D1=81=D1=85=D0=BE=D0=B4=D0=BD?= =?UTF-8?q?=D0=B8=D0=BA=D0=BE=D0=B2=20=D0=BD=D0=B5=20=D0=B2=D0=B8=D0=B4?= =?UTF-8?q?=D0=B5=D0=BB=D0=B0=20=D0=BC=D0=BE=D0=B4=D1=83=D0=BB=D0=B5=D0=B9?= =?UTF-8?q?=20=D0=B8=20=D1=84=D0=BE=D1=80=D0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Относительный путь при копировании содержимого объекта в конфигурацию-заглушку считался через Substring по длине переданной строки. Каталог может прийти с коротким именем (C:\Users\NSHIRO~1\...), а Get-ChildItem отдаёт полное — разница в один символ, и файлы уезжали в <Объект>\а\Ext\ObjectModule.bsl. Проверка при этом молча шла по объекту без модулей и форм и всегда была зелёной. Длина берётся у разрешённого пути; py-порт иммунен (os.path.relpath). Дефект нашли новые кейсы stub-db-create — конвертация внешней обработки в объект конфигурации: корневой тег и порождаемые типы, перевыпуск GUID, копирование .bsl байт в байт. Каждый сверен возвратом дефекта в обоих портах. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_013MQkqXxErBepYmoUycfkbn --- .../epf-build/scripts/stub-db-create.ps1 | 10 ++- .../epf-build/scripts/stub-db-create.py | 2 +- tests/skills/cases/stub-db-create/_skill.json | 5 ++ .../stub-db-create/embed-converts-object.json | 64 +++++++++++++++++++ .../cases/stub-db-create/embed-keeps-bsl.json | 52 +++++++++++++++ .../stub-db-create/embed-reissues-guids.json | 60 +++++++++++++++++ 6 files changed, 189 insertions(+), 4 deletions(-) create mode 100644 tests/skills/cases/stub-db-create/_skill.json create mode 100644 tests/skills/cases/stub-db-create/embed-converts-object.json create mode 100644 tests/skills/cases/stub-db-create/embed-keeps-bsl.json create mode 100644 tests/skills/cases/stub-db-create/embed-reissues-guids.json diff --git a/.claude/skills/epf-build/scripts/stub-db-create.ps1 b/.claude/skills/epf-build/scripts/stub-db-create.ps1 index c36a95029..df12dfaa3 100644 --- a/.claude/skills/epf-build/scripts/stub-db-create.ps1 +++ b/.claude/skills/epf-build/scripts/stub-db-create.ps1 @@ -1,4 +1,4 @@ -# stub-db-create v1.9 — Create temp 1C infobase with metadata stubs for EPF/ERF build +# stub-db-create v1.10 — Create temp 1C infobase with metadata stubs for EPF/ERF build # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills param( [Parameter(Mandatory)] @@ -442,9 +442,13 @@ function Add-SourceObjectToConfig { # Содержимое объекта — как есть; в XML та же подстановка типа, .bsl копируются байт в байт. $srcContent = Join-Path (Split-Path $SourceXml -Parent) $name if (Test-Path $srcContent) { + # Длину префикса берём у РАЗРЕШЁННОГО пути, а не у переданной строки: путь может + # прийти с коротким именем (C:\Users\NSHIRO~1\…), а Get-ChildItem отдаёт полное — тогда + # отрезание по длине исходной строки оставляет в относительном пути чужие символы. + $srcRoot = (Get-Item -LiteralPath $srcContent).FullName.TrimEnd('\', '/') $dstContent = Join-Path $objDir $name - foreach ($f in (Get-ChildItem -Path $srcContent -Recurse -File)) { - $rel = $f.FullName.Substring($srcContent.Length).TrimStart('\', '/') + foreach ($f in (Get-ChildItem -LiteralPath $srcRoot -Recurse -File)) { + $rel = $f.FullName.Substring($srcRoot.Length).TrimStart('\', '/') $dst = Join-Path $dstContent $rel New-Item -ItemType Directory -Path (Split-Path $dst -Parent) -Force | Out-Null if ($f.Extension -ieq '.xml') { diff --git a/.claude/skills/epf-build/scripts/stub-db-create.py b/.claude/skills/epf-build/scripts/stub-db-create.py index 8b8871968..4c16cb645 100644 --- a/.claude/skills/epf-build/scripts/stub-db-create.py +++ b/.claude/skills/epf-build/scripts/stub-db-create.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# stub-db-create v1.9 — Create temp 1C infobase with metadata stubs for EPF/ERF build +# stub-db-create v1.10 — Create temp 1C infobase with metadata stubs for EPF/ERF build # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import argparse diff --git a/tests/skills/cases/stub-db-create/_skill.json b/tests/skills/cases/stub-db-create/_skill.json new file mode 100644 index 000000000..f0f1cab2f --- /dev/null +++ b/tests/skills/cases/stub-db-create/_skill.json @@ -0,0 +1,5 @@ +{ + "script": "epf-build/scripts/stub-db-create", + "setup": "none", + "args": [] +} \ No newline at end of file diff --git a/tests/skills/cases/stub-db-create/embed-converts-object.json b/tests/skills/cases/stub-db-create/embed-converts-object.json new file mode 100644 index 000000000..1977724a4 --- /dev/null +++ b/tests/skills/cases/stub-db-create/embed-converts-object.json @@ -0,0 +1,64 @@ +{ + "name": "Внешняя обработка конвертируется в объект конфигурации", + "osOnly": "win32", + "fakePlatform": { + "exit": 1, + "log": "" + }, + "preRun": [ + { + "writeFile": { + "path": "src/Проба.xml", + "content": "\n\n\t\n\t\t\n\t\t\t\n\t\t\t\tcccccccc-4444-5555-6666-dddddddddddd\n\t\t\t\teeeeeeee-7777-8888-9999-ffffffffffff\n\t\t\t\n\t\t\n\t\t\n\t\t\tПроба\n\t\t\tExternalDataProcessor.Проба.Form.Форма\n\t\t\n\t\t\n\t\t\t
Форма
\n\t\t
\n\t
\n
\n" + } + }, + { + "writeFile": { + "path": "src/Проба/Ext/ObjectModule.bsl", + "content": "Процедура Проба()\r\n\tСообщить(\"ExternalDataProcessorObject.Проба\");\r\n\tСообщить(\"ExternalDataProcessor.Проба.Form.Форма\");\r\nКонецПроцедуры\r\n" + } + }, + { + "writeFile": { + "path": "src/Проба/Forms/Форма.xml", + "content": "\n\n\t
\n\t\t\n\t\t\tФорма\n\t\t\n\t
\n
\n" + } + } + ], + "args_extra": [ + "-SourceDir", + "{workDir}\\src", + "-V8Path", + "{workDir}\\fake.cmd", + "-TempBasePath", + "{workDir}\\base", + "-EmbedSourceFile", + "{workDir}\\src\\Проба.xml" + ], + "expect": { + "fileContains": [ + { + "file": "base\\cfg\\DataProcessors\\Проба.xml", + "text": [ + "", + "", + "DataProcessor.Проба.Form.Форма" + ] + }, + { + "file": "base\\cfg\\Configuration.xml", + "text": "Проба" + } + ], + "fileNotContains": { + "file": "base\\cfg\\DataProcessors\\Проба.xml", + "text": [ + "\n\n\t\n\t\t\n\t\t\t\n\t\t\t\tcccccccc-4444-5555-6666-dddddddddddd\n\t\t\t\teeeeeeee-7777-8888-9999-ffffffffffff\n\t\t\t\n\t\t\n\t\t\n\t\t\tПроба\n\t\t\tExternalDataProcessor.Проба.Form.Форма\n\t\t\n\t\t\n\t\t\t
Форма
\n\t\t
\n\t
\n
\n" + } + }, + { + "writeFile": { + "path": "src/Проба/Ext/ObjectModule.bsl", + "content": "Процедура Проба()\r\n\tСообщить(\"ExternalDataProcessorObject.Проба\");\r\n\tСообщить(\"ExternalDataProcessor.Проба.Form.Форма\");\r\nКонецПроцедуры\r\n" + } + }, + { + "writeFile": { + "path": "src/Проба/Forms/Форма.xml", + "content": "\n\n\t
\n\t\t\n\t\t\tФорма\n\t\t\n\t
\n
\n" + } + } + ], + "args_extra": [ + "-SourceDir", + "{workDir}\\src", + "-V8Path", + "{workDir}\\fake.cmd", + "-TempBasePath", + "{workDir}\\base", + "-EmbedSourceFile", + "{workDir}\\src\\Проба.xml" + ], + "expect": { + "filesEqual": [ + { + "actual": "base/cfg/DataProcessors/Проба/Ext/ObjectModule.bsl", + "expected": "src/Проба/Ext/ObjectModule.bsl" + } + ], + "fileContains": { + "file": "base\\cfg\\DataProcessors\\Проба\\Ext\\ObjectModule.bsl", + "text": "ExternalDataProcessorObject.Проба" + } + }, + "expectError": true, + "noSnapshot": "проверяется равенство файлов, а не снэпшот" +} \ No newline at end of file diff --git a/tests/skills/cases/stub-db-create/embed-reissues-guids.json b/tests/skills/cases/stub-db-create/embed-reissues-guids.json new file mode 100644 index 000000000..8c8f2f591 --- /dev/null +++ b/tests/skills/cases/stub-db-create/embed-reissues-guids.json @@ -0,0 +1,60 @@ +{ + "name": "У копии все GUID свои", + "osOnly": "win32", + "fakePlatform": { + "exit": 1, + "log": "" + }, + "preRun": [ + { + "writeFile": { + "path": "src/Проба.xml", + "content": "\n\n\t\n\t\t\n\t\t\t\n\t\t\t\tcccccccc-4444-5555-6666-dddddddddddd\n\t\t\t\teeeeeeee-7777-8888-9999-ffffffffffff\n\t\t\t\n\t\t\n\t\t\n\t\t\tПроба\n\t\t\tExternalDataProcessor.Проба.Form.Форма\n\t\t\n\t\t\n\t\t\t
Форма
\n\t\t
\n\t
\n
\n" + } + }, + { + "writeFile": { + "path": "src/Проба/Ext/ObjectModule.bsl", + "content": "Процедура Проба()\r\n\tСообщить(\"ExternalDataProcessorObject.Проба\");\r\n\tСообщить(\"ExternalDataProcessor.Проба.Form.Форма\");\r\nКонецПроцедуры\r\n" + } + }, + { + "writeFile": { + "path": "src/Проба/Forms/Форма.xml", + "content": "\n\n\t
\n\t\t\n\t\t\tФорма\n\t\t\n\t
\n
\n" + } + } + ], + "args_extra": [ + "-SourceDir", + "{workDir}\\src", + "-V8Path", + "{workDir}\\fake.cmd", + "-TempBasePath", + "{workDir}\\base", + "-EmbedSourceFile", + "{workDir}\\src\\Проба.xml" + ], + "expect": { + "fileNotContains": [ + { + "file": "base\\cfg\\DataProcessors\\Проба.xml", + "text": [ + "aaaaaaaa-1111-2222-3333-bbbbbbbbbbbb", + "cccccccc-4444-5555-6666-dddddddddddd", + "eeeeeeee-7777-8888-9999-ffffffffffff" + ] + }, + { + "file": "base\\cfg\\DataProcessors\\Проба\\Forms\\Форма.xml", + "text": "11111111-2222-3333-4444-555555555555" + } + ], + "fileContains": { + "file": "base\\cfg\\DataProcessors\\Проба.xml", + "text": "" + } + }, + "expectError": true, + "noSnapshot": "генерируются случайные GUID — снять эталон нельзя" +}