mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-07-16 15:55:16 +03:00
feat(cf-*): set-home-page + drill-down -Section home-page + form-ref валидация
- cf-edit: новая операция set-home-page перезаписывает Ext/HomePageWorkArea.xml. DSL принимает template (OneColumn/TwoColumnsEqualWidth/TwoColumnsVariableWidth), left/right с записями форм (строка или объект form/height/visibility/roles). Тихая нормализация ссылок: русские типы, 3-сегмент → авто-Form, файловые пути - cf-info: краткая HP-сводка (template + счётчики) в overview/full, детальный вид через -Section home-page (alias -Name) с раскладкой и переопределениями ролей - cf-validate: Check 9 — валидация ссылок на формы из HomePageWorkArea и Default*Form свойств; битая ссылка → error - reference.md: убран реализационный шум (canonical sort, авто-нормализация форм, panelDef detail, секция авто-валидации); путь src/ в примерах вместо репо-специфичных 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
# cf-validate v1.2 — Validate 1C configuration root structure
|
||||
# cf-validate v1.3 — Validate 1C configuration root structure
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
@@ -536,6 +536,72 @@ if ($childObjNode) {
|
||||
}
|
||||
}
|
||||
|
||||
# --- Check 9: Form references (HomePageWorkArea + Properties) ---
|
||||
function Test-FormRef([string]$ref) {
|
||||
if (-not $ref) { return $true }
|
||||
# UUID — cannot verify without scanning all forms; skip
|
||||
if ($ref -match $guidPattern) { return $true }
|
||||
$parts = $ref.Split(".")
|
||||
if ($parts.Count -eq 2 -and $parts[0] -eq "CommonForm") {
|
||||
$p = Join-Path (Join-Path (Join-Path $configDir "CommonForms") $parts[1]) "Form.xml"
|
||||
$pExt = Join-Path (Join-Path (Join-Path (Join-Path $configDir "CommonForms") $parts[1]) "Ext") "Form.xml"
|
||||
return (Test-Path $p) -or (Test-Path $pExt)
|
||||
}
|
||||
if ($parts.Count -eq 4 -and $parts[2] -eq "Form" -and $childTypeDirMap.ContainsKey($parts[0])) {
|
||||
$dir = $childTypeDirMap[$parts[0]]
|
||||
$p = Join-Path (Join-Path (Join-Path (Join-Path (Join-Path $configDir $dir) $parts[1]) "Forms") $parts[3]) "Form.xml"
|
||||
$pExt = Join-Path (Join-Path (Join-Path (Join-Path (Join-Path (Join-Path $configDir $dir) $parts[1]) "Forms") $parts[3]) "Ext") "Form.xml"
|
||||
return (Test-Path $p) -or (Test-Path $pExt)
|
||||
}
|
||||
return $false
|
||||
}
|
||||
|
||||
$formRefsChecked = 0
|
||||
$formRefErrors = @()
|
||||
|
||||
# HomePageWorkArea
|
||||
$hpPath = Join-Path (Join-Path $configDir "Ext") "HomePageWorkArea.xml"
|
||||
if (Test-Path $hpPath) {
|
||||
try {
|
||||
[xml]$hpDoc = Get-Content -Path $hpPath -Encoding UTF8
|
||||
$hpNs = New-Object System.Xml.XmlNamespaceManager($hpDoc.NameTable)
|
||||
$hpNs.AddNamespace("hp", "http://v8.1c.ru/8.3/xcf/extrnprops")
|
||||
foreach ($f in $hpDoc.DocumentElement.SelectNodes("//hp:Item/hp:Form", $hpNs)) {
|
||||
$ref = $f.InnerText.Trim()
|
||||
if (-not $ref) { continue }
|
||||
$formRefsChecked++
|
||||
if (-not (Test-FormRef $ref)) {
|
||||
$formRefErrors += "HomePageWorkArea.Form '$ref' — file not found"
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
$formRefErrors += "HomePageWorkArea.xml: parse error — $($_.Exception.Message)"
|
||||
}
|
||||
}
|
||||
|
||||
# Properties: DefaultXxxForm refs
|
||||
if ($propsNode) {
|
||||
$formProps = @("DefaultReportForm","DefaultReportVariantForm","DefaultReportSettingsForm","DefaultDynamicListSettingsForm","DefaultSearchForm","DefaultDataHistoryChangeHistoryForm","DefaultDataHistoryVersionDataForm","DefaultDataHistoryVersionDifferencesForm","DefaultCollaborationSystemUsersChoiceForm","DefaultConstantsForm")
|
||||
foreach ($pn in $formProps) {
|
||||
$node = $propsNode.SelectSingleNode("md:$pn", $ns)
|
||||
if ($node -and $node.InnerText.Trim()) {
|
||||
$ref = $node.InnerText.Trim()
|
||||
$formRefsChecked++
|
||||
if (-not (Test-FormRef $ref)) {
|
||||
$formRefErrors += "Properties.$pn '$ref' — form not found"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($formRefsChecked -eq 0) {
|
||||
Report-OK "9. Form references: none to check"
|
||||
} elseif ($formRefErrors.Count -eq 0) {
|
||||
Report-OK "9. Form references: $formRefsChecked verified"
|
||||
} else {
|
||||
foreach ($err in $formRefErrors) { Report-Error "9. $err" }
|
||||
}
|
||||
|
||||
# --- Final output ---
|
||||
& $finalize
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# cf-validate v1.2 — Validate 1C configuration XML structure
|
||||
# cf-validate v1.3 — Validate 1C configuration XML structure
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
"""Validates Configuration.xml: root structure, InternalInfo, properties, ChildObjects, languages."""
|
||||
import sys, os, argparse, re
|
||||
@@ -537,6 +537,60 @@ def main():
|
||||
else:
|
||||
pass # no ChildObjects
|
||||
|
||||
# --- Check 9: Form references (HomePageWorkArea + Properties) ---
|
||||
def test_form_ref(ref):
|
||||
if not ref:
|
||||
return True
|
||||
if GUID_PATTERN.match(ref):
|
||||
return True
|
||||
parts = ref.split('.')
|
||||
if len(parts) == 2 and parts[0] == 'CommonForm':
|
||||
p = os.path.join(config_dir, 'CommonForms', parts[1], 'Form.xml')
|
||||
p_ext = os.path.join(config_dir, 'CommonForms', parts[1], 'Ext', 'Form.xml')
|
||||
return os.path.isfile(p) or os.path.isfile(p_ext)
|
||||
if len(parts) == 4 and parts[2] == 'Form' and parts[0] in CHILD_TYPE_DIR_MAP:
|
||||
d = CHILD_TYPE_DIR_MAP[parts[0]]
|
||||
p = os.path.join(config_dir, d, parts[1], 'Forms', parts[3], 'Form.xml')
|
||||
p_ext = os.path.join(config_dir, d, parts[1], 'Forms', parts[3], 'Ext', 'Form.xml')
|
||||
return os.path.isfile(p) or os.path.isfile(p_ext)
|
||||
return False
|
||||
|
||||
form_refs_checked = 0
|
||||
form_ref_errors = []
|
||||
|
||||
hp_path = os.path.join(config_dir, 'Ext', 'HomePageWorkArea.xml')
|
||||
if os.path.isfile(hp_path):
|
||||
try:
|
||||
hp_tree = etree.parse(hp_path)
|
||||
HP_NS = 'http://v8.1c.ru/8.3/xcf/extrnprops'
|
||||
for f in hp_tree.getroot().iter(f'{{{HP_NS}}}Form'):
|
||||
ref = (f.text or '').strip()
|
||||
if not ref:
|
||||
continue
|
||||
form_refs_checked += 1
|
||||
if not test_form_ref(ref):
|
||||
form_ref_errors.append(f"HomePageWorkArea.Form '{ref}' — file not found")
|
||||
except Exception as e:
|
||||
form_ref_errors.append(f'HomePageWorkArea.xml: parse error — {e}')
|
||||
|
||||
if props_node is not None:
|
||||
form_props = ['DefaultReportForm','DefaultReportVariantForm','DefaultReportSettingsForm','DefaultDynamicListSettingsForm','DefaultSearchForm','DefaultDataHistoryChangeHistoryForm','DefaultDataHistoryVersionDataForm','DefaultDataHistoryVersionDifferencesForm','DefaultCollaborationSystemUsersChoiceForm','DefaultConstantsForm']
|
||||
for pn in form_props:
|
||||
node = props_node.find(f'md:{pn}', NS)
|
||||
if node is not None and node.text and node.text.strip():
|
||||
ref = node.text.strip()
|
||||
form_refs_checked += 1
|
||||
if not test_form_ref(ref):
|
||||
form_ref_errors.append(f"Properties.{pn} '{ref}' — form not found")
|
||||
|
||||
if form_refs_checked == 0:
|
||||
r.ok('9. Form references: none to check')
|
||||
elif not form_ref_errors:
|
||||
r.ok(f'9. Form references: {form_refs_checked} verified')
|
||||
else:
|
||||
for err in form_ref_errors:
|
||||
r.error(f'9. {err}')
|
||||
|
||||
# --- Final output ---
|
||||
r.finalize(out_file)
|
||||
sys.exit(1 if r.errors > 0 else 0)
|
||||
|
||||
Reference in New Issue
Block a user