mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-08-14 15:33:20 +03:00
fix(db-load-git,db-update): ловить тихие отказы платформы, как db-load-xml
Платформа рапортует об успехе (exit 0) и одновременно пишет в /Out-лог, что часть метаданных отброшена. Детектор этого был только в db-load-xml, хотя db-load-git гоняет тот же /LoadConfigFromFiles (и дописывает /UpdateDBCfg в тот же вызов), а db-update — вторую половину той же цепочки. Оба лог печатали, но не разбирали. Детектор извлечён в Find-SilentRejections / find_silent_rejections и внесён в реестр семей check-inline-drift: инлайн-код гард сверять не умеет, а именно расхождение копий и было бы главным риском такого дублирования. Добавлен восьмой паттерн — «Для работы с конфигурацией необходима версия платформы не меньше». Замерено при работе над issue #63: конфигурация с режимом совместимости выше платформы грузится с кодом 0, db-update тоже отвечает 0, объекты в базу не попадают, а отказ приходит только в рантайме. Строка обрезана до инвариантной части — конкретная версия в сообщении меняется. Текст предупреждения переписан. Убрана подсказка «pass -StrictLog to treat as error»: ключ предназначен для регрессов (его передаёт verify-snapshots), а совет бессмысленный — операция уже выполнена, и повторять её ради того же текста незачем. Формулировка больше не утверждает «dropped properties/refs»: класс проблемы разный, а строки лога печатаются следом и говорят за себя. Две правки по дороге: - `return ,$found` в паре с `@()` у вызывающего давал массив из одного пустого массива, то есть предупреждение «1 problem(s)» на чистом логе. Возврат без запятой-обёртки. - py-порт писал предупреждение в stderr, PS1 — в stdout. В самом py-порте stderr занят исключительно фатальными «Error:» перед exit 1, так что не-фатальное предупреждение там было единственным исключением. Приведено к stdout — и к соглашению своего же файла, и к поведению PS1; verify-snapshots на падении читает `stderr || stdout`, поэтому диагностика не теряется. Тесты: фейковая платформа .cmd, которая вычитывает путь из /Out и кладёт туда готовый лог, — по четыре кейса на db-load-xml и db-update (отбраковка, она же под -StrictLog, новый паттерн, чистый лог без предупреждения). Раньше детектор не был покрыт вообще. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
06f21ab3d1
commit
a024b7da9c
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# db-load-git v1.19 — Load Git changes into 1C database
|
||||
# db-load-git v1.20 — Load Git changes into 1C database
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
|
||||
import argparse
|
||||
@@ -344,6 +344,38 @@ def print_platform_output(result):
|
||||
print("--- End ---")
|
||||
|
||||
|
||||
def find_silent_rejections(log_text):
|
||||
"""Строки лога, о которых платформа сообщает, НЕ поднимая код возврата.
|
||||
|
||||
Метаданные отброшены или конфигурация нерабочая, а операция при этом «успешна».
|
||||
Возвращает подошедшие строки.
|
||||
|
||||
Копия этой функции есть в каждом навыке, который читает /Out-лог загрузки (навыки
|
||||
автономны). Держать копии одинаковыми — сознательно: разошедшиеся копии сводят на нет
|
||||
весь смысл.
|
||||
"""
|
||||
patterns = [
|
||||
"Неверное свойство объекта метаданных",
|
||||
"не входит в состав объекта метаданных",
|
||||
"Неизвестное имя типа",
|
||||
"Неизвестный объект метаданных",
|
||||
"Ни один из документов не является регистратором для регистра",
|
||||
"Неверное значение перечисления",
|
||||
"не может быть приведен к типу",
|
||||
# Режим совместимости выше платформы: объекты в базу не попадают, отказ приходит в
|
||||
# рантайме. Обрезано до инвариантной части — конкретная версия в сообщении меняется.
|
||||
"Для работы с конфигурацией необходима версия платформы не меньше",
|
||||
]
|
||||
found = []
|
||||
if log_text:
|
||||
for line in log_text.splitlines():
|
||||
for pat in patterns:
|
||||
if pat in line:
|
||||
found.append(line.strip())
|
||||
break
|
||||
return found
|
||||
|
||||
|
||||
def run_ibcmd(cmd, has_username=False, warn_no_user=True):
|
||||
"""Run an ibcmd command non-interactively.
|
||||
|
||||
@@ -446,6 +478,10 @@ def main():
|
||||
)
|
||||
parser.add_argument("-DryRun", action="store_true", help="Only show what would be loaded (no actual load)")
|
||||
parser.add_argument("-UpdateDB", action="store_true", help="Also update database configuration after load")
|
||||
# Ключ для регрессов и верификации снапшотов, не для повседневного вызова: в SKILL.md
|
||||
# намеренно не выносится. Поднимает код возврата, если платформа отчиталась об успехе,
|
||||
# но в логе есть отбраковка.
|
||||
parser.add_argument("-StrictLog", action="store_true")
|
||||
parser.add_argument("-AdditionalV8Arguments", nargs="*", default=[],
|
||||
help="Extra 1cv8 arguments, e.g. /UseHwLicenses+")
|
||||
parser.add_argument("-AdditionalIbcmdArguments", nargs="*", default=[],
|
||||
@@ -705,6 +741,7 @@ def main():
|
||||
else:
|
||||
print(f"Error loading configuration (code: {exit_code}){describe_exit(exit_code)}", file=sys.stderr)
|
||||
|
||||
log_content = ""
|
||||
if os.path.isfile(out_file):
|
||||
try:
|
||||
with open(out_file, "r", encoding="utf-8-sig") as f:
|
||||
@@ -717,6 +754,21 @@ def main():
|
||||
pass
|
||||
|
||||
print_platform_output(result)
|
||||
|
||||
# Причину не называем: строки лога печатаются следом и говорят за себя, а класс проблемы
|
||||
# разный — от отброшенного свойства до нерабочей на этой платформе конфигурации. Подсказку
|
||||
# про -StrictLog не даём: операция уже выполнена, повторять её ради того же текста незачем.
|
||||
silent_failures = find_silent_rejections(log_content)
|
||||
if silent_failures:
|
||||
print(
|
||||
f"[warning] platform reported success, but the log contains "
|
||||
f"{len(silent_failures)} problem(s):"
|
||||
)
|
||||
for line in silent_failures:
|
||||
print(f" {line}")
|
||||
if args.StrictLog and exit_code == 0:
|
||||
exit_code = 1
|
||||
|
||||
sys.exit(exit_code)
|
||||
|
||||
finally:
|
||||
|
||||
Reference in New Issue
Block a user