|
1 | 1 | # versions
|
2 |
| -function latest_version($app, $bucket, $url) { |
3 |
| - (manifest $app $bucket $url).version |
4 |
| -} |
5 |
| -function current_version($app, $global) { |
6 |
| - @(versions $app $global)[-1] |
| 2 | +function Get-LatestVersion { |
| 3 | + <# |
| 4 | + .SYNOPSIS |
| 5 | + Get latest version of app from manifest |
| 6 | + .PARAMETER AppName |
| 7 | + App's name |
| 8 | + .PARAMETER Bucket |
| 9 | + Bucket which the app belongs to |
| 10 | + .PARAMETER Uri |
| 11 | + Remote app manifest's URI |
| 12 | + #> |
| 13 | + [OutputType([String])] |
| 14 | + [CmdletBinding()] |
| 15 | + param ( |
| 16 | + [Parameter(Mandatory = $true, Position = 0, ValueFromPipeline = $true)] |
| 17 | + [Alias('App')] |
| 18 | + [String] |
| 19 | + $AppName, |
| 20 | + [Parameter(Position = 1)] |
| 21 | + [String] |
| 22 | + $Bucket, |
| 23 | + [Parameter(Position = 2)] |
| 24 | + [String] |
| 25 | + $Uri |
| 26 | + ) |
| 27 | + process { |
| 28 | + return (manifest $AppName $Bucket $Uri).version |
| 29 | + } |
7 | 30 | }
|
8 |
| -function versions($app, $global) { |
9 |
| - $appdir = appdir $app $global |
10 |
| - if(!(test-path $appdir)) { return @() } |
11 | 31 |
|
12 |
| - sort_versions (Get-ChildItem $appdir -dir -attr !reparsePoint | Where-Object { $null -ne $(Get-ChildItem $_.fullname) } | ForEach-Object { $_.name }) |
| 32 | +function Select-CurrentVersion { |
| 33 | + <# |
| 34 | + .SYNOPSIS |
| 35 | + Select current version of installed app, from 'current\manifest.json' or modified time of version directory |
| 36 | + .PARAMETER AppName |
| 37 | + App's name |
| 38 | + .PARAMETER Global |
| 39 | + Globally installed application |
| 40 | + #> |
| 41 | + [OutputType([String])] |
| 42 | + [CmdletBinding()] |
| 43 | + param ( |
| 44 | + [Parameter(Mandatory = $true, Position = 0, ValueFromPipeline = $true)] |
| 45 | + [Alias('App')] |
| 46 | + [String] |
| 47 | + $AppName, |
| 48 | + [Parameter(Position = 1)] |
| 49 | + [Switch] |
| 50 | + $Global |
| 51 | + ) |
| 52 | + process { |
| 53 | + $appPath = appdir $AppName $Global |
| 54 | + if (Test-Path "$appPath\current" -PathType Container) { |
| 55 | + $currentVersion = (installed_manifest $AppName 'current' $Global).version |
| 56 | + if ($currentVersion -eq 'nightly') { |
| 57 | + $currentVersion = (Get-Item "$appPath\current").Target | Split-Path -Leaf |
| 58 | + } |
| 59 | + } else { |
| 60 | + $installedVersion = Get-InstalledVersion -AppName $AppName -Global:$Global |
| 61 | + if ($installedVersion) { |
| 62 | + $currentVersion = $installedVersion[-1] |
| 63 | + } else { |
| 64 | + $currentVersion = $null |
| 65 | + } |
| 66 | + } |
| 67 | + return $currentVersion |
| 68 | + } |
13 | 69 | }
|
14 | 70 |
|
15 |
| -function version($ver) { |
16 |
| - $ver -split '[\.-]' | ForEach-Object { |
17 |
| - $num = $_ -as [int] |
18 |
| - if($num) { $num } else { $_ } |
| 71 | +function Get-InstalledVersion { |
| 72 | + <# |
| 73 | + .SYNOPSIS |
| 74 | + Get all installed version of app, by checking version directories' 'install.json' |
| 75 | + .PARAMETER AppName |
| 76 | + App's name |
| 77 | + .PARAMETER Global |
| 78 | + Globally installed application |
| 79 | + .NOTES |
| 80 | + Versions are sorted from oldest to newest, i.e., latest installed version is the last one in the output array. |
| 81 | + If no installed version found, empty array will be returned. |
| 82 | + #> |
| 83 | + [OutputType([Object[]])] |
| 84 | + [CmdletBinding()] |
| 85 | + param ( |
| 86 | + [Parameter(Mandatory = $true, Position = 0, ValueFromPipeline = $true)] |
| 87 | + [Alias('App')] |
| 88 | + [String] |
| 89 | + $AppName, |
| 90 | + [Parameter(Position = 1)] |
| 91 | + [Switch] |
| 92 | + $Global |
| 93 | + ) |
| 94 | + process { |
| 95 | + $appPath = appdir $AppName $Global |
| 96 | + if (Test-Path $appPath) { |
| 97 | + $versions = @((Get-ChildItem "$appPath\*\install.json" | Sort-Object -Property LastWriteTimeUtc).Directory.Name) |
| 98 | + return $versions | Where-Object { ($_ -ne 'current') -and ($_ -notlike '_*.old*') } |
| 99 | + } else { |
| 100 | + return @() |
| 101 | + } |
19 | 102 | }
|
| 103 | + # Deprecated |
| 104 | + # sort_versions (Get-ChildItem $appPath -dir -attr !reparsePoint | Where-Object { $null -ne $(Get-ChildItem $_.FullName) } | ForEach-Object { $_.Name }) |
20 | 105 | }
|
21 |
| -function compare_versions($a, $b) { |
22 |
| - $ver_a = @(version $a) |
23 |
| - $ver_b = @(version $b) |
24 | 106 |
|
25 |
| - for($i=0;$i -lt $ver_a.length;$i++) { |
26 |
| - if($i -gt $ver_b.length) { return 1; } |
| 107 | +function Compare-Version { |
| 108 | + <# |
| 109 | + .SYNOPSIS |
| 110 | + Compare versions, mainly according to SemVer's rules |
| 111 | + .PARAMETER ReferenceVersion |
| 112 | + Specifies a version used as a reference for comparison |
| 113 | + .PARAMETER DifferenceVersion |
| 114 | + Specifies the version that are compared to the reference version |
| 115 | + .PARAMETER Delimiter |
| 116 | + Specifies the delimiter of versions |
| 117 | + .OUTPUTS |
| 118 | + System.Int32 |
| 119 | + '0' if DifferenceVersion is equal to ReferenceVersion, |
| 120 | + '1' if DifferenceVersion is greater then ReferenceVersion, |
| 121 | + '-1' if DifferenceVersion is less then ReferenceVersion |
| 122 | + #> |
| 123 | + [OutputType([Int32])] |
| 124 | + [CmdletBinding()] |
| 125 | + param ( |
| 126 | + [Parameter(Mandatory = $true, Position = 0)] |
| 127 | + [AllowEmptyString()] |
| 128 | + [String] |
| 129 | + $ReferenceVersion, |
| 130 | + [Parameter(Mandatory = $true, Position = 1, ValueFromPipeline = $true)] |
| 131 | + [AllowEmptyString()] |
| 132 | + [String] |
| 133 | + $DifferenceVersion, |
| 134 | + [String] |
| 135 | + $Delimiter = '-' |
| 136 | + ) |
| 137 | + process { |
| 138 | + # Use '+' sign as post-release, see https://github.com/lukesampson/scoop/pull/3721#issuecomment-553718093 |
| 139 | + $ReferenceVersion, $DifferenceVersion = @($ReferenceVersion, $DifferenceVersion) -replace '\+', '-' |
27 | 140 |
|
28 |
| - # don't try to compare int to string |
29 |
| - if($ver_b[$i] -is [string] -and $ver_a[$i] -isnot [string]) { |
30 |
| - $ver_a[$i] = "$($ver_a[$i])" |
| 141 | + # Return 0 if versions are equal |
| 142 | + if ($DifferenceVersion -eq $ReferenceVersion) { |
| 143 | + return 0 |
31 | 144 | }
|
32 | 145 |
|
33 |
| - if($ver_a[$i] -gt $ver_b[$i]) { return 1; } |
34 |
| - if($ver_a[$i] -lt $ver_b[$i]) { return -1; } |
| 146 | + # Preprocess versions (split, convert and separate) |
| 147 | + $splitReferenceVersion = @(SplitVersion -Version $ReferenceVersion -Delimiter $Delimiter) |
| 148 | + $splitDifferenceVersion = @(SplitVersion -Version $DifferenceVersion -Delimiter $Delimiter) |
| 149 | + |
| 150 | + # Nightly versions are always equal |
| 151 | + if ($splitReferenceVersion[0] -eq 'nightly' -and $splitDifferenceVersion[0] -eq 'nightly') { |
| 152 | + return 0 |
| 153 | + } |
| 154 | + |
| 155 | + for ($i = 0; $i -lt [Math]::Max($splitReferenceVersion.Length, $splitDifferenceVersion.Length); $i++) { |
| 156 | + # '1.1-alpha' is less then '1.1' |
| 157 | + if ($i -ge $splitReferenceVersion.Length) { |
| 158 | + if ($splitDifferenceVersion[$i] -match 'alpha|beta|rc|pre') { |
| 159 | + return -1 |
| 160 | + } else { |
| 161 | + return 1 |
| 162 | + } |
| 163 | + } |
| 164 | + # '1.1' is greater then '1.1-beta' |
| 165 | + if ($i -ge $splitDifferenceVersion.Length) { |
| 166 | + if ($splitReferenceVersion[$i] -match 'alpha|beta|rc|pre') { |
| 167 | + return 1 |
| 168 | + } else { |
| 169 | + return -1 |
| 170 | + } |
| 171 | + } |
| 172 | + |
| 173 | + # If some parts of versions have '.', compare them with delimiter '.' |
| 174 | + if (($splitReferenceVersion[$i] -match '\.') -or ($splitDifferenceVersion[$i] -match '\.')) { |
| 175 | + $Result = Compare-Version -ReferenceVersion $splitReferenceVersion[$i] -DifferenceVersion $splitDifferenceVersion[$i] -Delimiter '.' |
| 176 | + # If the parts are equal, continue to next part, otherwise return |
| 177 | + if ($Result -ne 0) { |
| 178 | + return $Result |
| 179 | + } else { |
| 180 | + continue |
| 181 | + } |
| 182 | + } |
| 183 | + |
| 184 | + # Don't try to compare [Long] to [String] |
| 185 | + if ($null -ne $splitReferenceVersion[$i] -and $null -ne $splitDifferenceVersion[$i]) { |
| 186 | + if ($splitReferenceVersion[$i] -is [String] -and $splitDifferenceVersion[$i] -isnot [String]) { |
| 187 | + $splitDifferenceVersion[$i] = "$($splitDifferenceVersion[$i])" |
| 188 | + } |
| 189 | + if ($splitDifferenceVersion[$i] -is [String] -and $splitReferenceVersion[$i] -isnot [String]) { |
| 190 | + $splitReferenceVersion[$i] = "$($splitReferenceVersion[$i])" |
| 191 | + } |
| 192 | + } |
| 193 | + |
| 194 | + # Compare [String] or [Long] |
| 195 | + if ($splitDifferenceVersion[$i] -gt $splitReferenceVersion[$i]) { |
| 196 | + return 1 |
| 197 | + } |
| 198 | + if ($splitDifferenceVersion[$i] -lt $splitReferenceVersion[$i]) { |
| 199 | + return -1 |
| 200 | + } |
| 201 | + } |
35 | 202 | }
|
36 |
| - if($ver_b.length -gt $ver_a.length) { return -1 } |
37 |
| - return 0 |
38 | 203 | }
|
39 | 204 |
|
| 205 | +# Helper function |
| 206 | +function SplitVersion { |
| 207 | + <# |
| 208 | + .SYNOPSIS |
| 209 | + Split version by Delimiter, convert number string to number, and separate letters from numbers |
| 210 | + .PARAMETER Version |
| 211 | + Specifies a version |
| 212 | + .PARAMETER Delimiter |
| 213 | + Specifies the delimiter of version (Literal) |
| 214 | + #> |
| 215 | + [OutputType([Object[]])] |
| 216 | + [CmdletBinding()] |
| 217 | + param ( |
| 218 | + [Parameter(Mandatory = $true, Position = 0, ValueFromPipeline = $true)] |
| 219 | + [AllowEmptyString()] |
| 220 | + [String] |
| 221 | + $Version, |
| 222 | + [String] |
| 223 | + $Delimiter = '-' |
| 224 | + ) |
| 225 | + process { |
| 226 | + $Version = $Version -replace '[a-zA-Z]+', "$Delimiter$&$Delimiter" |
| 227 | + return ($Version -split [Regex]::Escape($Delimiter) -ne '' | ForEach-Object { if ($_ -match '^\d+$') { [Long]$_ } else { $_ } }) |
| 228 | + } |
| 229 | +} |
| 230 | + |
| 231 | +# Deprecated |
| 232 | +# Not used anymore in scoop core |
40 | 233 | function qsort($ary, $fn) {
|
41 |
| - if($null -eq $ary) { return @() } |
42 |
| - if(!($ary -is [array])) { return @($ary) } |
| 234 | + warn '"qsort" is deprecated. Please avoid using it anymore.' |
| 235 | + if ($null -eq $ary) { return @() } |
| 236 | + if (!($ary -is [array])) { return @($ary) } |
43 | 237 |
|
44 | 238 | $pivot = $ary[0]
|
45 |
| - $rem = $ary[1..($ary.length-1)] |
| 239 | + $rem = $ary[1..($ary.length - 1)] |
46 | 240 |
|
47 |
| - $lesser = qsort ($rem | Where-Object { (& $fn $_ $pivot) -lt 0 }) $fn |
| 241 | + $lesser = qsort ($rem | Where-Object { (& $fn $pivot $_) -lt 0 }) $fn |
48 | 242 |
|
49 |
| - $greater = qsort ($rem | Where-Object { (& $fn $_ $pivot) -ge 0 }) $fn |
| 243 | + $greater = qsort ($rem | Where-Object { (& $fn $pivot $_) -ge 0 }) $fn |
50 | 244 |
|
51 | 245 | return @() + $lesser + @($pivot) + $greater
|
52 | 246 | }
|
53 |
| -function sort_versions($versions) { qsort $versions compare_versions } |
| 247 | + |
| 248 | +# Deprecated |
| 249 | +# Not used anymore in scoop core |
| 250 | +function sort_versions($versions) { |
| 251 | + warn '"sort_versions" is deprecated. Please avoid using it anymore.' |
| 252 | + qsort $versions Compare-Version |
| 253 | +} |
| 254 | + |
| 255 | +function compare_versions($a, $b) { |
| 256 | + Show-DeprecatedWarning $MyInvocation 'Compare-Version' |
| 257 | + # Please note the parameters' sequence |
| 258 | + return Compare-Version -ReferenceVersion $b -DifferenceVersion $a |
| 259 | +} |
| 260 | + |
| 261 | +function latest_version($app, $bucket, $url) { |
| 262 | + Show-DeprecatedWarning $MyInvocation 'Get-LatestVersion' |
| 263 | + return Get-LatestVersion -AppName $app -Bucket $bucket -Uri $url |
| 264 | +} |
| 265 | + |
| 266 | +function current_version($app, $global) { |
| 267 | + Show-DeprecatedWarning $MyInvocation 'Select-CurrentVersion' |
| 268 | + return Select-CurrentVersion -AppName $app -Global:$global |
| 269 | +} |
| 270 | + |
| 271 | +function versions($app, $global) { |
| 272 | + Show-DeprecatedWarning $MyInvocation 'Get-InstalledVersion' |
| 273 | + return Get-InstalledVersion -AppName $app -Global:$global |
| 274 | +} |
0 commit comments