PortValhalla/scripts/lib/Settings.ps1
2024-11-29 01:15:08 +01:00

284 lines
7.5 KiB
PowerShell

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";
}
}