Private/Install/Build-PwshProfileInitializeCall.ps1
|
function Build-PwshProfileInitializeCall { <# .SYNOPSIS Turns a settings hashtable into the Initialize-PwshProfile command line to embed in a profile. .DESCRIPTION Renders the single line that Install-PwshProfile writes into the managed bootstrap block. To keep the generated profile tidy and resilient to future default changes, only the parameters that differ from the defaults are emitted — a settings object equal to the defaults for the screwcity theme yields a bare "Initialize-PwshProfile" with no arguments. The theme drives the comparison baseline: the banner branding (text/color/icon) is compared against Get-PwshProfileDefault for the *selected* theme, so a forestcity install that keeps the Forest City branding emits just "-Theme forestcity" rather than re-spelling the matching banner text/color/icon. A bundled theme other than screwcity emits "-Theme <name>"; a custom theme path emits "-CustomTheme '<path>'" (the two are mutually exclusive in the generated call, mirroring Initialize-PwshProfile's parameter sets). String values are single-quoted (embedded single quotes are doubled) so values such as the ':nut_and_bolt:' step icon survive verbatim. The one exception is -BannerText, which is double-quoted so values like $env:COMPUTERNAME interpolate at profile startup (embedded double quotes and backticks are backtick-escaped; $ is intentionally left unescaped). The -Skip / -SkipSection arrays are emitted as comma-joined tokens (their values come from a ValidateSet, so they need no quoting) and only when non-empty. .PARAMETER Setting The settings hashtable (keys as produced by Get-PwshProfileDefault / the wizard: Theme, CustomTheme, BannerText, BannerColor, BannerAlignment, BannerFont, StepIcon, ZoxideCommand, Skip, SkipSection). Keys that are absent fall back to the default and are not emitted. .PARAMETER Default The baseline to compare against. When omitted it is resolved as Get-PwshProfileDefault for the setting's selected theme; exposed mainly for testing. .EXAMPLE Build-PwshProfileInitializeCall -Setting (Get-PwshProfileDefault) Returns 'Initialize-PwshProfile' (all screwcity defaults, so no arguments). .EXAMPLE Build-PwshProfileInitializeCall -Setting (Get-PwshProfileDefault -Theme forestcity) Returns 'Initialize-PwshProfile -Theme forestcity' (the matching Forest City banner branding is the default for that theme, so it is not re-emitted). .EXAMPLE $s = Get-PwshProfileDefault; $s.BannerColor = '#00d7ff'; $s.Skip = @('Fnm', 'Xh') Build-PwshProfileInitializeCall -Setting $s Returns "Initialize-PwshProfile -BannerColor '#00d7ff' -Skip Fnm,Xh". .EXAMPLE $s = Get-PwshProfileDefault; $s.BannerText = '$env:COMPUTERNAME' Build-PwshProfileInitializeCall -Setting $s Returns 'Initialize-PwshProfile -BannerText "$env:COMPUTERNAME"' — double-quoted so the banner shows the machine name at startup. #> [CmdletBinding()] param( [Parameter(Mandatory, Position = 0)] [hashtable]$Setting, [Parameter(Position = 1)] [hashtable]$Default ) # The selected theme drives both the -Theme/-CustomTheme tokens and the banner comparison # baseline; 'screwcity' is the global default, so it is never emitted as -Theme. $theme = if ($Setting.ContainsKey('Theme') -and $Setting.Theme) { $Setting.Theme } else { 'screwcity' } $customTheme = if ($Setting.ContainsKey('CustomTheme')) { $Setting.CustomTheme } else { '' } if (-not $PSBoundParameters.ContainsKey('Default')) { $Default = Get-PwshProfileDefault -Theme $theme } # Single-quote a value for safe inclusion in the generated command, doubling embedded quotes. $quote = { param($value) "'" + ($value -replace "'", "''") + "'" } # Double-quote a value so PowerShell interpolation (e.g. $env:COMPUTERNAME) happens at startup. # Escape backticks first, then double quotes; $ is left intact deliberately so it interpolates. $quoteDouble = { param($value) '"' + ($value -replace '`', '``' -replace '"', '`"') + '"' } # Resolve a key from the supplied settings, falling back to the default when absent. $value = { param($key) if ($Setting.ContainsKey($key)) { $Setting[$key] } else { $Default[$key] } } $parts = [System.Collections.Generic.List[string]]::new() # Theme selection: a custom theme path takes precedence (and is mutually exclusive with a bundled # -Theme); a bundled theme is emitted only when it isn't the screwcity default. if ($customTheme) { $parts.Add("-CustomTheme $(& $quote $customTheme)") } elseif ($theme -ne 'screwcity') { $parts.Add("-Theme $theme") } # Scalar string parameters: emit only when they differ from the (themed) default. BannerText is # double-quoted (interpolation); the rest are single-quoted (verbatim). foreach ($key in 'BannerText', 'BannerColor', 'BannerAlignment', 'BannerFont', 'StepIcon', 'ZoxideCommand') { $v = & $value $key if ($v -ne $Default[$key]) { $rendered = if ($key -eq 'BannerText') { & $quoteDouble $v } else { & $quote $v } $parts.Add("-$key $rendered") } } # Array parameters: emit comma-joined tokens only when non-empty (default is empty). foreach ($key in 'Skip', 'SkipSection') { $v = @(& $value $key) if ($v.Count -gt 0) { $parts.Add("-$key $($v -join ',')") } } if ($parts.Count -eq 0) { return 'Initialize-PwshProfile' } return "Initialize-PwshProfile $($parts -join ' ')" } |