feat(form-compile): drop-on-miss warn для enum ориентации/behavior + выравнивание портов

Нераспознанное значение ориентации (group/columnGroup/page) и behavior теперь даёт
WARN с авторским набором допустимых значений — раньше промах по карте молча не
эмитил тег (тихая потеря). pass-through-ключи не трогаем (там verbatim, потери нет).

Заодно выровнен регистр enum-резолва ориентации между портами: py был
case-sensitive у columnGroup/page, ps1 (switch) — нет; теперь оба нечувствительны.

v1.172. Регресс form-compile 43/43 (ps1+py), form-validate 10/10.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Nick Shirokov
2026-06-14 13:16:28 +03:00
parent 09d7097476
commit 1c21bef26c
2 changed files with 32 additions and 8 deletions
@@ -1,4 +1,4 @@
# form-compile v1.171 — Compile 1C managed form from JSON or object metadata
# form-compile v1.172 — Compile 1C managed form from JSON or object metadata
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
param(
[string]$JsonPath,
@@ -3719,6 +3719,12 @@ function Emit-TitleLocation {
}
}
function Warn-Unrecognized {
# drop-on-miss enum: значение не распознано → тег не эмитится. Громко, чтобы автор увидел потерю.
param([string]$key, $raw, [string[]]$valid, [string]$owner)
Write-Warning "Unrecognized $key '$raw' on '$owner'. Valid values: $($valid -join ', '). Value ignored."
}
function Emit-Group {
param($el, [string]$name, [int]$id, [string]$indent)
@@ -3739,6 +3745,7 @@ function Emit-Group {
default { $null }
}
if ($orientation) { X "$inner<Group>$orientation</Group>" }
elseif ($groupVal) { Warn-Unrecognized 'group orientation' $el.group @('vertical','horizontalIfPossible','alwaysHorizontal') $name }
# Behavior: ключ behavior (usual/collapsible/popup) → <Behavior>; отсутствие = Авто (не эмитим).
# Legacy: group:'collapsible' эквивалентно behavior:'collapsible'.
@@ -3746,6 +3753,8 @@ function Emit-Group {
$bmap = @{ "usual"="Usual"; "collapsible"="Collapsible"; "popup"="PopUp" }
if ($behaviorVal -and $bmap.ContainsKey($behaviorVal)) {
X "$inner<Behavior>$($bmap[$behaviorVal])</Behavior>"
} elseif ($el.behavior -and -not $bmap.ContainsKey($behaviorVal)) {
Warn-Unrecognized 'behavior' $el.behavior @('collapsible','popup') $name
}
# Collapsed — у Collapsible и PopUp (не привязано к одному behavior)
if ($el.collapsed -eq $true) { X "$inner<Collapsed>true</Collapsed>" }
@@ -3815,6 +3824,7 @@ function Emit-ColumnGroup {
default { $null }
}
if ($orientation) { X "$inner<Group>$orientation</Group>" }
elseif ($groupVal) { Warn-Unrecognized 'columnGroup orientation' $el.columnGroup @('vertical','horizontal','inCell') $name }
if ($null -ne $el.showTitle) { X "$inner<ShowTitle>$(if ($el.showTitle){'true'}else{'false'})</ShowTitle>" }
# showInHeader эмитится общим Emit-CommonElementProps (через Emit-Layout)
@@ -4698,6 +4708,7 @@ function Emit-Page {
default { $null }
}
if ($orientation) { X "$inner<Group>$orientation</Group>" }
else { Warn-Unrecognized 'page group orientation' $el.group @('vertical','horizontalIfPossible','alwaysHorizontal') $name }
}
if ($null -ne $el.showTitle) { X "$inner<ShowTitle>$(if ($el.showTitle){'true'}else{'false'})</ShowTitle>" }
# Формат значения пути к данным заголовка (<Format>; парный к titleDataPath страницы)
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
# form-compile v1.171 — Compile 1C managed form from JSON or object metadata
# form-compile v1.172 — Compile 1C managed form from JSON or object metadata
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
import argparse
import copy
@@ -3827,6 +3827,11 @@ def emit_element(lines, el, indent, in_cmd_bar=False):
emitter(lines, el, name, eid, indent)
def _warn_unrecognized(key, raw, valid, owner):
# drop-on-miss enum: значение не распознано → тег не эмитится. Громко, чтобы автор увидел потерю.
print(f"[WARN] Unrecognized {key} '{raw}' on '{owner}'. Valid values: {', '.join(valid)}. Value ignored.")
def emit_group(lines, el, name, eid, indent):
lines.append(f'{indent}<UsualGroup name="{name}" id="{eid}"{di_attr(el)}>')
inner = f'{indent}\t'
@@ -3847,12 +3852,16 @@ def emit_group(lines, el, name, eid, indent):
orientation = orientation_map.get(group_val)
if orientation:
lines.append(f'{inner}<Group>{orientation}</Group>')
elif group_val:
_warn_unrecognized('group orientation', el.get('group'), ('vertical', 'horizontalIfPossible', 'alwaysHorizontal'), name)
# Behavior: ключ behavior (usual/collapsible/popup) → <Behavior>; отсутствие = Авто (не эмитим).
behavior_val = str(el['behavior']).lower() if el.get('behavior') else ('collapsible' if group_val == 'collapsible' else None)
bmap = {'usual': 'Usual', 'collapsible': 'Collapsible', 'popup': 'PopUp'}
if behavior_val and behavior_val in bmap:
lines.append(f'{inner}<Behavior>{bmap[behavior_val]}</Behavior>')
elif el.get('behavior') and behavior_val not in bmap:
_warn_unrecognized('behavior', el.get('behavior'), ('collapsible', 'popup'), name)
# Collapsed — у Collapsible и PopUp (не привязано к одному behavior)
if el.get('collapsed') is True:
lines.append(f'{inner}<Collapsed>true</Collapsed>')
@@ -3914,15 +3923,17 @@ def emit_column_group(lines, el, name, eid, indent):
emit_title(lines, el, name, inner)
group_val = str(el.get('columnGroup', ''))
group_val = str(el.get('columnGroup', '')).lower()
orientation_map = {
'horizontal': 'Horizontal',
'vertical': 'Vertical',
'inCell': 'InCell',
'incell': 'InCell',
}
orientation = orientation_map.get(group_val)
if orientation:
lines.append(f'{inner}<Group>{orientation}</Group>')
elif group_val:
_warn_unrecognized('columnGroup orientation', el.get('columnGroup'), ('vertical', 'horizontal', 'inCell'), name)
if el.get('showTitle') is not None:
lines.append(f'{inner}<ShowTitle>{"true" if el["showTitle"] else "false"}</ShowTitle>')
@@ -4428,13 +4439,15 @@ def emit_page(lines, el, name, eid, indent):
orientation_map = {
'horizontal': 'Horizontal',
'vertical': 'Vertical',
'alwaysHorizontal': 'AlwaysHorizontal',
'alwaysVertical': 'AlwaysVertical',
'horizontalIfPossible': 'HorizontalIfPossible',
'alwayshorizontal': 'AlwaysHorizontal',
'alwaysvertical': 'AlwaysVertical',
'horizontalifpossible': 'HorizontalIfPossible',
}
orientation = orientation_map.get(str(el['group']))
orientation = orientation_map.get(str(el['group']).lower())
if orientation:
lines.append(f'{inner}<Group>{orientation}</Group>')
else:
_warn_unrecognized('page group orientation', el['group'], ('vertical', 'horizontalIfPossible', 'alwaysHorizontal'), name)
if el.get('showTitle') is not None:
lines.append(f'{inner}<ShowTitle>{"true" if el["showTitle"] else "false"}</ShowTitle>')
# Формат значения пути к данным заголовка (<Format>; парный к titleDataPath страницы)