mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-09-20 00:45:54 +03:00
fix(role-edit): пустой узел после отброшенного запрета и разворот массива в PS
Два дефекта, найденных вычиткой перед ревью. deny-rights создавал узел объекта и, если фильтр умолчаний отбрасывал все запреты, оставлял его пустым — в файл он попадал, когда сохранение инициировала соседняя операция. Платформа пустых узлов не производит (0 на 223k узлов корпуса). Теперь созданный впустую узел убирается. Правило удаления узла было «не осталось разрешающих прав» — наследие решения «false это шум». Замеры показали обратное: узел с одними запретами осмыслен, так закрывают реквизит. Узел удаляется, только если в нём не осталось прав вообще. Там же закрыт разворот массива: `return @(...)` из функции отдаёт единственный элемент скаляром, у которого .Count равен $null, поэтому узел с ОДНИМ правом считался пустым и удалялся целиком. Поймал гард минимального дифа: снятие одного права давало -11 строк вместо -4. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FGkXwoXTuafcu1SXMsauFq
This commit is contained in:
co-authored by
Claude Opus 5
parent
e8c92362d5
commit
5ec732e12b
@@ -1,4 +1,4 @@
|
||||
# role-edit v1.5 — Edit existing 1C role rights in place
|
||||
# role-edit v1.6 — Edit existing 1C role rights in place
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
[CmdletBinding(PositionalBinding=$false)]
|
||||
param(
|
||||
@@ -1713,12 +1713,15 @@ function New-ObjectNode([string]$objName) {
|
||||
return $nodes[0]
|
||||
}
|
||||
|
||||
# Узел без единого разрешающего права платформа не производит: остаточные запреты уходят с ним.
|
||||
function Remove-ObjectIfNoTrueRights($objNode) {
|
||||
if ((Get-TrueRightNames $objNode).Count -gt 0) { return $false }
|
||||
# Пустых узлов платформа не производит. Узел с одними запретами — производит (так закрывают
|
||||
# реквизит), поэтому смотрим на наличие прав вообще, а не только разрешающих.
|
||||
function Remove-ObjectIfEmpty($objNode) {
|
||||
# @() на месте использования: return из функции разворачивает массив из одного элемента,
|
||||
# и .Count у него $null — узел с единственным правом считался бы пустым.
|
||||
if (@(Get-RightNodes $objNode).Count -gt 0) { return $false }
|
||||
$name = Get-ObjectNodeName $objNode
|
||||
Remove-NodeWithWhitespace $objNode
|
||||
Add-Note " ${name}: разрешающих прав не осталось — узел объекта удалён"
|
||||
Add-Note " ${name}: прав не осталось — узел объекта удалён"
|
||||
return $true
|
||||
}
|
||||
|
||||
@@ -1852,7 +1855,7 @@ function Apply-SetRights($spec) {
|
||||
$script:rightsDirty = $true
|
||||
Add-Note " $($spec.Name): набор прав заменён"
|
||||
if ($droppedRls -gt 0) { Add-Note "[WARN] $($spec.Name): снято ограничений RLS: $droppedRls" }
|
||||
Remove-ObjectIfNoTrueRights $objNode | Out-Null
|
||||
Remove-ObjectIfEmpty $objNode | Out-Null
|
||||
}
|
||||
|
||||
function Do-RemoveRights([string]$batchVal) {
|
||||
@@ -1901,7 +1904,7 @@ function Apply-RemoveRights($spec) {
|
||||
$note = " $($spec.Name): снято — $($removed -join ', ')"
|
||||
if ($cascade.Count -gt 0) { $note += " (каскадом: $($cascade -join ', '))" }
|
||||
Add-Note $note
|
||||
Remove-ObjectIfNoTrueRights $objNode | Out-Null
|
||||
Remove-ObjectIfEmpty $objNode | Out-Null
|
||||
}
|
||||
|
||||
function Do-DenyRights([string]$batchVal) {
|
||||
@@ -1914,9 +1917,11 @@ function Do-DenyRights([string]$batchVal) {
|
||||
|
||||
function Apply-DenyRights($spec) {
|
||||
$objNode = Find-ObjectNode $spec.Name
|
||||
$created = $false
|
||||
if (-not $objNode) {
|
||||
$objNode = New-ObjectNode $spec.Name
|
||||
Insert-ObjectNode $objNode $spec.Name
|
||||
$created = $true
|
||||
}
|
||||
$toDeny = @()
|
||||
foreach ($rightName in $spec.Rights) {
|
||||
@@ -1943,6 +1948,7 @@ function Apply-DenyRights($spec) {
|
||||
$script:rightsDirty = $true
|
||||
}
|
||||
if ($denied.Count -eq 0) {
|
||||
if ($created) { Remove-NodeWithWhitespace $objNode }
|
||||
$reason = if ($script:droppedByDefault -match [regex]::Escape($spec.Name)) { "запрет совпадает с умолчанием роли и платформой не хранится" } else { "права уже запрещены" }
|
||||
Add-Note " $($spec.Name): $reason, изменений нет"
|
||||
return
|
||||
@@ -2031,7 +2037,7 @@ function Apply-SetRls($spec) {
|
||||
# Строка без полей («прочие поля») идёт первой, строки с полями — после неё.
|
||||
$refNode = $null
|
||||
if ($spec.Fields.Count -eq 0) {
|
||||
foreach ($node in $existing) { if ((Get-RestrictionFields $node).Count -gt 0) { $refNode = $node; break } }
|
||||
foreach ($node in $existing) { if (@(Get-RestrictionFields $node).Count -gt 0) { $refNode = $node; break } }
|
||||
}
|
||||
Insert-BeforeElement $rightNode $new $refNode $indent
|
||||
$script:addCount++
|
||||
@@ -2062,7 +2068,7 @@ function Apply-RemoveRls($spec) {
|
||||
$removed = 0
|
||||
foreach ($node in @($rightNode.SelectNodes("rt:restrictionByCondition", $script:ns))) {
|
||||
# Адрес без скобок снимает все ограничения права, со скобками — строку с этим набором полей.
|
||||
if ($spec.Fields.Count -gt 0 -and -not (Test-SameFieldSet (Get-RestrictionFields $node) $spec.Fields)) { continue }
|
||||
if (@($spec.Fields).Count -gt 0 -and -not (Test-SameFieldSet (Get-RestrictionFields $node) $spec.Fields)) { continue }
|
||||
Remove-NodeWithWhitespace $node
|
||||
$removed++
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# role-edit v1.5 — Edit existing 1C role rights in place
|
||||
# role-edit v1.6 — Edit existing 1C role rights in place
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
import argparse
|
||||
import json
|
||||
@@ -1740,13 +1740,14 @@ class Editor:
|
||||
ref = templates[0]
|
||||
self.insert_child(self.root, new_el, ref, indent)
|
||||
|
||||
# Узел без единого разрешающего права платформа не производит.
|
||||
def remove_object_if_no_true_rights(self, obj_node):
|
||||
if self.true_right_names(obj_node):
|
||||
# Пустых узлов платформа не производит. Узел с одними запретами — производит (так закрывают
|
||||
# реквизит), поэтому смотрим на наличие прав вообще, а не только разрешающих.
|
||||
def remove_object_if_empty(self, obj_node):
|
||||
if self.right_nodes(obj_node):
|
||||
return
|
||||
name = node_text(obj_node, "name")
|
||||
self.remove_child(obj_node)
|
||||
self.note(f" {name}: разрешающих прав не осталось — узел объекта удалён")
|
||||
self.note(f" {name}: прав не осталось — узел объекта удалён")
|
||||
|
||||
# --- Зависимости ---
|
||||
|
||||
@@ -1857,7 +1858,7 @@ class Editor:
|
||||
self.note(f" {spec['Name']}: набор прав заменён")
|
||||
if dropped_rls:
|
||||
self.note(f"[WARN] {spec['Name']}: снято ограничений RLS: {dropped_rls}")
|
||||
self.remove_object_if_no_true_rights(obj_node)
|
||||
self.remove_object_if_empty(obj_node)
|
||||
|
||||
def apply_remove_rights(self, spec):
|
||||
obj_node = self.find_object(spec["Name"])
|
||||
@@ -1894,13 +1895,15 @@ class Editor:
|
||||
if cascade:
|
||||
note += f" (каскадом: {', '.join(cascade)})"
|
||||
self.note(note)
|
||||
self.remove_object_if_no_true_rights(obj_node)
|
||||
self.remove_object_if_empty(obj_node)
|
||||
|
||||
def apply_deny_rights(self, spec):
|
||||
obj_node = self.find_object(spec["Name"])
|
||||
created = False
|
||||
if obj_node is None:
|
||||
obj_node = self.make_object(spec["Name"], self.child_indent(self.root))
|
||||
self.insert_object_node(obj_node, spec["Name"])
|
||||
created = True
|
||||
to_deny = []
|
||||
for right_name in spec["Rights"]:
|
||||
to_deny.append(right_name)
|
||||
@@ -1925,6 +1928,8 @@ class Editor:
|
||||
denied.append(right_name)
|
||||
self.rights_dirty = True
|
||||
if not denied:
|
||||
if created:
|
||||
self.remove_child(obj_node)
|
||||
reason = ("запрет совпадает с умолчанием роли и платформой не хранится"
|
||||
if any(d.startswith(spec['Name'] + '.') for d in self.dropped_by_default)
|
||||
else "права уже запрещены")
|
||||
|
||||
Reference in New Issue
Block a user