src/functions/resolve-map.ps1
|
# in order to make imports from the map file work globally, we have to call dot-source from top-level scope. # hence this pattern: # $map = Resolve-ConfigMap $map | ForEach-Object { $_ -is [string] ? (. $_) : $_ } | Assert-ConfigMap function Resolve-ConfigMap { [OutputType([System.Collections.IDictionary])] param( [Parameter(Mandatory = $false)] [AllowNull()] # we want to allow passing objects or strings as map # somehow validateScript is throwing an error when $map is null # [ValidateScript({ $null -eq $_ -or $_ -is [string] -or $_ -is [System.Collections.IDictionary] })] $map, [Parameter(Mandatory = $false)] $fallback, [switch][bool]$lookUp = $true ) if ($map -is [string] -or !$map) { $map = Resolve-ConfigMapFile $map $fallback } if (!$map) { throw "No map provided and fallback '$fallback' not found" } return $map } function Resolve-ConfigMapFile { [OutputType([System.Collections.IDictionary])] param( [Parameter(Mandatory = $false)] [AllowNull()] [string]$mapFile, [Parameter(Mandatory = $false)] [string]$fallback ) # Set default map file if null if (!$map) { if (!$fallback) { throw "map is null and defaultMapFile is not provided" return $null } $map = $fallback } # Load map from file if it's a string path $fullPath = [System.IO.Path]::IsPathRooted($map) ? $map : (Join-Path $PWD.Path $map) $file = Split-Path $fullPath -Leaf $dir = Split-Path $fullPath -Parent do { $fullPath = Join-Path $dir $file if (Test-Path $fullPath) { return $fullPath } $dir = Split-Path $dir -Parent } while ($lookUp -and $dir) throw "map file '$map' not found" return $null } function Assert-ConfigMap { param( [Parameter(Mandatory = $true, ValueFromPipeline = $true)] $map ) # Validate that we have a loaded map if (!$map) { throw "failed to load map" return $null } if ($map -isnot [System.Collections.IDictionary]) { throw "map is not a dictionary" } return $map } |