fix(epf-build): конвертация в заглушку не калечит имена с суффиксом вида объекта

Замена ExternalReport. -> Report. шла по всему тексту XML и попадала внутрь
имени объекта, если оно оканчивается так же (ПриёмкаExternalReport). Имя берётся
из <Name> до замены и остаётся авторским везде — в имени файла, GeneratedType и
составе конфигурации, — а ссылка в скопированном XML расходилась с ним, и
заглушка не грузилась: «Неизвестный объект метаданных - Report.ПриёмкаReport…».

Заменяется только префикс вида объекта в начале квалифицированного имени.
Регрессии строят фикстуру навыками (erf-init --WithSKD, epf-init, form-add) —
так в кейс попадает и настоящая ссылка вида cfg:ExternalReportObject.<Имя>.
Соседние кейсы каталога переведены на {fakePlatform} и прямые слэши.

Closes #90

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Nick Shirokov
2026-09-14 12:09:58 +03:00
co-authored by Claude Opus 5
parent 56b0c0cfd7
commit e2c7f38518
7 changed files with 189 additions and 30 deletions
@@ -1,4 +1,4 @@
# stub-db-create v1.10 — Create temp 1C infobase with metadata stubs for EPF/ERF build
# stub-db-create v1.11 — Create temp 1C infobase with metadata stubs for EPF/ERF build
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
param(
[Parameter(Mandatory)]
@@ -387,6 +387,16 @@ if ($needsRegistrator) {
#
# Подстановка типа делается ТОЛЬКО в .xml (это DefaultForm и основной реквизит формы); в .bsl
# такой же текст был бы кодом, и трогать его нельзя.
function Convert-RefTags {
param([string]$Text, [string]$ExtTag, [string]$CfgTag)
# Только префикс вида объекта в начале квалифицированного имени. Глобальная замена подстроки
# резала бы и имя самого объекта, если оно оканчивается так же (ПриёмкаExternalReport), —
# ссылка расходилась с именем, и заглушка не грузилась. [regex]::Replace, а не -replace:
# оператор регистронезависим, а теги 1С регистрозависимы.
return [regex]::Replace($Text, "(?<![\w.])$ExtTag(Object)?\.", ($CfgTag + '$1.'))
}
function Add-SourceObjectToConfig {
param([string]$SourceXml, [string]$CfgDir)
@@ -416,7 +426,7 @@ function Add-SourceObjectToConfig {
$conv = $reGuid.Replace($text, $reissue)
$conv = $conv.Replace("<$extTag ", "<$cfgTag ").Replace("<$extTag>", "<$cfgTag>").Replace("</$extTag>", "</$cfgTag>")
$conv = $conv.Replace("${extTag}Object.", "${cfgTag}Object.").Replace("$extTag.", "$cfgTag.")
$conv = Convert-RefTags $conv $extTag $cfgTag
# Тип менеджера у внешней обработки не объявлен, а объекту конфигурации он обязателен:
# без него платформа отвечает «отсутствует один или более типов объекта».
@@ -454,7 +464,7 @@ function Add-SourceObjectToConfig {
if ($f.Extension -ieq '.xml') {
$t = [IO.File]::ReadAllText($f.FullName, [Text.Encoding]::UTF8)
$t = $reGuid.Replace($t, $reissue)
$t = $t.Replace("${extTag}Object.", "${cfgTag}Object.").Replace("$extTag.", "$cfgTag.")
$t = Convert-RefTags $t $extTag $cfgTag
[IO.File]::WriteAllText($dst, $t, $encBom)
} else {
Copy-Item -Path $f.FullName -Destination $dst -Force
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
# stub-db-create v1.10 — Create temp 1C infobase with metadata stubs for EPF/ERF build
# stub-db-create v1.11 — Create temp 1C infobase with metadata stubs for EPF/ERF build
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
import argparse
@@ -1133,6 +1133,14 @@ def write_bom(path, content):
GUID_RE = re.compile(r'[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}')
def retag_refs(text, ext_tag, cfg_tag):
# Только префикс вида объекта в начале квалифицированного имени. Глобальная замена подстроки
# резала бы и имя самого объекта, если оно оканчивается так же (ПриёмкаExternalReport), —
# ссылка расходилась с именем, и заглушка не грузилась.
return re.sub(r'(?<![\w.])%s(Object)?\.' % ext_tag,
lambda m: cfg_tag + (m.group(1) or '') + '.', text)
def add_source_object_to_config(source_xml, cfg_dir):
# Копия объекта живёт в конфигурации базы, а следом в ту же базу грузится исходник как ВНЕШНЯЯ
# обработка. С одинаковыми идентификаторами платформа путает их и через раз отвечает «Исключение
@@ -1163,7 +1171,7 @@ def add_source_object_to_config(source_xml, cfg_dir):
conv = reissue(text)
conv = conv.replace('<%s ' % ext_tag, '<%s ' % cfg_tag).replace('<%s>' % ext_tag, '<%s>' % cfg_tag)
conv = conv.replace('</%s>' % ext_tag, '</%s>' % cfg_tag)
conv = conv.replace('%sObject.' % ext_tag, '%sObject.' % cfg_tag).replace('%s.' % ext_tag, '%s.' % cfg_tag)
conv = retag_refs(conv, ext_tag, cfg_tag)
# Тип менеджера у внешней обработки не объявлен, а объекту конфигурации он обязателен:
# без него платформа отвечает «отсутствует один или более типов объекта».
@@ -1200,7 +1208,7 @@ def add_source_object_to_config(source_xml, cfg_dir):
with io.open(full, encoding='utf-8-sig') as fh:
t = fh.read()
t = reissue(t)
t = t.replace('%sObject.' % ext_tag, '%sObject.' % cfg_tag).replace('%s.' % ext_tag, '%s.' % cfg_tag)
t = retag_refs(t, ext_tag, cfg_tag)
write_bom(dst, t)
else:
shutil.copyfile(full, dst)