Private/StandardInheritance.ps1
|
# Resolve standards without evaluating code or depending on the caller's folder. # Discovery and the Extends chain live in Bootstrap\Import-SecondLine.ps1, shared # with the pre-import bootstrap. This file merges the chain into one standard. $script:SLDevelopmentStandard = Join-Path (Split-Path $PSScriptRoot -Parent) 'Standards\development.psd1' # Sections merged by key, child values winning, instead of replaced whole. $script:SLKeyedSections = @('ModuleVersions', 'Updates') function Read-SLStandardData { param([string] $Path) $chain = @(Get-SLStandardChain -Path $Path -DevelopmentPath $script:SLDevelopmentStandard) $merged = $chain[$chain.Count - 1].Data for ($i = $chain.Count - 2; $i -ge 0; $i--) { $merged = Merge-SLStandardData -Base $merged -Data $chain[$i].Data } return $merged } # One inheritance step: Data (the child) over Base (its merged parents). function Merge-SLStandardData { param([Parameter(Mandatory)] [hashtable] $Base, [Parameter(Mandatory)] [hashtable] $Data) $merged = @{} foreach ($key in $Base.Keys) { $merged[$key] = $Base[$key] } foreach ($key in $Data.Keys) { if ($key -in @('Tools', 'GitAttributes', 'Extends')) { continue } if ($key -in $script:SLKeyedSections -and $Base[$key] -is [hashtable] -and $Data[$key] -is [hashtable]) { $values = @{} foreach ($entry in $Base[$key].Keys) { $values[$entry] = $Base[$key][$entry] } foreach ($entry in $Data[$key].Keys) { $values[$entry] = $Data[$key][$entry] } $merged[$key] = $values } else { $merged[$key] = $Data[$key] } } # Child entries replace complete tools by Name, preserving distinct inherited tools. $tools = @($Base.Tools) if ($null -eq $Base.Tools) { $tools = @() } foreach ($tool in @($Data.Tools)) { if ($null -eq $tool) { continue } if ($tool -is [hashtable] -and $tool.Name) { $tools = @($tools | Where-Object { $_.Name -ne $tool.Name }) } $tools += $tool } if ($Base.ContainsKey('Tools') -or $Data.ContainsKey('Tools')) { $merged.Tools = $tools } if ($Data.ContainsKey('GitAttributes')) { if ($Data.GitAttributes -isnot [hashtable] -or $Base.GitAttributes -isnot [hashtable]) { $merged.GitAttributes = $Data.GitAttributes } else { $section = @{} foreach ($key in $Base.GitAttributes.Keys) { $section[$key] = $Base.GitAttributes[$key] } foreach ($key in $Data.GitAttributes.Keys) { if ($section[$key] -is [hashtable] -and $Data.GitAttributes[$key] -is [hashtable]) { $values = @{} foreach ($entry in $section[$key].Keys) { $values[$entry] = $section[$key][$entry] } foreach ($entry in $Data.GitAttributes[$key].Keys) { $values[$entry] = $Data.GitAttributes[$key][$entry] } $section[$key] = $values } else { $section[$key] = $Data.GitAttributes[$key] } } $merged.GitAttributes = $section } } return $merged } |