mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-08-21 10:39:42 +03:00
fix(17 навыков): CRLF в разделителях строк XML (#57)
Головной дефект тикета: 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>
This commit is contained in:
co-authored by
Claude Opus 5
parent
abe9431d8f
commit
0b8231c467
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# epf-init v1.1 — Init 1C external data processor scaffold
|
||||
# epf-init v1.2 — Init 1C external data processor scaffold
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
"""Generates minimal XML source files for a 1C external data processor."""
|
||||
import sys, os, argparse, uuid
|
||||
@@ -14,6 +14,13 @@ def write_utf8_bom(path, content):
|
||||
with open(path, 'w', encoding='utf-8-sig', newline='') as f:
|
||||
f.write(content)
|
||||
|
||||
def write_xml_file(path, content):
|
||||
# Канон выгрузки Конфигуратора: CRLF в разделителях строк, без перевода в конце
|
||||
# файла. Скелет собирается тройными кавычками, а .py хранится с LF — отсюда LF и
|
||||
# смешанный EOL. Нормализация здесь безопасна: многострочных текстовых узлов в
|
||||
# скелете нет. Модули .bsl и текстовые макеты через неё НЕ пишутся.
|
||||
text = content.replace('\r\n', '\n').replace('\n', '\r\n').rstrip('\r\n')
|
||||
write_utf8_bom(path, text)
|
||||
def main():
|
||||
sys.stdout.reconfigure(encoding="utf-8")
|
||||
sys.stderr.reconfigure(encoding="utf-8")
|
||||
@@ -72,7 +79,7 @@ def main():
|
||||
ext_dir = os.path.join(processor_dir, "Ext")
|
||||
os.makedirs(ext_dir, exist_ok=True)
|
||||
|
||||
write_utf8_bom(os.path.join(os.path.abspath(src_dir), f"{name}.xml"), xml)
|
||||
write_xml_file(os.path.join(os.path.abspath(src_dir), f"{name}.xml"), xml)
|
||||
|
||||
# --- Модуль объекта ---
|
||||
module_bsl = """\
|
||||
|
||||
Reference in New Issue
Block a user