mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-08-07 20:20:20 +03:00
feat(cfe-borrow,cfe-init,form-add,form-compile,role-compile,subsystem-compile,subsystem-edit,template-add,xdto-compile): xmlns:pal в формате 2.21
Платформа 8.5 объявляет пространство палитры в шапках MetaDataObject и Form. Радиус снят по выгрузке УНФ 8.5, а не угадан: pal есть у MetaDataObject, Form, document (тело MXL), Style, AppearanceTemplate, GraphicalSchema; у Rights, Help, CommandInterface, DataCompositionSchema и корней extrnprops его нет. Поэтому role-compile правит шапку Role.xml и не трогает Rights.xml. Вставка идёт на место — после lf, перед style: объявления платформа держит по алфавиту, дописать в конец нельзя. Попутно в cfe-borrow тег <Form> больше не копируется из исходной формы целиком: из него берутся только объявления пространств, а version подставляется своя. Раньше версия источника молча побеждала — вопреки комментарию рядом. Тесты: снята нормализация xmlns в снэпшотах py-прогона (она прятала ровно этот класс расхождений и к моменту снятия была мёртвой — ни один кейс на неё не опирался); добавлены expect.fileContains/fileNotContains по сырым байтам и гейт на неизвестные ключи expect.* — он вскрыл два кейса-пустышки (skd-compile, skd-edit), они починены. 648/648 ps1, 645/648 py. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
d60dd47f0b
commit
53c1d59ec1
@@ -1,4 +1,4 @@
|
||||
# cfe-borrow v1.15 — Borrow objects from configuration into extension (CFE)
|
||||
# cfe-borrow v1.16 — Borrow objects from configuration into extension (CFE)
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
param(
|
||||
[Parameter(Mandatory)][string]$ExtensionPath,
|
||||
@@ -388,6 +388,20 @@ $script:formatVersion = Detect-FormatVersion $extDir
|
||||
# --- 8. Namespaces declaration for object XML ---
|
||||
$script:xmlnsDecl = '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"'
|
||||
|
||||
# Версия формата как число для сравнений: "2.20" → 220, "2.9" → 209.
|
||||
# Строковое сравнение здесь неверно ("2.9" > "2.17" лексикографически) — известная ловушка.
|
||||
function Get-FormatRank([string]$ver) {
|
||||
if ($ver -match '^(\d+)\.(\d+)$') { return [int]$Matches[1] * 100 + [int]$Matches[2] }
|
||||
return 0
|
||||
}
|
||||
|
||||
# 2.21 (8.5) добавила в шапку пространство палитры — ради <Color> у значений перечисления.
|
||||
# Вставляем НА МЕСТО (после lf, перед style): платформа держит объявления по алфавиту,
|
||||
# дописать в конец нельзя.
|
||||
if ((Get-FormatRank $script:formatVersion) -ge 221) {
|
||||
$script:xmlnsDecl = $script:xmlnsDecl -replace ' xmlns:style=', ' xmlns:pal="http://v8.1c.ru/8.1/data/ui/colors/palette" xmlns:style='
|
||||
}
|
||||
|
||||
# --- 9. Parse -Object into items ---
|
||||
$items = @()
|
||||
foreach ($part in $Object.Split(";;")) {
|
||||
@@ -824,11 +838,22 @@ function Borrow-Form {
|
||||
}
|
||||
}
|
||||
|
||||
# Extract the <Form ...> opening tag from source text (preserves namespace declarations)
|
||||
# Открывающий тег <Form ...> берём из исходной формы — ради её объявлений пространств имён,
|
||||
# но version подставляем СВОЮ: форма обязана нести версию расширения, иначе платформа
|
||||
# отвергает импорт (форма 2.13 внутри расширения 2.17). Раньше тег копировался целиком,
|
||||
# и версия источника молча побеждала.
|
||||
$xmlDecl = '<?xml version="1.0" encoding="UTF-8"?>'
|
||||
$formTag = "<Form version=`"${formVersion}`">"
|
||||
if ($srcFormContent -match '(?s)^(<\?xml[^?]*\?>)') { $xmlDecl = $Matches[1] }
|
||||
if ($srcFormContent -match '(<Form[^>]*>)') { $formTag = $Matches[1] }
|
||||
if ($srcFormContent -match '(<Form[^>]*>)') {
|
||||
$srcTag = $Matches[1]
|
||||
$srcNs = $srcTag -replace '^<Form\s*', '' -replace '\s*/?>$', '' -replace '\s*version="[^"]*"', ''
|
||||
# 2.21 (8.5): пространство палитры. Место строгое — после lf, перед style.
|
||||
if ((Get-FormatRank $formVersion) -ge 221 -and $srcNs -notmatch 'xmlns:pal=') {
|
||||
$srcNs = $srcNs -replace ' xmlns:style=', ' xmlns:pal="http://v8.1c.ru/8.1/data/ui/colors/palette" xmlns:style='
|
||||
}
|
||||
$formTag = if ($srcNs) { "<Form $srcNs version=`"${formVersion}`">" } else { "<Form version=`"${formVersion}`">" }
|
||||
}
|
||||
|
||||
# Build output Form.xml
|
||||
$formXmlSb = New-Object System.Text.StringBuilder
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# cfe-borrow v1.15 — Borrow objects from configuration into extension (CFE)
|
||||
# cfe-borrow v1.16 — Borrow objects from configuration into extension (CFE)
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
|
||||
import argparse
|
||||
@@ -323,6 +323,23 @@ def detect_format_version(d):
|
||||
return "2.17"
|
||||
|
||||
|
||||
def format_rank(ver):
|
||||
""""2.20" → 220, "2.9" → 209. Строковое сравнение неверно ("2.9" > "2.17")."""
|
||||
m = re.match(r'^(\d+)\.(\d+)$', ver or '')
|
||||
return int(m.group(1)) * 100 + int(m.group(2)) if m else 0
|
||||
|
||||
|
||||
def apply_pal_ns(format_version):
|
||||
"""2.21 (8.5) добавила в шапку пространство палитры — ради <Color> у значений перечисления.
|
||||
Вставляем НА МЕСТО (после lf, перед style): платформа держит объявления по алфавиту,
|
||||
дописать в конец нельзя."""
|
||||
global XMLNS_DECL
|
||||
if format_rank(format_version) >= 221:
|
||||
XMLNS_DECL = XMLNS_DECL.replace(
|
||||
' xmlns:style=',
|
||||
' xmlns:pal="http://v8.1c.ru/8.1/data/ui/colors/palette" xmlns:style=')
|
||||
|
||||
|
||||
def get_child_indent(container):
|
||||
if container.text and "\n" in container.text:
|
||||
after_nl = container.text.rsplit("\n", 1)[-1]
|
||||
@@ -491,6 +508,7 @@ def main():
|
||||
cfg_dir = os.path.dirname(cfg_resolved)
|
||||
|
||||
format_version = detect_format_version(ext_dir)
|
||||
apply_pal_ns(format_version)
|
||||
|
||||
# --- 2. Load extension Configuration.xml ---
|
||||
xml_parser = etree.XMLParser(remove_blank_text=False)
|
||||
@@ -1509,7 +1527,10 @@ def main():
|
||||
else:
|
||||
warn(f" Enum.{enum_name} not found in source config")
|
||||
|
||||
# Extract the <Form ...> opening tag from source text
|
||||
# Открывающий тег <Form ...> берём из исходной формы — ради её объявлений пространств
|
||||
# имён, но version подставляем СВОЮ: форма обязана нести версию расширения, иначе
|
||||
# платформа отвергает импорт (форма 2.13 внутри расширения 2.17). Раньше тег
|
||||
# копировался целиком, и версия источника молча побеждала.
|
||||
xml_decl = '<?xml version="1.0" encoding="UTF-8"?>'
|
||||
form_tag = f'<Form version="{form_version}">'
|
||||
m_decl = re.search(r'^(<\?xml[^?]*\?>)', src_form_content)
|
||||
@@ -1517,7 +1538,15 @@ def main():
|
||||
xml_decl = m_decl.group(1)
|
||||
m_tag = re.search(r'(<Form[^>]*>)', src_form_content)
|
||||
if m_tag:
|
||||
form_tag = m_tag.group(1)
|
||||
src_ns = re.sub(r'^<Form\s*', '', m_tag.group(1))
|
||||
src_ns = re.sub(r'\s*/?>$', '', src_ns)
|
||||
src_ns = re.sub(r'\s*version="[^"]*"', '', src_ns)
|
||||
# 2.21 (8.5): пространство палитры. Место строгое — после lf, перед style.
|
||||
if format_rank(form_version) >= 221 and 'xmlns:pal=' not in src_ns:
|
||||
src_ns = src_ns.replace(
|
||||
' xmlns:style=',
|
||||
' xmlns:pal="http://v8.1c.ru/8.1/data/ui/colors/palette" xmlns:style=')
|
||||
form_tag = f'<Form {src_ns} version="{form_version}">' if src_ns else f'<Form version="{form_version}">'
|
||||
|
||||
# Build output
|
||||
parts = []
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# cfe-init v1.5 — Create 1C configuration extension scaffold (CFE)
|
||||
# cfe-init v1.6 — Create 1C configuration extension scaffold (CFE)
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
@@ -151,6 +151,20 @@ $childObjectsXml += "`r`n`t`t"
|
||||
# Правки шапки (как xmlns:pal в формате 2.21) делаются здесь, в одном месте.
|
||||
$xmlnsDecl = '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"'
|
||||
|
||||
# Версия формата как число для сравнений: "2.20" → 220, "2.9" → 209.
|
||||
# Строковое сравнение здесь неверно ("2.9" > "2.17" лексикографически) — известная ловушка.
|
||||
function Get-FormatRank([string]$ver) {
|
||||
if ($ver -match '^(\d+)\.(\d+)$') { return [int]$Matches[1] * 100 + [int]$Matches[2] }
|
||||
return 0
|
||||
}
|
||||
|
||||
# 2.21 (8.5) добавила в шапку пространство палитры — ради <Color> у значений перечисления.
|
||||
# Вставляем НА МЕСТО (после lf, перед style): платформа держит объявления по алфавиту,
|
||||
# дописать в конец нельзя.
|
||||
if ((Get-FormatRank $formatVersion) -ge 221) {
|
||||
$xmlnsDecl = $xmlnsDecl -replace ' xmlns:style=', ' xmlns:pal="http://v8.1c.ru/8.1/data/ui/colors/palette" xmlns:style='
|
||||
}
|
||||
|
||||
# --- Configuration.xml ---
|
||||
$cfgXml = @"
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#!/usr/bin/env python3
|
||||
# cfe-init v1.5 — Create 1C configuration extension scaffold (CFE)
|
||||
# cfe-init v1.6 — 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
|
||||
import sys, os, re, argparse, uuid
|
||||
from xml.etree import ElementTree as ET
|
||||
|
||||
def esc_xml(s):
|
||||
@@ -25,6 +25,12 @@ def write_xml_file(path, content):
|
||||
write_utf8_bom(path, text)
|
||||
|
||||
|
||||
def format_rank(ver):
|
||||
""""2.20" → 220, "2.9" → 209. Строковое сравнение неверно ("2.9" > "2.17")."""
|
||||
m = re.match(r'^(\d+)\.(\d+)$', ver or '')
|
||||
return int(m.group(1)) * 100 + int(m.group(2)) if m else 0
|
||||
|
||||
|
||||
def main():
|
||||
sys.stdout.reconfigure(encoding="utf-8")
|
||||
sys.stderr.reconfigure(encoding="utf-8")
|
||||
@@ -193,6 +199,14 @@ def main():
|
||||
' xmlns:xs="http://www.w3.org/2001/XMLSchema"'
|
||||
' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"'
|
||||
)
|
||||
|
||||
# 2.21 (8.5) добавила в шапку пространство палитры — ради <Color> у значений перечисления.
|
||||
# Вставляем НА МЕСТО (после lf, перед style): платформа держит объявления по алфавиту,
|
||||
# дописать в конец нельзя.
|
||||
if format_rank(format_version) >= 221:
|
||||
xmlns_decl = xmlns_decl.replace(
|
||||
' xmlns:style=',
|
||||
' xmlns:pal="http://v8.1c.ru/8.1/data/ui/colors/palette" xmlns:style=')
|
||||
for i in range(7):
|
||||
contained_objects += f"""\t\t\t<xr:ContainedObject>
|
||||
\t\t\t\t<xr:ClassId>{class_ids[i]}</xr:ClassId>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# form-add v1.20 — Add managed form to 1C config object
|
||||
# form-add v1.21 — Add managed form to 1C config object
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
@@ -169,6 +169,13 @@ function Detect-FormatVersion([string]$dir) {
|
||||
return "2.17"
|
||||
}
|
||||
|
||||
# Версия формата как число для сравнений: "2.20" → 220, "2.9" → 209.
|
||||
# Строковое сравнение здесь неверно ("2.9" > "2.17" лексикографически) — известная ловушка.
|
||||
function Get-FormatRank([string]$ver) {
|
||||
if ($ver -match '^(\d+)\.(\d+)$') { return [int]$Matches[1] * 100 + [int]$Matches[2] }
|
||||
return 0
|
||||
}
|
||||
|
||||
# --- Фаза 1: Определение типа объекта ---
|
||||
|
||||
# Resolve ObjectPath (directory → .xml)
|
||||
@@ -197,6 +204,14 @@ $script:formatVersion = Detect-FormatVersion (Split-Path $objectXmlFull.Path -Pa
|
||||
$script:xmlnsDecl = '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"'
|
||||
$script:formNsDecl = '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"'
|
||||
|
||||
# 2.21 (8.5) добавила в шапку пространство палитры — ради <Color> у значений перечисления.
|
||||
# Вставляем НА МЕСТО (после lf, перед style): платформа держит объявления по алфавиту,
|
||||
# дописать в конец нельзя.
|
||||
if ((Get-FormatRank $script:formatVersion) -ge 221) {
|
||||
$script:xmlnsDecl = $script:xmlnsDecl -replace ' xmlns:style=', ' xmlns:pal="http://v8.1c.ru/8.1/data/ui/colors/palette" xmlns:style='
|
||||
$script:formNsDecl = $script:formNsDecl -replace ' xmlns:style=', ' xmlns:pal="http://v8.1c.ru/8.1/data/ui/colors/palette" xmlns:style='
|
||||
}
|
||||
|
||||
$xmlDoc = New-Object System.Xml.XmlDocument
|
||||
$xmlDoc.PreserveWhitespace = $true
|
||||
$xmlDoc.Load($objectXmlFull.Path)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# form-add v1.20 — Add managed form to 1C config object
|
||||
# form-add v1.21 — Add managed form to 1C config object
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
|
||||
import argparse
|
||||
@@ -210,6 +210,12 @@ def detect_format_version(d):
|
||||
return "2.17"
|
||||
|
||||
|
||||
def format_rank(ver):
|
||||
""""2.20" → 220, "2.9" → 209. Строковое сравнение неверно ("2.9" > "2.17")."""
|
||||
m = re.match(r'^(\d+)\.(\d+)$', ver or '')
|
||||
return int(m.group(1)) * 100 + int(m.group(2)) if m else 0
|
||||
|
||||
|
||||
def _detect_xml_style(path):
|
||||
"""Стиль существующего файла для round-trip-сохранения: BOM / EOL / регистр encoding /
|
||||
финальный перенос. None → файл новый (сохранить текущее поведение)."""
|
||||
@@ -356,6 +362,14 @@ def main():
|
||||
' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"'
|
||||
)
|
||||
|
||||
# 2.21 (8.5) добавила в шапку пространство палитры — ради <Color> у значений перечисления.
|
||||
# Вставляем НА МЕСТО (после lf, перед style): платформа держит объявления по алфавиту,
|
||||
# дописать в конец нельзя.
|
||||
if format_rank(format_version) >= 221:
|
||||
pal = ' xmlns:pal="http://v8.1c.ru/8.1/data/ui/colors/palette" xmlns:style='
|
||||
xmlns_decl = xmlns_decl.replace(' xmlns:style=', pal)
|
||||
form_ns_decl = form_ns_decl.replace(' xmlns:style=', pal)
|
||||
|
||||
parser_xml = etree.XMLParser(remove_blank_text=False)
|
||||
tree = etree.parse(object_xml_full, parser_xml)
|
||||
root = tree.getroot()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# form-compile v1.183 — Compile 1C managed form from JSON or object metadata
|
||||
# form-compile v1.184 — Compile 1C managed form from JSON or object metadata
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
param(
|
||||
[string]$JsonPath,
|
||||
@@ -1350,6 +1350,13 @@ function Detect-FormatVersion([string]$dir) {
|
||||
return "2.17"
|
||||
}
|
||||
|
||||
# Версия формата как число для сравнений: "2.20" → 220, "2.9" → 209.
|
||||
# Строковое сравнение здесь неверно ("2.9" > "2.17" лексикографически) — известная ловушка.
|
||||
function Get-FormatRank([string]$ver) {
|
||||
if ($ver -match '^(\d+)\.(\d+)$') { return [int]$Matches[1] * 100 + [int]$Matches[2] }
|
||||
return 0
|
||||
}
|
||||
|
||||
# --- Support guard (Ext/ParentConfigurations.bin) ---
|
||||
# See docs/1c-support-state-spec.md. Blocks edits of vendor objects "на замке" /
|
||||
# read-only configs unless allowed. Trigger = bin present; reaction from
|
||||
@@ -1489,6 +1496,13 @@ $script:formatVersion = Detect-FormatVersion ([System.IO.Path]::GetDirectoryName
|
||||
# Правки шапки (как xmlns:pal в формате 2.21) делаются здесь, в одном месте.
|
||||
$script:formNsDecl = '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:dcssch="http://v8.1c.ru/8.1/data-composition-system/schema" 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"'
|
||||
|
||||
# 2.21 (8.5) добавила в шапку пространство палитры — ради <Color> у значений перечисления.
|
||||
# Вставляем НА МЕСТО (после lf, перед style): платформа держит объявления по алфавиту,
|
||||
# дописать в конец нельзя.
|
||||
if ((Get-FormatRank $script:formatVersion) -ge 221) {
|
||||
$script:formNsDecl = $script:formNsDecl -replace ' xmlns:style=', ' xmlns:pal="http://v8.1c.ru/8.1/data/ui/colors/palette" xmlns:style='
|
||||
}
|
||||
|
||||
# --- 0. Path normalization and mode dispatch ---
|
||||
|
||||
# Form name → purpose mapping
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# form-compile v1.183 — Compile 1C managed form from JSON or object metadata
|
||||
# form-compile v1.184 — Compile 1C managed form from JSON or object metadata
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
import argparse
|
||||
import copy
|
||||
@@ -6075,6 +6075,12 @@ def detect_format_version(d):
|
||||
return "2.17"
|
||||
|
||||
|
||||
def format_rank(ver):
|
||||
""""2.20" → 220, "2.9" → 209. Строковое сравнение неверно ("2.9" > "2.17")."""
|
||||
m = re.match(r'^(\d+)\.(\d+)$', ver or '')
|
||||
return int(m.group(1)) * 100 + int(m.group(2)) if m else 0
|
||||
|
||||
|
||||
def _normalize_elements(defn):
|
||||
"""Convert dict-style elements from --from-object generators to list-style expected by compiler.
|
||||
Generator format: elements = {"ИмяЭлемента": {"element": "input", "path": "..."}, ...}
|
||||
@@ -6236,6 +6242,14 @@ def main():
|
||||
' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"'
|
||||
)
|
||||
|
||||
# 2.21 (8.5) добавила в шапку пространство палитры — ради <Color> у значений перечисления.
|
||||
# Вставляем НА МЕСТО (после lf, перед style): платформа держит объявления по алфавиту,
|
||||
# дописать в конец нельзя.
|
||||
if format_rank(format_version) >= 221:
|
||||
form_ns_decl = form_ns_decl.replace(
|
||||
' xmlns:style=',
|
||||
' xmlns:pal="http://v8.1c.ru/8.1/data/ui/colors/palette" xmlns:style=')
|
||||
|
||||
# --- 0. From-object mode ---
|
||||
if args.FromObject:
|
||||
# Resolve object path and purpose from OutputPath convention:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# role-compile v1.16 — Compile 1C role from JSON
|
||||
# role-compile v1.17 — Compile 1C role from JSON
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
@@ -659,7 +659,14 @@ function Detect-FormatVersion([string]$dir) {
|
||||
return "2.17"
|
||||
}
|
||||
|
||||
$resolvedOutputDir = if ([System.IO.Path]::IsPathRooted($OutputDir)) { $OutputDir } else { Join-Path (Get-Location) $OutputDir }
|
||||
# Версия формата как число для сравнений: "2.20" → 220, "2.9" → 209.
|
||||
# Строковое сравнение здесь неверно ("2.9" > "2.17" лексикографически) — известная ловушка.
|
||||
function Get-FormatRank([string]$ver) {
|
||||
if ($ver -match '^(\d+)\.(\d+)$') { return [int]$Matches[1] * 100 + [int]$Matches[2] }
|
||||
return 0
|
||||
}
|
||||
|
||||
$resolvedOutputDir =if ([System.IO.Path]::IsPathRooted($OutputDir)) { $OutputDir } else { Join-Path (Get-Location) $OutputDir }
|
||||
Assert-EditAllowed $resolvedOutputDir 'editable'
|
||||
$formatVersion = Detect-FormatVersion $resolvedOutputDir
|
||||
|
||||
@@ -678,6 +685,11 @@ X ' xmlns:cfg="http://v8.1c.ru/8.1/data/enterprise/current-config"'
|
||||
X ' xmlns:cmi="http://v8.1c.ru/8.2/managed-application/cmi"'
|
||||
X ' xmlns:ent="http://v8.1c.ru/8.1/data/enterprise"'
|
||||
X ' xmlns:lf="http://v8.1c.ru/8.2/managed-application/logform"'
|
||||
# 2.21 (8.5) добавила в шапку пространство палитры. Место строгое — после lf, перед style:
|
||||
# платформа держит объявления по алфавиту. В Rights.xml палитра НЕ идёт (проверено по выгрузке 8.5).
|
||||
if ((Get-FormatRank $formatVersion) -ge 221) {
|
||||
X ' xmlns:pal="http://v8.1c.ru/8.1/data/ui/colors/palette"'
|
||||
}
|
||||
X ' xmlns:style="http://v8.1c.ru/8.1/data/ui/style"'
|
||||
X ' xmlns:sys="http://v8.1c.ru/8.1/data/ui/fonts/system"'
|
||||
X ' xmlns:v8="http://v8.1c.ru/8.1/data/core"'
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# role-compile v1.16 — Compile 1C role from JSON
|
||||
# role-compile v1.17 — 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 format_rank(ver):
|
||||
""""2.20" → 220, "2.9" → 209. Строковое сравнение неверно ("2.9" > "2.17")."""
|
||||
m = re.match(r'^(\d+)\.(\d+)$', ver or '')
|
||||
return int(m.group(1)) * 100 + int(m.group(2)) if m else 0
|
||||
|
||||
|
||||
def detect_eol(text):
|
||||
# Перевод строки ВСТАВКИ берём из самого файла: канон CRLF относится к файлам,
|
||||
# которые мы создаём, а правка существующего сохраняет его стиль (#44/#46/#47).
|
||||
@@ -687,6 +693,10 @@ def main():
|
||||
lines.append(' xmlns:cmi="http://v8.1c.ru/8.2/managed-application/cmi"')
|
||||
lines.append(' xmlns:ent="http://v8.1c.ru/8.1/data/enterprise"')
|
||||
lines.append(' xmlns:lf="http://v8.1c.ru/8.2/managed-application/logform"')
|
||||
# 2.21 (8.5) добавила в шапку пространство палитры. Место строгое — после lf, перед style:
|
||||
# платформа держит объявления по алфавиту. В Rights.xml палитра НЕ идёт (проверено по выгрузке 8.5).
|
||||
if format_rank(format_version) >= 221:
|
||||
lines.append(' xmlns:pal="http://v8.1c.ru/8.1/data/ui/colors/palette"')
|
||||
lines.append(' xmlns:style="http://v8.1c.ru/8.1/data/ui/style"')
|
||||
lines.append(' xmlns:sys="http://v8.1c.ru/8.1/data/ui/fonts/system"')
|
||||
lines.append(' xmlns:v8="http://v8.1c.ru/8.1/data/core"')
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# subsystem-compile v1.18 — Create 1C subsystem from JSON definition
|
||||
# subsystem-compile v1.19 — Create 1C subsystem from JSON definition
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
param(
|
||||
[string]$DefinitionFile,
|
||||
@@ -451,6 +451,20 @@ $formatVersion = Detect-FormatVersion $OutputDir
|
||||
# Правки шапки (как xmlns:pal в формате 2.21) делаются здесь, в одном месте.
|
||||
$script:xmlnsDecl = '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"'
|
||||
|
||||
# Версия формата как число для сравнений: "2.20" → 220, "2.9" → 209.
|
||||
# Строковое сравнение здесь неверно ("2.9" > "2.17" лексикографически) — известная ловушка.
|
||||
function Get-FormatRank([string]$ver) {
|
||||
if ($ver -match '^(\d+)\.(\d+)$') { return [int]$Matches[1] * 100 + [int]$Matches[2] }
|
||||
return 0
|
||||
}
|
||||
|
||||
# 2.21 (8.5) добавила в шапку пространство палитры — ради <Color> у значений перечисления.
|
||||
# Вставляем НА МЕСТО (после lf, перед style): платформа держит объявления по алфавиту,
|
||||
# дописать в конец нельзя.
|
||||
if ((Get-FormatRank $formatVersion) -ge 221) {
|
||||
$script:xmlnsDecl = $script:xmlnsDecl -replace ' xmlns:style=', ' xmlns:pal="http://v8.1c.ru/8.1/data/ui/colors/palette" xmlns:style='
|
||||
}
|
||||
|
||||
# --- 4. Build XML ---
|
||||
$uuid = New-Guid-String
|
||||
$indent = "`t`t`t"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# subsystem-compile v1.18 — Create 1C subsystem from JSON definition
|
||||
# subsystem-compile v1.19 — Create 1C subsystem from JSON definition
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
import argparse
|
||||
import json
|
||||
@@ -203,6 +203,12 @@ def detect_format_version(d):
|
||||
d = parent
|
||||
return "2.17"
|
||||
|
||||
def format_rank(ver):
|
||||
""""2.20" → 220, "2.9" → 209. Строковое сравнение неверно ("2.9" > "2.17")."""
|
||||
m = re.match(r'^(\d+)\.(\d+)$', ver or '')
|
||||
return int(m.group(1)) * 100 + int(m.group(2)) if m else 0
|
||||
|
||||
|
||||
|
||||
def detect_eol(text):
|
||||
# Перевод строки ВСТАВКИ берём из самого файла: канон CRLF относится к файлам,
|
||||
@@ -271,6 +277,17 @@ XMLNS_DECL = (
|
||||
)
|
||||
|
||||
|
||||
def apply_pal_ns(format_version):
|
||||
"""2.21 (8.5) добавила в шапку пространство палитры — ради <Color> у значений перечисления.
|
||||
Вставляем НА МЕСТО (после lf, перед style): платформа держит объявления по алфавиту,
|
||||
дописать в конец нельзя."""
|
||||
global XMLNS_DECL
|
||||
if format_rank(format_version) >= 221:
|
||||
XMLNS_DECL = XMLNS_DECL.replace(
|
||||
' xmlns:style=',
|
||||
' xmlns:pal="http://v8.1c.ru/8.1/data/ui/colors/palette" xmlns:style=')
|
||||
|
||||
|
||||
def write_child_subsystem_stub(child_path, child_name, format_version):
|
||||
child_uuid = new_uuid()
|
||||
lines = []
|
||||
@@ -422,6 +439,7 @@ def main():
|
||||
return f'{type_part}.{name_part}'
|
||||
|
||||
format_version = detect_format_version(output_dir)
|
||||
apply_pal_ns(format_version)
|
||||
xmlns_decl = XMLNS_DECL
|
||||
|
||||
# --- 3. Resolve defaults ---
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# subsystem-edit v1.14 — Edit existing 1C subsystem XML
|
||||
# subsystem-edit v1.15 — Edit existing 1C subsystem XML
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
param(
|
||||
[Parameter(Mandatory)][Alias('Path')][string]$SubsystemPath,
|
||||
@@ -265,6 +265,20 @@ if (-not $script:formatVersion) { $script:formatVersion = "2.17" }
|
||||
# Объявления пространств имён — одной переменной: место эмиссии её только интерполирует.
|
||||
# Правки шапки (как xmlns:pal в формате 2.21) делаются здесь, в одном месте.
|
||||
$script:xmlnsDecl = '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"'
|
||||
|
||||
# Версия формата как число для сравнений: "2.20" → 220, "2.9" → 209.
|
||||
# Строковое сравнение здесь неверно ("2.9" > "2.17" лексикографически) — известная ловушка.
|
||||
function Get-FormatRank([string]$ver) {
|
||||
if ($ver -match '^(\d+)\.(\d+)$') { return [int]$Matches[1] * 100 + [int]$Matches[2] }
|
||||
return 0
|
||||
}
|
||||
|
||||
# 2.21 (8.5) добавила в шапку пространство палитры — ради <Color> у значений перечисления.
|
||||
# Вставляем НА МЕСТО (после lf, перед style): платформа держит объявления по алфавиту,
|
||||
# дописать в конец нельзя.
|
||||
if ((Get-FormatRank $script:formatVersion) -ge 221) {
|
||||
$script:xmlnsDecl = $script:xmlnsDecl -replace ' xmlns:style=', ' xmlns:pal="http://v8.1c.ru/8.1/data/ui/colors/palette" xmlns:style='
|
||||
}
|
||||
$script:utf8Bom = New-Object System.Text.UTF8Encoding($true)
|
||||
|
||||
$script:addCount = 0
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# subsystem-edit v1.14 — Edit existing 1C subsystem XML
|
||||
# subsystem-edit v1.15 — Edit existing 1C subsystem XML
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
|
||||
import argparse
|
||||
@@ -226,6 +226,23 @@ XMLNS_DECL = (
|
||||
)
|
||||
|
||||
|
||||
def format_rank(ver):
|
||||
""""2.20" → 220, "2.9" → 209. Строковое сравнение неверно ("2.9" > "2.17")."""
|
||||
m = re.match(r'^(\d+)\.(\d+)$', ver or '')
|
||||
return int(m.group(1)) * 100 + int(m.group(2)) if m else 0
|
||||
|
||||
|
||||
def apply_pal_ns(format_version):
|
||||
"""2.21 (8.5) добавила в шапку пространство палитры — ради <Color> у значений перечисления.
|
||||
Вставляем НА МЕСТО (после lf, перед style): платформа держит объявления по алфавиту,
|
||||
дописать в конец нельзя."""
|
||||
global XMLNS_DECL
|
||||
if format_rank(format_version) >= 221:
|
||||
XMLNS_DECL = XMLNS_DECL.replace(
|
||||
' xmlns:style=',
|
||||
' xmlns:pal="http://v8.1c.ru/8.1/data/ui/colors/palette" xmlns:style=')
|
||||
|
||||
|
||||
def write_child_subsystem_stub(child_path, child_name, format_version):
|
||||
child_uuid = new_uuid()
|
||||
lines = []
|
||||
@@ -543,6 +560,7 @@ def main():
|
||||
tree = etree.parse(resolved_path, xml_parser)
|
||||
xml_root = tree.getroot()
|
||||
format_version = xml_root.get("version") or "2.17"
|
||||
apply_pal_ns(format_version)
|
||||
|
||||
add_count = 0
|
||||
remove_count = 0
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# template-add v1.19 — Add template to 1C object
|
||||
# template-add v1.20 — Add template to 1C object
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
@@ -241,6 +241,20 @@ $formatVersion = Detect-FormatVersion (Resolve-Path $SrcDir).Path
|
||||
# Правки шапки (как xmlns:pal в формате 2.21) делаются здесь, в одном месте.
|
||||
$xmlnsDecl = '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"'
|
||||
|
||||
# Версия формата как число для сравнений: "2.20" → 220, "2.9" → 209.
|
||||
# Строковое сравнение здесь неверно ("2.9" > "2.17" лексикографически) — известная ловушка.
|
||||
function Get-FormatRank([string]$ver) {
|
||||
if ($ver -match '^(\d+)\.(\d+)$') { return [int]$Matches[1] * 100 + [int]$Matches[2] }
|
||||
return 0
|
||||
}
|
||||
|
||||
# 2.21 (8.5) добавила в шапку пространство палитры — ради <Color> у значений перечисления.
|
||||
# Вставляем НА МЕСТО (после lf, перед style): платформа держит объявления по алфавиту,
|
||||
# дописать в конец нельзя.
|
||||
if ((Get-FormatRank $formatVersion) -ge 221) {
|
||||
$xmlnsDecl = $xmlnsDecl -replace ' xmlns:style=', ' xmlns:pal="http://v8.1c.ru/8.1/data/ui/colors/palette" xmlns:style='
|
||||
}
|
||||
|
||||
# --- 1. Метаданные макета (Templates/<TemplateName>.xml) ---
|
||||
|
||||
$templateUuid = [guid]::NewGuid().ToString()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# template-add v1.19 — Add template to 1C object
|
||||
# template-add v1.20 — Add template to 1C object
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
|
||||
import argparse
|
||||
@@ -284,6 +284,12 @@ def detect_format_version(d):
|
||||
d = parent
|
||||
return "2.17"
|
||||
|
||||
def format_rank(ver):
|
||||
""""2.20" → 220, "2.9" → 209. Строковое сравнение неверно ("2.9" > "2.17")."""
|
||||
m = re.match(r'^(\d+)\.(\d+)$', ver or '')
|
||||
return int(m.group(1)) * 100 + int(m.group(2)) if m else 0
|
||||
|
||||
|
||||
|
||||
def main():
|
||||
sys.stdout.reconfigure(encoding="utf-8")
|
||||
@@ -331,6 +337,14 @@ def main():
|
||||
' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"'
|
||||
)
|
||||
|
||||
# 2.21 (8.5) добавила в шапку пространство палитры — ради <Color> у значений перечисления.
|
||||
# Вставляем НА МЕСТО (после lf, перед style): платформа держит объявления по алфавиту,
|
||||
# дописать в конец нельзя.
|
||||
if format_rank(format_version) >= 221:
|
||||
xmlns_decl = xmlns_decl.replace(
|
||||
' xmlns:style=',
|
||||
' xmlns:pal="http://v8.1c.ru/8.1/data/ui/colors/palette" xmlns:style=')
|
||||
|
||||
# --- Checks ---
|
||||
|
||||
object_type_folders = [
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# xdto-compile v1.7 — Build a 1C XDTO package from an XML Schema (XSD)
|
||||
# xdto-compile v1.8 — 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')]
|
||||
@@ -838,6 +838,20 @@ $script:formatVersion = Detect-FormatVersion $OutputDir
|
||||
# Правки шапки (как xmlns:pal в формате 2.21) делаются здесь, в одном месте.
|
||||
$script:xmlnsDecl = '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"'
|
||||
|
||||
# Версия формата как число для сравнений: "2.20" → 220, "2.9" → 209.
|
||||
# Строковое сравнение здесь неверно ("2.9" > "2.17" лексикографически) — известная ловушка.
|
||||
function Get-FormatRank([string]$ver) {
|
||||
if ($ver -match '^(\d+)\.(\d+)$') { return [int]$Matches[1] * 100 + [int]$Matches[2] }
|
||||
return 0
|
||||
}
|
||||
|
||||
# 2.21 (8.5) добавила в шапку пространство палитры — ради <Color> у значений перечисления.
|
||||
# Вставляем НА МЕСТО (после lf, перед style): платформа держит объявления по алфавиту,
|
||||
# дописать в конец нельзя.
|
||||
if ((Get-FormatRank $script:formatVersion) -ge 221) {
|
||||
$script:xmlnsDecl = $script:xmlnsDecl -replace ' xmlns:style=', ' xmlns:pal="http://v8.1c.ru/8.1/data/ui/colors/palette" xmlns:style='
|
||||
}
|
||||
|
||||
$pkgRoot = Join-Path $OutputDir "XDTOPackages"
|
||||
$pkgDir = Join-Path $pkgRoot $Name
|
||||
$extDir = Join-Path $pkgDir "Ext"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# xdto-compile v1.7 — Build a 1C XDTO package from an XML Schema (XSD) (Python port)
|
||||
# xdto-compile v1.8 — 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
|
||||
@@ -119,6 +119,12 @@ def detect_format_version(d):
|
||||
d = parent
|
||||
return "2.17"
|
||||
|
||||
def format_rank(ver):
|
||||
""""2.20" → 220, "2.9" → 209. Строковое сравнение неверно ("2.9" > "2.17")."""
|
||||
m = re.match(r'^(\d+)\.(\d+)$', ver or '')
|
||||
return int(m.group(1)) * 100 + int(m.group(2)) if m else 0
|
||||
|
||||
|
||||
|
||||
def assert_edit_allowed(target_path):
|
||||
d = os.path.abspath(target_path)
|
||||
@@ -883,6 +889,14 @@ xmlns_decl = (
|
||||
' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"'
|
||||
)
|
||||
|
||||
# 2.21 (8.5) добавила в шапку пространство палитры — ради <Color> у значений перечисления.
|
||||
# Вставляем НА МЕСТО (после lf, перед style): платформа держит объявления по алфавиту,
|
||||
# дописать в конец нельзя.
|
||||
if format_rank(format_version) >= 221:
|
||||
xmlns_decl = xmlns_decl.replace(
|
||||
' xmlns:style=',
|
||||
' xmlns:pal="http://v8.1c.ru/8.1/data/ui/colors/palette" xmlns:style=')
|
||||
|
||||
pkg_root = os.path.join(args.OutputDir, "XDTOPackages")
|
||||
pkg_dir = os.path.join(pkg_root, name)
|
||||
ext_dir = os.path.join(pkg_dir, "Ext")
|
||||
|
||||
@@ -37,11 +37,14 @@
|
||||
"validatePath": "Template.xml",
|
||||
"expect": {
|
||||
"files": ["Template.xml"],
|
||||
"contains": [
|
||||
"ОбъединятьПоГоризонтали",
|
||||
"ОбъединятьПоВертикали",
|
||||
"Поступление",
|
||||
"Выбытие"
|
||||
]
|
||||
"fileContains": {
|
||||
"file": "Template.xml",
|
||||
"text": [
|
||||
"ОбъединятьПоГоризонтали",
|
||||
"ОбъединятьПоВертикали",
|
||||
"Поступление",
|
||||
"Выбытие"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,6 @@
|
||||
"value": "Auto ;; Поле1 ;; Поле2"
|
||||
},
|
||||
"expect": {
|
||||
"stdout": "WARN.*SelectedItemAuto already exists"
|
||||
"stdoutContains": "[WARN] SelectedItemAuto already exists in variant \"Основной\""
|
||||
}
|
||||
}
|
||||
|
||||
+65
-11
@@ -311,21 +311,18 @@ const UUID_RE = /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi
|
||||
// was about (PS wrote `<a />` plus a trailing newline, python wrote `<a/>` without one),
|
||||
// so port parity was being checked through the mask. Do not bring them back: the byte
|
||||
// canon itself is now asserted per case via `preserves`.
|
||||
function normalizeXmlContent(text, opts = {}) {
|
||||
//
|
||||
// Четвёртый шаг — вырезание объявлений xmlns — снят по той же причине: он прятал
|
||||
// целый класс расхождений (лишнее/недостающее объявление в шапке, как xmlns:pal
|
||||
// формата 2.21) и к моменту снятия был мёртвым — ни один кейс на него не опирался.
|
||||
function normalizeXmlContent(text) {
|
||||
let s = text;
|
||||
// 1. XML declaration: normalize quotes and encoding case
|
||||
s = s.replace(
|
||||
/<\?xml\s+version=['"]1\.0['"]\s+encoding=['"]([^'"]+)['"]\s*\?>/gi,
|
||||
(_, enc) => `<?xml version="1.0" encoding="${enc.toLowerCase()}"?>`
|
||||
);
|
||||
// 2. Strip xmlns declarations (Python etree strips unused ones).
|
||||
// Skipped for Configuration.xml: those declarations are load-bearing (they back
|
||||
// xsi:type values like app:ApplicationUsePurpose in UsePurposes) and dropping them
|
||||
// is exactly the corruption of issue #38 — keeping them lets the test guard against it.
|
||||
if (!opts.keepXmlns) {
|
||||
s = s.replace(/\s+xmlns(?::[\w]+)?="[^"]*"/g, '');
|
||||
}
|
||||
// 3. Collapse whitespace between tags: "> \n\t <" → "><". Kept: the ports indent a
|
||||
// 2. Collapse whitespace between tags: "> \n\t <" → "><". Kept: the ports indent a
|
||||
// few blocks differently, which is formatting rather than the byte canon.
|
||||
s = s.replace(/>\s+</g, '><');
|
||||
return s;
|
||||
@@ -338,8 +335,7 @@ function normalizeContent(text, config, relFile) {
|
||||
s = s.replace(/\r\n/g, '\n');
|
||||
// Normalize XML differences (Python etree serialization quirks)
|
||||
if (config?.runtime === 'python') {
|
||||
const base = relFile ? relFile.split(/[\\/]/).pop() : '';
|
||||
s = normalizeXmlContent(s, { keepXmlns: base === 'Configuration.xml' });
|
||||
s = normalizeXmlContent(s);
|
||||
}
|
||||
|
||||
// Normalize UUIDs
|
||||
@@ -359,6 +355,42 @@ function normalizeContent(text, config, relFile) {
|
||||
return s;
|
||||
}
|
||||
|
||||
// ─── Проверка содержимого файла по СЫРЫМ байтам ────────────────────────────
|
||||
// Снэпшотное сравнение в py-прогоне режет объявления xmlns (normalizeXmlContent),
|
||||
// поэтому наличие/отсутствие конкретного объявления через снэпшот не проверить —
|
||||
// он совпадёт при любом исходе. Эта проверка читает файл как есть.
|
||||
// spec: { file, text } | { file, text: [...] }. Возвращает массив ошибок.
|
||||
function checkFileContains(workDir, spec, expectPresent) {
|
||||
const errs = [];
|
||||
const target = join(workDir, spec.file);
|
||||
if (!existsSync(target)) {
|
||||
errs.push(`${expectPresent ? 'fileContains' : 'fileNotContains'}: file not found: ${spec.file}`);
|
||||
return errs;
|
||||
}
|
||||
const text = readFileSync(target).toString('utf8').replace(/^/, '');
|
||||
const needles = Array.isArray(spec.text) ? spec.text : [spec.text];
|
||||
for (const needle of needles) {
|
||||
const found = text.includes(needle);
|
||||
if (expectPresent && !found) errs.push(`${spec.file} does not contain "${needle}"`);
|
||||
if (!expectPresent && found) errs.push(`${spec.file} unexpectedly contains "${needle}"`);
|
||||
}
|
||||
return errs;
|
||||
}
|
||||
|
||||
// Ключи expect, которые раннер действительно умеет. Неизвестный ключ = кейс,
|
||||
// который молча ничего не проверяет (так уже было с 9 кейсами meta-edit) —
|
||||
// поэтому он ошибка, а не игнор.
|
||||
const KNOWN_EXPECT_KEYS = new Set([
|
||||
'files', 'stdoutContains', 'stdoutNotContains', 'preserves',
|
||||
'fileContains', 'fileNotContains',
|
||||
]);
|
||||
|
||||
function checkExpectKeys(caseData) {
|
||||
if (!caseData.expect) return [];
|
||||
const unknown = Object.keys(caseData.expect).filter(k => !KNOWN_EXPECT_KEYS.has(k));
|
||||
return unknown.map(k => `expect.${k}: раннер такого ключа не знает — кейс ничего не проверяет`);
|
||||
}
|
||||
|
||||
// ─── Byte-style preservation check (round-trip #44/#46/#47, канон #57) ──────
|
||||
// Проверяет СЫРЫЕ байты файла (в обход normalizeContent): BOM / EOL / регистр
|
||||
// encoding / финальный перенос / отсутствие / форма пустого элемента.
|
||||
@@ -709,6 +741,7 @@ async function runCaseAsync(testCase, opts) {
|
||||
|
||||
// Assertions
|
||||
const errors = [];
|
||||
errors.push(...checkExpectKeys(caseData));
|
||||
if (caseData.expectError) {
|
||||
if (exitCode === 0) errors.push('Expected error (non-zero exit) but got exitCode=0');
|
||||
if (typeof caseData.expectError === 'string' && !stderr.includes(caseData.expectError)) {
|
||||
@@ -748,6 +781,16 @@ async function runCaseAsync(testCase, opts) {
|
||||
? caseData.expect.preserves : [caseData.expect.preserves];
|
||||
for (const spec of specs) errors.push(...checkPreserves(workDir, spec));
|
||||
}
|
||||
if (caseData.expect?.fileContains) {
|
||||
const specs = Array.isArray(caseData.expect.fileContains)
|
||||
? caseData.expect.fileContains : [caseData.expect.fileContains];
|
||||
for (const spec of specs) errors.push(...checkFileContains(workDir, spec, true));
|
||||
}
|
||||
if (caseData.expect?.fileNotContains) {
|
||||
const specs = Array.isArray(caseData.expect.fileNotContains)
|
||||
? caseData.expect.fileNotContains : [caseData.expect.fileNotContains];
|
||||
for (const spec of specs) errors.push(...checkFileContains(workDir, spec, false));
|
||||
}
|
||||
if (errors.length === 0 && !caseData.expectError && !workspace.readOnly) {
|
||||
const snapshotConfig = { ...skillConfig.snapshot, runtime: opts.runtime };
|
||||
if (opts.updateSnapshots) {
|
||||
@@ -898,6 +941,7 @@ function runCase(testCase, opts) {
|
||||
|
||||
// 4. Assertions
|
||||
const errors = [];
|
||||
errors.push(...checkExpectKeys(caseData));
|
||||
|
||||
if (caseData.expectError) {
|
||||
// Negative case — expect failure
|
||||
@@ -949,6 +993,16 @@ function runCase(testCase, opts) {
|
||||
? caseData.expect.preserves : [caseData.expect.preserves];
|
||||
for (const spec of specs) errors.push(...checkPreserves(workDir, spec));
|
||||
}
|
||||
if (caseData.expect?.fileContains) {
|
||||
const specs = Array.isArray(caseData.expect.fileContains)
|
||||
? caseData.expect.fileContains : [caseData.expect.fileContains];
|
||||
for (const spec of specs) errors.push(...checkFileContains(workDir, spec, true));
|
||||
}
|
||||
if (caseData.expect?.fileNotContains) {
|
||||
const specs = Array.isArray(caseData.expect.fileNotContains)
|
||||
? caseData.expect.fileNotContains : [caseData.expect.fileNotContains];
|
||||
for (const spec of specs) errors.push(...checkFileContains(workDir, spec, false));
|
||||
}
|
||||
|
||||
// Snapshot comparison (skip for external/read-only workspaces)
|
||||
if (errors.length === 0 && !caseData.expectError && !workspace.readOnly) {
|
||||
|
||||
Reference in New Issue
Block a user