mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-08-07 20:20:20 +03:00
feat(meta-validate): add method reference and DocumentJournal column checks
Check 13: validates EventSubscription.Handler and ScheduledJob.MethodName reference format (CommonModuleName.ProcedureName), verifies CommonModule exists and optionally checks BSL for exported procedure. Check 14: validates DocumentJournal Column References are non-empty (empty References causes LoadConfigFromFiles to fail). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
ca328e3e8f
commit
87dc18b120
@@ -1160,6 +1160,100 @@ if ($propsNode -and $forbiddenProperties.ContainsKey($mdType)) {
|
|||||||
Report-OK "12. Forbidden properties: N/A"
|
Report-OK "12. Forbidden properties: N/A"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($script:stopped) { & $finalize; exit 1 }
|
||||||
|
|
||||||
|
# --- Check 13: Method reference validation (EventSubscription.Handler, ScheduledJob.MethodName) ---
|
||||||
|
|
||||||
|
if ($propsNode -and $mdType -in @("EventSubscription","ScheduledJob") -and $script:configDir) {
|
||||||
|
$check13Ok = $true
|
||||||
|
$methodRef = $null
|
||||||
|
$propLabel = $null
|
||||||
|
|
||||||
|
if ($mdType -eq "EventSubscription") {
|
||||||
|
$hNode = $propsNode.SelectSingleNode("md:Handler", $ns)
|
||||||
|
if ($hNode) { $methodRef = $hNode.InnerText.Trim() }
|
||||||
|
$propLabel = "Handler"
|
||||||
|
} elseif ($mdType -eq "ScheduledJob") {
|
||||||
|
$mNode = $propsNode.SelectSingleNode("md:MethodName", $ns)
|
||||||
|
if ($mNode) { $methodRef = $mNode.InnerText.Trim() }
|
||||||
|
$propLabel = "MethodName"
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($methodRef) {
|
||||||
|
$parts = $methodRef.Split('.')
|
||||||
|
if ($parts.Count -ne 2) {
|
||||||
|
Report-Error "13. ${mdType}.${propLabel} = '$methodRef': expected format 'CommonModuleName.ProcedureName'"
|
||||||
|
$check13Ok = $false
|
||||||
|
} else {
|
||||||
|
$cmName = $parts[0]
|
||||||
|
$procName = $parts[1]
|
||||||
|
$cmXml = Join-Path (Join-Path $script:configDir "CommonModules") "$cmName.xml"
|
||||||
|
if (-not (Test-Path $cmXml)) {
|
||||||
|
Report-Error "13. ${mdType}.${propLabel}: CommonModule '$cmName' not found (expected $cmXml)"
|
||||||
|
$check13Ok = $false
|
||||||
|
} else {
|
||||||
|
# Check BSL file for exported procedure
|
||||||
|
$bslPath = Join-Path (Join-Path (Join-Path $script:configDir "CommonModules") $cmName) "Ext/Module.bsl"
|
||||||
|
if (Test-Path $bslPath) {
|
||||||
|
$bslContent = [System.IO.File]::ReadAllText($bslPath, [System.Text.Encoding]::UTF8)
|
||||||
|
# Match: Procedure/Function ProcName(...) Export or Процедура/Функция ProcName(...) Экспорт
|
||||||
|
$exportPattern = "(?mi)^[\s]*(Procedure|Function|Процедура|Функция)\s+$([regex]::Escape($procName))\s*\(.*\)\s+(Export|Экспорт)"
|
||||||
|
if (-not [regex]::IsMatch($bslContent, $exportPattern)) {
|
||||||
|
Report-Warn "13. ${mdType}.${propLabel}: procedure '$procName' not found as exported in CommonModule '$cmName'"
|
||||||
|
$check13Ok = $false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Report-Warn "13. ${mdType}.${propLabel}: BSL file not found ($bslPath), cannot verify procedure"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($check13Ok) {
|
||||||
|
Report-OK "13. Method reference: $propLabel = '$methodRef'"
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Report-OK "13. Method reference: N/A"
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($script:stopped) { & $finalize; exit 1 }
|
||||||
|
|
||||||
|
# --- Check 14: DocumentJournal Column content ---
|
||||||
|
|
||||||
|
if ($mdType -eq "DocumentJournal" -and $childObjNode) {
|
||||||
|
$columns = $childObjNode.SelectNodes("md:Column", $ns)
|
||||||
|
$check14Ok = $true
|
||||||
|
$colCount = 0
|
||||||
|
$emptyRefCount = 0
|
||||||
|
|
||||||
|
foreach ($col in $columns) {
|
||||||
|
$colCount++
|
||||||
|
$colProps = $col.SelectSingleNode("md:Properties", $ns)
|
||||||
|
$colNameNode = if ($colProps) { $colProps.SelectSingleNode("md:Name", $ns) } else { $null }
|
||||||
|
$colName = if ($colNameNode) { $colNameNode.InnerText } else { "(unnamed)" }
|
||||||
|
|
||||||
|
$refs = if ($colProps) { $colProps.SelectSingleNode("md:References", $ns) } else { $null }
|
||||||
|
$hasItems = $false
|
||||||
|
if ($refs) {
|
||||||
|
$items = $refs.SelectNodes("xr:Item", $ns)
|
||||||
|
if ($items.Count -gt 0) { $hasItems = $true }
|
||||||
|
}
|
||||||
|
if (-not $hasItems) {
|
||||||
|
Report-Error "14. DocumentJournal Column '$colName': empty References (will fail on LoadConfigFromFiles)"
|
||||||
|
$check14Ok = $false
|
||||||
|
$emptyRefCount++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($check14Ok -and $colCount -gt 0) {
|
||||||
|
Report-OK "14. DocumentJournal Columns: $colCount column(s), all have References"
|
||||||
|
} elseif ($colCount -eq 0) {
|
||||||
|
Report-OK "14. DocumentJournal Columns: none"
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Report-OK "14. DocumentJournal Columns: N/A"
|
||||||
|
}
|
||||||
|
|
||||||
# --- Final output ---
|
# --- Final output ---
|
||||||
|
|
||||||
& $finalize
|
& $finalize
|
||||||
|
|||||||
@@ -1082,6 +1082,94 @@ if props_node is not None and md_type in forbidden_properties:
|
|||||||
else:
|
else:
|
||||||
report_ok("12. Forbidden properties: N/A")
|
report_ok("12. Forbidden properties: N/A")
|
||||||
|
|
||||||
|
if stopped:
|
||||||
|
finalize()
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
# ── Check 13: Method reference validation ─────────────────────
|
||||||
|
|
||||||
|
if props_node is not None and md_type in ("EventSubscription", "ScheduledJob") and config_dir:
|
||||||
|
check13_ok = True
|
||||||
|
method_ref = None
|
||||||
|
prop_label = None
|
||||||
|
|
||||||
|
if md_type == "EventSubscription":
|
||||||
|
h_node = find(props_node, "md:Handler")
|
||||||
|
if h_node is not None:
|
||||||
|
method_ref = text_of(h_node)
|
||||||
|
prop_label = "Handler"
|
||||||
|
elif md_type == "ScheduledJob":
|
||||||
|
m_node = find(props_node, "md:MethodName")
|
||||||
|
if m_node is not None:
|
||||||
|
method_ref = text_of(m_node)
|
||||||
|
prop_label = "MethodName"
|
||||||
|
|
||||||
|
if method_ref:
|
||||||
|
parts = method_ref.split(".")
|
||||||
|
if len(parts) != 2:
|
||||||
|
report_error(f"13. {md_type}.{prop_label} = '{method_ref}': expected format 'CommonModuleName.ProcedureName'")
|
||||||
|
check13_ok = False
|
||||||
|
else:
|
||||||
|
cm_name = parts[0]
|
||||||
|
proc_name = parts[1]
|
||||||
|
cm_xml = os.path.join(config_dir, "CommonModules", f"{cm_name}.xml")
|
||||||
|
if not os.path.exists(cm_xml):
|
||||||
|
report_error(f"13. {md_type}.{prop_label}: CommonModule '{cm_name}' not found (expected {cm_xml})")
|
||||||
|
check13_ok = False
|
||||||
|
else:
|
||||||
|
# Check BSL file for exported procedure
|
||||||
|
bsl_path = os.path.join(config_dir, "CommonModules", cm_name, "Ext", "Module.bsl")
|
||||||
|
if os.path.exists(bsl_path):
|
||||||
|
with open(bsl_path, "r", encoding="utf-8-sig") as f:
|
||||||
|
bsl_content = f.read()
|
||||||
|
export_pattern = rf"(?mi)^\s*(Procedure|Function|Процедура|Функция)\s+{re.escape(proc_name)}\s*\(.*\)\s+(Export|Экспорт)"
|
||||||
|
if not re.search(export_pattern, bsl_content):
|
||||||
|
report_warn(f"13. {md_type}.{prop_label}: procedure '{proc_name}' not found as exported in CommonModule '{cm_name}'")
|
||||||
|
check13_ok = False
|
||||||
|
else:
|
||||||
|
report_warn(f"13. {md_type}.{prop_label}: BSL file not found ({bsl_path}), cannot verify procedure")
|
||||||
|
|
||||||
|
if check13_ok:
|
||||||
|
report_ok(f"13. Method reference: {prop_label} = '{method_ref}'")
|
||||||
|
else:
|
||||||
|
report_ok("13. Method reference: N/A")
|
||||||
|
|
||||||
|
if stopped:
|
||||||
|
finalize()
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
# ── Check 14: DocumentJournal Column content ──────────────────
|
||||||
|
|
||||||
|
if md_type == "DocumentJournal" and child_obj_node is not None:
|
||||||
|
columns = find_all(child_obj_node, "md:Column")
|
||||||
|
check14_ok = True
|
||||||
|
col_count = 0
|
||||||
|
empty_ref_count = 0
|
||||||
|
|
||||||
|
for col in columns:
|
||||||
|
col_count += 1
|
||||||
|
col_props = find(col, "md:Properties")
|
||||||
|
col_name_node = find(col_props, "md:Name") if col_props is not None else None
|
||||||
|
col_name = inner_text(col_name_node) if col_name_node is not None else "(unnamed)"
|
||||||
|
|
||||||
|
refs = find(col_props, "md:References") if col_props is not None else None
|
||||||
|
has_items = False
|
||||||
|
if refs is not None:
|
||||||
|
items = find_all(refs, "xr:Item")
|
||||||
|
if len(items) > 0:
|
||||||
|
has_items = True
|
||||||
|
if not has_items:
|
||||||
|
report_error(f"14. DocumentJournal Column '{col_name}': empty References (will fail on LoadConfigFromFiles)")
|
||||||
|
check14_ok = False
|
||||||
|
empty_ref_count += 1
|
||||||
|
|
||||||
|
if check14_ok and col_count > 0:
|
||||||
|
report_ok(f"14. DocumentJournal Columns: {col_count} column(s), all have References")
|
||||||
|
elif col_count == 0:
|
||||||
|
report_ok("14. DocumentJournal Columns: none")
|
||||||
|
else:
|
||||||
|
report_ok("14. DocumentJournal Columns: N/A")
|
||||||
|
|
||||||
# ── Final output ──────────────────────────────────────────────
|
# ── Final output ──────────────────────────────────────────────
|
||||||
|
|
||||||
finalize()
|
finalize()
|
||||||
|
|||||||
Reference in New Issue
Block a user