mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-08-15 07:49:01 +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,4 +1,4 @@
|
|||||||
# 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
|
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||||
# NB: *nix-раскладку платформы (/opt/1cv8/<ver>/1cv8, без .exe) знает только .py-порт — PS на *nix не исполняется.
|
# NB: *nix-раскладку платформы (/opt/1cv8/<ver>/1cv8, без .exe) знает только .py-порт — PS на *nix не исполняется.
|
||||||
<#
|
<#
|
||||||
@@ -110,6 +110,12 @@ param(
|
|||||||
[Parameter(Mandatory=$false)]
|
[Parameter(Mandatory=$false)]
|
||||||
[switch]$UpdateDB,
|
[switch]$UpdateDB,
|
||||||
|
|
||||||
|
[Parameter(Mandatory=$false)]
|
||||||
|
# Ключ для регрессов и верификации снапшотов, не для повседневного вызова: в SKILL.md
|
||||||
|
# намеренно не выносится. Поднимает код возврата, если платформа отчиталась об успехе,
|
||||||
|
# но в логе есть отбраковка.
|
||||||
|
[switch]$StrictLog,
|
||||||
|
|
||||||
[Parameter(Mandatory=$false)]
|
[Parameter(Mandatory=$false)]
|
||||||
[string[]]$AdditionalV8Arguments = @(),
|
[string[]]$AdditionalV8Arguments = @(),
|
||||||
|
|
||||||
@@ -394,6 +400,41 @@ function Write-PlatformOutput {
|
|||||||
Write-Host "--- End ---"
|
Write-Host "--- End ---"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Строки лога, о которых платформа сообщает, НЕ поднимая код возврата: метаданные отброшены или
|
||||||
|
# конфигурация нерабочая, а операция при этом «успешна». Возвращает подошедшие строки.
|
||||||
|
#
|
||||||
|
# Копия этой функции есть в каждом навыке, который читает /Out-лог загрузки (навыки автономны).
|
||||||
|
# Держать копии одинаковыми — сознательно: разошедшиеся копии сводят на нет весь смысл.
|
||||||
|
function Find-SilentRejections {
|
||||||
|
param([string]$LogText)
|
||||||
|
$patterns = @(
|
||||||
|
'Неверное свойство объекта метаданных',
|
||||||
|
'не входит в состав объекта метаданных',
|
||||||
|
'Неизвестное имя типа',
|
||||||
|
'Неизвестный объект метаданных',
|
||||||
|
'Ни один из документов не является регистратором для регистра',
|
||||||
|
'Неверное значение перечисления',
|
||||||
|
'не может быть приведен к типу',
|
||||||
|
# Режим совместимости выше платформы: объекты в базу не попадают, отказ приходит в рантайме.
|
||||||
|
# Обрезано до инвариантной части — конкретная версия в сообщении меняется.
|
||||||
|
'Для работы с конфигурацией необходима версия платформы не меньше'
|
||||||
|
)
|
||||||
|
$found = @()
|
||||||
|
if ($LogText) {
|
||||||
|
foreach ($line in ($LogText -split "`r?`n")) {
|
||||||
|
foreach ($pat in $patterns) {
|
||||||
|
if ($line -match [regex]::Escape($pat)) {
|
||||||
|
$found += $line.Trim()
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
# Возвращаем массив БЕЗ запятой-обёртки: вызывающий берёт результат в @(), а `return ,$found`
|
||||||
|
# дал бы массив из одного пустого массива — фантомное срабатывание на чистом логе.
|
||||||
|
return $found
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
$engine = if ((Split-Path $V8Path -Leaf) -match '^ibcmd') { "ibcmd" } else { "1cv8" }
|
$engine = if ((Split-Path $V8Path -Leaf) -match '^ibcmd') { "ibcmd" } else { "1cv8" }
|
||||||
if ($engine -eq "ibcmd") {
|
if ($engine -eq "ibcmd") {
|
||||||
@@ -667,6 +708,7 @@ try {
|
|||||||
Write-Host "Error loading configuration (code: $exitCode)$(Get-ExitAnnotation $exitCode)" -ForegroundColor Red
|
Write-Host "Error loading configuration (code: $exitCode)$(Get-ExitAnnotation $exitCode)" -ForegroundColor Red
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$logContent = $null
|
||||||
if (Test-Path $outFile) {
|
if (Test-Path $outFile) {
|
||||||
$logContent = Get-Content $outFile -Raw -ErrorAction SilentlyContinue
|
$logContent = Get-Content $outFile -Raw -ErrorAction SilentlyContinue
|
||||||
if ($logContent) {
|
if ($logContent) {
|
||||||
@@ -677,6 +719,16 @@ try {
|
|||||||
}
|
}
|
||||||
Write-PlatformOutput $__v8.Output
|
Write-PlatformOutput $__v8.Output
|
||||||
|
|
||||||
|
# Причину не называем: строки лога печатаются следом и говорят за себя, а класс проблемы
|
||||||
|
# разный — от отброшенного свойства до нерабочей на этой платформе конфигурации. Подсказку
|
||||||
|
# про -StrictLog не даём: операция уже выполнена, повторять её ради того же текста незачем.
|
||||||
|
$silentFailures = @(Find-SilentRejections $logContent)
|
||||||
|
if ($silentFailures.Count -gt 0) {
|
||||||
|
Write-Host "[warning] platform reported success, but the log contains $($silentFailures.Count) problem(s):" -ForegroundColor Yellow
|
||||||
|
foreach ($f in $silentFailures) { Write-Host " $f" -ForegroundColor Yellow }
|
||||||
|
if ($StrictLog -and $exitCode -eq 0) { $exitCode = 1 }
|
||||||
|
}
|
||||||
|
|
||||||
exit $exitCode
|
exit $exitCode
|
||||||
|
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#!/usr/bin/env python3
|
#!/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
|
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
@@ -344,6 +344,38 @@ def print_platform_output(result):
|
|||||||
print("--- End ---")
|
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):
|
def run_ibcmd(cmd, has_username=False, warn_no_user=True):
|
||||||
"""Run an ibcmd command non-interactively.
|
"""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("-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")
|
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=[],
|
parser.add_argument("-AdditionalV8Arguments", nargs="*", default=[],
|
||||||
help="Extra 1cv8 arguments, e.g. /UseHwLicenses+")
|
help="Extra 1cv8 arguments, e.g. /UseHwLicenses+")
|
||||||
parser.add_argument("-AdditionalIbcmdArguments", nargs="*", default=[],
|
parser.add_argument("-AdditionalIbcmdArguments", nargs="*", default=[],
|
||||||
@@ -705,6 +741,7 @@ def main():
|
|||||||
else:
|
else:
|
||||||
print(f"Error loading configuration (code: {exit_code}){describe_exit(exit_code)}", file=sys.stderr)
|
print(f"Error loading configuration (code: {exit_code}){describe_exit(exit_code)}", file=sys.stderr)
|
||||||
|
|
||||||
|
log_content = ""
|
||||||
if os.path.isfile(out_file):
|
if os.path.isfile(out_file):
|
||||||
try:
|
try:
|
||||||
with open(out_file, "r", encoding="utf-8-sig") as f:
|
with open(out_file, "r", encoding="utf-8-sig") as f:
|
||||||
@@ -717,6 +754,21 @@ def main():
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
print_platform_output(result)
|
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)
|
sys.exit(exit_code)
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# db-load-xml v1.20 — Load 1C configuration from XML files
|
# db-load-xml v1.21 — Load 1C configuration from XML files
|
||||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||||
# NB: *nix-раскладку платформы (/opt/1cv8/<ver>/1cv8, без .exe) знает только .py-порт — PS на *nix не исполняется.
|
# NB: *nix-раскладку платформы (/opt/1cv8/<ver>/1cv8, без .exe) знает только .py-порт — PS на *nix не исполняется.
|
||||||
<#
|
<#
|
||||||
@@ -416,6 +416,41 @@ function Write-PlatformOutput {
|
|||||||
Write-Host "--- End ---"
|
Write-Host "--- End ---"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Строки лога, о которых платформа сообщает, НЕ поднимая код возврата: метаданные отброшены или
|
||||||
|
# конфигурация нерабочая, а операция при этом «успешна». Возвращает подошедшие строки.
|
||||||
|
#
|
||||||
|
# Копия этой функции есть в каждом навыке, который читает /Out-лог загрузки (навыки автономны).
|
||||||
|
# Держать копии одинаковыми — сознательно: разошедшиеся копии сводят на нет весь смысл.
|
||||||
|
function Find-SilentRejections {
|
||||||
|
param([string]$LogText)
|
||||||
|
$patterns = @(
|
||||||
|
'Неверное свойство объекта метаданных',
|
||||||
|
'не входит в состав объекта метаданных',
|
||||||
|
'Неизвестное имя типа',
|
||||||
|
'Неизвестный объект метаданных',
|
||||||
|
'Ни один из документов не является регистратором для регистра',
|
||||||
|
'Неверное значение перечисления',
|
||||||
|
'не может быть приведен к типу',
|
||||||
|
# Режим совместимости выше платформы: объекты в базу не попадают, отказ приходит в рантайме.
|
||||||
|
# Обрезано до инвариантной части — конкретная версия в сообщении меняется.
|
||||||
|
'Для работы с конфигурацией необходима версия платформы не меньше'
|
||||||
|
)
|
||||||
|
$found = @()
|
||||||
|
if ($LogText) {
|
||||||
|
foreach ($line in ($LogText -split "`r?`n")) {
|
||||||
|
foreach ($pat in $patterns) {
|
||||||
|
if ($line -match [regex]::Escape($pat)) {
|
||||||
|
$found += $line.Trim()
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
# Возвращаем массив БЕЗ запятой-обёртки: вызывающий берёт результат в @(), а `return ,$found`
|
||||||
|
# дал бы массив из одного пустого массива — фантомное срабатывание на чистом логе.
|
||||||
|
return $found
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
$engine = if ((Split-Path $V8Path -Leaf) -match '^ibcmd') { "ibcmd" } else { "1cv8" }
|
$engine = if ((Split-Path $V8Path -Leaf) -match '^ibcmd') { "ibcmd" } else { "1cv8" }
|
||||||
|
|
||||||
@@ -607,28 +642,7 @@ try {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# --- Scan log for silent rejections ---
|
# --- Scan log for silent rejections ---
|
||||||
# Platform often writes load-time rejections into /Out but exits with code 0.
|
$silentFailures = @(Find-SilentRejections $logContent)
|
||||||
# These patterns flag cases where metadata was dropped or rejected silently.
|
|
||||||
$fatalLogPatterns = @(
|
|
||||||
'Неверное свойство объекта метаданных',
|
|
||||||
'не входит в состав объекта метаданных',
|
|
||||||
'Неизвестное имя типа',
|
|
||||||
'Неизвестный объект метаданных',
|
|
||||||
'Ни один из документов не является регистратором для регистра',
|
|
||||||
'Неверное значение перечисления',
|
|
||||||
'не может быть приведен к типу'
|
|
||||||
)
|
|
||||||
$silentFailures = @()
|
|
||||||
if ($logContent) {
|
|
||||||
foreach ($line in ($logContent -split "`r?`n")) {
|
|
||||||
foreach ($pat in $fatalLogPatterns) {
|
|
||||||
if ($line -match [regex]::Escape($pat)) {
|
|
||||||
$silentFailures += $line.Trim()
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# --- Result ---
|
# --- Result ---
|
||||||
# Default: mirror platform's verdict via exit code. Log content (including any
|
# Default: mirror platform's verdict via exit code. Log content (including any
|
||||||
@@ -647,10 +661,11 @@ try {
|
|||||||
}
|
}
|
||||||
Write-PlatformOutput $__v8.Output
|
Write-PlatformOutput $__v8.Output
|
||||||
|
|
||||||
|
# Причину не называем: строки лога печатаются следом и говорят за себя, а класс проблемы
|
||||||
|
# разный — от отброшенного свойства до нерабочей на этой платформе конфигурации. Подсказку
|
||||||
|
# про -StrictLog не даём: загрузка уже выполнена, повторять её ради того же текста незачем.
|
||||||
if ($silentFailures.Count -gt 0) {
|
if ($silentFailures.Count -gt 0) {
|
||||||
$msg = "[warning] log contains $($silentFailures.Count) rejection(s) — platform loaded config but dropped properties/refs"
|
Write-Host "[warning] platform reported success, but the log contains $($silentFailures.Count) problem(s):" -ForegroundColor Yellow
|
||||||
if (-not $StrictLog) { $msg += " (pass -StrictLog to treat as error)" }
|
|
||||||
Write-Host $msg -ForegroundColor Yellow
|
|
||||||
foreach ($f in $silentFailures) { Write-Host " $f" -ForegroundColor Yellow }
|
foreach ($f in $silentFailures) { Write-Host " $f" -ForegroundColor Yellow }
|
||||||
if ($StrictLog -and $exitCode -eq 0) { $exitCode = 1 }
|
if ($StrictLog -and $exitCode -eq 0) { $exitCode = 1 }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# db-load-xml v1.20 — Load 1C configuration from XML files
|
# db-load-xml v1.21 — Load 1C configuration from XML files
|
||||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
@@ -344,6 +344,38 @@ def print_platform_output(result):
|
|||||||
print("--- End ---")
|
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):
|
def run_ibcmd(cmd, has_username=False, warn_no_user=True):
|
||||||
"""Run an ibcmd command non-interactively.
|
"""Run an ibcmd command non-interactively.
|
||||||
|
|
||||||
@@ -636,22 +668,7 @@ def main():
|
|||||||
# --- Scan log for silent rejections ---
|
# --- Scan log for silent rejections ---
|
||||||
# Platform often writes load-time rejections into /Out but exits with code 0.
|
# Platform often writes load-time rejections into /Out but exits with code 0.
|
||||||
# These patterns flag cases where metadata was dropped or rejected silently.
|
# These patterns flag cases where metadata was dropped or rejected silently.
|
||||||
fatal_log_patterns = [
|
silent_failures = find_silent_rejections(log_content)
|
||||||
"Неверное свойство объекта метаданных",
|
|
||||||
"не входит в состав объекта метаданных",
|
|
||||||
"Неизвестное имя типа",
|
|
||||||
"Неизвестный объект метаданных",
|
|
||||||
"Ни один из документов не является регистратором для регистра",
|
|
||||||
"Неверное значение перечисления",
|
|
||||||
"не может быть приведен к типу",
|
|
||||||
]
|
|
||||||
silent_failures = []
|
|
||||||
if log_content:
|
|
||||||
for line in log_content.splitlines():
|
|
||||||
for pat in fatal_log_patterns:
|
|
||||||
if pat in line:
|
|
||||||
silent_failures.append(line.strip())
|
|
||||||
break
|
|
||||||
|
|
||||||
# --- Result ---
|
# --- Result ---
|
||||||
# Default: mirror platform's verdict via exit code. Log content (including any
|
# Default: mirror platform's verdict via exit code. Log content (including any
|
||||||
@@ -668,15 +685,19 @@ def main():
|
|||||||
print("--- End ---")
|
print("--- End ---")
|
||||||
|
|
||||||
print_platform_output(result)
|
print_platform_output(result)
|
||||||
|
# Причину не называем: строки лога печатаются следом и говорят за себя, а класс проблемы
|
||||||
|
# разный — от отброшенного свойства до нерабочей на этой платформе конфигурации. Подсказку
|
||||||
|
# про -StrictLog не даём: загрузка уже выполнена, повторять её ради того же текста незачем.
|
||||||
|
# Поток — stdout, как у PS1-порта: предупреждение относится к содержимому загрузки, а не к
|
||||||
|
# отказу навыка, и при code 0 остаётся предупреждением. Раньше py писал его в stderr —
|
||||||
|
# наблюдаемое поведение портов расходилось, и один кейс не мог проверить оба.
|
||||||
if silent_failures:
|
if silent_failures:
|
||||||
suffix = "" if args.StrictLog else " (pass -StrictLog to treat as error)"
|
|
||||||
print(
|
print(
|
||||||
f"[warning] log contains {len(silent_failures)} rejection(s) — "
|
f"[warning] platform reported success, but the log contains "
|
||||||
f"platform loaded config but dropped properties/refs{suffix}",
|
f"{len(silent_failures)} problem(s):"
|
||||||
file=sys.stderr,
|
|
||||||
)
|
)
|
||||||
for f in silent_failures:
|
for f in silent_failures:
|
||||||
print(f" {f}", file=sys.stderr)
|
print(f" {f}")
|
||||||
if args.StrictLog and exit_code == 0:
|
if args.StrictLog and exit_code == 0:
|
||||||
exit_code = 1
|
exit_code = 1
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# db-update v1.14 — Update 1C database configuration
|
# db-update v1.15 — Update 1C database configuration
|
||||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||||
# NB: *nix-раскладку платформы (/opt/1cv8/<ver>/1cv8, без .exe) знает только .py-порт — PS на *nix не исполняется.
|
# NB: *nix-раскладку платформы (/opt/1cv8/<ver>/1cv8, без .exe) знает только .py-порт — PS на *nix не исполняется.
|
||||||
<#
|
<#
|
||||||
@@ -91,6 +91,12 @@ param(
|
|||||||
[Parameter(Mandatory=$false)]
|
[Parameter(Mandatory=$false)]
|
||||||
[switch]$WarningsAsErrors,
|
[switch]$WarningsAsErrors,
|
||||||
|
|
||||||
|
[Parameter(Mandatory=$false)]
|
||||||
|
# Ключ для регрессов и верификации снапшотов, не для повседневного вызова: в SKILL.md
|
||||||
|
# намеренно не выносится. Поднимает код возврата, если платформа отчиталась об успехе,
|
||||||
|
# но в логе есть отбраковка.
|
||||||
|
[switch]$StrictLog,
|
||||||
|
|
||||||
[Parameter(Mandatory=$false)]
|
[Parameter(Mandatory=$false)]
|
||||||
[string[]]$AdditionalV8Arguments = @(),
|
[string[]]$AdditionalV8Arguments = @(),
|
||||||
|
|
||||||
@@ -395,6 +401,41 @@ function Write-PlatformOutput {
|
|||||||
Write-Host "--- End ---"
|
Write-Host "--- End ---"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Строки лога, о которых платформа сообщает, НЕ поднимая код возврата: метаданные отброшены или
|
||||||
|
# конфигурация нерабочая, а операция при этом «успешна». Возвращает подошедшие строки.
|
||||||
|
#
|
||||||
|
# Копия этой функции есть в каждом навыке, который читает /Out-лог загрузки (навыки автономны).
|
||||||
|
# Держать копии одинаковыми — сознательно: разошедшиеся копии сводят на нет весь смысл.
|
||||||
|
function Find-SilentRejections {
|
||||||
|
param([string]$LogText)
|
||||||
|
$patterns = @(
|
||||||
|
'Неверное свойство объекта метаданных',
|
||||||
|
'не входит в состав объекта метаданных',
|
||||||
|
'Неизвестное имя типа',
|
||||||
|
'Неизвестный объект метаданных',
|
||||||
|
'Ни один из документов не является регистратором для регистра',
|
||||||
|
'Неверное значение перечисления',
|
||||||
|
'не может быть приведен к типу',
|
||||||
|
# Режим совместимости выше платформы: объекты в базу не попадают, отказ приходит в рантайме.
|
||||||
|
# Обрезано до инвариантной части — конкретная версия в сообщении меняется.
|
||||||
|
'Для работы с конфигурацией необходима версия платформы не меньше'
|
||||||
|
)
|
||||||
|
$found = @()
|
||||||
|
if ($LogText) {
|
||||||
|
foreach ($line in ($LogText -split "`r?`n")) {
|
||||||
|
foreach ($pat in $patterns) {
|
||||||
|
if ($line -match [regex]::Escape($pat)) {
|
||||||
|
$found += $line.Trim()
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
# Возвращаем массив БЕЗ запятой-обёртки: вызывающий берёт результат в @(), а `return ,$found`
|
||||||
|
# дал бы массив из одного пустого массива — фантомное срабатывание на чистом логе.
|
||||||
|
return $found
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
$engine = if ((Split-Path $V8Path -Leaf) -match '^ibcmd') { "ibcmd" } else { "1cv8" }
|
$engine = if ((Split-Path $V8Path -Leaf) -match '^ibcmd') { "ibcmd" } else { "1cv8" }
|
||||||
|
|
||||||
@@ -496,6 +537,7 @@ try {
|
|||||||
Write-Host "Error updating database configuration (code: $exitCode)$(Get-ExitAnnotation $exitCode)" -ForegroundColor Red
|
Write-Host "Error updating database configuration (code: $exitCode)$(Get-ExitAnnotation $exitCode)" -ForegroundColor Red
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$logContent = $null
|
||||||
if (Test-Path $outFile) {
|
if (Test-Path $outFile) {
|
||||||
$logContent = Get-Content $outFile -Raw -ErrorAction SilentlyContinue
|
$logContent = Get-Content $outFile -Raw -ErrorAction SilentlyContinue
|
||||||
if ($logContent) {
|
if ($logContent) {
|
||||||
@@ -506,6 +548,16 @@ try {
|
|||||||
}
|
}
|
||||||
Write-PlatformOutput $__v8.Output
|
Write-PlatformOutput $__v8.Output
|
||||||
|
|
||||||
|
# Причину не называем: строки лога печатаются следом и говорят за себя, а класс проблемы
|
||||||
|
# разный — от отброшенного свойства до нерабочей на этой платформе конфигурации. Подсказку
|
||||||
|
# про -StrictLog не даём: операция уже выполнена, повторять её ради того же текста незачем.
|
||||||
|
$silentFailures = @(Find-SilentRejections $logContent)
|
||||||
|
if ($silentFailures.Count -gt 0) {
|
||||||
|
Write-Host "[warning] platform reported success, but the log contains $($silentFailures.Count) problem(s):" -ForegroundColor Yellow
|
||||||
|
foreach ($f in $silentFailures) { Write-Host " $f" -ForegroundColor Yellow }
|
||||||
|
if ($StrictLog -and $exitCode -eq 0) { $exitCode = 1 }
|
||||||
|
}
|
||||||
|
|
||||||
exit $exitCode
|
exit $exitCode
|
||||||
|
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# db-update v1.14 — Update 1C database configuration
|
# db-update v1.15 — Update 1C database configuration
|
||||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
@@ -344,6 +344,38 @@ def print_platform_output(result):
|
|||||||
print("--- End ---")
|
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):
|
def run_ibcmd(cmd, has_username=False, warn_no_user=True):
|
||||||
"""Run an ibcmd command non-interactively.
|
"""Run an ibcmd command non-interactively.
|
||||||
|
|
||||||
@@ -411,6 +443,10 @@ def main():
|
|||||||
parser.add_argument("-Dynamic", default="", choices=["", "+", "-"])
|
parser.add_argument("-Dynamic", default="", choices=["", "+", "-"])
|
||||||
parser.add_argument("-Server", action="store_true")
|
parser.add_argument("-Server", action="store_true")
|
||||||
parser.add_argument("-WarningsAsErrors", action="store_true")
|
parser.add_argument("-WarningsAsErrors", action="store_true")
|
||||||
|
# Ключ для регрессов и верификации снапшотов, не для повседневного вызова: в SKILL.md
|
||||||
|
# намеренно не выносится. Поднимает код возврата, если платформа отчиталась об успехе,
|
||||||
|
# но в логе есть отбраковка.
|
||||||
|
parser.add_argument("-StrictLog", action="store_true")
|
||||||
parser.add_argument("-AdditionalV8Arguments", nargs="*", default=[],
|
parser.add_argument("-AdditionalV8Arguments", nargs="*", default=[],
|
||||||
help="Extra 1cv8 arguments, e.g. /UseHwLicenses+")
|
help="Extra 1cv8 arguments, e.g. /UseHwLicenses+")
|
||||||
parser.add_argument("-AdditionalIbcmdArguments", nargs="*", default=[],
|
parser.add_argument("-AdditionalIbcmdArguments", nargs="*", default=[],
|
||||||
@@ -527,6 +563,7 @@ def main():
|
|||||||
else:
|
else:
|
||||||
print(f"Error updating database configuration (code: {exit_code}){describe_exit(exit_code)}", file=sys.stderr)
|
print(f"Error updating database configuration (code: {exit_code}){describe_exit(exit_code)}", file=sys.stderr)
|
||||||
|
|
||||||
|
log_content = ""
|
||||||
if os.path.isfile(out_file):
|
if os.path.isfile(out_file):
|
||||||
try:
|
try:
|
||||||
with open(out_file, "r", encoding="utf-8-sig") as f:
|
with open(out_file, "r", encoding="utf-8-sig") as f:
|
||||||
@@ -539,6 +576,21 @@ def main():
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
print_platform_output(result)
|
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)
|
sys.exit(exit_code)
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
{
|
||||||
|
"name": "Чистый лог: предупреждения нет (иначе паттерн, ловящий всё подряд, прошёл бы остальные кейсы)",
|
||||||
|
"osOnly": "win32",
|
||||||
|
"preRun": [
|
||||||
|
{
|
||||||
|
"writeFile": {
|
||||||
|
"path": "fake.cmd",
|
||||||
|
"content": "@echo off\r\nrem SELF запоминаем ДО цикла: shift сдвигает и %0, после него %~dp0 указывает не на скрипт\r\nset SELF=%~dp0\r\n:loop\r\nif \"%~1\"==\"\" goto done\r\nif /i \"%~1\"==\"/Out\" set OUT=%~2\r\nshift\r\ngoto loop\r\n:done\r\ncopy /y \"%SELF%log.txt\" \"%OUT%\" >nul\r\nexit /b 0\r\n"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"writeFile": {
|
||||||
|
"path": "log.txt",
|
||||||
|
"content": "Загрузка конфигурации из файлов.\r\nЗагрузка завершена. Суммарное время выполнения операции: 780 миллисекунд.\r\n"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"writeFile": {
|
||||||
|
"path": "ib/1Cv8.1CD",
|
||||||
|
"content": "stub"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"writeFile": {
|
||||||
|
"path": "src/Configuration.xml",
|
||||||
|
"content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<MetaDataObject/>"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"args_extra": [
|
||||||
|
"-V8Path",
|
||||||
|
"{workDir}\\fake.cmd",
|
||||||
|
"-InfoBasePath",
|
||||||
|
"{workDir}\\ib",
|
||||||
|
"-ConfigDir",
|
||||||
|
"{workDir}\\src"
|
||||||
|
],
|
||||||
|
"expect": {
|
||||||
|
"stdoutNotContains": "[warning] platform reported success, but the log contains"
|
||||||
|
},
|
||||||
|
"noSnapshot": "навык ничего не пишет в рабочий каталог — проверяется разбор лога платформы"
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
{
|
||||||
|
"name": "Режим совместимости выше платформы: сообщение классифицируется как отказ (issue #63)",
|
||||||
|
"osOnly": "win32",
|
||||||
|
"preRun": [
|
||||||
|
{
|
||||||
|
"writeFile": {
|
||||||
|
"path": "fake.cmd",
|
||||||
|
"content": "@echo off\r\nrem SELF запоминаем ДО цикла: shift сдвигает и %0, после него %~dp0 указывает не на скрипт\r\nset SELF=%~dp0\r\n:loop\r\nif \"%~1\"==\"\" goto done\r\nif /i \"%~1\"==\"/Out\" set OUT=%~2\r\nshift\r\ngoto loop\r\n:done\r\ncopy /y \"%SELF%log.txt\" \"%OUT%\" >nul\r\nexit /b 0\r\n"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"writeFile": {
|
||||||
|
"path": "log.txt",
|
||||||
|
"content": "Для работы с конфигурацией необходима версия платформы не меньше, чем 8.3.27.\r\nТекущая версия 8.3.24.1691.\r\n"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"writeFile": {
|
||||||
|
"path": "ib/1Cv8.1CD",
|
||||||
|
"content": "stub"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"writeFile": {
|
||||||
|
"path": "src/Configuration.xml",
|
||||||
|
"content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<MetaDataObject/>"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"args_extra": [
|
||||||
|
"-V8Path",
|
||||||
|
"{workDir}\\fake.cmd",
|
||||||
|
"-InfoBasePath",
|
||||||
|
"{workDir}\\ib",
|
||||||
|
"-ConfigDir",
|
||||||
|
"{workDir}\\src"
|
||||||
|
],
|
||||||
|
"expect": {
|
||||||
|
"stdoutContains": [
|
||||||
|
"[warning] platform reported success, but the log contains 1 problem(s):",
|
||||||
|
"необходима версия платформы не меньше"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"noSnapshot": "навык ничего не пишет в рабочий каталог — проверяется разбор лога платформы"
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
{
|
||||||
|
"name": "Тихий отказ в логе: платформа вернула 0, навык предупреждает (fake platform)",
|
||||||
|
"osOnly": "win32",
|
||||||
|
"preRun": [
|
||||||
|
{
|
||||||
|
"writeFile": {
|
||||||
|
"path": "fake.cmd",
|
||||||
|
"content": "@echo off\r\nrem SELF запоминаем ДО цикла: shift сдвигает и %0, после него %~dp0 указывает не на скрипт\r\nset SELF=%~dp0\r\n:loop\r\nif \"%~1\"==\"\" goto done\r\nif /i \"%~1\"==\"/Out\" set OUT=%~2\r\nshift\r\ngoto loop\r\n:done\r\ncopy /y \"%SELF%log.txt\" \"%OUT%\" >nul\r\nexit /b 0\r\n"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"writeFile": {
|
||||||
|
"path": "log.txt",
|
||||||
|
"content": "Загрузка конфигурации из файлов.\r\nНеверное свойство объекта метаданных. Свойство LineNumberLength не входит в состав объекта метаданных TabularSection. - LineNumberLength\r\nЗагрузка завершена.\r\n"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"writeFile": {
|
||||||
|
"path": "ib/1Cv8.1CD",
|
||||||
|
"content": "stub"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"writeFile": {
|
||||||
|
"path": "src/Configuration.xml",
|
||||||
|
"content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<MetaDataObject/>"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"args_extra": [
|
||||||
|
"-V8Path",
|
||||||
|
"{workDir}\\fake.cmd",
|
||||||
|
"-InfoBasePath",
|
||||||
|
"{workDir}\\ib",
|
||||||
|
"-ConfigDir",
|
||||||
|
"{workDir}\\src"
|
||||||
|
],
|
||||||
|
"expect": {
|
||||||
|
"stdoutContains": [
|
||||||
|
"[warning] platform reported success, but the log contains 1 problem(s):",
|
||||||
|
"Свойство LineNumberLength не входит в состав объекта метаданных"
|
||||||
|
],
|
||||||
|
"stdoutNotContains": "-StrictLog"
|
||||||
|
},
|
||||||
|
"noSnapshot": "навык ничего не пишет в рабочий каталог — проверяется разбор лога платформы"
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
{
|
||||||
|
"name": "Тот же лог под -StrictLog: код возврата поднимается до 1 (fake platform)",
|
||||||
|
"osOnly": "win32",
|
||||||
|
"preRun": [
|
||||||
|
{
|
||||||
|
"writeFile": {
|
||||||
|
"path": "fake.cmd",
|
||||||
|
"content": "@echo off\r\nrem SELF запоминаем ДО цикла: shift сдвигает и %0, после него %~dp0 указывает не на скрипт\r\nset SELF=%~dp0\r\n:loop\r\nif \"%~1\"==\"\" goto done\r\nif /i \"%~1\"==\"/Out\" set OUT=%~2\r\nshift\r\ngoto loop\r\n:done\r\ncopy /y \"%SELF%log.txt\" \"%OUT%\" >nul\r\nexit /b 0\r\n"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"writeFile": {
|
||||||
|
"path": "log.txt",
|
||||||
|
"content": "Загрузка конфигурации из файлов.\r\nНеверное свойство объекта метаданных. Свойство LineNumberLength не входит в состав объекта метаданных TabularSection. - LineNumberLength\r\nЗагрузка завершена.\r\n"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"writeFile": {
|
||||||
|
"path": "ib/1Cv8.1CD",
|
||||||
|
"content": "stub"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"writeFile": {
|
||||||
|
"path": "src/Configuration.xml",
|
||||||
|
"content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<MetaDataObject/>"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"args_extra": [
|
||||||
|
"-V8Path",
|
||||||
|
"{workDir}\\fake.cmd",
|
||||||
|
"-InfoBasePath",
|
||||||
|
"{workDir}\\ib",
|
||||||
|
"-ConfigDir",
|
||||||
|
"{workDir}\\src",
|
||||||
|
"-StrictLog"
|
||||||
|
],
|
||||||
|
"expect": {
|
||||||
|
"stdoutContains": "[warning] platform reported success, but the log contains 1 problem(s):"
|
||||||
|
},
|
||||||
|
"noSnapshot": "навык ничего не пишет в рабочий каталог — проверяется разбор лога платформы",
|
||||||
|
"expectError": true
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
{
|
||||||
|
"name": "Чистый лог: предупреждения нет (иначе паттерн, ловящий всё подряд, прошёл бы остальные кейсы)",
|
||||||
|
"osOnly": "win32",
|
||||||
|
"preRun": [
|
||||||
|
{
|
||||||
|
"writeFile": {
|
||||||
|
"path": "fake.cmd",
|
||||||
|
"content": "@echo off\r\nrem SELF запоминаем ДО цикла: shift сдвигает и %0, после него %~dp0 указывает не на скрипт\r\nset SELF=%~dp0\r\n:loop\r\nif \"%~1\"==\"\" goto done\r\nif /i \"%~1\"==\"/Out\" set OUT=%~2\r\nshift\r\ngoto loop\r\n:done\r\ncopy /y \"%SELF%log.txt\" \"%OUT%\" >nul\r\nexit /b 0\r\n"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"writeFile": {
|
||||||
|
"path": "log.txt",
|
||||||
|
"content": "Загрузка конфигурации из файлов.\r\nЗагрузка завершена. Суммарное время выполнения операции: 780 миллисекунд.\r\n"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"writeFile": {
|
||||||
|
"path": "ib/1Cv8.1CD",
|
||||||
|
"content": "stub"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"args_extra": [
|
||||||
|
"-V8Path",
|
||||||
|
"{workDir}\\fake.cmd",
|
||||||
|
"-InfoBasePath",
|
||||||
|
"{workDir}\\ib"
|
||||||
|
],
|
||||||
|
"expect": {
|
||||||
|
"stdoutNotContains": "[warning] platform reported success, but the log contains"
|
||||||
|
},
|
||||||
|
"noSnapshot": "навык ничего не пишет в рабочий каталог — проверяется разбор лога платформы"
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
{
|
||||||
|
"name": "Режим совместимости выше платформы: сообщение классифицируется как отказ (issue #63)",
|
||||||
|
"osOnly": "win32",
|
||||||
|
"preRun": [
|
||||||
|
{
|
||||||
|
"writeFile": {
|
||||||
|
"path": "fake.cmd",
|
||||||
|
"content": "@echo off\r\nrem SELF запоминаем ДО цикла: shift сдвигает и %0, после него %~dp0 указывает не на скрипт\r\nset SELF=%~dp0\r\n:loop\r\nif \"%~1\"==\"\" goto done\r\nif /i \"%~1\"==\"/Out\" set OUT=%~2\r\nshift\r\ngoto loop\r\n:done\r\ncopy /y \"%SELF%log.txt\" \"%OUT%\" >nul\r\nexit /b 0\r\n"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"writeFile": {
|
||||||
|
"path": "log.txt",
|
||||||
|
"content": "Для работы с конфигурацией необходима версия платформы не меньше, чем 8.3.27.\r\nТекущая версия 8.3.24.1691.\r\n"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"writeFile": {
|
||||||
|
"path": "ib/1Cv8.1CD",
|
||||||
|
"content": "stub"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"args_extra": [
|
||||||
|
"-V8Path",
|
||||||
|
"{workDir}\\fake.cmd",
|
||||||
|
"-InfoBasePath",
|
||||||
|
"{workDir}\\ib"
|
||||||
|
],
|
||||||
|
"expect": {
|
||||||
|
"stdoutContains": [
|
||||||
|
"[warning] platform reported success, but the log contains 1 problem(s):",
|
||||||
|
"необходима версия платформы не меньше"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"noSnapshot": "навык ничего не пишет в рабочий каталог — проверяется разбор лога платформы"
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
{
|
||||||
|
"name": "Тихий отказ в логе: платформа вернула 0, навык предупреждает (fake platform)",
|
||||||
|
"osOnly": "win32",
|
||||||
|
"preRun": [
|
||||||
|
{
|
||||||
|
"writeFile": {
|
||||||
|
"path": "fake.cmd",
|
||||||
|
"content": "@echo off\r\nrem SELF запоминаем ДО цикла: shift сдвигает и %0, после него %~dp0 указывает не на скрипт\r\nset SELF=%~dp0\r\n:loop\r\nif \"%~1\"==\"\" goto done\r\nif /i \"%~1\"==\"/Out\" set OUT=%~2\r\nshift\r\ngoto loop\r\n:done\r\ncopy /y \"%SELF%log.txt\" \"%OUT%\" >nul\r\nexit /b 0\r\n"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"writeFile": {
|
||||||
|
"path": "log.txt",
|
||||||
|
"content": "Загрузка конфигурации из файлов.\r\nНеверное свойство объекта метаданных. Свойство LineNumberLength не входит в состав объекта метаданных TabularSection. - LineNumberLength\r\nЗагрузка завершена.\r\n"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"writeFile": {
|
||||||
|
"path": "ib/1Cv8.1CD",
|
||||||
|
"content": "stub"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"args_extra": [
|
||||||
|
"-V8Path",
|
||||||
|
"{workDir}\\fake.cmd",
|
||||||
|
"-InfoBasePath",
|
||||||
|
"{workDir}\\ib"
|
||||||
|
],
|
||||||
|
"expect": {
|
||||||
|
"stdoutContains": [
|
||||||
|
"[warning] platform reported success, but the log contains 1 problem(s):",
|
||||||
|
"Свойство LineNumberLength не входит в состав объекта метаданных"
|
||||||
|
],
|
||||||
|
"stdoutNotContains": "-StrictLog"
|
||||||
|
},
|
||||||
|
"noSnapshot": "навык ничего не пишет в рабочий каталог — проверяется разбор лога платформы"
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
{
|
||||||
|
"name": "Тот же лог под -StrictLog: код возврата поднимается до 1 (fake platform)",
|
||||||
|
"osOnly": "win32",
|
||||||
|
"preRun": [
|
||||||
|
{
|
||||||
|
"writeFile": {
|
||||||
|
"path": "fake.cmd",
|
||||||
|
"content": "@echo off\r\nrem SELF запоминаем ДО цикла: shift сдвигает и %0, после него %~dp0 указывает не на скрипт\r\nset SELF=%~dp0\r\n:loop\r\nif \"%~1\"==\"\" goto done\r\nif /i \"%~1\"==\"/Out\" set OUT=%~2\r\nshift\r\ngoto loop\r\n:done\r\ncopy /y \"%SELF%log.txt\" \"%OUT%\" >nul\r\nexit /b 0\r\n"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"writeFile": {
|
||||||
|
"path": "log.txt",
|
||||||
|
"content": "Загрузка конфигурации из файлов.\r\nНеверное свойство объекта метаданных. Свойство LineNumberLength не входит в состав объекта метаданных TabularSection. - LineNumberLength\r\nЗагрузка завершена.\r\n"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"writeFile": {
|
||||||
|
"path": "ib/1Cv8.1CD",
|
||||||
|
"content": "stub"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"args_extra": [
|
||||||
|
"-V8Path",
|
||||||
|
"{workDir}\\fake.cmd",
|
||||||
|
"-InfoBasePath",
|
||||||
|
"{workDir}\\ib",
|
||||||
|
"-StrictLog"
|
||||||
|
],
|
||||||
|
"expect": {
|
||||||
|
"stdoutContains": "[warning] platform reported success, but the log contains 1 problem(s):"
|
||||||
|
},
|
||||||
|
"noSnapshot": "навык ничего не пишет в рабочий каталог — проверяется разбор лога платформы",
|
||||||
|
"expectError": true
|
||||||
|
}
|
||||||
@@ -214,6 +214,15 @@ const FAMILIES = [
|
|||||||
},
|
},
|
||||||
|
|
||||||
// ─── Обвязка вызова платформы 1С (db-* и потребители) ────────────────────
|
// ─── Обвязка вызова платформы 1С (db-* и потребители) ────────────────────
|
||||||
|
// Детектор строк, о которых платформа сообщает, НЕ поднимая код возврата. Живёт во всех
|
||||||
|
// навыках, читающих /Out-лог загрузки: разъехавшийся список паттернов означал бы, что один
|
||||||
|
// навык ловит тихий отказ, а соседний по той же операции — нет.
|
||||||
|
{
|
||||||
|
name: 'platform: silent_rejections', py: 'find_silent_rejections', ps1: 'Find-SilentRejections',
|
||||||
|
variants: [
|
||||||
|
{ id: 'base', authority: 'db-load-xml', consumers: ['db-load-git', 'db-update'] },
|
||||||
|
],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'platform: resolve_extra_args', py: 'resolve_extra_args', ps1: 'Resolve-ExtraArgs',
|
name: 'platform: resolve_extra_args', py: 'resolve_extra_args', ps1: 'Resolve-ExtraArgs',
|
||||||
variants: [
|
variants: [
|
||||||
|
|||||||
Reference in New Issue
Block a user