mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-08-13 06:53:21 +03:00
fix(form-validate): команда без Action — предупреждение, а не ошибка
Проверка объявляла ошибкой любую команду формы без <Action>. Корпусный прогон (УТ 8.3.27, БП 8.3.27, ERP 8.3.24 — 21 097 форм) показал 406 таких команд на 275 формах, и все они произведены самой платформой: формат это допускает, конфигурации грузятся. Приём типовых: действие назначается в рантайме, в ПриСозданииНаСервере — `Команда.Действие = "Подключаемый_" + Имя + "Локализация"`. Назначать может и чужой модуль (переопределяемый слой, подключаемые команды), поэтому по одному Form.xml вердикт не вынести — отсюда предупреждение, а не ошибка, и никакого подглядывания в соседний модуль. Корпус после правки: форм с ошибками 283 → 8, новых срабатываний нет. Оставшиеся 8 — четыре других класса, разбираются отдельно. Кейс с фикстурой: команда без Action на кнопке → предупреждение, exit 0.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
# form-validate v1.12 — Validate 1C managed form
|
||||
# form-validate v1.13 — Validate 1C managed form
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
@@ -569,13 +569,18 @@ if (-not $stopped) {
|
||||
$actionErrors = 0
|
||||
$actionChecked = 0
|
||||
|
||||
# Предупреждение, а не ошибка: <Action> может назначаться в рантайме
|
||||
# (`Команда.Действие = "Подключаемый_…"` в ПриСозданииНаСервере) — приём типовых конфигураций
|
||||
# там, где обработчик существует не во всякой сборке. Назначать может и чужой модуль
|
||||
# (переопределяемый слой, подключаемые команды), так что по одному Form.xml не решить.
|
||||
# Корпус УТ/БП/ERP: 406 таких команд на 275 формах, произведённых платформой.
|
||||
foreach ($cmd in $cmdNodes) {
|
||||
if ($stopped) { break }
|
||||
$cmdName = $cmd.GetAttribute("name")
|
||||
$actionNode = $cmd.SelectSingleNode("f:Action", $nsMgr)
|
||||
$actionChecked++
|
||||
if (-not $actionNode -or -not $actionNode.InnerText.Trim()) {
|
||||
Report-Error "Command '$cmdName': missing or empty Action"
|
||||
Report-Warn "Command '$cmdName': no Action — handler must be assigned at runtime, otherwise the command does nothing"
|
||||
$actionErrors++
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# form-validate v1.12 — Validate 1C managed form
|
||||
# form-validate v1.13 — Validate 1C managed form
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
|
||||
import argparse
|
||||
@@ -570,6 +570,11 @@ def main():
|
||||
action_errors = 0
|
||||
action_checked = 0
|
||||
|
||||
# Предупреждение, а не ошибка: <Action> может назначаться в рантайме
|
||||
# (`Команда.Действие = "Подключаемый_…"` в ПриСозданииНаСервере) — приём типовых конфигураций
|
||||
# там, где обработчик существует не во всякой сборке. Назначать может и чужой модуль
|
||||
# (переопределяемый слой, подключаемые команды), так что по одному Form.xml не решить.
|
||||
# Корпус УТ/БП/ERP: 406 таких команд на 275 формах, произведённых платформой.
|
||||
for cmd in cmd_nodes:
|
||||
if stopped:
|
||||
break
|
||||
@@ -577,7 +582,7 @@ def main():
|
||||
action_node = cmd.find(f"{{{F_NS}}}Action")
|
||||
action_checked += 1
|
||||
if action_node is None or not (action_node.text or "").strip():
|
||||
report_error(f"Command '{cmd_name}': missing or empty Action")
|
||||
report_warn(f"Command '{cmd_name}': no Action — handler must be assigned at runtime, otherwise the command does nothing")
|
||||
action_errors += 1
|
||||
|
||||
if action_errors == 0 and action_checked > 0:
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"name": "Команда без Action — предупреждение, а не ошибка (действие назначается в рантайме)",
|
||||
"setup": "fixture:command-without-action",
|
||||
"params": { "formPath": "DataProcessors/БезДействия/Forms/Форма" },
|
||||
"expect": { "stdoutContains": "no Action" }
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Form xmlns="http://v8.1c.ru/8.3/xcf/logform" xmlns:v8="http://v8.1c.ru/8.1/data/core" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.20">
|
||||
<AutoCommandBar name="ФормаКоманднаяПанель" id="-1">
|
||||
<Autofill>true</Autofill>
|
||||
<ChildItems>
|
||||
<Button name="КнопкаЛокализация" id="5">
|
||||
<CommandName>Form.Command.ЛокализованнаяКоманда</CommandName>
|
||||
<ExtendedTooltip name="КнопкаЛокализацияРасширеннаяПодсказка" id="6"/>
|
||||
</Button>
|
||||
</ChildItems>
|
||||
</AutoCommandBar>
|
||||
<ChildItems>
|
||||
<InputField name="Поле" id="2">
|
||||
<DataPath>Объект.Наименование</DataPath>
|
||||
<ContextMenu name="ПолеКонтекстноеМеню" id="3"/>
|
||||
<ExtendedTooltip name="ПолеРасширеннаяПодсказка" id="4"/>
|
||||
</InputField>
|
||||
</ChildItems>
|
||||
<Attributes>
|
||||
<Attribute name="Объект" id="1">
|
||||
<Type>
|
||||
<v8:Type>cfg:DataProcessorObject.БезДействия</v8:Type>
|
||||
</Type>
|
||||
<MainAttribute>true</MainAttribute>
|
||||
<SavedData>true</SavedData>
|
||||
</Attribute>
|
||||
</Attributes>
|
||||
<Commands>
|
||||
<Command name="ЛокализованнаяКоманда" id="1">
|
||||
<Title>
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
<v8:content>Локализованная команда</v8:content>
|
||||
</v8:item>
|
||||
</Title>
|
||||
</Command>
|
||||
</Commands>
|
||||
</Form>
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Form xmlns="http://v8.1c.ru/8.3/xcf/logform" xmlns:v8="http://v8.1c.ru/8.1/data/core" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.20">
|
||||
<AutoCommandBar name="ФормаКоманднаяПанель" id="-1">
|
||||
<Autofill>true</Autofill>
|
||||
<ChildItems>
|
||||
<Button name="КнопкаЛокализация" id="5">
|
||||
<CommandName>Form.Command.ЛокализованнаяКоманда</CommandName>
|
||||
<ExtendedTooltip name="КнопкаЛокализацияРасширеннаяПодсказка" id="6"/>
|
||||
</Button>
|
||||
</ChildItems>
|
||||
</AutoCommandBar>
|
||||
<ChildItems>
|
||||
<InputField name="Поле" id="2">
|
||||
<DataPath>Объект.Наименование</DataPath>
|
||||
<ContextMenu name="ПолеКонтекстноеМеню" id="3"/>
|
||||
<ExtendedTooltip name="ПолеРасширеннаяПодсказка" id="4"/>
|
||||
</InputField>
|
||||
</ChildItems>
|
||||
<Attributes>
|
||||
<Attribute name="Объект" id="1">
|
||||
<Type>
|
||||
<v8:Type>cfg:DataProcessorObject.БезДействия</v8:Type>
|
||||
</Type>
|
||||
<MainAttribute>true</MainAttribute>
|
||||
<SavedData>true</SavedData>
|
||||
</Attribute>
|
||||
</Attributes>
|
||||
<Commands>
|
||||
<Command name="ЛокализованнаяКоманда" id="1">
|
||||
<Title>
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
<v8:content>Локализованная команда</v8:content>
|
||||
</v8:item>
|
||||
</Title>
|
||||
</Command>
|
||||
</Commands>
|
||||
</Form>
|
||||
Reference in New Issue
Block a user