mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-08-21 02:29:42 +03:00
Головной дефект тикета: cfe-init выдавал Configuration.xml с 10 CR на 70 строк, а роль и язык — вовсе без CR. Теперь 70/70, последний байт `>`. Правило: меняем только РАЗДЕЛИТЕЛИ строк, содержимое текстовых узлов не трогаем. Платформа его не трогает тоже — в запросах СКД из чистой выгрузки встречаются и CRLF, и одиночный LF. Поэтому сплошная нормализация файла применяется только там, где многострочных текстовых узлов нет по построению (скелеты), а в объектном XML и формах разделители правятся в точке сборки. Источников оказалось четыре, а не один: 1. Скелеты (cf-init, cfe-init, epf-init, erf-init, form-add, help-add, template-add) собираются here-string'ами, а .ps1/.py в репозитории хранятся с LF — отсюда LF и смешанный EOL. 2. py-порты склеивали документ через '\n'.join(lines); PS в тех же местах давал CRLF через AppendLine — порты расходились побайтово. 3. Билдеры Predefined в meta-compile собирались с явным LF и даже сворачивали CRLF→LF из общего эмиттера типов. 4. Чтение существующего файла в python БЕЗ newline='' молча схлопывает CRLF в LF (универсальные переводы строк), и запись потом кладёт LF. Так role-compile и subsystem-compile переписывали в LF весь Configuration.xml. meta-compile это уже делал правильно — там newline='' стоял с фикса #44/#46/#47. Отдельно: XML-парсер по спецификации схлопывает CRLF при разборе, поэтому lxml-порты (xdto-compile, xdto-edit) отдавали LF-документ там, где .NET возвращал CRLF через NewLineHandling. Восстанавливаем EOL исходного файла. Разделение канона и сохранения стиля: - файл СОЗДАЁМ — канон (CRLF, без хвоста); - существующий ПРАВИМ — наследуем его EOL, включая перевод строки вставки (контракт #44/#46/#47). Иначе LF-проект получал бы смешанные файлы — ровно то, на что заведён #57. Кейсы roundtrip-crlf-preserve остаются зелёными. Хелпер записи скопирован в каждый навык (навыки автономны). У meta-compile он называется Write-XmlFileKeepEol / write_xml_file_keep_eol: там нормализовать EOL НЕЛЬЗЯ (многострочные запрос, синоним, значение заполнения), и одинаковое имя при разном поведении было бы ловушкой. Заодно: имя временного файла батча в meta-compile.ps1 получило GUID. Фиксированное "meta-compile-batch-$idx.json" в общем %TEMP% сталкивало два параллельных запуска («file is being used by another process») — из-за этого полный набор приходилось гонять с урезанной параллельностью. py-порт уже брал mkstemp. Аудит: было ~250 файлов с дефектом EOL, стало 0 в обоих портах. Осталось четыре законных случая — фикстуры roundtrip-crlf-preserve (сохранение стиля) и запрос динсписка с многострочным текстом. Дрейф снэпшотов — 1 файл. Тесты 641/641. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
100 lines
3.9 KiB
PowerShell
100 lines
3.9 KiB
PowerShell
# epf-init v1.2 — Init 1C external data processor scaffold
|
||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||
param(
|
||
[Parameter(Mandatory)]
|
||
[string]$Name,
|
||
|
||
[string]$Synonym = $Name,
|
||
|
||
[string]$SrcDir = "src"
|
||
)
|
||
|
||
$ErrorActionPreference = "Stop"
|
||
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
|
||
[Console]::InputEncoding = [System.Text.Encoding]::UTF8
|
||
|
||
$uuid1 = [guid]::NewGuid().ToString()
|
||
$uuid2 = [guid]::NewGuid().ToString()
|
||
$uuid3 = [guid]::NewGuid().ToString()
|
||
$uuid4 = [guid]::NewGuid().ToString()
|
||
|
||
$xml = @"
|
||
<?xml version="1.0" encoding="UTF-8"?>
|
||
<MetaDataObject xmlns="http://v8.1c.ru/8.3/MDClasses" xmlns:app="http://v8.1c.ru/8.2/managed-application/core" xmlns:cfg="http://v8.1c.ru/8.1/data/enterprise/current-config" xmlns:cmi="http://v8.1c.ru/8.2/managed-application/cmi" xmlns:ent="http://v8.1c.ru/8.1/data/enterprise" xmlns:lf="http://v8.1c.ru/8.2/managed-application/logform" xmlns:style="http://v8.1c.ru/8.1/data/ui/style" xmlns:sys="http://v8.1c.ru/8.1/data/ui/fonts/system" xmlns:v8="http://v8.1c.ru/8.1/data/core" xmlns:v8ui="http://v8.1c.ru/8.1/data/ui" xmlns:web="http://v8.1c.ru/8.1/data/ui/colors/web" xmlns:win="http://v8.1c.ru/8.1/data/ui/colors/windows" xmlns:xen="http://v8.1c.ru/8.3/xcf/enums" xmlns:xpr="http://v8.1c.ru/8.3/xcf/predef" xmlns:xr="http://v8.1c.ru/8.3/xcf/readable" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.17">
|
||
<ExternalDataProcessor uuid="$uuid1">
|
||
<InternalInfo>
|
||
<xr:ContainedObject>
|
||
<xr:ClassId>c3831ec8-d8d5-4f93-8a22-f9bfae07327f</xr:ClassId>
|
||
<xr:ObjectId>$uuid2</xr:ObjectId>
|
||
</xr:ContainedObject>
|
||
<xr:GeneratedType name="ExternalDataProcessorObject.$Name" category="Object">
|
||
<xr:TypeId>$uuid3</xr:TypeId>
|
||
<xr:ValueId>$uuid4</xr:ValueId>
|
||
</xr:GeneratedType>
|
||
</InternalInfo>
|
||
<Properties>
|
||
<Name>$Name</Name>
|
||
<Synonym>
|
||
<v8:item>
|
||
<v8:lang>ru</v8:lang>
|
||
<v8:content>$Synonym</v8:content>
|
||
</v8:item>
|
||
</Synonym>
|
||
<Comment/>
|
||
<DefaultForm/>
|
||
<AuxiliaryForm/>
|
||
</Properties>
|
||
<ChildObjects/>
|
||
</ExternalDataProcessor>
|
||
</MetaDataObject>
|
||
"@
|
||
|
||
$rootFile = Join-Path $SrcDir "$Name.xml"
|
||
$processorDir = Join-Path $SrcDir $Name
|
||
|
||
if (Test-Path $rootFile) {
|
||
Write-Error "Файл уже существует: $rootFile"
|
||
exit 1
|
||
}
|
||
|
||
if (-not (Test-Path $SrcDir)) {
|
||
New-Item -ItemType Directory -Path $SrcDir -Force | Out-Null
|
||
}
|
||
$extDir = Join-Path $processorDir "Ext"
|
||
New-Item -ItemType Directory -Path $extDir -Force | Out-Null
|
||
|
||
$enc = New-Object System.Text.UTF8Encoding($true)
|
||
# Канон выгрузки Конфигуратора: CRLF в разделителях строк, без перевода в конце
|
||
# файла. Скелет собирается here-string'ами, а .ps1 хранится с LF — отсюда LF и
|
||
# смешанный EOL. Нормализация здесь безопасна: многострочных текстовых узлов в
|
||
# скелете нет. Модули .bsl и текстовые макеты через эту функцию НЕ пишутся.
|
||
function Write-XmlFile([string]$path, [string]$text, $encoding) {
|
||
$t = ($text -replace "`r`n", "`n") -replace "`n", "`r`n"
|
||
[System.IO.File]::WriteAllText($path, $t.TrimEnd("`r", "`n"), $encoding)
|
||
}
|
||
|
||
Write-XmlFile (Resolve-Path $SrcDir | Join-Path -ChildPath "$Name.xml") $xml $enc
|
||
|
||
# --- Модуль объекта ---
|
||
|
||
$moduleBsl = @"
|
||
#Область ОписаниеПеременных
|
||
|
||
#КонецОбласти
|
||
|
||
#Область ПрограммныйИнтерфейс
|
||
|
||
#КонецОбласти
|
||
|
||
#Область СлужебныеПроцедурыИФункции
|
||
|
||
#КонецОбласти
|
||
"@
|
||
|
||
$modulePath = Join-Path $extDir "ObjectModule.bsl"
|
||
[System.IO.File]::WriteAllText($modulePath, $moduleBsl, $enc)
|
||
|
||
Write-Host "[OK] Создана обработка: $rootFile"
|
||
Write-Host " Каталог: $processorDir"
|
||
Write-Host " Модуль: $modulePath"
|