Parts/ExpandComponents.ps1
<#
.Synopsis Expands Component Files into one Object .Description Component Files are .ps1 or datafiles within a directory that tells you what type they are. #> param( # A table of data that could contain components. [Parameter(Mandatory)] [Collections.IDictionary] $PartTable, # The parent object $Parent, # If set, the component will be expanded as a singleton (single object) [switch]$Singleton, # A list of item names that automatically become singletons [string[]]$SingleItemName, # The type of component, currently, ADO or GitHubActions. [ValidateSet('ADO','GitHubActions')] [string]$ComponentType ) $theComponentMetaData = $ComponentMetaData.$ComponentType $theComponentNames = $ComponentNames.$ComponentType $outObject = [Ordered]@{} $splatMe = @{} + $PSBoundParameters $splatMe.Remove('PartTable') :nextKey foreach ($kv in $PartTable.GetEnumerator()) { if ($kv.Key.EndsWith('s') -and -not $singleton) { # Already pluralized $thingType = $kv.Key.Substring(0,$kv.Key.Length -1) $propName = $kv.Key } elseif ($parent) { $thingType = $kv.Key $propName = $kv.Key } else { $thingType = $kv.Key $propName = if ($SingleItemName -notcontains $thingType -and $thingType -notmatch '\W$' -and $theComponentNames.Keys -contains $thingType) { $kv.Key.Substring(0,1).ToLower() + $kv.Key.Substring(1) + 's' } else { $kv.Key.Substring(0,1).ToLower() + $kv.Key.Substring(1) $singleton = $true } } $outValue = :nextValue foreach ($v in $kv.Value) { $metaData = $theComponentMetaData["$thingType.$v"] $ft = if ($metaData.Path) { [IO.File]::ReadAllText($metaData.Path) } if ($propName -eq $thingType -and -not $singleton) { if ($v -is [Collections.IDictionary]) { $splatMe.PartTable = $v & $ExpandComponents @splatMe } else { $v } continue nextValue } $o = if ($metaData.Extension -eq '.ps1') { $sb = [ScriptBlock]::Create($ft) if (-not $sb) { continue } $out = [Ordered]@{} if ($ComponentType -eq 'ADO') { if ($outObject.pool -and $outObject.pool.vmimage -notlike '*win*') { $out.pwsh = "$sb" } else { $out.powershell = "$sb" } $out.displayName = $metaData.Name if ($UseSystemAccessToken) { $out.env = @{"SYSTEM_ACCESSTOKEN"='$(System.AccessToken)'} } } elseif ($ComponentType -eq 'GitHubActions') { $out.name = $metaData.Name $out.runs = "$sb" $out.shell = 'pwsh' } $out } elseif ($metaData.Extension -eq '.psd1') { $data = Import-LocalizedData -BaseDirectory ([IO.Path]::GetDirectoryName($metaData.Path)) -FileName ([IO.PATH]::GetFileName($metaData.Path)) if (-not $data) { continue nextValue } $data = & ([ScriptBlock]::Create(($ft -replace '@{', '[Ordered]@{'))) $splatMe.Parent = $PartTable if ($data -is [Collections.IDictionary]) { $splatMe.PartTable = $data try { & $ExpandComponents @splatMe } catch { Write-Debug "Could not Expand $($kv.Id): $_" } } else { $data } } elseif ($metaData.Extension -eq '.sh') { $out = [Ordered]@{bash="$ft";displayName=$metaData.Name} $out } elseif ($v -is [Collections.IDictionary]) { $splatMe.Parent = $PartTable $splatMe.PartTable = $v & $ExpandComponents @splatMe } else { $v } if ($metaData.Name -and $Option.$($metaData.Name) -is [Collections.IDictionary]) { $o2 = [Ordered]@{} + $o foreach ($ov in @($Option.($metaData.Name).GetEnumerator())) { $o2[$ov.Key] = $ov.Value } $o2 } else { $o } } $outObject[$propName] = $outValue if ($outObject[$propName] -isnot [Collections.IList] -and $kv.Value -is [Collections.IList] -and -not $singleton) { $outObject[$propName] = @($outObject[$propName]) } elseif ($outObject[$propName] -is [Collections.IList] -and $kv.Value -isnot [Collections.IList]) { $outObject[$propName] = $outObject[$propName][0] } } $outObject |