Release 0.3.4 with external processing indexing.
Add virtual baseconf support for external data processors so reindex can discover and index them alongside regular src-based configurations, and update docs to use generic examples without workspace-specific names.
This commit is contained in:
@@ -5,6 +5,22 @@
|
|||||||
Формат: [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
Формат: [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
||||||
Версионирование: [Semantic Versioning](https://semver.org/lang/ru/).
|
Версионирование: [Semantic Versioning](https://semver.org/lang/ru/).
|
||||||
|
|
||||||
|
## [0.3.4] - 2026-07-21
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Поддержка внешних обработок как virtual `--baseconf`: можно указать папку (например `my-transfer.ext`), и `reindex` автоматически развернёт её в `my-transfer.ext.<ИмяОбработки>` для каждой найденной пары `<Имя>.xml + <Имя>/`.
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Проверка `--baseconf` и автоскан `list/reindex` теперь учитывают не только `<name>/src/`, но и внешние обработки.
|
||||||
|
- Индексация metadata/modules для virtual external baseconf:
|
||||||
|
- metadata: `<root>/<ExternalDataProcessor>.xml`,
|
||||||
|
- модули: `*.bsl` только внутри `<root>/<ExternalDataProcessor>/`.
|
||||||
|
- Определение owner для модулей внешней обработки:
|
||||||
|
- `ExternalDataProcessor.<ИмяОбработки>` для `Ext/ObjectModule.bsl`,
|
||||||
|
- `ExternalDataProcessor.<ИмяОбработки>.Form.<ИмяФормы>` для модулей форм.
|
||||||
|
|
||||||
## [0.3.3] - 2026-07-17
|
## [0.3.3] - 2026-07-17
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Индекс метаданных и модулей конфигураций 1С
|
# Индекс метаданных и модулей конфигураций 1С
|
||||||
|
|
||||||
**Версия:** см. [`VERSION`](VERSION) (текущая: **0.3.3**) · [CHANGELOG](CHANGELOG.md)
|
**Версия:** см. [`VERSION`](VERSION) (текущая: **0.3.4**) · [CHANGELOG](CHANGELOG.md)
|
||||||
**Автор:** Michael BAG · [mk@p7net.ru](mailto:mk@p7net.ru)
|
**Автор:** Michael BAG · [mk@p7net.ru](mailto:mk@p7net.ru)
|
||||||
**Лицензия:** [GNU GPL v3](LICENSE) · [русский перевод (справочно)](LICENSE.ru)
|
**Лицензия:** [GNU GPL v3](LICENSE) · [русский перевод (справочно)](LICENSE.ru)
|
||||||
|
|
||||||
@@ -42,7 +42,7 @@ python query_1c.py --version
|
|||||||
|----------|----------|------------|
|
|----------|----------|------------|
|
||||||
| `--config` | `-c` | Файл **настроек утилиты** (YAML). **Не** конфигурация 1С. См. [`config.example.yml`](config.example.yml). |
|
| `--config` | `-c` | Файл **настроек утилиты** (YAML). **Не** конфигурация 1С. См. [`config.example.yml`](config.example.yml). |
|
||||||
| `--root` | `-r` | Корень проекта с выгрузками 1С (если запуск не из дерева проекта). |
|
| `--root` | `-r` | Корень проекта с выгрузками 1С (если запуск не из дерева проекта). |
|
||||||
| `--baseconf` | `-b` | Выгрузка конфигурации 1С: папка `<name>/src/` в репозитории. Можно несколько раз. |
|
| `--baseconf` | `-b` | Источник индексации: `<name>/src/` или virtual внешняя обработка `<dir>.<ИмяОбработки>`. Можно несколько раз. |
|
||||||
| `--version` | | Версия утилиты. |
|
| `--version` | | Версия утилиты. |
|
||||||
|
|
||||||
Приоритет корня проекта: `--root` > `project_root` в `--config` > авто (каталог с `index_1c.py` и `VERSION`).
|
Приоритет корня проекта: `--root` > `project_root` в `--config` > авто (каталог с `index_1c.py` и `VERSION`).
|
||||||
@@ -63,7 +63,7 @@ baseconf_aliases:
|
|||||||
После этого `-b main` эквивалентно `-b my-config`.
|
После этого `-b main` эквивалентно `-b my-config`.
|
||||||
|
|
||||||
Если в YAML задан блок `default_baseconfs`, то `reindex` без `-b` использует этот список.
|
Если в YAML задан блок `default_baseconfs`, то `reindex` без `-b` использует этот список.
|
||||||
Если блока нет — `reindex` без `-b` индексирует **все** каталоги с `src/` в корне проекта.
|
Если блока нет — `reindex` без `-b` индексирует **все** каталоги с `src/` и найденные внешние обработки.
|
||||||
`query_1c.py` без `-b` ищет по **всем** конфигурациям в индексе.
|
`query_1c.py` без `-b` ищет по **всем** конфигурациям в индексе.
|
||||||
|
|
||||||
Список выгрузок: `python index_1c.py list`
|
Список выгрузок: `python index_1c.py list`
|
||||||
@@ -78,7 +78,7 @@ baseconf_aliases:
|
|||||||
|---------|----------|
|
|---------|----------|
|
||||||
| `reindex` | обновить индекс |
|
| `reindex` | обновить индекс |
|
||||||
| `status` | размер БД, meta, список проиндексированных baseconf |
|
| `status` | размер БД, meta, список проиндексированных baseconf |
|
||||||
| `list` | выгрузки с `src/` в репозитории + что уже в индексе |
|
| `list` | источники индексации в репозитории + что уже в индексе |
|
||||||
|
|
||||||
### Режимы `reindex`
|
### Режимы `reindex`
|
||||||
|
|
||||||
@@ -95,7 +95,8 @@ baseconf_aliases:
|
|||||||
|
|
||||||
### Что индексируется
|
### Что индексируется
|
||||||
|
|
||||||
- **Метаданные** `src/<Тип>/*.xml`: имя, синоним, комментарий, реквизиты / измерения / ресурсы / ТЧ, типы (в т.ч. `TypeSet`), ссылки, `FillChecking`, `RegisterRecords` (документ → регистры движений).
|
- **Метаданные конфигураций/расширений** `src/<Тип>/*.xml`: имя, синоним, комментарий, реквизиты / измерения / ресурсы / ТЧ, типы (в т.ч. `TypeSet`), ссылки, `FillChecking`, `RegisterRecords` (документ → регистры движений).
|
||||||
|
- **Метаданные внешних обработок**: `<dir>/<ИмяОбработки>.xml` (как `ExternalDataProcessor`).
|
||||||
- **Модули** `**/*.bsl`: путь, owner (`Document.X`), вид модуля, имена процедур/функций, тело (до 200 КБ в FTS).
|
- **Модули** `**/*.bsl`: путь, owner (`Document.X`), вид модуля, имена процедур/функций, тело (до 200 КБ в FTS).
|
||||||
- **Связи движений** — таблица `register_records` (обратный индекс регистраторов).
|
- **Связи движений** — таблица `register_records` (обратный индекс регистраторов).
|
||||||
|
|
||||||
@@ -113,6 +114,9 @@ python index_1c.py reindex --full -j 12
|
|||||||
# основная конфигурация + расширение, только документы и справочники
|
# основная конфигурация + расширение, только документы и справочники
|
||||||
python index_1c.py reindex -b main -b ext -t Documents,Catalogs -j 8
|
python index_1c.py reindex -b main -b ext -t Documents,Catalogs -j 8
|
||||||
|
|
||||||
|
# внешние обработки: развернуть папку в virtual baseconf
|
||||||
|
python index_1c.py reindex -b my-transfer.ext -j 8
|
||||||
|
|
||||||
python index_1c.py status
|
python index_1c.py status
|
||||||
python index_1c.py list
|
python index_1c.py list
|
||||||
```
|
```
|
||||||
|
|||||||
+13
-2
@@ -172,7 +172,13 @@ def _index_one_config(
|
|||||||
existing = dbmod.get_file_index(conn, cfg.name) if not full else {}
|
existing = dbmod.get_file_index(conn, cfg.name) if not full else {}
|
||||||
seen_paths: set[str] = set()
|
seen_paths: set[str] = set()
|
||||||
|
|
||||||
meta_files = iter_object_xml_files(cfg.src, types=types, skip_types=skip_types)
|
meta_files = iter_object_xml_files(
|
||||||
|
cfg.src,
|
||||||
|
types=types,
|
||||||
|
skip_types=skip_types,
|
||||||
|
source_kind=cfg.source_kind,
|
||||||
|
external_name=cfg.external_name,
|
||||||
|
)
|
||||||
meta_jobs: list[tuple[str, str, str]] = []
|
meta_jobs: list[tuple[str, str, str]] = []
|
||||||
meta_skipped = 0
|
meta_skipped = 0
|
||||||
for otype, path in meta_files:
|
for otype, path in meta_files:
|
||||||
@@ -222,7 +228,12 @@ def _index_one_config(
|
|||||||
mod_skipped = 0
|
mod_skipped = 0
|
||||||
if index_modules:
|
if index_modules:
|
||||||
mod_jobs: list[tuple[str, str, str]] = []
|
mod_jobs: list[tuple[str, str, str]] = []
|
||||||
for path in iter_bsl_files(cfg.src):
|
bsl_paths = (
|
||||||
|
sorted((cfg.src / cfg.external_name).rglob("*.bsl"))
|
||||||
|
if cfg.source_kind == "external_processor" and cfg.external_name
|
||||||
|
else iter_bsl_files(cfg.src)
|
||||||
|
)
|
||||||
|
for path in bsl_paths:
|
||||||
rel = path.relative_to(cfg.src).as_posix()
|
rel = path.relative_to(cfg.src).as_posix()
|
||||||
seen_paths.add(rel)
|
seen_paths.add(rel)
|
||||||
mtime_ns, size = _file_stamp(path)
|
mtime_ns, size = _file_stamp(path)
|
||||||
|
|||||||
+12
-8
@@ -137,7 +137,7 @@ def add_baseconf_args(
|
|||||||
if mode == "index":
|
if mode == "index":
|
||||||
default_hint = (
|
default_hint = (
|
||||||
"Без параметра — default_baseconfs из --config; "
|
"Без параметра — default_baseconfs из --config; "
|
||||||
"если блок не задан, индексировать все выгрузки с src/."
|
"если блок не задан, индексировать все выгрузки с src/ и внешние обработки."
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
default_hint = "Без параметра — поиск по всем проиндексированным."
|
default_hint = "Без параметра — поиск по всем проиндексированным."
|
||||||
@@ -148,7 +148,7 @@ def add_baseconf_args(
|
|||||||
metavar="NAME",
|
metavar="NAME",
|
||||||
dest="baseconf",
|
dest="baseconf",
|
||||||
help=(
|
help=(
|
||||||
"Конфигурация 1С в репозитории (папка <name>/src/). "
|
"Источник индексации 1С: <name>/src/ или virtual <dir>.<Обработка>. "
|
||||||
"Можно несколько раз или через запятую: -b cfg1,cfg2. "
|
"Можно несколько раз или через запятую: -b cfg1,cfg2. "
|
||||||
"Краткие имена (алиасы) — в baseconf_aliases файла --config. "
|
"Краткие имена (алиасы) — в baseconf_aliases файла --config. "
|
||||||
f"{default_hint}"
|
f"{default_hint}"
|
||||||
@@ -234,28 +234,32 @@ def validate_baseconfs(
|
|||||||
require_indexed: bool = True,
|
require_indexed: bool = True,
|
||||||
) -> list[str]:
|
) -> list[str]:
|
||||||
"""
|
"""
|
||||||
Проверить --baseconf: папка src/, наличие в индексе.
|
Проверить --baseconf: src-выгрузка или virtual внешняя обработка, наличие в индексе.
|
||||||
Возвращает канонические имена. Иначе BaseconfError с подсказками.
|
Возвращает канонические имена. Иначе BaseconfError с подсказками.
|
||||||
"""
|
"""
|
||||||
if not names:
|
if not names:
|
||||||
return []
|
return []
|
||||||
|
|
||||||
resolved = resolve_baseconf_names(names)
|
resolved = resolve_baseconf_names(names)
|
||||||
|
available = {c.name for c in discover_configs(project_root, None)}
|
||||||
missing_src: list[str] = []
|
missing_src: list[str] = []
|
||||||
for name in resolved:
|
for name in resolved:
|
||||||
if not (project_root / name / "src").is_dir():
|
if discover_configs(project_root, [name]):
|
||||||
|
continue
|
||||||
|
if name not in available:
|
||||||
missing_src.append(name)
|
missing_src.append(name)
|
||||||
|
|
||||||
if missing_src:
|
if missing_src:
|
||||||
available = [c.name for c in discover_configs(project_root, None)]
|
available_list = sorted(available)
|
||||||
lines = [
|
lines = [
|
||||||
"Конфигурация 1С не найдена в репозитории (нет каталога <name>/src/):",
|
"Источник индексации 1С не найден в репозитории "
|
||||||
|
"(нет <name>/src/ или внешней обработки <dir>/<name>.xml + <dir>/<name>/):",
|
||||||
*(f" - {n}" for n in missing_src),
|
*(f" - {n}" for n in missing_src),
|
||||||
"",
|
"",
|
||||||
"Доступные выгрузки в проекте:",
|
"Доступные выгрузки в проекте:",
|
||||||
]
|
]
|
||||||
if available:
|
if available_list:
|
||||||
lines.extend(f" - {n}" for n in available)
|
lines.extend(f" - {n}" for n in available_list)
|
||||||
else:
|
else:
|
||||||
lines.append(" (нет)")
|
lines.append(" (нет)")
|
||||||
lines.extend(
|
lines.extend(
|
||||||
|
|||||||
+116
-2
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import re
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
@@ -53,6 +54,7 @@ OBJECT_TYPE_FOLDERS: dict[str, str] = {
|
|||||||
"XDTOPackages": "XDTOPackage",
|
"XDTOPackages": "XDTOPackage",
|
||||||
"Bots": "Bot",
|
"Bots": "Bot",
|
||||||
"ExternalDataSources": "ExternalDataSource",
|
"ExternalDataSources": "ExternalDataSource",
|
||||||
|
"ExternalDataProcessors": "ExternalDataProcessor",
|
||||||
"Languages": "Language",
|
"Languages": "Language",
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,6 +94,10 @@ TYPE_ALIASES: dict[str, str] = {
|
|||||||
"dataprocessors": "DataProcessor",
|
"dataprocessors": "DataProcessor",
|
||||||
"обработка": "DataProcessor",
|
"обработка": "DataProcessor",
|
||||||
"обработки": "DataProcessor",
|
"обработки": "DataProcessor",
|
||||||
|
"externaldataprocessor": "ExternalDataProcessor",
|
||||||
|
"externaldataprocessors": "ExternalDataProcessor",
|
||||||
|
"внешняяобработка": "ExternalDataProcessor",
|
||||||
|
"внешниеобработки": "ExternalDataProcessor",
|
||||||
"report": "Report",
|
"report": "Report",
|
||||||
"reports": "Report",
|
"reports": "Report",
|
||||||
"отчет": "Report",
|
"отчет": "Report",
|
||||||
@@ -171,6 +177,8 @@ class ConfigPaths:
|
|||||||
name: str
|
name: str
|
||||||
root: Path
|
root: Path
|
||||||
src: Path
|
src: Path
|
||||||
|
source_kind: str = "src" # src | external_processor
|
||||||
|
external_name: str = ""
|
||||||
|
|
||||||
|
|
||||||
def project_root_from_here() -> Path:
|
def project_root_from_here() -> Path:
|
||||||
@@ -210,7 +218,12 @@ def resolve_config_name(name: str) -> str:
|
|||||||
|
|
||||||
|
|
||||||
def list_config_dirs(project_root: Path) -> list[str]:
|
def list_config_dirs(project_root: Path) -> list[str]:
|
||||||
"""Все каталоги с выгрузкой 1С (<name>/src/) в корне проекта."""
|
"""Все источники индексации в корне проекта.
|
||||||
|
|
||||||
|
Возвращает:
|
||||||
|
- обычные конфигурации/расширения: <name> (если есть <name>/src/)
|
||||||
|
- внешние обработки: <dir>.<Обработка> для каталогов вида <dir>/*.xml + <dir>/<Обработка>/
|
||||||
|
"""
|
||||||
if not project_root.is_dir():
|
if not project_root.is_dir():
|
||||||
return []
|
return []
|
||||||
found: list[str] = []
|
found: list[str] = []
|
||||||
@@ -219,9 +232,52 @@ def list_config_dirs(project_root: Path) -> list[str]:
|
|||||||
continue
|
continue
|
||||||
if (child / "src").is_dir():
|
if (child / "src").is_dir():
|
||||||
found.append(child.name)
|
found.append(child.name)
|
||||||
|
continue
|
||||||
|
if child.name.endswith(".ext"):
|
||||||
|
found.extend(_discover_external_processors(child))
|
||||||
return found
|
return found
|
||||||
|
|
||||||
|
|
||||||
|
_SAFE_NAME_RE = re.compile(r"^[A-Za-zА-Яа-яЁё0-9_]+$")
|
||||||
|
|
||||||
|
|
||||||
|
def _looks_like_external_processor_xml(path: Path) -> bool:
|
||||||
|
try:
|
||||||
|
text = path.read_text(encoding="utf-8", errors="ignore")
|
||||||
|
except OSError:
|
||||||
|
return False
|
||||||
|
probe = text[:8000]
|
||||||
|
return "<ExternalDataProcessor" in probe and "<MetaDataObject" in probe
|
||||||
|
|
||||||
|
|
||||||
|
def _discover_external_processor_entries(root: Path) -> list[tuple[str, str, Path]]:
|
||||||
|
"""Найти внешние обработки под root (включая вложенные папки).
|
||||||
|
|
||||||
|
Возвращает кортежи: (virtual_name, processor_name, processor_root_dir).
|
||||||
|
"""
|
||||||
|
out: list[tuple[str, str, Path]] = []
|
||||||
|
try:
|
||||||
|
xml_files = sorted(root.rglob("*.xml"))
|
||||||
|
except OSError:
|
||||||
|
return out
|
||||||
|
for xml in xml_files:
|
||||||
|
parent = xml.parent
|
||||||
|
name = xml.stem.strip()
|
||||||
|
if not name or not _SAFE_NAME_RE.match(name):
|
||||||
|
continue
|
||||||
|
obj_dir = parent / name
|
||||||
|
if not obj_dir.is_dir():
|
||||||
|
continue
|
||||||
|
if not _looks_like_external_processor_xml(xml):
|
||||||
|
continue
|
||||||
|
out.append((f"{root.name}.{name}", name, parent))
|
||||||
|
return out
|
||||||
|
|
||||||
|
|
||||||
|
def _discover_external_processors(root: Path) -> list[str]:
|
||||||
|
return [name for name, _proc, _parent in _discover_external_processor_entries(root)]
|
||||||
|
|
||||||
|
|
||||||
def resolve_object_type(name: str) -> str:
|
def resolve_object_type(name: str) -> str:
|
||||||
raw = name.strip()
|
raw = name.strip()
|
||||||
if raw in FOLDER_BY_TYPE:
|
if raw in FOLDER_BY_TYPE:
|
||||||
@@ -240,11 +296,69 @@ def resolve_object_type(name: str) -> str:
|
|||||||
def discover_configs(project_root: Path, names: list[str] | None = None) -> list[ConfigPaths]:
|
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)
|
wanted = [resolve_config_name(n) for n in names] if names else list_config_dirs(project_root)
|
||||||
found: list[ConfigPaths] = []
|
found: list[ConfigPaths] = []
|
||||||
|
seen: set[str] = set()
|
||||||
|
|
||||||
|
def _append(cfg: ConfigPaths) -> None:
|
||||||
|
if cfg.name in seen:
|
||||||
|
return
|
||||||
|
seen.add(cfg.name)
|
||||||
|
found.append(cfg)
|
||||||
|
|
||||||
for name in wanted:
|
for name in wanted:
|
||||||
root = project_root / name
|
root = project_root / name
|
||||||
src = root / "src"
|
src = root / "src"
|
||||||
if src.is_dir():
|
if src.is_dir():
|
||||||
found.append(ConfigPaths(name=name, root=root, src=src))
|
_append(ConfigPaths(name=name, root=root, src=src))
|
||||||
|
continue
|
||||||
|
# virtual baseconf для внешних обработок:
|
||||||
|
# <dir>.<processor> → ищем <...>/<processor>.xml + <...>/<processor>/
|
||||||
|
if "." in name:
|
||||||
|
base, ext_name = name.rsplit(".", 1)
|
||||||
|
ext_root = project_root / base
|
||||||
|
if ext_root.is_dir():
|
||||||
|
entries = _discover_external_processor_entries(ext_root)
|
||||||
|
for _virtual_name, proc_name, proc_root in entries:
|
||||||
|
if proc_name != ext_name:
|
||||||
|
continue
|
||||||
|
_append(
|
||||||
|
ConfigPaths(
|
||||||
|
name=name,
|
||||||
|
root=proc_root,
|
||||||
|
src=proc_root,
|
||||||
|
source_kind="external_processor",
|
||||||
|
external_name=proc_name,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
# имя может уже быть каноническим virtual name
|
||||||
|
for virtual_name, proc_name, proc_root in entries:
|
||||||
|
if virtual_name != name:
|
||||||
|
continue
|
||||||
|
_append(
|
||||||
|
ConfigPaths(
|
||||||
|
name=virtual_name,
|
||||||
|
root=proc_root,
|
||||||
|
src=proc_root,
|
||||||
|
source_kind="external_processor",
|
||||||
|
external_name=proc_name,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
break
|
||||||
|
if name in seen:
|
||||||
|
continue
|
||||||
|
# если передали только папку (например my-transfer.ext), развернуть все обработки
|
||||||
|
if root.is_dir():
|
||||||
|
for virtual_name, proc_name, proc_root in _discover_external_processor_entries(root):
|
||||||
|
_append(
|
||||||
|
ConfigPaths(
|
||||||
|
name=virtual_name,
|
||||||
|
root=proc_root,
|
||||||
|
src=proc_root,
|
||||||
|
source_kind="external_processor",
|
||||||
|
external_name=proc_name,
|
||||||
|
)
|
||||||
|
)
|
||||||
return found
|
return found
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+16
-1
@@ -336,12 +336,27 @@ def iter_object_xml_files(
|
|||||||
src: Path,
|
src: Path,
|
||||||
types: set[str] | None = None,
|
types: set[str] | None = None,
|
||||||
skip_types: set[str] | None = None,
|
skip_types: set[str] | None = None,
|
||||||
|
*,
|
||||||
|
source_kind: str = "src",
|
||||||
|
external_name: str = "",
|
||||||
) -> list[tuple[str, Path]]:
|
) -> list[tuple[str, Path]]:
|
||||||
"""Список (object_type, xml_path) только верхний уровень src/<Folder>/*.xml."""
|
"""Список (object_type, xml_path) для обычной выгрузки или external processing."""
|
||||||
skip = skip_types or set()
|
skip = skip_types or set()
|
||||||
out: list[tuple[str, Path]] = []
|
out: list[tuple[str, Path]] = []
|
||||||
if not src.is_dir():
|
if not src.is_dir():
|
||||||
return out
|
return out
|
||||||
|
if source_kind == "external_processor":
|
||||||
|
otype = "ExternalDataProcessor"
|
||||||
|
if otype in skip:
|
||||||
|
return out
|
||||||
|
if types is not None and otype not in types:
|
||||||
|
return out
|
||||||
|
if not external_name:
|
||||||
|
return out
|
||||||
|
xml = src / f"{external_name}.xml"
|
||||||
|
if xml.is_file():
|
||||||
|
out.append((otype, xml))
|
||||||
|
return out
|
||||||
for folder in sorted(src.iterdir()):
|
for folder in sorted(src.iterdir()):
|
||||||
if not folder.is_dir():
|
if not folder.is_dir():
|
||||||
continue
|
continue
|
||||||
|
|||||||
@@ -53,6 +53,12 @@ def _owner_from_rel(rel: Path) -> str:
|
|||||||
parts = rel.parts
|
parts = rel.parts
|
||||||
if not parts:
|
if not parts:
|
||||||
return ""
|
return ""
|
||||||
|
# Внешняя обработка: <Обработка>/Ext/ObjectModule.bsl
|
||||||
|
if len(parts) >= 3 and parts[1] == "Ext":
|
||||||
|
return f"ExternalDataProcessor.{parts[0]}"
|
||||||
|
# Форма внешней обработки: <Обработка>/Forms/<Форма>/Ext/Form/Module.bsl
|
||||||
|
if len(parts) >= 6 and parts[1] == "Forms":
|
||||||
|
return f"ExternalDataProcessor.{parts[0]}.Form.{parts[2]}"
|
||||||
folder = parts[0]
|
folder = parts[0]
|
||||||
otype = OBJECT_TYPE_FOLDERS.get(folder)
|
otype = OBJECT_TYPE_FOLDERS.get(folder)
|
||||||
if otype and len(parts) >= 2:
|
if otype and len(parts) >= 2:
|
||||||
|
|||||||
+6
-5
@@ -1,9 +1,9 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
"""Переиндексация метаданных и модулей конфигураций 1С → cache/1c_meta/index.sqlite.
|
"""Переиндексация метаданных и модулей 1С (конфигурации + внешние обработки) → cache/1c_meta/index.sqlite.
|
||||||
|
|
||||||
Параметры:
|
Параметры:
|
||||||
--config, -c файл настроек утилиты (YAML)
|
--config, -c файл настроек утилиты (YAML)
|
||||||
--baseconf, -b какие выгрузки 1С индексировать (имя каталога с src/)
|
--baseconf, -b какие источники 1С индексировать (каталог с src/ или virtual external)
|
||||||
|
|
||||||
Примеры:
|
Примеры:
|
||||||
|
|
||||||
@@ -90,7 +90,8 @@ def cmd_reindex(args: argparse.Namespace) -> int:
|
|||||||
configs = _select_configs_for_reindex(args, root)
|
configs = _select_configs_for_reindex(args, root)
|
||||||
if not configs:
|
if not configs:
|
||||||
print(
|
print(
|
||||||
"Нет конфигураций для индексации (нужна папка <name>/src/).\n"
|
"Нет источников для индексации (нужна папка <name>/src/ "
|
||||||
|
"или внешняя обработка <dir>/<name>.xml + <dir>/<name>/).\n"
|
||||||
"Укажите -b <имя-выгрузки> или проверьте: python index_1c.py list",
|
"Укажите -b <имя-выгрузки> или проверьте: python index_1c.py list",
|
||||||
file=sys.stderr,
|
file=sys.stderr,
|
||||||
)
|
)
|
||||||
@@ -235,10 +236,10 @@ def build_parser() -> argparse.ArgumentParser:
|
|||||||
|
|
||||||
lc = sub.add_parser(
|
lc = sub.add_parser(
|
||||||
"list",
|
"list",
|
||||||
help="Выгрузки в репозитории и в индексе",
|
help="Источники в репозитории и в индексе",
|
||||||
parents=[tool_parent],
|
parents=[tool_parent],
|
||||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||||
description="Выгрузки 1С с src/ в репозитории и что уже в index.sqlite.",
|
description="Источники 1С в репозитории (src/ и external) и что уже в index.sqlite.",
|
||||||
)
|
)
|
||||||
lc.set_defaults(func=cmd_list_configs)
|
lc.set_defaults(func=cmd_list_configs)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user