src/PowerShell/Paths.ps1
|
# cdp PowerShell domain: Paths.ps1 # Loaded by src/cdp.psm1; do not dot-source peer files. function Convert-WindowsPathToWSL { param([Parameter(Mandatory = $true)][string]$WindowsPath) $normalizedPath = $WindowsPath -replace '\\', '/' if ($normalizedPath -match '^([A-Za-z]):(.*)$') { return "/mnt/$($matches[1].ToLower())$($matches[2])" } $normalizedPath } function Get-CdpDetectedPathProfile { if ([Environment]::OSVersion.Platform -eq [PlatformID]::Win32NT) { return 'windows' } if (-not [string]::IsNullOrWhiteSpace($env:WSL_DISTRO_NAME) -or -not [string]::IsNullOrWhiteSpace($env:WSL_INTEROP)) { return 'wsl' } if (Test-Path -LiteralPath '/proc/version' -PathType Leaf) { $kernelVersion = Get-Content -LiteralPath '/proc/version' -Raw -ErrorAction SilentlyContinue if ($kernelVersion -match '(?i)microsoft|wsl') { return 'wsl' } } $systemName = '' try { $systemName = (& uname -s 2>$null) } catch {} if ([string]::Equals([string]$systemName, 'Darwin', [StringComparison]::OrdinalIgnoreCase)) { return 'macos' } 'linux' } function Get-CdpCurrentPathProfile { param([Parameter(Mandatory = $false)][string]$Profile) $candidate = $Profile if ([string]::IsNullOrWhiteSpace($candidate)) { $candidate = $env:CDP_PATH_PROFILE } if ([string]::IsNullOrWhiteSpace($candidate)) { return Get-CdpDetectedPathProfile } $normalized = $candidate.Trim().ToLowerInvariant() if ($normalized -notin @('windows', 'wsl', 'linux', 'macos')) { throw "Invalid CDP_PATH_PROFILE '$candidate'. Expected windows, wsl, linux, or macos." } $normalized } function Get-CdpProjectPathProperty { param( [Parameter(Mandatory = $true)][object]$Paths, [Parameter(Mandatory = $true)][string]$Profile ) if ($Paths -is [System.Collections.IDictionary]) { if (-not $Paths.Contains($Profile)) { return $null } return [PSCustomObject]@{ Exists = $true; Value = $Paths[$Profile] } } $property = $Paths.PSObject.Properties[$Profile] if (-not $property) { return $null } [PSCustomObject]@{ Exists = $true; Value = $property.Value } } function New-CdpPathResolution { param( [string]$RawPath, [string]$ResolvedPath, [string]$Profile, [string]$Source, [bool]$IsExplicit, [string]$ErrorCode = '', [string]$ErrorMessage = '' ) [PSCustomObject]@{ RawPath = $RawPath ResolvedPath = $ResolvedPath Profile = $Profile Source = $Source IsExplicit = $IsExplicit ErrorCode = $ErrorCode ErrorMessage = $ErrorMessage } } function Get-CdpInvalidKnownPathProfile { param([Parameter(Mandatory = $true)][object]$Paths) foreach ($knownProfile in @('windows', 'wsl', 'linux', 'macos')) { $knownValue = Get-CdpProjectPathProperty -Paths $Paths -Profile $knownProfile if ($knownValue -and (-not ($knownValue.Value -is [string]) -or [string]::IsNullOrWhiteSpace([string]$knownValue.Value))) { return $knownProfile } } $null } function Resolve-CdpProjectPath { param( [Parameter(Mandatory = $true)][object]$Project, [Parameter(Mandatory = $false)][string]$Profile ) $selectedProfile = Get-CdpCurrentPathProfile -Profile $Profile $rawPath = [string]$Project.rootPath if ([string]::IsNullOrWhiteSpace($rawPath)) { return New-CdpPathResolution -RawPath $rawPath -ResolvedPath '' ` -Profile $selectedProfile -Source 'rootPath' -IsExplicit $false ` -ErrorCode 'path_profile_invalid' -ErrorMessage 'Project rootPath must be a non-empty string.' } $pathsProperty = $Project.PSObject.Properties['paths'] if ($pathsProperty) { $paths = $pathsProperty.Value $isObject = $null -ne $paths -and ($paths -is [System.Collections.IDictionary] -or $paths -is [PSCustomObject]) if (-not $isObject) { return New-CdpPathResolution -RawPath $rawPath -ResolvedPath '' ` -Profile $selectedProfile -Source "paths.$selectedProfile" -IsExplicit $true ` -ErrorCode 'path_profile_invalid' -ErrorMessage 'Project paths must be a JSON object.' } $invalidProfile = Get-CdpInvalidKnownPathProfile -Paths $paths if ($invalidProfile) { return New-CdpPathResolution -RawPath $rawPath -ResolvedPath '' ` -Profile $selectedProfile -Source "paths.$invalidProfile" ` -IsExplicit ($invalidProfile -eq $selectedProfile) ` -ErrorCode 'path_profile_invalid' ` -ErrorMessage "Project paths.$invalidProfile must be a non-empty string." } $selected = Get-CdpProjectPathProperty -Paths $paths -Profile $selectedProfile if ($selected) { return New-CdpPathResolution -RawPath $rawPath -ResolvedPath ([string]$selected.Value) ` -Profile $selectedProfile -Source "paths.$selectedProfile" -IsExplicit $true } } if ($selectedProfile -eq 'wsl') { return New-CdpPathResolution -RawPath $rawPath ` -ResolvedPath (Convert-WindowsPathToWSL -WindowsPath $rawPath) ` -Profile $selectedProfile -Source 'rootPath:wsl-converted' -IsExplicit $false } New-CdpPathResolution -RawPath $rawPath -ResolvedPath $rawPath ` -Profile $selectedProfile -Source 'rootPath' -IsExplicit $false } function New-CdpProjectPathMap { param( [Parameter(Mandatory = $true)][string]$RootPath, [Parameter(Mandatory = $false)][string]$Profile ) $selectedProfile = Get-CdpCurrentPathProfile -Profile $Profile $values = [ordered]@{} $values[$selectedProfile] = $RootPath [PSCustomObject]$values } function Find-CdpProjectByLocalPath { param( [Parameter(Mandatory = $true)][AllowEmptyCollection()][object[]]$Projects, [Parameter(Mandatory = $true)][string]$Path ) $target = Get-CdpComparablePath -Path $Path foreach ($project in $Projects) { $resolution = Resolve-CdpProjectPath -Project $project if ($resolution.ErrorCode) { continue } if ((Get-CdpComparablePath -Path $resolution.ResolvedPath) -eq $target) { return $project } } $null } |