Files
index/index1c/config.py
T
mihailkudravcev 404659a545 Release 0.3.2: YAML config, default_baseconfs, autodiscover.
Конфиг утилиты переведён на YAML; default_baseconfs для reindex без -b;
автопоиск config.local.yml/.yaml/.json; обобщённая документация.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-17 11:09:51 +03:00

253 lines
8.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""Каталоги конфигураций проекта и типы объектов метаданных 1С."""
from __future__ import annotations
from dataclasses import dataclass
from pathlib import Path
# Алиасы имён конфигураций 1С для CLI (--baseconf / -b), задаются через --config
# (поле baseconf_aliases в YAML). См. config.example.yml.
_RUNTIME_ALIASES: dict[str, str] = {}
_RUNTIME_DEFAULT_BASECONFS: list[str] = []
# Папка EDT → канонический тип (английский идентификатор выгрузки).
OBJECT_TYPE_FOLDERS: dict[str, str] = {
"AccumulationRegisters": "AccumulationRegister",
"BusinessProcesses": "BusinessProcess",
"Catalogs": "Catalog",
"ChartsOfAccounts": "ChartOfAccounts",
"ChartsOfCalculationTypes": "ChartOfCalculationTypes",
"ChartsOfCharacteristicTypes": "ChartOfCharacteristicTypes",
"CommandGroups": "CommandGroup",
"CommonAttributes": "CommonAttribute",
"CommonCommands": "CommonCommand",
"CommonForms": "CommonForm",
"CommonModules": "CommonModule",
"CommonPictures": "CommonPicture",
"CommonTemplates": "CommonTemplate",
"Constants": "Constant",
"DataProcessors": "DataProcessor",
"DefinedTypes": "DefinedType",
"DocumentJournals": "DocumentJournal",
"DocumentNumerators": "DocumentNumerator",
"Documents": "Document",
"Enums": "Enum",
"EventSubscriptions": "EventSubscription",
"ExchangePlans": "ExchangePlan",
"FilterCriteria": "FilterCriterion",
"FunctionalOptions": "FunctionalOption",
"FunctionalOptionsParameters": "FunctionalOptionsParameter",
"HTTPServices": "HTTPService",
"InformationRegisters": "InformationRegister",
"IntegrationServices": "IntegrationService",
"Reports": "Report",
"Roles": "Role",
"ScheduledJobs": "ScheduledJob",
"SessionParameters": "SessionParameter",
"SettingsStorages": "SettingsStorage",
"StyleItems": "StyleItem",
"Subsystems": "Subsystem",
"Tasks": "Task",
"WebServices": "WebService",
"WSReferences": "WSReference",
"XDTOPackages": "XDTOPackage",
"Bots": "Bot",
"ExternalDataSources": "ExternalDataSource",
"Languages": "Language",
}
# Алиасы типов для --types (русский / короткий / мн.ч.).
TYPE_ALIASES: dict[str, str] = {
"catalog": "Catalog",
"catalogs": "Catalog",
"справочник": "Catalog",
"справочники": "Catalog",
"document": "Document",
"documents": "Document",
"документ": "Document",
"документы": "Document",
"informationregister": "InformationRegister",
"informationregisters": "InformationRegister",
"регистрсведений": "InformationRegister",
"регистрысведений": "InformationRegister",
"рс": "InformationRegister",
"accumulationregister": "AccumulationRegister",
"accumulationregisters": "AccumulationRegister",
"регистрнакопления": "AccumulationRegister",
"регистрынакопления": "AccumulationRegister",
"рн": "AccumulationRegister",
"constant": "Constant",
"constants": "Constant",
"константа": "Constant",
"константы": "Constant",
"enum": "Enum",
"enums": "Enum",
"перечисление": "Enum",
"перечисления": "Enum",
"commonmodule": "CommonModule",
"commonmodules": "CommonModule",
"общиймодуль": "CommonModule",
"общиемодули": "CommonModule",
"dataprocessor": "DataProcessor",
"dataprocessors": "DataProcessor",
"обработка": "DataProcessor",
"обработки": "DataProcessor",
"report": "Report",
"reports": "Report",
"отчет": "Report",
"отчеты": "Report",
"exchangeplan": "ExchangePlan",
"exchangeplans": "ExchangePlan",
"планыобмена": "ExchangePlan",
"definedtype": "DefinedType",
"definedtypes": "DefinedType",
"определяемыетипы": "DefinedType",
"chartofcharacteristictypes": "ChartOfCharacteristicTypes",
"пвх": "ChartOfCharacteristicTypes",
"role": "Role",
"roles": "Role",
"роль": "Role",
"роли": "Role",
"subsystem": "Subsystem",
"subsystems": "Subsystem",
"подсистема": "Subsystem",
"подсистемы": "Subsystem",
"httpservice": "HTTPService",
"httpservices": "HTTPService",
"documentjournal": "DocumentJournal",
"documentjournals": "DocumentJournal",
"журналыдокументов": "DocumentJournal",
"task": "Task",
"tasks": "Task",
"задача": "Task",
"задачи": "Task",
"businessprocess": "BusinessProcess",
"businessprocesses": "BusinessProcess",
"бизнеспроцесс": "BusinessProcess",
"бизнеспроцессы": "BusinessProcess",
"модуль": "CommonModule",
"модули": "CommonModule",
"bsl": "CommonModule",
}
# Типы с разбором реквизитов / измерений / ссылок.
FIELD_RICH_TYPES: frozenset[str] = frozenset(
{
"Catalog",
"Document",
"InformationRegister",
"AccumulationRegister",
"ChartOfCharacteristicTypes",
"ChartOfAccounts",
"ChartOfCalculationTypes",
"ExchangePlan",
"BusinessProcess",
"Task",
"DocumentJournal",
"Constant",
"DefinedType",
"CommonAttribute",
"Enum",
}
)
# Типы, которые по умолчанию пропускаем (шум / картинки).
DEFAULT_SKIP_TYPES: frozenset[str] = frozenset(
{
"CommonPicture",
"StyleItem",
"XDTOPackage",
"CommonTemplate",
"Language",
"Bot",
}
)
FOLDER_BY_TYPE: dict[str, str] = {v: k for k, v in OBJECT_TYPE_FOLDERS.items()}
@dataclass(frozen=True)
class ConfigPaths:
name: str
root: Path
src: Path
def project_root_from_here() -> Path:
"""Корень проекта: каталог с index_1c.py и VERSION."""
here = Path(__file__).resolve().parent
for candidate in (here.parent, here.parent.parent, here.parent.parent.parent):
if (candidate / "index_1c.py").is_file() and (candidate / "VERSION").is_file():
return candidate
return here.parent
def set_config_aliases(aliases: dict[str, str] | None) -> None:
"""Задать алиасы baseconf из файла --config (baseconf_aliases)."""
global _RUNTIME_ALIASES
_RUNTIME_ALIASES = {str(k): str(v) for k, v in (aliases or {}).items()}
def get_config_aliases() -> dict[str, str]:
return dict(_RUNTIME_ALIASES)
def set_default_baseconfs(names: list[str] | None) -> None:
"""Задать default_baseconfs из файла --config (YAML)."""
global _RUNTIME_DEFAULT_BASECONFS
_RUNTIME_DEFAULT_BASECONFS = [str(x) for x in (names or []) if str(x).strip()]
def get_default_baseconfs() -> list[str]:
"""Список baseconf по умолчанию для reindex без -b."""
return list(_RUNTIME_DEFAULT_BASECONFS)
def resolve_config_name(name: str) -> str:
key = name.strip()
aliases = get_config_aliases()
return aliases.get(key, aliases.get(key.lower(), key))
def list_config_dirs(project_root: Path) -> list[str]:
"""Все каталоги с выгрузкой 1С (<name>/src/) в корне проекта."""
if not project_root.is_dir():
return []
found: list[str] = []
for child in sorted(project_root.iterdir()):
if not child.is_dir() or child.name.startswith("."):
continue
if (child / "src").is_dir():
found.append(child.name)
return found
def resolve_object_type(name: str) -> str:
raw = name.strip()
if raw in FOLDER_BY_TYPE:
return raw
if raw in OBJECT_TYPE_FOLDERS:
return OBJECT_TYPE_FOLDERS[raw]
compact = raw.replace(" ", "").replace("_", "").replace("-", "").casefold()
if compact in TYPE_ALIASES:
return TYPE_ALIASES[compact]
for folder, otype in OBJECT_TYPE_FOLDERS.items():
if folder.casefold() == raw.casefold() or otype.casefold() == raw.casefold():
return otype
raise ValueError(f"Неизвестный тип объекта метаданных: {name!r}")
def discover_configs(project_root: Path, names: list[str] | None = None) -> list[ConfigPaths]:
wanted = [resolve_config_name(n) for n in names] if names else list_config_dirs(project_root)
found: list[ConfigPaths] = []
for name in wanted:
root = project_root / name
src = root / "src"
if src.is_dir():
found.append(ConfigPaths(name=name, root=root, src=src))
return found
def cache_dir(project_root: Path) -> Path:
return project_root / "cache" / "1c_meta"