Auto-register role in Configuration.xml

role-compile: after generating files, automatically inserts
<Role>Name</Role> into Configuration.xml ChildObjects (idempotent).
role-validate: checks that the role is registered, warns if not.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Nick Shirokov
2026-02-10 13:29:50 +03:00
parent 3a4c1905f4
commit e229fc4873
3 changed files with 127 additions and 3 deletions
+1 -1
View File
@@ -24,7 +24,7 @@ allowed-tools:
powershell.exe -NoProfile -File .claude\skills\role-compile\scripts\role-compile.ps1 -JsonPath "<json>" -OutputDir "<RolesDir>"
```
После генерации: добавить `<Role>ИмяРоли</Role>` в `<ChildObjects>` файла `Configuration.xml`.
`<Role>ИмяРоли</Role>` автоматически добавляется в `<ChildObjects>` файла `Configuration.xml` (ожидается в parent от `RolesDir`).
## JSON DSL
@@ -628,10 +628,86 @@ $enc = New-Object System.Text.UTF8Encoding($true)
[System.IO.File]::WriteAllText($metadataPath, $metadataXml, $enc)
[System.IO.File]::WriteAllText($rightsPath, $rightsXml, $enc)
# --- 12. Summary ---
# --- 12. Register in Configuration.xml ---
$configDir = Split-Path $outDir -Parent
$configXmlPath = Join-Path $configDir "Configuration.xml"
$regResult = $null
if (Test-Path $configXmlPath) {
$configDoc = New-Object System.Xml.XmlDocument
$configDoc.PreserveWhitespace = $true
$configDoc.Load($configXmlPath)
$nsMgr = New-Object System.Xml.XmlNamespaceManager($configDoc.NameTable)
$nsMgr.AddNamespace("md", "http://v8.1c.ru/8.3/MDClasses")
$childObjects = $configDoc.SelectSingleNode("//md:Configuration/md:ChildObjects", $nsMgr)
if ($childObjects) {
$existing = $childObjects.SelectNodes("md:Role", $nsMgr)
$alreadyExists = $false
foreach ($r in $existing) {
if ($r.InnerText -eq $roleName) {
$alreadyExists = $true
break
}
}
if ($alreadyExists) {
$regResult = "already"
} else {
$roleElem = $configDoc.CreateElement("Role", "http://v8.1c.ru/8.3/MDClasses")
$roleElem.InnerText = $roleName
if ($existing.Count -gt 0) {
# Insert after last existing <Role>
$lastRole = $existing[$existing.Count - 1]
$newWs = $configDoc.CreateWhitespace("`n`t`t`t")
$childObjects.InsertAfter($newWs, $lastRole) | Out-Null
$childObjects.InsertAfter($roleElem, $newWs) | Out-Null
} else {
# No existing roles — insert before closing whitespace
$lastChild = $childObjects.LastChild
if ($lastChild.NodeType -eq [System.Xml.XmlNodeType]::Whitespace) {
$newWs = $configDoc.CreateWhitespace("`n`t`t`t")
$childObjects.InsertBefore($newWs, $lastChild) | Out-Null
$childObjects.InsertBefore($roleElem, $lastChild) | Out-Null
} else {
$childObjects.AppendChild($configDoc.CreateWhitespace("`n`t`t`t")) | Out-Null
$childObjects.AppendChild($roleElem) | Out-Null
$childObjects.AppendChild($configDoc.CreateWhitespace("`n`t`t")) | Out-Null
}
}
# Save
$cfgSettings = New-Object System.Xml.XmlWriterSettings
$cfgSettings.Encoding = New-Object System.Text.UTF8Encoding($true)
$cfgSettings.Indent = $false
$stream = New-Object System.IO.FileStream($configXmlPath, [System.IO.FileMode]::Create)
$writer = [System.Xml.XmlWriter]::Create($stream, $cfgSettings)
$configDoc.Save($writer)
$writer.Close()
$stream.Close()
$regResult = "added"
}
} else {
$regResult = "no-childobj"
}
} else {
$regResult = "no-config"
}
# --- 13. Summary ---
Write-Host "[OK] Role '$roleName' compiled"
Write-Host " UUID: $uuid"
Write-Host " Metadata: $metadataPath"
Write-Host " Rights: $rightsPath"
Write-Host " Objects: $($parsedObjects.Count), Rights: $totalRights, Templates: $templateCount"
switch ($regResult) {
"added" { Write-Host " Configuration.xml: <Role>$roleName</Role> added to ChildObjects" }
"already" { Write-Host " Configuration.xml: <Role>$roleName</Role> already registered" }
"no-childobj" { Write-Warning "Configuration.xml found but <ChildObjects> not found" }
"no-config" { Write-Warning "Configuration.xml not found at $configXmlPath — register manually" }
}
@@ -401,7 +401,55 @@ if ($MetadataPath) {
}
}
# --- 5. Summary ---
# --- 5. Check registration in Configuration.xml ---
# Infer paths: RightsPath = .../Roles/Name/Ext/Rights.xml
$extDir2 = Split-Path (Resolve-Path $RightsPath).Path -Parent
$roleDir2 = Split-Path $extDir2 -Parent
$rolesDir2 = Split-Path $roleDir2 -Parent
$configDir2 = Split-Path $rolesDir2 -Parent
$configXmlPath2 = Join-Path $configDir2 "Configuration.xml"
$inferredRoleName = Split-Path $roleDir2 -Leaf
# Use metadata name if available
if ($MetadataPath -and (Test-Path $MetadataPath)) {
try {
[xml]$metaXml2 = Get-Content -Path $MetadataPath -Encoding UTF8
$nameNode2 = $metaXml2.DocumentElement.SelectSingleNode("//*[local-name()='Role']//*[local-name()='Name']")
if ($nameNode2 -and $nameNode2.InnerText) {
$inferredRoleName = $nameNode2.InnerText
}
} catch { }
}
if (Test-Path $configXmlPath2) {
$script:lines += ""
try {
[xml]$cfgXml = Get-Content -Path $configXmlPath2 -Encoding UTF8
$cfgNs = New-Object System.Xml.XmlNamespaceManager($cfgXml.NameTable)
$cfgNs.AddNamespace("md", "http://v8.1c.ru/8.3/MDClasses")
$childObj = $cfgXml.SelectSingleNode("//md:Configuration/md:ChildObjects", $cfgNs)
if ($childObj) {
$roleNodes = $childObj.SelectNodes("md:Role", $cfgNs)
$found = $false
foreach ($rn in $roleNodes) {
if ($rn.InnerText -eq $inferredRoleName) {
$found = $true
break
}
}
if ($found) {
Out-OK "Configuration.xml: <Role>$inferredRoleName</Role> registered"
} else {
Out-WARN "Configuration.xml: <Role>$inferredRoleName</Role> NOT found in ChildObjects"
}
}
} catch {
Out-WARN "Configuration.xml: parse error — $($_.Exception.Message)"
}
}
# --- 6. Summary ---
$script:lines += "---"
$script:lines += "Result: $($script:errors) error(s), $($script:warnings) warning(s)"