mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-08-07 20:20:20 +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,4 +1,4 @@
|
||||
# cf-edit v1.12 — Edit 1C configuration root (Configuration.xml)
|
||||
# cf-edit v1.14 — Edit 1C configuration root (Configuration.xml)
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
param(
|
||||
[Parameter(Mandatory)][Alias('Path')][string]$ConfigPath,
|
||||
@@ -163,6 +163,11 @@ function Assert-EditAllowed([string]$targetPath, [string]$require) {
|
||||
Assert-EditAllowed $resolvedPath 'editable'
|
||||
|
||||
# --- Load XML with PreserveWhitespace ---
|
||||
# EOL исходного файла запоминаем ДО разбора: парсер XML по спецификации схлопывает
|
||||
# CRLF в LF, а вставки ниже собираются с явным CRLF — без восстановления в точке
|
||||
# записи LF-файл стал бы смешанным. Канон CRLF относится к файлам, которые мы
|
||||
# СОЗДАЁМ; правка существующего сохраняет его стиль (#44/#46/#47).
|
||||
$script:srcEol = if (([System.IO.File]::ReadAllText($resolvedPath)) -match "`r`n") { "`r`n" } else { "`n" }
|
||||
$script:xmlDoc = New-Object System.Xml.XmlDocument
|
||||
$script:xmlDoc.PreserveWhitespace = $true
|
||||
$script:xmlDoc.Load($resolvedPath)
|
||||
@@ -691,7 +696,8 @@ $bodyBlock$declarations
|
||||
if (-not (Test-Path $extDir)) { New-Item -ItemType Directory -Path $extDir -Force | Out-Null }
|
||||
$caiPath = Join-Path $extDir "ClientApplicationInterface.xml"
|
||||
$utf8Bom = New-Object System.Text.UTF8Encoding($true)
|
||||
[System.IO.File]::WriteAllText($caiPath, $caiXml, $utf8Bom)
|
||||
# Файл создаём мы — канон: CRLF в разделителях, без перевода строки в конце.
|
||||
[System.IO.File]::WriteAllText($caiPath, (($caiXml -replace "`r`n", "`n") -replace "`n", "`r`n").TrimEnd("`r", "`n"), $utf8Bom)
|
||||
$script:modifyCount++
|
||||
Info "Wrote panel layout: $caiPath"
|
||||
}
|
||||
@@ -880,7 +886,8 @@ $rightXml
|
||||
if (-not (Test-Path $extDir)) { New-Item -ItemType Directory -Path $extDir -Force | Out-Null }
|
||||
$hpPath = Join-Path $extDir "HomePageWorkArea.xml"
|
||||
$utf8Bom = New-Object System.Text.UTF8Encoding($true)
|
||||
[System.IO.File]::WriteAllText($hpPath, $hpXml, $utf8Bom)
|
||||
# Файл создаём мы — канон: CRLF в разделителях, без перевода строки в конце.
|
||||
[System.IO.File]::WriteAllText($hpPath, (($hpXml -replace "`r`n", "`n") -replace "`n", "`r`n").TrimEnd("`r", "`n"), $utf8Bom)
|
||||
$script:modifyCount++
|
||||
Info "Wrote home page layout: $hpPath"
|
||||
}
|
||||
@@ -985,6 +992,8 @@ $text = $text.Replace('encoding="utf-8"', 'encoding="UTF-8"')
|
||||
# Пустой элемент: XmlWriter пишет `<a />`, Конфигуратор — `<a/>`. Гард на CDATA/комментарии:
|
||||
# только там `>` не экранируется, и ` />` может быть содержимым, а не концом тега.
|
||||
if ($text -notmatch '<!\[CDATA\[|<!--') { $text = [regex]::Replace($text, '(?<=\S) />', '/>') }
|
||||
# Возвращаем EOL исходного файла: вставки собраны с CRLF, а сам документ мог быть LF.
|
||||
$text = ($text -replace "`r`n", "`n") -replace "`n", $script:srcEol
|
||||
|
||||
$utf8Bom = New-Object System.Text.UTF8Encoding($true)
|
||||
[System.IO.File]::WriteAllText($resolvedPath, $text, $utf8Bom)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# cf-edit v1.12 — Edit 1C configuration root (Configuration.xml)
|
||||
# cf-edit v1.14 — Edit 1C configuration root (Configuration.xml)
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
|
||||
import argparse
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# cf-init v1.4 — Create empty 1C configuration scaffold
|
||||
# cf-init v1.5 — Create empty 1C configuration scaffold
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
@@ -240,11 +240,20 @@ if (-not (Test-Path $extDir)) {
|
||||
# --- Write files with UTF-8 BOM ---
|
||||
$enc = New-Object System.Text.UTF8Encoding($true)
|
||||
|
||||
[System.IO.File]::WriteAllText($cfgFile, $cfgXml, $enc)
|
||||
# Канон выгрузки Конфигуратора: 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 $cfgFile $cfgXml $enc
|
||||
$langFile = Join-Path $langDir "Русский.xml"
|
||||
[System.IO.File]::WriteAllText($langFile, $langXml, $enc)
|
||||
Write-XmlFile $langFile $langXml $enc
|
||||
$caiFile = Join-Path $extDir "ClientApplicationInterface.xml"
|
||||
[System.IO.File]::WriteAllText($caiFile, $caiXml, $enc)
|
||||
Write-XmlFile $caiFile $caiXml $enc
|
||||
|
||||
# --- Output ---
|
||||
Write-Host "[OK] Создана конфигурация: $Name"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# cf-init v1.4 — Create empty 1C configuration scaffold
|
||||
# cf-init v1.5 — Create empty 1C configuration scaffold
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
"""Generates minimal XML source files for a 1C configuration."""
|
||||
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")
|
||||
@@ -222,11 +229,11 @@ def main():
|
||||
os.makedirs(ext_dir, exist_ok=True)
|
||||
|
||||
# --- Write files ---
|
||||
write_utf8_bom(cfg_file, cfg_xml)
|
||||
write_xml_file(cfg_file, cfg_xml)
|
||||
lang_file = os.path.join(lang_dir, "Русский.xml")
|
||||
write_utf8_bom(lang_file, lang_xml)
|
||||
write_xml_file(lang_file, lang_xml)
|
||||
cai_file = os.path.join(ext_dir, "ClientApplicationInterface.xml")
|
||||
write_utf8_bom(cai_file, cai_xml)
|
||||
write_xml_file(cai_file, cai_xml)
|
||||
|
||||
print(f"[OK] Создана конфигурация: {name}")
|
||||
print(f" Каталог: {output_dir}")
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# cfe-init v1.2 — Create 1C configuration extension scaffold (CFE)
|
||||
# cfe-init v1.3 — Create 1C configuration extension scaffold (CFE)
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
@@ -252,9 +252,18 @@ if (-not (Test-Path $langDir)) {
|
||||
# --- Write files with UTF-8 BOM ---
|
||||
$enc = New-Object System.Text.UTF8Encoding($true)
|
||||
|
||||
[System.IO.File]::WriteAllText($cfgFile, $cfgXml, $enc)
|
||||
# Канон выгрузки Конфигуратора: 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 $cfgFile $cfgXml $enc
|
||||
$langFile = Join-Path $langDir "Русский.xml"
|
||||
[System.IO.File]::WriteAllText($langFile, $langXml, $enc)
|
||||
Write-XmlFile $langFile $langXml $enc
|
||||
|
||||
# --- Role ---
|
||||
if (-not $NoRole) {
|
||||
@@ -263,7 +272,7 @@ if (-not $NoRole) {
|
||||
New-Item -ItemType Directory -Path $roleDir -Force | Out-Null
|
||||
}
|
||||
$roleFile = Join-Path $roleDir "$roleName.xml"
|
||||
[System.IO.File]::WriteAllText($roleFile, $roleXml, $enc)
|
||||
Write-XmlFile $roleFile $roleXml $enc
|
||||
}
|
||||
|
||||
# --- Output ---
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# cfe-init v1.2 — Create 1C configuration extension scaffold (CFE)
|
||||
# cfe-init v1.3 — Create 1C configuration extension scaffold (CFE)
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
"""Generates minimal XML source files for a 1C configuration extension."""
|
||||
import sys, os, argparse, uuid
|
||||
@@ -15,6 +15,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")
|
||||
@@ -229,9 +236,9 @@ def main():
|
||||
os.makedirs(lang_dir, exist_ok=True)
|
||||
|
||||
# --- Write files ---
|
||||
write_utf8_bom(cfg_file, cfg_xml)
|
||||
write_xml_file(cfg_file, cfg_xml)
|
||||
lang_file = os.path.join(lang_dir, "Русский.xml")
|
||||
write_utf8_bom(lang_file, lang_xml)
|
||||
write_xml_file(lang_file, lang_xml)
|
||||
|
||||
# --- Role ---
|
||||
role_file = None
|
||||
@@ -239,7 +246,7 @@ def main():
|
||||
role_dir = os.path.join(output_dir, "Roles")
|
||||
os.makedirs(role_dir, exist_ok=True)
|
||||
role_file = os.path.join(role_dir, f"{role_name}.xml")
|
||||
write_utf8_bom(role_file, role_xml)
|
||||
write_xml_file(role_file, role_xml)
|
||||
|
||||
# --- Output ---
|
||||
print(f"[OK] Создано расширение: {name}")
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# 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
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
@@ -64,7 +64,16 @@ $extDir = Join-Path $processorDir "Ext"
|
||||
New-Item -ItemType Directory -Path $extDir -Force | Out-Null
|
||||
|
||||
$enc = New-Object System.Text.UTF8Encoding($true)
|
||||
[System.IO.File]::WriteAllText((Resolve-Path $SrcDir | Join-Path -ChildPath "$Name.xml"), $xml, $enc)
|
||||
# Канон выгрузки Конфигуратора: 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
|
||||
|
||||
# --- Модуль объекта ---
|
||||
|
||||
|
||||
@@ -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 = """\
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# erf-init v1.1 — Init 1C external report scaffold
|
||||
# erf-init v1.2 — Init 1C external report scaffold
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
@@ -98,7 +98,16 @@ $extDir = Join-Path $reportDir "Ext"
|
||||
New-Item -ItemType Directory -Path $extDir -Force | Out-Null
|
||||
|
||||
$enc = New-Object System.Text.UTF8Encoding($true)
|
||||
[System.IO.File]::WriteAllText((Resolve-Path $SrcDir | Join-Path -ChildPath "$Name.xml"), $xml, $enc)
|
||||
# Канон выгрузки Конфигуратора: 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
|
||||
|
||||
# --- Модуль объекта ---
|
||||
|
||||
@@ -153,7 +162,7 @@ if ($WithSKD) {
|
||||
</MetaDataObject>
|
||||
"@
|
||||
|
||||
[System.IO.File]::WriteAllText($skdMetaPath, $skdMetaXml, $enc)
|
||||
Write-XmlFile $skdMetaPath $skdMetaXml $enc
|
||||
|
||||
$skdContent = @"
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
@@ -173,7 +182,7 @@ if ($WithSKD) {
|
||||
"@
|
||||
|
||||
$skdFilePath = Join-Path $skdExtDir "Template.xml"
|
||||
[System.IO.File]::WriteAllText($skdFilePath, $skdContent, $enc)
|
||||
Write-XmlFile $skdFilePath $skdContent $enc
|
||||
|
||||
Write-Host " СКД: $skdMetaPath"
|
||||
Write-Host " Тело: $skdFilePath"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# erf-init v1.1 — Init 1C external report scaffold
|
||||
# erf-init v1.2 — Init 1C external report scaffold
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
"""Generates minimal XML source files for a 1C external report."""
|
||||
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")
|
||||
@@ -90,7 +97,7 @@ def main():
|
||||
ext_dir = os.path.join(report_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 = """\
|
||||
@@ -140,7 +147,7 @@ def main():
|
||||
\t</Template>
|
||||
</MetaDataObject>'''
|
||||
|
||||
write_utf8_bom(skd_meta_path, skd_meta_xml)
|
||||
write_xml_file(skd_meta_path, skd_meta_xml)
|
||||
|
||||
skd_content = '''<?xml version="1.0" encoding="UTF-8"?>
|
||||
<DataCompositionSchema xmlns="http://v8.1c.ru/8.1/data-composition-system/schema"
|
||||
@@ -158,7 +165,7 @@ def main():
|
||||
</DataCompositionSchema>'''
|
||||
|
||||
skd_file_path = os.path.join(skd_ext_dir, "Template.xml")
|
||||
write_utf8_bom(skd_file_path, skd_content)
|
||||
write_xml_file(skd_file_path, skd_content)
|
||||
|
||||
print(f" СКД: {skd_meta_path}")
|
||||
print(f" Тело: {skd_file_path}")
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# form-add v1.14 — Add managed form to 1C config object
|
||||
# form-add v1.16 — Add managed form to 1C config object
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
@@ -337,7 +337,16 @@ $formMetaXml = @"
|
||||
</MetaDataObject>
|
||||
"@
|
||||
|
||||
[System.IO.File]::WriteAllText($formMetaPath, $formMetaXml.TrimEnd("`r", "`n"), $encBom)
|
||||
# Канон выгрузки Конфигуратора: 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 $formMetaPath $formMetaXml $encBom
|
||||
|
||||
# --- 3b. Form.xml ---
|
||||
|
||||
@@ -444,7 +453,7 @@ if ($Purpose -eq "List" -or $Purpose -eq "Choice") {
|
||||
if (Test-Path $formXmlPath) {
|
||||
Write-Host "[SKIP] Form.xml already exists: $formXmlPath — not overwriting"
|
||||
} else {
|
||||
[System.IO.File]::WriteAllText($formXmlPath, $formXml.TrimEnd("`r", "`n"), $encBom)
|
||||
Write-XmlFile $formXmlPath $formXml $encBom
|
||||
}
|
||||
|
||||
# --- 3c. Module.bsl ---
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# form-add v1.14 — Add managed form to 1C config object
|
||||
# form-add v1.16 — Add managed form to 1C config object
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
|
||||
import argparse
|
||||
@@ -259,10 +259,22 @@ def save_xml_with_bom(tree, path):
|
||||
|
||||
def write_text_with_bom(path, text):
|
||||
"""Write text to file with UTF-8 BOM."""
|
||||
with open(path, "w", encoding="utf-8-sig") as f:
|
||||
# newline="" => без трансляции: в текстовом режиме Python на Windows превратил
|
||||
# бы \n в \r\n, а на macOS оставил \n — вывод зависел бы от ОС.
|
||||
with open(path, "w", encoding="utf-8-sig", newline="") as f:
|
||||
f.write(text)
|
||||
|
||||
|
||||
def write_xml_file(path, text):
|
||||
"""XML в каноне выгрузки Конфигуратора: CRLF, без перевода строки в конце.
|
||||
|
||||
Скелет формы собирается литералами с \n. Сплошная нормализация здесь
|
||||
безопасна: многострочных текстовых узлов в скелете нет. Модуль .bsl
|
||||
пишется отдельно, через write_text_with_bom.
|
||||
"""
|
||||
write_text_with_bom(path, text.replace("\r\n", "\n").replace("\n", "\r\n").rstrip("\r\n"))
|
||||
|
||||
|
||||
def main():
|
||||
sys.stdout.reconfigure(encoding="utf-8")
|
||||
sys.stderr.reconfigure(encoding="utf-8")
|
||||
@@ -428,7 +440,7 @@ def main():
|
||||
'</MetaDataObject>'
|
||||
)
|
||||
|
||||
write_text_with_bom(form_meta_path, form_meta_xml)
|
||||
write_xml_file(form_meta_path, form_meta_xml)
|
||||
|
||||
# --- 3b. Form.xml ---
|
||||
|
||||
@@ -551,7 +563,7 @@ def main():
|
||||
if os.path.exists(form_xml_path):
|
||||
print(f"[SKIP] Form.xml already exists: {form_xml_path} — not overwriting")
|
||||
else:
|
||||
write_text_with_bom(form_xml_path, form_xml)
|
||||
write_xml_file(form_xml_path, form_xml)
|
||||
|
||||
# --- 3c. Module.bsl ---
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# form-compile v1.178 — Compile 1C managed form from JSON or object metadata
|
||||
# form-compile v1.180 — Compile 1C managed form from JSON or object metadata
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
param(
|
||||
[string]$JsonPath,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# form-compile v1.178 — Compile 1C managed form from JSON or object metadata
|
||||
# form-compile v1.180 — Compile 1C managed form from JSON or object metadata
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
import argparse
|
||||
import copy
|
||||
@@ -6580,7 +6580,7 @@ def main():
|
||||
if out_dir and not os.path.exists(out_dir):
|
||||
os.makedirs(out_dir, exist_ok=True)
|
||||
|
||||
content = '\n'.join(lines)
|
||||
content = '\r\n'.join(lines)
|
||||
write_utf8_bom(out_path, content)
|
||||
|
||||
# --- 4. Auto-register form in parent object XML ---
|
||||
@@ -6598,17 +6598,22 @@ def main():
|
||||
if forms_leaf == 'Forms':
|
||||
object_xml_path = os.path.join(type_plural_dir, f'{object_name}.xml')
|
||||
if os.path.exists(object_xml_path):
|
||||
with open(object_xml_path, 'r', encoding='utf-8-sig') as f:
|
||||
# newline='' => без трансляции переводов строк: иначе CRLF молча
|
||||
# схлопнется в LF при чтении и файл будет переписан в LF (#44/#46/#47).
|
||||
with open(object_xml_path, 'r', encoding='utf-8-sig', newline='') as f:
|
||||
raw_text = f.read()
|
||||
# Перевод строки вставки берём из самого файла, а не из канона:
|
||||
# правка существующего файла сохраняет его стиль.
|
||||
eol = '\r\n' if '\r\n' in raw_text else '\n'
|
||||
|
||||
# Check if already registered
|
||||
if f'<Form>{form_name}</Form>' not in raw_text:
|
||||
# Insert before </ChildObjects>
|
||||
if '</ChildObjects>' in raw_text:
|
||||
insert_line = f'\t\t\t<Form>{form_name}</Form>\n'
|
||||
insert_line = f'\t\t\t<Form>{form_name}</Form>' + eol
|
||||
raw_text = raw_text.replace('</ChildObjects>', insert_line + '\t\t</ChildObjects>', 1)
|
||||
elif '<ChildObjects/>' in raw_text:
|
||||
replacement = f'<ChildObjects>\n\t\t\t<Form>{form_name}</Form>\n\t\t</ChildObjects>'
|
||||
replacement = ('<ChildObjects>' + eol + f'\t\t\t<Form>{form_name}</Form>' + eol + '\t\t</ChildObjects>')
|
||||
raw_text = raw_text.replace('<ChildObjects/>', replacement, 1)
|
||||
|
||||
write_utf8_bom(object_xml_path, raw_text)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# help-add v1.11 — Add built-in help to 1C object
|
||||
# help-add v1.12 — Add built-in help to 1C object
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
@@ -195,7 +195,16 @@ $helpXml = @"
|
||||
</Help>
|
||||
"@
|
||||
|
||||
[System.IO.File]::WriteAllText($helpXmlPath, $helpXml.TrimEnd("`r", "`n"), $encBom)
|
||||
# Канон выгрузки Конфигуратора: 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 $helpXmlPath $helpXml $encBom
|
||||
|
||||
# --- 2. Help/<lang>.html ---
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# add-help v1.11 — Add built-in help to 1C object
|
||||
# add-help v1.12 — Add built-in help to 1C object
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
|
||||
import argparse
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# meta-compile v1.78 — Compile 1C metadata object from JSON
|
||||
# meta-compile v1.80 — Compile 1C metadata object from JSON
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
@@ -161,7 +161,10 @@ if ($def -is [array] -or ($null -ne $def -and $def.GetType().BaseType.Name -eq '
|
||||
$idx = 0
|
||||
foreach ($item in $def) {
|
||||
$idx++
|
||||
$tmpJson = Join-Path ([System.IO.Path]::GetTempPath()) "meta-compile-batch-$idx.json"
|
||||
# Имя с GUID, а не "batch-$idx": фиксированное имя в общем %TEMP% сталкивало
|
||||
# два параллельных запуска навыка на одной машине — Set-Content падал с
|
||||
# «file is being used by another process». py-порт уже брал mkstemp.
|
||||
$tmpJson = Join-Path ([System.IO.Path]::GetTempPath()) "meta-compile-batch-$idx-$([guid]::NewGuid().ToString('N')).json"
|
||||
try {
|
||||
$item | ConvertTo-Json -Depth 20 | Set-Content -Encoding UTF8 $tmpJson
|
||||
$proc = Start-Process -FilePath "powershell.exe" -ArgumentList "-NoProfile -File `"$PSCommandPath`" -JsonPath `"$tmpJson`" -OutputDir `"$OutputDir`"" -NoNewWindow -Wait -PassThru
|
||||
@@ -4611,7 +4614,7 @@ function Build-PredefinedXml {
|
||||
[void]$sb.Append("<PredefinedData xmlns=`"http://v8.1c.ru/8.3/xcf/predef`" xmlns:v8=`"http://v8.1c.ru/8.1/data/core`" 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`" xsi:type=`"$xsiType`" version=`"$($script:formatVersion)`">`n")
|
||||
foreach ($it in $items) { Emit-PredefItem $sb $it "`t" $codeType }
|
||||
[void]$sb.Append("</PredefinedData>`n")
|
||||
return $sb.ToString()
|
||||
return ($sb.ToString() -replace "`r`n", "`n") -replace "`n", "`r`n"
|
||||
}
|
||||
|
||||
# --- Предопределённые СЧЕТА Плана счетов (отдельная грамматика: AccountType/OffBalance/Order/AccountingFlags/
|
||||
@@ -4699,7 +4702,7 @@ function Build-PredefinedAccountXml {
|
||||
[void]$sb.Append("<PredefinedData xmlns=`"http://v8.1c.ru/8.3/xcf/predef`" xmlns:v8=`"http://v8.1c.ru/8.1/data/core`" 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`" xsi:type=`"ChartOfAccountsPredefinedItems`" version=`"$($script:formatVersion)`">`n")
|
||||
foreach ($it in $items) { Emit-PredefAccount $sb $it "`t" $objName $acctFlagNames $extDimFlagNames $extDimTypesRef }
|
||||
[void]$sb.Append("</PredefinedData>`n")
|
||||
return $sb.ToString()
|
||||
return ($sb.ToString() -replace "`r`n", "`n") -replace "`n", "`r`n"
|
||||
}
|
||||
|
||||
# --- Предопределённые ВИДЫ РАСЧЁТА (плоские: Name/Code/Description/ActionPeriodIsBase). Строка "(Код) Имя [Наим]"
|
||||
@@ -4726,7 +4729,7 @@ function Build-PredefinedCalcTypeXml {
|
||||
[void]$sb.Append("<PredefinedData xmlns=`"http://v8.1c.ru/8.3/xcf/predef`" xmlns:v8=`"http://v8.1c.ru/8.1/data/core`" 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`" xsi:type=`"CalculationTypePredefinedItems`" version=`"$($script:formatVersion)`">`n")
|
||||
foreach ($it in $items) { Emit-PredefCalcType $sb $it "`t" }
|
||||
[void]$sb.Append("</PredefinedData>`n")
|
||||
return $sb.ToString()
|
||||
return ($sb.ToString() -replace "`r`n", "`n") -replace "`n", "`r`n"
|
||||
}
|
||||
|
||||
$extDir = Join-Path $objSubDir "Ext"
|
||||
@@ -4743,13 +4746,18 @@ if ($objType -notin $typesNoSubDir) {
|
||||
$enc = New-Object System.Text.UTF8Encoding($true)
|
||||
|
||||
# Единая точка записи XML. Конфигуратор не пишет перевод строки в конце файла —
|
||||
# последний байт `>`; сборка через AppendLine (и через явный `n в билдерах
|
||||
# Predefined/Content) добавляла лишний. Модули .bsl сюда НЕ идут: у них свой хвост.
|
||||
function Write-XmlFile([string]$path, [string]$text, $encoding) {
|
||||
# последний байт `>`; сборка через AppendLine добавляла лишний.
|
||||
# KeepEol в имени — отличие от одноимённой функции в скелетных навыках
|
||||
# (cf-init и др.): та ЕЩЁ и нормализует EOL к CRLF, а здесь этого делать
|
||||
# НЕЛЬЗЯ — в объектном XML бывают многострочные текстовые узлы (запрос,
|
||||
# синоним, значение заполнения), и сплошная нормализация меняла бы содержимое.
|
||||
# Разделители тут и так CRLF: документ собран через AppendLine.
|
||||
# Модули .bsl сюда НЕ идут: у них свой хвост.
|
||||
function Write-XmlFileKeepEol([string]$path, [string]$text, $encoding) {
|
||||
[System.IO.File]::WriteAllText($path, $text.TrimEnd("`r", "`n"), $encoding)
|
||||
}
|
||||
|
||||
Write-XmlFile $mainXmlPath $metadataXml $enc
|
||||
Write-XmlFileKeepEol $mainXmlPath $metadataXml $enc
|
||||
|
||||
# Module files
|
||||
$modulesCreated = @()
|
||||
@@ -4830,8 +4838,8 @@ if ($objType -eq "CommonForm") {
|
||||
$cfFormXmlPath = Join-Path $extDir "Form.xml"
|
||||
if (-not (Test-Path $cfFormXmlPath)) {
|
||||
$cfFormNs = 'xmlns="http://v8.1c.ru/8.3/xcf/logform" xmlns:app="http://v8.1c.ru/8.2/managed-application/core" xmlns:cfg="http://v8.1c.ru/8.1/data/enterprise/current-config" xmlns:dcscor="http://v8.1c.ru/8.1/data-composition-system/core" xmlns:dcsset="http://v8.1c.ru/8.1/data-composition-system/settings" 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: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"'
|
||||
$cfFormXml = "<?xml version=`"1.0`" encoding=`"UTF-8`"?>`n<Form $cfFormNs version=`"$($script:formatVersion)`">`n`t<AutoCommandBar name=`"ФормаКоманднаяПанель`" id=`"-1`">`n`t`t<Autofill>true</Autofill>`n`t</AutoCommandBar>`n`t<ChildItems/>`n</Form>`n"
|
||||
Write-XmlFile $cfFormXmlPath $cfFormXml $enc
|
||||
$cfFormXml = "<?xml version=`"1.0`" encoding=`"UTF-8`"?>`r`n<Form $cfFormNs version=`"$($script:formatVersion)`">`r`n`t<AutoCommandBar name=`"ФормаКоманднаяПанель`" id=`"-1`">`r`n`t`t<Autofill>true</Autofill>`r`n`t</AutoCommandBar>`r`n`t<ChildItems/>`r`n</Form>`r`n"
|
||||
Write-XmlFileKeepEol $cfFormXmlPath $cfFormXml $enc
|
||||
$modulesCreated += $cfFormXmlPath
|
||||
}
|
||||
$cfModuleDir = Join-Path $extDir "Form"
|
||||
@@ -4884,7 +4892,7 @@ if ($objType -eq "ExchangePlan") {
|
||||
[void]$sbC.Append("`t</Item>`r`n")
|
||||
}
|
||||
[void]$sbC.Append("</ExchangePlanContent>`r`n")
|
||||
Write-XmlFile $contentPath $sbC.ToString() $enc
|
||||
Write-XmlFileKeepEol $contentPath $sbC.ToString() $enc
|
||||
$modulesCreated += $contentPath
|
||||
} elseif (-not (Test-Path $contentPath)) {
|
||||
# При пустом составе платформа всё равно пишет пустой <ExchangePlanContent/> — проверено на
|
||||
@@ -4892,7 +4900,7 @@ if ($objType -eq "ExchangePlan") {
|
||||
# (Единственный план обмена БЕЗ файла найден в УТ — хвостовая аномалия конфигурации, не правило.)
|
||||
Ensure-ExtDir
|
||||
$contentXml = "<?xml version=`"1.0`" encoding=`"UTF-8`"?>`r`n<ExchangePlanContent $xepNs version=`"$($script:formatVersion)`"/>`r`n"
|
||||
Write-XmlFile $contentPath $contentXml $enc
|
||||
Write-XmlFileKeepEol $contentPath $contentXml $enc
|
||||
$modulesCreated += $contentPath
|
||||
}
|
||||
}
|
||||
@@ -4901,7 +4909,7 @@ if ($objType -eq "BusinessProcess") {
|
||||
if (-not (Test-Path $flowchartPath)) {
|
||||
Ensure-ExtDir
|
||||
$flowchartXml = "<?xml version=`"1.0`" encoding=`"UTF-8`"?>`r`n<Flowchart xmlns=`"http://v8.1c.ru/8.3/MDClasses`" version=`"$($script:formatVersion)`"/>`r`n"
|
||||
Write-XmlFile $flowchartPath $flowchartXml $enc
|
||||
Write-XmlFileKeepEol $flowchartPath $flowchartXml $enc
|
||||
$modulesCreated += $flowchartPath
|
||||
}
|
||||
}
|
||||
@@ -4916,20 +4924,20 @@ if ($objType -eq 'ChartOfAccounts' -and $def.predefined -and @($def.predefined).
|
||||
$edtRef = if ($def.extDimensionTypes) { Resolve-TypePrefixSyn "$($def.extDimensionTypes)" } else { '' }
|
||||
$predefXml = Build-PredefinedAccountXml @($def.predefined) $objName $afNames $edfNames $edtRef
|
||||
$predefPath = Join-Path $extDir "Predefined.xml"
|
||||
Write-XmlFile $predefPath $predefXml $enc
|
||||
Write-XmlFileKeepEol $predefPath $predefXml $enc
|
||||
$modulesCreated += $predefPath
|
||||
} elseif ($objType -eq 'ChartOfCalculationTypes' -and $def.predefined -and @($def.predefined).Count -gt 0) {
|
||||
Ensure-ExtDir
|
||||
$predefXml = Build-PredefinedCalcTypeXml @($def.predefined)
|
||||
$predefPath = Join-Path $extDir "Predefined.xml"
|
||||
Write-XmlFile $predefPath $predefXml $enc
|
||||
Write-XmlFileKeepEol $predefPath $predefXml $enc
|
||||
$modulesCreated += $predefPath
|
||||
} elseif ($predefRootByType.ContainsKey($objType) -and $def.predefined -and @($def.predefined).Count -gt 0) {
|
||||
Ensure-ExtDir
|
||||
$catCodeType = if ($def.codeType) { "$($def.codeType)" } else { 'String' }
|
||||
$predefXml = Build-PredefinedXml @($def.predefined) $predefRootByType[$objType] $catCodeType
|
||||
$predefPath = Join-Path $extDir "Predefined.xml"
|
||||
Write-XmlFile $predefPath $predefXml $enc
|
||||
Write-XmlFileKeepEol $predefPath $predefXml $enc
|
||||
$modulesCreated += $predefPath
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# meta-compile v1.78 — Compile 1C metadata object from JSON
|
||||
# meta-compile v1.80 — Compile 1C metadata object from JSON
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
|
||||
import argparse
|
||||
@@ -209,6 +209,16 @@ def write_utf8_bom(path, content):
|
||||
with open(path, 'w', encoding='utf-8-sig', newline='') as f:
|
||||
f.write(content)
|
||||
|
||||
def write_xml_file_keep_eol(path, content):
|
||||
# Единая точка записи XML. Конфигуратор не пишет перевод строки в конце файла —
|
||||
# последний байт `>`.
|
||||
# keep_eol в имени — отличие от одноимённой функции в скелетных навыках
|
||||
# (cf-init и др.): та ЕЩЁ и нормализует EOL к CRLF, а здесь этого делать
|
||||
# НЕЛЬЗЯ — в объектном XML бывают многострочные текстовые узлы (запрос,
|
||||
# синоним, значение заполнения). Разделители и так CRLF — их даёт join строк.
|
||||
# Модули .bsl сюда НЕ идут: у них свой хвост.
|
||||
write_utf8_bom(path, content.rstrip('\r\n'))
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# XML builder (lines list)
|
||||
# ---------------------------------------------------------------------------
|
||||
@@ -4360,7 +4370,7 @@ if obj_type == 'WebService':
|
||||
X(f'\t</{obj_type}>')
|
||||
X('</MetaDataObject>')
|
||||
|
||||
metadata_xml = '\n'.join(lines)
|
||||
metadata_xml = '\r\n'.join(lines)
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# 16. Write files
|
||||
@@ -4422,7 +4432,7 @@ os.makedirs(type_dir, exist_ok=True)
|
||||
if obj_type not in types_no_sub_dir:
|
||||
os.makedirs(obj_sub_dir, exist_ok=True)
|
||||
|
||||
write_utf8_bom(main_xml_path, metadata_xml)
|
||||
write_xml_file_keep_eol(main_xml_path, metadata_xml)
|
||||
|
||||
# Module files
|
||||
modules_created = []
|
||||
@@ -4498,10 +4508,10 @@ if obj_type == 'CommonForm':
|
||||
'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: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"')
|
||||
cf_form_xml = ('<?xml version="1.0" encoding="UTF-8"?>\n<Form ' + cf_ns + ' version="' + format_version + '">\n'
|
||||
'\t<AutoCommandBar name="ФормаКоманднаяПанель" id="-1">\n\t\t<Autofill>true</Autofill>\n\t</AutoCommandBar>\n'
|
||||
'\t<ChildItems/>\n</Form>\n')
|
||||
write_utf8_bom(cf_form_xml_path, cf_form_xml)
|
||||
cf_form_xml = ('<?xml version="1.0" encoding="UTF-8"?>\r\n<Form ' + cf_ns + ' version="' + format_version + '">\r\n'
|
||||
'\t<AutoCommandBar name="ФормаКоманднаяПанель" id="-1">\r\n\t\t<Autofill>true</Autofill>\r\n\t</AutoCommandBar>\r\n'
|
||||
'\t<ChildItems/>\r\n</Form>\r\n')
|
||||
write_xml_file_keep_eol(cf_form_xml_path, cf_form_xml)
|
||||
modules_created.append(cf_form_xml_path)
|
||||
cf_module_dir = os.path.join(ext_dir, 'Form')
|
||||
os.makedirs(cf_module_dir, exist_ok=True)
|
||||
@@ -4592,7 +4602,7 @@ def build_predefined_xml(items, xsi_type, code_type):
|
||||
for it in items:
|
||||
emit_predef_item(out, it, '\t', code_type)
|
||||
out.append('</PredefinedData>')
|
||||
return '\n'.join(out) + '\n'
|
||||
return '\r\n'.join(out)
|
||||
|
||||
# --- Предопределённые СЧЕТА Плана счетов (отдельная грамматика: AccountType/OffBalance/Order/AccountingFlags/
|
||||
# ExtDimensionTypes/ChildItems). Флаги перечисляем по def-порядку признаков плана; в DSL — только TRUE. ---
|
||||
@@ -4690,7 +4700,7 @@ def build_predefined_account_xml(items, obj_nm, acct_flag_names, ext_dim_flag_na
|
||||
for it in items:
|
||||
emit_predef_account(out, it, '\t', obj_nm, acct_flag_names, ext_dim_flag_names, ext_dim_types_ref)
|
||||
out.append('</PredefinedData>')
|
||||
return '\n'.join(out) + '\n'
|
||||
return '\r\n'.join(out)
|
||||
|
||||
# Предопределённые ВИДЫ РАСЧЁТА (плоские: Name/Code/Description/ActionPeriodIsBase).
|
||||
def emit_predef_calc_type(out, val, indent):
|
||||
@@ -4712,7 +4722,7 @@ def build_predefined_calc_type_xml(items):
|
||||
for it in items:
|
||||
emit_predef_calc_type(out, it, '\t')
|
||||
out.append('</PredefinedData>')
|
||||
return '\n'.join(out) + '\n'
|
||||
return '\r\n'.join(out)
|
||||
|
||||
# Special files
|
||||
# --- Состав плана обмена (ExchangePlan, Ext/Content.xml). Ключ `content`/`Состав`:
|
||||
@@ -4766,7 +4776,7 @@ if obj_type == 'ExchangePlan':
|
||||
parts.append(f'\t\t<AutoRecord>{it["autoRecord"]}</AutoRecord>\r\n')
|
||||
parts.append('\t</Item>\r\n')
|
||||
parts.append('</ExchangePlanContent>\r\n')
|
||||
write_utf8_bom(content_path, ''.join(parts))
|
||||
write_xml_file_keep_eol(content_path, ''.join(parts))
|
||||
modules_created.append(content_path)
|
||||
elif not os.path.isfile(content_path):
|
||||
# При пустом составе платформа всё равно пишет пустой <ExchangePlanContent/> — проверено на
|
||||
@@ -4774,7 +4784,7 @@ if obj_type == 'ExchangePlan':
|
||||
# (Единственный план обмена БЕЗ файла найден в УТ — хвостовая аномалия конфигурации, не правило.)
|
||||
ensure_ext_dir()
|
||||
content_xml = f'<?xml version="1.0" encoding="UTF-8"?>\r\n<ExchangePlanContent {xep_ns} version="{format_version}"/>\r\n'
|
||||
write_utf8_bom(content_path, content_xml)
|
||||
write_xml_file_keep_eol(content_path, content_xml)
|
||||
modules_created.append(content_path)
|
||||
|
||||
if obj_type == 'BusinessProcess':
|
||||
@@ -4782,7 +4792,7 @@ if obj_type == 'BusinessProcess':
|
||||
if not os.path.isfile(flowchart_path):
|
||||
ensure_ext_dir()
|
||||
flowchart_xml = f'<?xml version="1.0" encoding="UTF-8"?>\r\n<Flowchart xmlns="http://v8.1c.ru/8.3/MDClasses" version="{format_version}"/>\r\n'
|
||||
write_utf8_bom(flowchart_path, flowchart_xml)
|
||||
write_xml_file_keep_eol(flowchart_path, flowchart_xml)
|
||||
modules_created.append(flowchart_path)
|
||||
|
||||
# Предопределённые элементы (Ext/Predefined.xml). Root-элемент по типу.
|
||||
@@ -4795,20 +4805,20 @@ if obj_type == 'ChartOfAccounts' and defn.get('predefined'):
|
||||
edt_ref = resolve_type_prefix_syn(str(defn['extDimensionTypes'])) if defn.get('extDimensionTypes') else ''
|
||||
predef_xml = build_predefined_account_xml(defn['predefined'], obj_name, af_names, edf_names, edt_ref)
|
||||
predef_path = os.path.join(ext_dir, 'Predefined.xml')
|
||||
write_utf8_bom(predef_path, predef_xml)
|
||||
write_xml_file_keep_eol(predef_path, predef_xml)
|
||||
modules_created.append(predef_path)
|
||||
elif obj_type == 'ChartOfCalculationTypes' and defn.get('predefined'):
|
||||
ensure_ext_dir()
|
||||
predef_xml = build_predefined_calc_type_xml(defn['predefined'])
|
||||
predef_path = os.path.join(ext_dir, 'Predefined.xml')
|
||||
write_utf8_bom(predef_path, predef_xml)
|
||||
write_xml_file_keep_eol(predef_path, predef_xml)
|
||||
modules_created.append(predef_path)
|
||||
elif obj_type in predef_root_by_type and defn.get('predefined'):
|
||||
ensure_ext_dir()
|
||||
cat_code_type = str(defn['codeType']) if defn.get('codeType') else 'String'
|
||||
predef_xml = build_predefined_xml(defn['predefined'], predef_root_by_type[obj_type], cat_code_type)
|
||||
predef_path = os.path.join(ext_dir, 'Predefined.xml')
|
||||
write_utf8_bom(predef_path, predef_xml)
|
||||
write_xml_file_keep_eol(predef_path, predef_xml)
|
||||
modules_created.append(predef_path)
|
||||
|
||||
# Модули команд (Commands/<Имя>/Ext/CommandModule.bsl) — заготовка обработчика.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# meta-edit v1.25 — Edit existing 1C metadata object XML
|
||||
# meta-edit v1.26 — Edit existing 1C metadata object XML
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
param(
|
||||
[string]$DefinitionFile,
|
||||
@@ -3138,7 +3138,8 @@ function Add-PredefinedItems($items) {
|
||||
$hdr = "<?xml version=`"1.0`" encoding=`"UTF-8`"?>`r`n<PredefinedData xmlns=`"http://v8.1c.ru/8.3/xcf/predef`" xmlns:v8=`"http://v8.1c.ru/8.1/data/core`" 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`" xsi:type=`"$xsiType`" version=`"$version`">`r`n"
|
||||
$text = "$hdr$itemsXml</PredefinedData>`r`n"
|
||||
}
|
||||
[System.IO.File]::WriteAllText($path, $text, $utf8Bom)
|
||||
# Создаваемый файл — по канону: без перевода строки в конце.
|
||||
[System.IO.File]::WriteAllText($path, $text.TrimEnd("`r", "`n"), $utf8Bom)
|
||||
$n = @($items).Count
|
||||
Info "Added $n predefined item(s) → $path"
|
||||
$script:addCount += $n
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# meta-edit v1.25 — Edit existing 1C metadata object XML
|
||||
# meta-edit v1.26 — Edit existing 1C metadata object XML
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
|
||||
import argparse
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# mxl-compile v1.6 — Compile 1C spreadsheet from JSON
|
||||
# mxl-compile v1.7 — Compile 1C spreadsheet from JSON
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# mxl-compile v1.6 — Compile 1C spreadsheet from JSON
|
||||
# mxl-compile v1.7 — Compile 1C spreadsheet from JSON
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
import argparse
|
||||
import json
|
||||
@@ -802,7 +802,7 @@ def main():
|
||||
if out_dir and not os.path.exists(out_dir):
|
||||
os.makedirs(out_dir, exist_ok=True)
|
||||
|
||||
content = '\n'.join(lines)
|
||||
content = '\r\n'.join(lines)
|
||||
write_utf8_bom(out_path, content)
|
||||
|
||||
# --- 9. Summary ---
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# role-compile v1.12 — Compile 1C role from JSON
|
||||
# role-compile v1.14 — Compile 1C role from JSON
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# role-compile v1.12 — Compile 1C role from JSON
|
||||
# role-compile v1.14 — Compile 1C role from JSON
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
import argparse
|
||||
import json
|
||||
@@ -203,6 +203,12 @@ def detect_format_version(d):
|
||||
return "2.17"
|
||||
|
||||
|
||||
def detect_eol(text):
|
||||
# Перевод строки ВСТАВКИ берём из самого файла: канон CRLF относится к файлам,
|
||||
# которые мы создаём, а правка существующего сохраняет его стиль (#44/#46/#47).
|
||||
crlf = text.count('\r\n')
|
||||
return '\r\n' if crlf and crlf >= text.count('\n') - crlf else '\n'
|
||||
|
||||
def esc_xml(s):
|
||||
"""Экранирование ТЕКСТА элемента: только & < > . Кавычки платформа в тексте не экранирует
|
||||
(92142 сырых кавычки на корпус, ни одной "); " она принимает, но нормализует обратно."""
|
||||
@@ -708,7 +714,7 @@ def main():
|
||||
lines.append(' </Role>')
|
||||
lines.append('</MetaDataObject>')
|
||||
|
||||
metadata_xml = '\n'.join(lines)
|
||||
metadata_xml = '\r\n'.join(lines)
|
||||
|
||||
# --- 5. Emit Rights XML (Roles/Name/Ext/Rights.xml) ---
|
||||
lines = []
|
||||
@@ -756,7 +762,7 @@ def main():
|
||||
|
||||
lines.append('</Rights>')
|
||||
|
||||
rights_xml = '\n'.join(lines)
|
||||
rights_xml = '\r\n'.join(lines)
|
||||
|
||||
# --- 6. Write output files ---
|
||||
out_dir = args.OutputDir
|
||||
@@ -791,9 +797,13 @@ def main():
|
||||
reg_result = None
|
||||
|
||||
if os.path.exists(config_xml_path):
|
||||
with open(config_xml_path, 'r', encoding='utf-8-sig') as f:
|
||||
# newline='' => без трансляции переводов строк: иначе CRLF молча схлопнется
|
||||
# в LF при чтении и файл будет переписан в LF (#44/#46/#47).
|
||||
with open(config_xml_path, 'r', encoding='utf-8-sig', newline='') as f:
|
||||
raw_text = f.read()
|
||||
|
||||
eol = detect_eol(raw_text)
|
||||
|
||||
# Check if already registered
|
||||
if f'<Role>{role_name}</Role>' in raw_text:
|
||||
reg_result = 'already'
|
||||
@@ -807,10 +817,10 @@ def main():
|
||||
# Insert after last existing <Role>
|
||||
last_match = matches[-1]
|
||||
insert_pos = last_match.end()
|
||||
raw_text = raw_text[:insert_pos] + f'\n\t\t\t{new_role_tag}' + raw_text[insert_pos:]
|
||||
raw_text = raw_text[:insert_pos] + eol + f'\t\t\t{new_role_tag}' + raw_text[insert_pos:]
|
||||
else:
|
||||
# No existing roles — insert before </ChildObjects>
|
||||
raw_text = raw_text.replace('</ChildObjects>', f'\t\t\t{new_role_tag}\n\t\t</ChildObjects>')
|
||||
raw_text = raw_text.replace('</ChildObjects>', f'\t\t\t{new_role_tag}' + eol + '\t\t</ChildObjects>')
|
||||
|
||||
write_utf8_bom(config_xml_path, raw_text)
|
||||
reg_result = 'added'
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# skd-compile v1.110 — Compile 1C DCS from JSON
|
||||
# skd-compile v1.111 — Compile 1C DCS from JSON
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
param(
|
||||
[string]$DefinitionFile,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# skd-compile v1.110 — Compile 1C DCS from JSON
|
||||
# skd-compile v1.111 — Compile 1C DCS from JSON
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
import argparse
|
||||
import json
|
||||
@@ -3069,7 +3069,7 @@ def main():
|
||||
if parent_dir and not os.path.exists(parent_dir):
|
||||
os.makedirs(parent_dir, exist_ok=True)
|
||||
|
||||
content = '\n'.join(lines)
|
||||
content = '\r\n'.join(lines)
|
||||
write_utf8_bom(output_path, content)
|
||||
|
||||
# --- 5. Statistics ---
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# subsystem-compile v1.13 — Create 1C subsystem from JSON definition
|
||||
# subsystem-compile v1.15 — Create 1C subsystem from JSON definition
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
param(
|
||||
[string]$DefinitionFile,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# subsystem-compile v1.13 — Create 1C subsystem from JSON definition
|
||||
# subsystem-compile v1.15 — Create 1C subsystem from JSON definition
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
import argparse
|
||||
import json
|
||||
@@ -204,6 +204,12 @@ def detect_format_version(d):
|
||||
return "2.17"
|
||||
|
||||
|
||||
def detect_eol(text):
|
||||
# Перевод строки ВСТАВКИ берём из самого файла: канон CRLF относится к файлам,
|
||||
# которые мы создаём, а правка существующего сохраняет его стиль (#44/#46/#47).
|
||||
crlf = text.count('\r\n')
|
||||
return '\r\n' if crlf and crlf >= text.count('\n') - crlf else '\n'
|
||||
|
||||
def esc_xml(s):
|
||||
"""Экранирование ТЕКСТА элемента: только & < > . Кавычки платформа в тексте не экранирует
|
||||
(92142 сырых кавычки на корпус, ни одной "); " она принимает, но нормализует обратно."""
|
||||
@@ -279,7 +285,7 @@ def write_child_subsystem_stub(child_path, child_name, format_version):
|
||||
lines.append('\t\t<ChildObjects/>')
|
||||
lines.append('\t</Subsystem>')
|
||||
lines.append('</MetaDataObject>')
|
||||
write_utf8_bom(child_path, '\n'.join(lines))
|
||||
write_utf8_bom(child_path, '\r\n'.join(lines))
|
||||
|
||||
|
||||
def main():
|
||||
@@ -525,7 +531,7 @@ def main():
|
||||
target_xml = os.path.join(subs_dir, f'{obj_name}.xml')
|
||||
|
||||
# Write XML
|
||||
xml_content = '\n'.join(lines)
|
||||
xml_content = '\r\n'.join(lines)
|
||||
write_utf8_bom(target_xml, xml_content)
|
||||
print(f"[OK] Created: {target_xml}")
|
||||
|
||||
@@ -555,9 +561,12 @@ def main():
|
||||
parent_xml_path = config_xml
|
||||
|
||||
if parent_xml_path and os.path.exists(parent_xml_path):
|
||||
with open(parent_xml_path, 'r', encoding='utf-8-sig') as f:
|
||||
# newline='' => без трансляции переводов строк: иначе CRLF молча схлопнется
|
||||
# в LF при чтении и файл будет переписан в LF (#44/#46/#47).
|
||||
with open(parent_xml_path, 'r', encoding='utf-8-sig', newline='') as f:
|
||||
raw_text = f.read()
|
||||
|
||||
eol = detect_eol(raw_text)
|
||||
doc = ET.ElementTree(ET.fromstring(raw_text))
|
||||
root = doc.getroot()
|
||||
md_ns = 'http://v8.1c.ru/8.3/MDClasses'
|
||||
@@ -593,10 +602,10 @@ def main():
|
||||
if not already_exists:
|
||||
# Use raw text manipulation to preserve formatting
|
||||
if '<ChildObjects/>' in raw_text:
|
||||
replacement = f'<ChildObjects>\n\t\t\t<Subsystem>{esc_xml(obj_name)}</Subsystem>\n\t\t</ChildObjects>'
|
||||
replacement = ('<ChildObjects>' + eol + f'\t\t\t<Subsystem>{esc_xml(obj_name)}</Subsystem>' + eol + '\t\t</ChildObjects>')
|
||||
raw_text = raw_text.replace('<ChildObjects/>', replacement, 1)
|
||||
elif '</ChildObjects>' in raw_text:
|
||||
insert_line = f'\t\t\t<Subsystem>{esc_xml(obj_name)}</Subsystem>\n'
|
||||
insert_line = f'\t\t\t<Subsystem>{esc_xml(obj_name)}</Subsystem>' + eol
|
||||
raw_text = raw_text.replace('</ChildObjects>', insert_line + '\t\t</ChildObjects>', 1)
|
||||
|
||||
write_utf8_bom(parent_xml_path, raw_text)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# subsystem-edit v1.10 — Edit existing 1C subsystem XML
|
||||
# subsystem-edit v1.11 — Edit existing 1C subsystem XML
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
param(
|
||||
[Parameter(Mandatory)][Alias('Path')][string]$SubsystemPath,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# subsystem-edit v1.10 — Edit existing 1C subsystem XML
|
||||
# subsystem-edit v1.11 — Edit existing 1C subsystem XML
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
|
||||
import argparse
|
||||
@@ -242,7 +242,7 @@ def write_child_subsystem_stub(child_path, child_name, format_version):
|
||||
lines.append('\t\t<ChildObjects/>')
|
||||
lines.append('\t</Subsystem>')
|
||||
lines.append('</MetaDataObject>')
|
||||
write_utf8_bom(child_path, '\n'.join(lines))
|
||||
write_utf8_bom(child_path, '\r\n'.join(lines))
|
||||
|
||||
MD_NS = "http://v8.1c.ru/8.3/MDClasses"
|
||||
XR_NS = "http://v8.1c.ru/8.3/xcf/readable"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# template-add v1.12 — Add template to 1C object
|
||||
# template-add v1.14 — Add template to 1C object
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
@@ -260,7 +260,16 @@ $templateMetaXml = @"
|
||||
</MetaDataObject>
|
||||
"@
|
||||
|
||||
[System.IO.File]::WriteAllText($templateMetaPath, $templateMetaXml, $encBom)
|
||||
# Канон выгрузки Конфигуратора: 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 $templateMetaPath $templateMetaXml $encBom
|
||||
|
||||
# --- 2. Содержимое макета (Templates/<TemplateName>/Ext/Template.<ext>) ---
|
||||
|
||||
@@ -290,7 +299,7 @@ switch ($TemplateType) {
|
||||
<SpreadsheetDocument xmlns="http://v8.1c.ru/spreadsheet/document" xmlns:ss="http://v8.1c.ru/spreadsheet/document" xmlns:v8="http://v8.1c.ru/8.1/data/core" xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||
</SpreadsheetDocument>
|
||||
"@
|
||||
[System.IO.File]::WriteAllText($templateFilePath, $content, $encBom)
|
||||
Write-XmlFile $templateFilePath $content $encBom
|
||||
}
|
||||
"BinaryData" {
|
||||
[System.IO.File]::WriteAllBytes($templateFilePath, @())
|
||||
@@ -312,7 +321,7 @@ switch ($TemplateType) {
|
||||
</dataSource>
|
||||
</DataCompositionSchema>
|
||||
"@
|
||||
[System.IO.File]::WriteAllText($templateFilePath, $content, $encBom)
|
||||
Write-XmlFile $templateFilePath $content $encBom
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# add-template v1.12 — Add template to 1C object
|
||||
# add-template v1.14 — Add template to 1C object
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
|
||||
import argparse
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# xdto-compile v1.3 — Build a 1C XDTO package from an XML Schema (XSD)
|
||||
# xdto-compile v1.4 — Build a 1C XDTO package from an XML Schema (XSD)
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
param(
|
||||
[Parameter(Mandatory=$true, ParameterSetName='File')]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# xdto-compile v1.3 — Build a 1C XDTO package from an XML Schema (XSD) (Python port)
|
||||
# xdto-compile v1.4 — Build a 1C XDTO package from an XML Schema (XSD) (Python port)
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
import argparse
|
||||
import json
|
||||
@@ -960,6 +960,12 @@ if os.path.exists(config_xml):
|
||||
else:
|
||||
new_elem.tail = child_objects.text
|
||||
data = etree.tostring(cfg_doc, xml_declaration=True, encoding="UTF-8")
|
||||
# Парсер XML по спецификации схлопывает CRLF в LF, поэтому tostring отдаёт
|
||||
# LF-документ. Возвращаем EOL исходного файла: правка существующего файла
|
||||
# сохраняет его стиль (#44/#46/#47), а .NET-порт делает это через
|
||||
# NewLineHandling — иначе порты расходятся побайтово.
|
||||
src_eol = b"\r\n" if b"\r\n" in raw else b"\n"
|
||||
data = data.replace(b"\r\n", b"\n").replace(b"\n", src_eol)
|
||||
if had_bom:
|
||||
data = b"\xef\xbb\xbf" + data
|
||||
with open(config_xml, "wb") as f:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# xdto-edit v1.1 — Point edits of a 1C XDTO package
|
||||
# xdto-edit v1.2 — Point edits of a 1C XDTO package
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
param(
|
||||
[Parameter(Mandatory=$true)]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# xdto-edit v1.1 — Point edits of a 1C XDTO package (Python port)
|
||||
# xdto-edit v1.2 — Point edits of a 1C XDTO package (Python port)
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
import argparse
|
||||
import json
|
||||
@@ -194,6 +194,17 @@ def invoke_sibling(script, argv, what):
|
||||
|
||||
def save_xml(doc, path):
|
||||
raw = etree.tostring(doc, xml_declaration=True, encoding="UTF-8")
|
||||
# Парсер XML по спецификации схлопывает CRLF в LF, поэтому tostring отдаёт
|
||||
# LF-документ. Возвращаем EOL исходного файла: правка существующего файла
|
||||
# сохраняет его стиль (#44/#46/#47), а .NET-порт делает это через
|
||||
# NewLineHandling — иначе порты расходятся побайтово.
|
||||
src_eol = b"\r\n"
|
||||
try:
|
||||
with open(path, "rb") as f:
|
||||
src_eol = b"\r\n" if b"\r\n" in f.read() else b"\n"
|
||||
except OSError:
|
||||
pass
|
||||
raw = raw.replace(b"\r\n", b"\n").replace(b"\n", src_eol)
|
||||
with open(path, "wb") as f:
|
||||
f.write(b"\xef\xbb\xbf" + raw)
|
||||
|
||||
|
||||
+1
-1
@@ -26,4 +26,4 @@
|
||||
</Item>
|
||||
</ChildItems>
|
||||
</Item>
|
||||
</PredefinedData>
|
||||
</PredefinedData>
|
||||
Reference in New Issue
Block a user