Private/alias_yaml.ps1
|
# aliases: # typora: # path: "C:\Program Files\Typora\Typora.exe" # wechat: # path: "C:\Program Files (x86)\Tencent\WeChat\WeChat.exe" # Import the YAML module if its commands are not already available if (-not (Get-Command ConvertFrom-Yaml -ErrorAction SilentlyContinue)) { try { Import-Module powershell-yaml -ErrorAction Stop Write-Verbose "Successfully imported powershell-yaml module" } catch { throw "Failed to import powershell-yaml module. Please run: Install-Module powershell-yaml -Scope CurrentUser -Force" } } function Initialize-AliasYaml { param ( [Parameter(Mandatory)] [string]$Path ) if (-not (Test-Path $Path)) { $dir = Split-Path $Path -Parent if ($dir -and -not (Test-Path $dir)) { New-Item -ItemType Directory -Path $dir -Force | Out-Null } [ordered]@{ aliases = [ordered]@{} } | ConvertTo-Yaml | Set-Content -Path $Path -Encoding UTF8 Write-Verbose "Initialized YAML configuration file: $Path" } } function Read-AliasYaml { param ( [Parameter(Mandatory)] [string]$Path ) if (-not (Test-Path $Path)) { return [ordered]@{} } try { # Keep -Ordered so the read result preserves key order $data = Get-Content $Path -Raw | ConvertFrom-Yaml -Ordered } catch { throw "Failed to parse YAML file: $Path`nError details: $_" } if (-not $data -or -not $data.aliases) { return [ordered]@{} } $result = [ordered]@{} foreach ($name in $data.aliases.Keys) { $entry = $data.aliases[$name] # Defensive guard in case an entry is missing or malformed if ($entry -and $entry.path) { $result[$name] = $entry.path } } return $result } function Write-AliasYaml { param ( [Parameter(Mandatory)] [object]$Data, [Parameter(Mandatory)] [string]$Path ) # Build an ordered hashtable whose nested keys are sorted ascending $sortedOrderedData = [ordered]@{} foreach ($topKey in $Data.Keys) { $topValue = $Data[$topKey] if ($topValue -is [hashtable] -or $topValue -is [System.Collections.Specialized.OrderedDictionary]) { $sortedAlias = [ordered]@{} # Sort alias keys in ascending order before writing them back $topValue.GetEnumerator() | Sort-Object -Property Key | ForEach-Object { $sortedAlias[$_.Key] = $_.Value } $sortedOrderedData[$topKey] = $sortedAlias } else { $sortedOrderedData[$topKey] = $topValue } } # No -Ordered switch here; rely on the ordered hashtable to preserve output order try { $sortedOrderedData | ConvertTo-Yaml | Set-Content -Path $Path -Encoding UTF8 -Force Write-Verbose "Successfully wrote to YAML configuration file: $Path" } catch { throw "Failed to write to YAML file: $Path`nError details: $_" } } # Private helper: read a writable YAML document and ensure the aliases node always exists function Read-AliasYamlDocument { param ( [Parameter(Mandatory)] [string]$Path ) Initialize-AliasYaml -Path $Path try { $data = Get-Content $Path -Raw | ConvertFrom-Yaml -Ordered } catch { throw "Failed to read configuration file: $Path`nError details: $_" } if (-not $data) { $data = [ordered]@{ aliases = [ordered]@{} } } if (-not $data.aliases) { $data.aliases = [ordered]@{} } return $data } function Add-AliasPath { param ( [Parameter(Mandatory)] [string]$Path, [Parameter(Mandatory)] [string]$AliasName, [Parameter(Mandatory)] [string]$ShortcutPath ) $data = Read-AliasYamlDocument -Path $Path # Store the alias under the aliases node using the normalized path $data.aliases[$AliasName] = [ordered]@{ path = $ShortcutPath } # Persist the updated document Write-AliasYaml -Data $data -Path $Path } function Remove-AliasPath { param ( [Parameter(Mandatory)] [string]$Path, [Parameter(Mandatory)] [string]$AliasName ) # Exit early if the configuration file does not exist if (-not (Test-Path $Path)) { Write-Verbose "Configuration file does not exist: $Path, no need to remove alias" return $false } $data = Read-AliasYamlDocument -Path $Path # Check whether the alias exists in the current document $aliasExists = $false if ($data.aliases -is [System.Collections.Specialized.OrderedDictionary]) { # OrderedDictionary uses Contains $aliasExists = $data.aliases.Contains($AliasName) } elseif ($data.aliases -is [hashtable]) { # Hashtable uses ContainsKey $aliasExists = $data.aliases.ContainsKey($AliasName) } # Remove and persist only when the alias exists if ($aliasExists) { $data.aliases.Remove($AliasName) | Out-Null Write-AliasYaml -Data $data -Path $Path Write-Verbose "Alias '$AliasName' removed successfully" return $true } else { Write-Verbose "Alias '$AliasName' does not exist" return $false } } |