feat(cf-edit): виды с осмысленным порядком не сортируются автоматически

Правило «Subsystem не упорядочиваем» распространено на четыре вида и вынесено в
семью is_order_sensitive_type / Test-OrderSensitiveType: раньше литерал "Subsystem"
был размазан по четырём точкам — регистрация в Register-InChildObjects,
add-childObject, заимствование в расширение и сортировка.

CommonAttribute — исключение самого стандарта #std467: у общих реквизитов-разделителей
порядок в дереве задаёт порядок установки параметров сеанса
(https://github.com/1C-Company/v8-code-style/issues/78). Единственный из четырёх, где
сортировка ломает поведение, а не только диф.

CommandGroup и Language добавлены по замерам. В ACC 15 живых групп команд из 39 не
перечислены ни в одном GroupsOrder — как и подсистемы, они падают на порядок дерева.
Порядок языков задаёт порядок <v8:item> в мультиязычных строках по всей выгрузке.

Прежний вывод «сортировать их безопасно» опирался на стендовый прогон, где не было
ни подсистем (а значит и CommandInterface.xml), ни второго языка у объектов: ломаться
там было нечему, и отсутствие изменений ничего не доказывало.

PaletteColor сортируется — это переменные цветов.

Второе послабление стандарта (объекты «Удалить*» можно держать в конце ветки) не
реализуем: типовые им не пользуются — в ACC 360 таких объектов из 373 стоят по
алфавиту, а сортировка стандарту не противоречит. Оговорено в гайде.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QoAJmoNbgWKobA7JGgN5S3
This commit is contained in:
Nick Shirokov
2026-08-29 20:21:55 +03:00
co-authored by Claude Opus 5
parent ecde0d1c41
commit 1046e6018c
49 changed files with 2076 additions and 35 deletions
@@ -5268,6 +5268,19 @@ function Get-NewObjectPosition([string]$cfgDir) {
} catch { return "end" }
}
# Виды, у которых порядок в дереве несёт смысл: автоматически их не упорядочиваем.
# CommonAttribute — исключение самого стандарта (#std467): у общих реквизитов-разделителей
# порядок в дереве задаёт порядок установки параметров сеанса. Subsystem и CommandGroup:
# пока они не перечислены в <SubsystemsOrder> / <GroupsOrder> файла Ext/CommandInterface.xml,
# порядок дерева задаёт порядок в интерфейсе, а платформа эти списки сама не заводит
# (в выгрузке ACC вне GroupsOrder 15 живых групп из 39). Language: порядок языков задаёт
# порядок <v8:item> в мультиязычных строках по всей выгрузке.
# Явно названный вид сортируется в любом случае.
# Реестр семьи: tests/skills/check-inline-drift.mjs.
function Test-OrderSensitiveType([string]$typeName) {
return @("CommonAttribute", "Subsystem", "CommandGroup", "Language") -ccontains $typeName
}
# Порядок имён объектов метаданных, как в дереве Конфигуратора.
# Ключ — пары «ранг+символ»: регистр не учитывается, подчёркивание раньше цифр, цифры раньше
# букв, буквы по кодам (латиница раньше кириллицы), ё на месте е. Культурные таблицы не
@@ -5336,10 +5349,9 @@ function Register-InChildObjects([string]$ParentXmlPath, [string]$ParentTag, [st
return "added"
}
# byName: перед первым объектом того же вида, чьё имя больше нового. Subsystem — никогда:
# порядок подсистем в дереве задаёт порядок разделов в панели, пока их не перечислили в
# <SubsystemsOrder> файла Ext/CommandInterface.xml (платформа этот список сама не заводит).
if ($ChildTag -cne "Subsystem" -and (Get-NewObjectPosition ([System.IO.Path]::GetDirectoryName([System.IO.Path]::GetFullPath($ParentXmlPath)))) -eq "byName") {
# byName: перед первым объектом того же вида, чьё имя больше нового.
# Виды с осмысленным порядком в дереве пропускаем — см. Test-OrderSensitiveType.
if (-not (Test-OrderSensitiveType $ChildTag) -and (Get-NewObjectPosition ([System.IO.Path]::GetDirectoryName([System.IO.Path]::GetFullPath($ParentXmlPath)))) -eq "byName") {
$lineRx = [regex]"(?m)^([ \t]*)<$ChildTag>([^<]*)</$ChildTag>"
$m = $lineRx.Match($configContent, $block.Index, $block.Length)
while ($m.Success) {
@@ -5241,6 +5241,21 @@ def get_new_object_position(cfg_dir):
return "end"
def is_order_sensitive_type(type_name):
"""Виды, у которых порядок в дереве несёт смысл: автоматически их не упорядочиваем.
CommonAttribute исключение самого стандарта (#std467): у общих реквизитов-разделителей
порядок в дереве задаёт порядок установки параметров сеанса. Subsystem и CommandGroup:
пока они не перечислены в <SubsystemsOrder> / <GroupsOrder> файла Ext/CommandInterface.xml,
порядок дерева задаёт порядок в интерфейсе, а платформа эти списки сама не заводит
(в выгрузке ACC вне GroupsOrder 15 живых групп из 39). Language: порядок языков задаёт
порядок <v8:item> в мультиязычных строках по всей выгрузке.
Явно названный вид сортируется в любом случае.
Реестр семьи: tests/skills/check-inline-drift.mjs.
"""
return type_name in ("CommonAttribute", "Subsystem", "CommandGroup", "Language")
def compare_metadata_names(a, b):
"""Порядок имён объектов метаданных, как в дереве Конфигуратора.
@@ -5324,10 +5339,9 @@ def register_in_childobjects(parent_xml_path, parent_tag, child_tag, child_name)
write_utf8_bom(parent_xml_path, new_content)
return 'added'
# byName: перед первым объектом того же вида, чьё имя больше нового. Subsystem — никогда:
# порядок подсистем в дереве задаёт порядок разделов в панели, пока их не перечислили в
# <SubsystemsOrder> файла Ext/CommandInterface.xml (платформа этот список сама не заводит).
if (child_tag != 'Subsystem'
# byName: перед первым объектом того же вида, чьё имя больше нового.
# Виды с осмысленным порядком в дереве пропускаем — см. is_order_sensitive_type.
if (not is_order_sensitive_type(child_tag)
and get_new_object_position(os.path.dirname(os.path.abspath(parent_xml_path))) == 'byName'):
line_rx = re.compile(rf'(?m)^([ \t]*)<{child_tag}>([^<]*)</{child_tag}>')
for m in line_rx.finditer(config_content, block.start(), block.end()):