Shared/ConvertTo-DFPath.ps1
|
#Requires -Version 7.0 function ConvertTo-DFPath { <# .SYNOPSIS Canonicalizes an absolute path: native separators, no ./.., no trailing separator, with a leading ~ expanded to $HOME. .DESCRIPTION The single path-normalization primitive for DotForge. Returns [System.IO.Path]::GetFullPath's canonical form with a root-aware trailing-separator strip. Null/empty pass through untouched. A relative path is a probable bug: it is returned unchanged with a warning, never silently bound to the current directory. Works on paths that do not exist yet (no filesystem access, except that an existing 8.3 short-name segment is expanded to its long form). .PARAMETER Path The path to canonicalize. .OUTPUTS [string] the canonical path, or the input unchanged for null/empty/relative. #> [CmdletBinding()] [OutputType([string])] param([Parameter(Position = 0)][string]$Path) if ([string]::IsNullOrEmpty($Path)) { return $Path } # Expand a leading ~ (whole path, or immediately followed by a separator) to # $HOME. Never a ~ elsewhere — that would corrupt Windows 8.3 short names # (C:\PROGRA~1) or a literal filename. if ($Path -eq '~' -or $Path -match '^~[\\/]') { $Path = $HOME + $Path.Substring(1) } if (-not [System.IO.Path]::IsPathRooted($Path)) { Write-Warning "ConvertTo-DFPath: '$Path' is not an absolute path — returned unchanged." return $Path } $full = [System.IO.Path]::GetFullPath($Path) $root = [System.IO.Path]::GetPathRoot($full) if ($full.Length -gt $root.Length) { $full = $full.TrimEnd([System.IO.Path]::DirectorySeparatorChar, [System.IO.Path]::AltDirectorySeparatorChar) } $full } function Get-DFXdgPath { <# .SYNOPSIS Returns one XDG base folder: the environment variable if set, otherwise the XDG default under $HOME. .DESCRIPTION The single place DotForge decides where its config, data, state, cache and bin folders are, so "the variable isn't set" is never a special case anywhere else. Defaults follow the XDG Base Directory spec: Config $HOME\.config Data $HOME\.local\share State $HOME\.local\state Cache $HOME\.cache Bin $HOME\.local\bin (XDG_BIN_HOME is not in the spec; the location is) The result is canonical (ConvertTo-DFPath). Reading never sets the variable; Start-DFSession exports them for other programs. .PARAMETER Kind Config, Data, State, Cache or Bin. .OUTPUTS System.String. #> [CmdletBinding()] [OutputType([string])] param( [Parameter(Mandatory, Position = 0)] [ValidateSet('Config', 'Data', 'State', 'Cache', 'Bin')] [string]$Kind ) $value = [Environment]::GetEnvironmentVariable("XDG_$($Kind.ToUpperInvariant())_HOME") if (-not $value) { $value = switch ($Kind) { 'Config' { Join-Path $HOME '.config' } 'Data' { Join-Path $HOME '.local' 'share' } 'State' { Join-Path $HOME '.local' 'state' } 'Cache' { Join-Path $HOME '.cache' } 'Bin' { Join-Path $HOME '.local' 'bin' } } } ConvertTo-DFPath $value } |