Cover full 1C metadata object catalog
CI / python (push) Has been cancelled
CI / rust (push) Has been cancelled

This commit is contained in:
2026-05-21 18:05:28 +03:00
parent 9dc35bae20
commit 3c7b1825c4
9 changed files with 448 additions and 3 deletions
@@ -78,6 +78,37 @@ _METADATA_OWNER_KINDS = {
NodeKind.SCHEDULED_JOB,
NodeKind.BUSINESS_PROCESS,
NodeKind.TASK,
NodeKind.SUBSYSTEM,
NodeKind.SEQUENCE,
NodeKind.DOCUMENT_NUMERATOR,
NodeKind.EVENT_SUBSCRIPTION,
NodeKind.SESSION_PARAMETER,
NodeKind.COMMON_ATTRIBUTE,
NodeKind.FILTER_CRITERION,
NodeKind.FUNCTIONAL_OPTION,
NodeKind.FUNCTIONAL_OPTION_PARAMETER,
NodeKind.DEFINED_TYPE,
NodeKind.SETTINGS_STORAGE,
NodeKind.COMMON_COMMAND,
NodeKind.COMMAND_GROUP,
NodeKind.COMMON_FORM,
NodeKind.COMMON_LAYOUT,
NodeKind.COMMON_PICTURE,
NodeKind.WEB_SERVICE,
NodeKind.HTTP_SERVICE,
NodeKind.WS_REFERENCE,
NodeKind.WEBSOCKET_CLIENT,
NodeKind.INTEGRATION_SERVICE,
NodeKind.BOT,
NodeKind.INTERFACE,
NodeKind.FULL_TEXT_SEARCH_DICTIONARY,
NodeKind.PALETTE_COLOR,
NodeKind.STYLE_ITEM,
NodeKind.STYLE,
NodeKind.LANGUAGE,
NodeKind.XDTO_PACKAGE,
NodeKind.EXTENSION,
NodeKind.ROLE,
}
_PATH_METADATA_ALIASES = {
"catalogs": ("Справочник", NodeKind.CATALOG),
@@ -120,6 +151,69 @@ _PATH_METADATA_ALIASES = {
"бизнеспроцессы": ("БизнесПроцесс", NodeKind.BUSINESS_PROCESS),
"tasks": ("Задача", NodeKind.TASK),
"задачи": ("Задача", NodeKind.TASK),
"subsystems": ("Подсистема", NodeKind.SUBSYSTEM),
"подсистемы": ("Подсистема", NodeKind.SUBSYSTEM),
"roles": ("Роль", NodeKind.ROLE),
"роли": ("Роль", NodeKind.ROLE),
"sequences": ("Последовательность", NodeKind.SEQUENCE),
"последовательности": ("Последовательность", NodeKind.SEQUENCE),
"documentnumerators": ("НумераторДокументов", NodeKind.DOCUMENT_NUMERATOR),
"нумераторыдокументов": ("НумераторДокументов", NodeKind.DOCUMENT_NUMERATOR),
"eventsubscriptions": ("ПодпискаНаСобытие", NodeKind.EVENT_SUBSCRIPTION),
"подпискинасобытия": ("ПодпискаНаСобытие", NodeKind.EVENT_SUBSCRIPTION),
"sessionparameters": ("ПараметрСеанса", NodeKind.SESSION_PARAMETER),
"параметрысеанса": ("ПараметрСеанса", NodeKind.SESSION_PARAMETER),
"commonattributes": ("ОбщийРеквизит", NodeKind.COMMON_ATTRIBUTE),
"общиереквизиты": ("ОбщийРеквизит", NodeKind.COMMON_ATTRIBUTE),
"filtercriteria": ("КритерийОтбора", NodeKind.FILTER_CRITERION),
"критерииотбора": ("КритерийОтбора", NodeKind.FILTER_CRITERION),
"functionaloptions": ("ФункциональнаяОпция", NodeKind.FUNCTIONAL_OPTION),
"функциональныеопции": ("ФункциональнаяОпция", NodeKind.FUNCTIONAL_OPTION),
"functionaloptionsparameters": ("ПараметрФункциональнойОпции", NodeKind.FUNCTIONAL_OPTION_PARAMETER),
"параметрыфункциональныхопций": ("ПараметрФункциональнойОпции", NodeKind.FUNCTIONAL_OPTION_PARAMETER),
"definedtypes": ("ОпределяемыйТип", NodeKind.DEFINED_TYPE),
"определяемыетипы": ("ОпределяемыйТип", NodeKind.DEFINED_TYPE),
"settingsstorages": ("ХранилищеНастроек", NodeKind.SETTINGS_STORAGE),
"хранилищанастроек": ("ХранилищеНастроек", NodeKind.SETTINGS_STORAGE),
"commoncommands": ("ОбщаяКоманда", NodeKind.COMMON_COMMAND),
"общиекоманды": ("ОбщаяКоманда", NodeKind.COMMON_COMMAND),
"commandgroups": ("ГруппаКоманд", NodeKind.COMMAND_GROUP),
"группыкоманд": ("ГруппаКоманд", NodeKind.COMMAND_GROUP),
"commonforms": ("ОбщаяФорма", NodeKind.COMMON_FORM),
"общиеформы": ("ОбщаяФорма", NodeKind.COMMON_FORM),
"commontemplates": ("ОбщийМакет", NodeKind.COMMON_LAYOUT),
"commonlayouts": ("ОбщийМакет", NodeKind.COMMON_LAYOUT),
"общиемакеты": ("ОбщийМакет", NodeKind.COMMON_LAYOUT),
"commonpictures": ("ОбщаяКартинка", NodeKind.COMMON_PICTURE),
"общиекартинки": ("ОбщаяКартинка", NodeKind.COMMON_PICTURE),
"xdtopackages": ("XDTO", NodeKind.XDTO_PACKAGE),
"xdtoпакеты": ("XDTO", NodeKind.XDTO_PACKAGE),
"webservices": ("WebСервис", NodeKind.WEB_SERVICE),
"webсервисы": ("WebСервис", NodeKind.WEB_SERVICE),
"httpservices": ("HTTPСервис", NodeKind.HTTP_SERVICE),
"httpсервисы": ("HTTPСервис", NodeKind.HTTP_SERVICE),
"wsreferences": ("WSСсылка", NodeKind.WS_REFERENCE),
"wsссылки": ("WSСсылка", NodeKind.WS_REFERENCE),
"websocketclients": ("WebSocketКлиент", NodeKind.WEBSOCKET_CLIENT),
"websocketклиенты": ("WebSocketКлиент", NodeKind.WEBSOCKET_CLIENT),
"integrationservices": ("СервисИнтеграции", NodeKind.INTEGRATION_SERVICE),
"сервисыинтеграции": ("СервисИнтеграции", NodeKind.INTEGRATION_SERVICE),
"bots": ("Бот", NodeKind.BOT),
"боты": ("Бот", NodeKind.BOT),
"interfaces": ("Интерфейс", NodeKind.INTERFACE),
"интерфейсы": ("Интерфейс", NodeKind.INTERFACE),
"fulltextsearchdictionaries": ("СловарьПолнотекстовогоПоиска", NodeKind.FULL_TEXT_SEARCH_DICTIONARY),
"словариполнотекстовогопоиска": ("СловарьПолнотекстовогоПоиска", NodeKind.FULL_TEXT_SEARCH_DICTIONARY),
"palettecolors": ("ЦветПалитры", NodeKind.PALETTE_COLOR),
"цветапалитры": ("ЦветПалитры", NodeKind.PALETTE_COLOR),
"styleitems": ("ЭлементСтиля", NodeKind.STYLE_ITEM),
"элементыстиля": ("ЭлементСтиля", NodeKind.STYLE_ITEM),
"styles": ("Стиль", NodeKind.STYLE),
"стили": ("Стиль", NodeKind.STYLE),
"languages": ("Язык", NodeKind.LANGUAGE),
"языки": ("Язык", NodeKind.LANGUAGE),
"extensions": ("Расширение", NodeKind.EXTENSION),
"расширения": ("Расширение", NodeKind.EXTENSION),
}
@@ -348,6 +442,36 @@ def index_project(path: str | Path, *, project_id: str | None = None, structure_
NodeKind.SCHEDULED_JOB,
NodeKind.BUSINESS_PROCESS,
NodeKind.TASK,
NodeKind.SUBSYSTEM,
NodeKind.SEQUENCE,
NodeKind.DOCUMENT_NUMERATOR,
NodeKind.EVENT_SUBSCRIPTION,
NodeKind.SESSION_PARAMETER,
NodeKind.COMMON_ATTRIBUTE,
NodeKind.FILTER_CRITERION,
NodeKind.FUNCTIONAL_OPTION,
NodeKind.FUNCTIONAL_OPTION_PARAMETER,
NodeKind.DEFINED_TYPE,
NodeKind.SETTINGS_STORAGE,
NodeKind.COMMON_COMMAND,
NodeKind.COMMAND_GROUP,
NodeKind.COMMON_FORM,
NodeKind.COMMON_LAYOUT,
NodeKind.COMMON_PICTURE,
NodeKind.WEB_SERVICE,
NodeKind.HTTP_SERVICE,
NodeKind.WS_REFERENCE,
NodeKind.WEBSOCKET_CLIENT,
NodeKind.INTEGRATION_SERVICE,
NodeKind.BOT,
NodeKind.INTERFACE,
NodeKind.FULL_TEXT_SEARCH_DICTIONARY,
NodeKind.PALETTE_COLOR,
NodeKind.STYLE_ITEM,
NodeKind.STYLE,
NodeKind.LANGUAGE,
NodeKind.XDTO_PACKAGE,
NodeKind.EXTENSION,
NodeKind.ROLE,
NodeKind.FORM,
NodeKind.TABULAR_SECTION,
@@ -958,7 +1082,33 @@ def _xml_node_kind(object_kind: str) -> NodeKind | None:
"BUSINESS_PROCESS": NodeKind.BUSINESS_PROCESS,
"TASK": NodeKind.TASK,
"SUBSYSTEM": NodeKind.SUBSYSTEM,
"SEQUENCE": NodeKind.SEQUENCE,
"DOCUMENT_NUMERATOR": NodeKind.DOCUMENT_NUMERATOR,
"EVENT_SUBSCRIPTION": NodeKind.EVENT_SUBSCRIPTION,
"SESSION_PARAMETER": NodeKind.SESSION_PARAMETER,
"COMMON_ATTRIBUTE": NodeKind.COMMON_ATTRIBUTE,
"FILTER_CRITERION": NodeKind.FILTER_CRITERION,
"FUNCTIONAL_OPTION": NodeKind.FUNCTIONAL_OPTION,
"FUNCTIONAL_OPTION_PARAMETER": NodeKind.FUNCTIONAL_OPTION_PARAMETER,
"DEFINED_TYPE": NodeKind.DEFINED_TYPE,
"SETTINGS_STORAGE": NodeKind.SETTINGS_STORAGE,
"COMMON_COMMAND": NodeKind.COMMON_COMMAND,
"COMMAND_GROUP": NodeKind.COMMAND_GROUP,
"COMMON_FORM": NodeKind.COMMON_FORM,
"COMMON_LAYOUT": NodeKind.COMMON_LAYOUT,
"COMMON_PICTURE": NodeKind.COMMON_PICTURE,
"WEB_SERVICE": NodeKind.WEB_SERVICE,
"HTTP_SERVICE": NodeKind.HTTP_SERVICE,
"WS_REFERENCE": NodeKind.WS_REFERENCE,
"WEBSOCKET_CLIENT": NodeKind.WEBSOCKET_CLIENT,
"INTEGRATION_SERVICE": NodeKind.INTEGRATION_SERVICE,
"BOT": NodeKind.BOT,
"INTERFACE": NodeKind.INTERFACE,
"FULL_TEXT_SEARCH_DICTIONARY": NodeKind.FULL_TEXT_SEARCH_DICTIONARY,
"PALETTE_COLOR": NodeKind.PALETTE_COLOR,
"STYLE_ITEM": NodeKind.STYLE_ITEM,
"STYLE": NodeKind.STYLE,
"LANGUAGE": NodeKind.LANGUAGE,
"XDTO_PACKAGE": NodeKind.XDTO_PACKAGE,
"EXTENSION": NodeKind.EXTENSION,
"LAYOUT": NodeKind.LAYOUT,
@@ -70,6 +70,43 @@ def test_index_project_extracts_1c_metadata_objects(tmp_path: Path):
assert any(edge.kind == EdgeKind.HAS_COMMAND for edge in snapshot.edges)
def test_index_project_keeps_extended_1c_metadata_objects(tmp_path: Path):
xml = tmp_path / "metadata.xml"
xml.write_text(
"""
<Configuration>
<Subsystem name="Продажи" qualifiedName="Подсистема.Продажи" />
<Role name="Менеджер" qualifiedName="Роль.Менеджер" />
<Sequence name="ПроведениеДокументов" qualifiedName="Последовательность.ПроведениеДокументов" />
<DocumentNumerator name="ОбщийНумератор" qualifiedName="НумераторДокументов.ОбщийНумератор" />
<CommonForm name="ФормаПодбора" qualifiedName="ОбщаяФорма.ФормаПодбора" />
<FunctionalOption name="ДоступностьСкидок" qualifiedName="ФункциональнаяОпция.ДоступностьСкидок" />
<WebService name="Обмен" qualifiedName="WebСервис.Обмен" />
<WSReference name="ВнешнийСервис" qualifiedName="WSСсылка.ВнешнийСервис" />
<WebSocketClient name="Чат" qualifiedName="WebSocketКлиент.Чат" />
<IntegrationService name="Интеграция" qualifiedName="СервисИнтеграции.Интеграция" />
</Configuration>
""",
encoding="utf-8",
)
snapshot = index_project(tmp_path, project_id="extended-metadata")
by_kind = {node.kind for node in snapshot.nodes}
assert {
NodeKind.SUBSYSTEM,
NodeKind.ROLE,
NodeKind.SEQUENCE,
NodeKind.DOCUMENT_NUMERATOR,
NodeKind.COMMON_FORM,
NodeKind.FUNCTIONAL_OPTION,
NodeKind.WEB_SERVICE,
NodeKind.WS_REFERENCE,
NodeKind.WEBSOCKET_CLIENT,
NodeKind.INTEGRATION_SERVICE,
}.issubset(by_kind)
def test_index_project_remaps_edges_from_duplicate_metadata_nodes(tmp_path: Path):
first = tmp_path / "first.xml"
first.write_text(