Skip to content

Commit 456ddcc

Browse files
CopilotDRSDavidSoft
andcommitted
Improve version comparison using dot-notation segment comparison
Co-authored-by: DRSDavidSoft <[email protected]>
1 parent f6adae5 commit 456ddcc

File tree

1 file changed

+34
-11
lines changed

1 file changed

+34
-11
lines changed

vendor/psmodules/Cmder.ps1

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -50,22 +50,45 @@ function Compare-Version {
5050
[string]$VendorVersion
5151
)
5252

53-
if ($null -eq $UserVersion) { return -1 }
54-
if ($null -eq $VendorVersion) { return 1 }
53+
if ([string]::IsNullOrEmpty($UserVersion)) { return -1 }
54+
if ([string]::IsNullOrEmpty($VendorVersion)) { return 1 }
5555

56-
# Extract all numeric parts from version strings (e.g., "2.49.0.windows.1" -> 2, 49, 0, 1)
57-
# This handles Git version strings like "2.49.0.windows.1" correctly
58-
$userParts = [regex]::Matches($UserVersion, '\d+') | ForEach-Object { [int]$_.Value }
59-
$vendorParts = [regex]::Matches($VendorVersion, '\d+') | ForEach-Object { [int]$_.Value }
56+
# Split version strings by dots to compare segment by segment
57+
# For "2.49.0.windows.1", we get: ["2", "49", "0", "windows", "1"]
58+
$userParts = $UserVersion -split '\.'
59+
$vendorParts = $VendorVersion -split '\.'
6060

61-
# Compare each numeric part sequentially
6261
$maxLength = [Math]::Max($userParts.Count, $vendorParts.Count)
62+
6363
for ($i = 0; $i -lt $maxLength; $i++) {
64-
$userPart = if ($i -lt $userParts.Count) { $userParts[$i] } else { 0 }
65-
$vendorPart = if ($i -lt $vendorParts.Count) { $vendorParts[$i] } else { 0 }
64+
$userPart = if ($i -lt $userParts.Count) { $userParts[$i] } else { '' }
65+
$vendorPart = if ($i -lt $vendorParts.Count) { $vendorParts[$i] } else { '' }
66+
67+
# Check if both parts are purely numeric
68+
$userIsNumeric = $userPart -match '^\d+$'
69+
$vendorIsNumeric = $vendorPart -match '^\d+$'
6670

67-
if ($userPart -gt $vendorPart) { return 1 }
68-
if ($userPart -lt $vendorPart) { return -1 }
71+
if ($userIsNumeric -and $vendorIsNumeric) {
72+
# Both numeric: compare as integers (so 49 > 5, not lexicographic)
73+
$userNum = [int]$userPart
74+
$vendorNum = [int]$vendorPart
75+
76+
if ($userNum -gt $vendorNum) { return 1 }
77+
if ($userNum -lt $vendorNum) { return -1 }
78+
}
79+
elseif ($userIsNumeric -and -not $vendorIsNumeric) {
80+
# Numeric segment comes before text segment (e.g., "2.0" < "2.0.rc1")
81+
return -1
82+
}
83+
elseif (-not $userIsNumeric -and $vendorIsNumeric) {
84+
# Text segment comes after numeric segment
85+
return 1
86+
}
87+
else {
88+
# Both are text: use case-insensitive lexicographic comparison
89+
$cmp = [string]::Compare($userPart, $vendorPart, $true)
90+
if ($cmp -ne 0) { return [Math]::Sign($cmp) }
91+
}
6992
}
7093

7194
return 0

0 commit comments

Comments
 (0)