diff --git a/bin/checkver.ps1 b/bin/checkver.ps1 index 50e3178718..70d3560797 100644 --- a/bin/checkver.ps1 +++ b/bin/checkver.ps1 @@ -289,7 +289,7 @@ while ($in_progress -gt 0) { Write-Host $ver -ForegroundColor DarkRed -NoNewline Write-Host " (scoop version is $expected_ver)" -NoNewline - $update_available = (Compare-Version $ver $expected_ver) -ne 0 + $update_available = (compare_versions $expected_ver $ver) -eq -1 if ($json.autoupdate -and $update_available) { Write-Host ' autoupdate available' -ForegroundColor Cyan diff --git a/lib/core.ps1 b/lib/core.ps1 index 4305254270..a917f2673e 100644 --- a/lib/core.ps1 +++ b/lib/core.ps1 @@ -305,7 +305,7 @@ function app_status($app, $global) { $status.outdated = $false if($status.version -and $status.latest_version) { - $status.outdated = ((Compare-Version $status.version $status.latest_version) -ne 0) + $status.outdated = ((compare_versions $status.latest_version $status.version) -gt 0) } $status.missing_deps = @() diff --git a/lib/versions.ps1 b/lib/versions.ps1 index e560b79f26..4f55e653e7 100644 --- a/lib/versions.ps1 +++ b/lib/versions.ps1 @@ -12,69 +12,28 @@ function versions($app, $global) { sort_versions (Get-ChildItem $appdir -dir -attr !reparsePoint | Where-Object { $null -ne $(Get-ChildItem $_.fullname) } | ForEach-Object { $_.name }) } -function Compare-Version { - [CmdletBinding()] - param ( - [Parameter(Position = 0)] - [String] - $ReferenceVersion, - [Parameter(Position = 1)] - [String] - $DifferenceVersion, - [String] - $Delimiter = '-' - ) - - if ($DifferenceVersion -eq $ReferenceVersion) { - return 0 +function version($ver) { + $ver -split '[\.-]' | ForEach-Object { + $num = $_ -as [int] + if($num) { $num } else { $_ } } +} +function compare_versions($a, $b) { + $ver_a = @(version $a) + $ver_b = @(version $b) - $SplitReferenceVersion = @($ReferenceVersion -split $Delimiter | ForEach-Object { if ($_ -match "^\d+$") { [int]$_ } else { ($_ -replace '[a-zA-Z]+', '.$&.').Replace('..', '.').Trim('.') } }) - $SplitDifferenceVersion = @($DifferenceVersion -split $Delimiter | ForEach-Object { if ($_ -match "^\d+$") { [int]$_ } else { ($_ -replace '[a-zA-Z]+', '.$&.').Replace('..', '.').Trim('.') } }) - - if ($SplitReferenceVersion[0] -eq 'nightly' -and $SplitDifferenceVersion[0] -eq 'nightly') { - return 0 - } - - for ($i = 0; $i -lt [Math]::Max($SplitReferenceVersion.Length, $SplitDifferenceVersion.Length); $i++) { - if ($i -ge $SplitReferenceVersion.Length) { - if ($SplitDifferenceVersion[$i] -match "alpha|beta|rc|pre") { - return -1 - } else { - return 1 - } - } - if ($i -ge $SplitDifferenceVersion.Length) { - if ($SplitReferenceVersion[$i] -match "alpha|beta|rc|pre") { - return 1 - } else { - return -1 - } - } - - if (($SplitReferenceVersion[$i] -match "\.") -or ($SplitDifferenceVersion[$i] -match "\.")) { - $Result = Compare-Version $SplitReferenceVersion[$i] $SplitDifferenceVersion[$i] -Delimiter '\.' - if ($Result -ne 0) { - return $Result - } else { - continue - } - } + for($i=0;$i -lt $ver_a.length;$i++) { + if($i -gt $ver_b.length) { return 1; } - if ($null -ne $SplitReferenceVersion[$i] -and $null -ne $SplitDifferenceVersion[$i]) { - # don't try to compare int to string - if ($SplitReferenceVersion[$i] -is [string] -and $SplitDifferenceVersion[$i] -isnot [string]) { - $SplitDifferenceVersion[$i] = "$($SplitDifferenceVersion[$i])" - } - if ($SplitDifferenceVersion[$i] -is [string] -and $SplitReferenceVersion[$i] -isnot [string]) { - $SplitReferenceVersion[$i] = "$($SplitReferenceVersion[$i])" - } + # don't try to compare int to string + if($ver_b[$i] -is [string] -and $ver_a[$i] -isnot [string]) { + $ver_a[$i] = "$($ver_a[$i])" } - if ($SplitDifferenceVersion[$i] -gt $SplitReferenceVersion[$i]) { return 1 } - if ($SplitDifferenceVersion[$i] -lt $SplitReferenceVersion[$i]) { return -1 } + if($ver_a[$i] -gt $ver_b[$i]) { return 1; } + if($ver_a[$i] -lt $ver_b[$i]) { return -1; } } - + if($ver_b.length -gt $ver_a.length) { return -1 } return 0 } @@ -85,10 +44,10 @@ function qsort($ary, $fn) { $pivot = $ary[0] $rem = $ary[1..($ary.length-1)] - $lesser = qsort ($rem | Where-Object { (& $fn $pivot $_) -lt 0 }) $fn + $lesser = qsort ($rem | Where-Object { (& $fn $_ $pivot) -lt 0 }) $fn - $greater = qsort ($rem | Where-Object { (& $fn $pivot $_) -ge 0 }) $fn + $greater = qsort ($rem | Where-Object { (& $fn $_ $pivot) -ge 0 }) $fn return @() + $lesser + @($pivot) + $greater } -function sort_versions($versions) { qsort $versions Compare-Version } +function sort_versions($versions) { qsort $versions compare_versions } diff --git a/test/Scoop-Versions.Tests.ps1 b/test/Scoop-Versions.Tests.ps1 index e45a2f761c..a02e968213 100644 --- a/test/Scoop-Versions.Tests.ps1 +++ b/test/Scoop-Versions.Tests.ps1 @@ -3,46 +3,35 @@ describe "versions" -Tag 'Scoop' { it 'compares versions with integer-string mismatch' { - Compare-Version '1.8.9' '1.8.5-1' | Should -Be -1 + $a = '1.8.9' + $b = '1.8.5-1' + $res = compare_versions $a $b + + $res | should -be 1 } it 'handles plain string version comparison to int version' { - Compare-Version 'latest' '20150405' | Should -Be -1 - Compare-Version '0.5alpha' '0.5' | Should -Be 1 - Compare-Version '0.5' '0.5Beta' | Should -Be -1 + $a = 'latest' + $b = '20150405' + $res = compare_versions $a $b + + $res | should -be 1 } it 'handles dashed version components' { - Compare-Version '7.0.4-9' '7.0.4-10' | Should -Be 1 - Compare-Version '7.0.4' '7.0.4-9' | Should -Be 1 - Compare-Version '7.0.4-beta9' '7.0.4' | Should -Be 1 - Compare-Version '7.0.4-9' '7.0.4-8' | Should -Be -1 - Compare-Version '7.0.4' '7.0.4-beta9' | Should -Be -1 - } + $a = '7.0.4-9' + $b = '7.0.4-10' + + $res = compare_versions $a $b - it 'handle example comparisons' { - Compare-Version '1' '1.1' | Should -Be 1 - Compare-Version '1.0' '1.1' | Should -Be 1 - Compare-Version '1.9.8' '1.10.0' | Should -Be 1 - Compare-Version '1.1' '1.0' | Should -Be -1 - Compare-Version '1.1' '1' | Should -Be -1 - Compare-Version '1.10.0' '1.9.8' | Should -Be -1 - Compare-Version '1.1.1_8' '1.1.1' | Should -Be -1 - Compare-Version '1.1.1b' '1.1.1a' | Should -Be -1 - Compare-Version '1.1.1a' '1.1.1b' | Should -Be 1 - Compare-Version '2019-01-01' '2019-01-02' | Should -Be 1 - Compare-Version '2019-01-02' '2019-01-01' | Should -Be -1 - Compare-Version '2018-01-01' '2019-01-01' | Should -Be 1 - Compare-Version '2019-01-01' '2018-01-01' | Should -Be -1 + $res | should -be -1 } it 'handles comparsion against en empty string' { - Compare-Version '7.0.4-9' '' | Should -Be -1 + compare_versions '7.0.4-9' '' | should -be 1 } it 'handles equal versions' { - Compare-Version '12.0' '12.0' | Should -Be 0 - Compare-Version '7.0.4-9' '7.0.4-9' | Should -Be 0 - Compare-Version 'nightly-20190801' 'nightly' | Should -Be 0 + compare_versions '12.0' '12.0' | should -be 0 } }