using namespace Microsoft.Win32; using namespace System.Management.Automation.Host; $null = New-Module { . "$PSScriptRoot/SoftwareManagement.ps1"; . "$PSScriptRoot/../Windows/lib/Registry.ps1"; . "$PSScriptRoot/../Windows/lib/WSL.ps1"; . "$PSScriptRoot/../Windows/Types/WindowsInstallerAction.ps1"; <# .SYNOPSIS Prompts the user to select a profile to act on. #> function Show-ProfileNamePrompt { $profiles = & { if (-not $IsWindows -or (Test-Command "wsl")) { return Invoke-ConfigScript "getProfiles"; } else { return Get-ChildItem "$PSScriptRoot/../../.config" | ForEach-Object { Split-Path -LeafBase $_ }; } }; $choice = $Host.UI.PromptForChoice( "Select Profile", (& { if ($IsWindows) { switch (Get-Stage) { ([WindowsInstallerAction]::Backup) { "Which profile do you wish to back up?"; } ([WindowsInstallerAction]::Install) { "Which profile do you wish to install?"; } $null { "Which profile do you wish to set up?"; } } } else { "Please select a profile:"; } }), (& { for ($i = 0; $i -lt $profiles.Count; $i++) { [ChoiceDescription]"&$i - $($profiles[$i])"; } [ChoiceDescription]"&Abort"; }), $profiles.Count); if ($choice -eq $profiles.Count) { exit; } else { $env:CONFIG_NAME = $profiles[$choice]; } } <# .SYNOPSIS Runs a script based on the `settings.fish` script. .PARAMETER Script The script to run. #> function Invoke-ConfigScript { param( [string] $Script ) $scriptPath = "$PSScriptRoot/settings.fish"; if ($env:CONFIG_NAME -or ($Script -eq "getProfiles")) { $output = & { if (-not $IsWindows) { $escapedPath = (fish -c 'string escape $argv' "$scriptPath"); fish -c ". $escapedPath; $Script"; } else { if (-not $env:VALHALLA_FLAKE_ROOT) { $cleanup = { }; $projectRoot = "$PSScriptRoot/../.."; $archisoDir = "$projectRoot/archiso"; if (Test-Path -PathType Container "$archisoDir") { $git = { git -C "$projectRoot" -c safe.directory="$("$(Resolve-Path $projectRoot)".Replace("\", "/"))" @args; }; & $git rm -r --cached "$archisoDir" *> $null; $cleanup = { & $git restore --staged "$archisoDir" }; } $env:VALHALLA_FLAKE_ROOT = (Invoke-Nix flake metadata (ConvertTo-LinuxPath "$PSScriptRoot/../..") --json | ConvertFrom-Json).path; & $cleanup *> $null; } $output = Invoke-Fish -c ". $(ConvertTo-LinuxPath $scriptPath); $Script"; if (-not $?) { Write-Error "The configuration could not be retrieved!"; } else { $output; } } }; if (-not ($output -and ($output | Test-Json))) { Write-Error "The value ``$output`` is not valid JSON."; } else { $output | ConvertFrom-Json; } } else { $null; } } <# .SYNOPSIS Gets a configuration option. .PARAMETER Name The name of the configuration value to get. .PARAMETER ArgumentList The arguments to send to the configuration script. #> function Get-Config { param( [string] $Name, [Parameter(ValueFromRemainingArguments)] [string[]] $ArgumentList ) Invoke-ConfigScript "getConfig $Name --json $ArgumentList"; } <# .SYNOPSIS Gets the name of the config root. #> function Get-OSConfigRoot { return "valhalla.$($IsWindows ? "windows" : "linux")"; } <# .SYNOPSIS Gets the configuration value for the current operating system. .PARAMETER Name The name of the configuration value to get. .PARAMETER ArgumentList The arguments to send to the configuration script. #> function Get-OSConfig { param( [string] $Name, [Parameter(ValueFromRemainingArguments)] [string[]] $ArgumentList ) return Get-Config -Name "$(Get-OSConfigRoot).$Name" @PSBoundParameters; } <# .SYNOPSIS Gets the configuration of the specified program. .PARAMETER Name The name of the program to get the configuration for. #> function Get-ProgramConfig { param( $User, [Parameter(Position = 0)] $Name ) $programs = & { if ($User) { return Get-UserConfig -UserName $User @args; } else { return Get-OSConfig @args; } } "programs"; return $programs.$Name; } <# .SYNOPSIS Tests whether the program #> function Test-Program { param( $User, [Parameter(Position = 0)] $Name ) try { (Get-ProgramConfig @PSBoundParameters).enable; } catch { $false; } } <# .SYNOPSIS Gets the name of the user root. #> function Get-UserConfigRoot { return "$(Get-OSConfigRoot).$($IsWindows ? "winUsers" : "users")"; } <# .SYNOPSIS Gets a user configuration. .PARAMETER UserName The name of the user to get the configuration for. .PARAMETER Name The name of the configuration to get. #> function Get-UserConfig { param( [string] $UserName = ($IsWindows ? $env:UserName : $env:USER), [Parameter(Mandatory, Position = 0)] [string] $Name ) if ((Get-Users) -contains $UserName) { Get-Config "$(Get-UserConfigRoot).$UserName.$Name"; } else { return $null; } } <# .SYNOPSIS Gets the attributes of a configuration object. .PARAMETER Name The name of the configuration to get the attributes of. #> function Get-Attributes { param( [string] $Name ) Invoke-ConfigScript "getAttributes $Name"; } <# .SYNOPSIS Gets the names of the users to create. #> function Get-Users { [OutputType([string[]])] param() Get-Attributes "$(Get-UserConfigRoot)"; } <# .SYNOPSIS Gets the name of the setup user. #> function Get-SetupUser { [OutputType([string])] param() Get-OSConfig "setupUser.name"; } }