Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(versions): Refactor 'versions.ps1' #3721

Merged
merged 23 commits into from
Nov 13, 2021
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion bin/checkver.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -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_versions $expected_ver $ver) -eq -1
$update_available = (Compare-Version $ver $expected_ver) -ne 0

if ($json.autoupdate -and $update_available) {
Write-Host ' autoupdate available' -ForegroundColor Cyan
Expand Down
2 changes: 1 addition & 1 deletion bin/uninstall.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ $errors = $false

# Uninstall given app
function do_uninstall($app, $global) {
$version = current_version $app $global
$version = Select-CurrentVersion -App $app -Global:$global
$dir = versiondir $app $version $global
$manifest = installed_manifest $app $version $global
$install = install_info $app $version $global
Expand Down
4 changes: 2 additions & 2 deletions lib/core.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ function Test-Aria2Enabled {
function app_status($app, $global) {
$status = @{}
$status.installed = (installed $app $global)
$status.version = current_version $app $global
$status.version = Select-CurrentVersion -App $app -Global:$global
$status.latest_version = $status.version

$install_info = install_info $app $status.version $global
Expand All @@ -305,7 +305,7 @@ function app_status($app, $global) {

$status.outdated = $false
if($status.version -and $status.latest_version) {
$status.outdated = ((compare_versions $status.latest_version $status.version) -gt 0)
$status.outdated = ((Compare-Version $status.version $status.latest_version) -ne 0)
}

$status.missing_deps = @()
Expand Down
2 changes: 1 addition & 1 deletion lib/install.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -1021,7 +1021,7 @@ function prune_installed($apps, $global) {

# check whether the app failed to install
function failed($app, $global) {
$ver = current_version $app $global
$ver = Select-CurrentVersion -App $app -Global:$global
if(!$ver) { return $false }
$info = install_info $app $ver $global
if(!$info) { return $true }
Expand Down
194 changes: 158 additions & 36 deletions lib/versions.ps1
Original file line number Diff line number Diff line change
@@ -1,53 +1,175 @@
# versions
function latest_version($app, $bucket, $url) {
(manifest $app $bucket $url).version
function Get-LatestVersion {
<#
.SYNOPSIS
Get latest version of app
.DESCRIPTION
Get latest version of app from manifest
#>
param (
[String]
# App's name
$App,
[String]
# Bucket which the app is belong to
$Bucket,
[String]
# Remote app manifest's URI
$URL
)
return (manifest $App $Bucket $URL).version
}
function current_version($app, $global) {
@(versions $app $global)[-1]
}
function versions($app, $global) {
$appdir = appdir $app $global
if(!(test-path $appdir)) { return @() }

sort_versions (Get-ChildItem $appdir -dir -attr !reparsePoint | Where-Object { $null -ne $(Get-ChildItem $_.fullname) } | ForEach-Object { $_.name })
function Select-CurrentVersion {
<#
.SYNOPSIS
Select current version of app
.DESCRIPTION
Select current version of installed app, from 'current\manifest.json' or modified time of version directory
#>
param (
[String]
# App's name
$App,
[Switch]
# If global installed
$Global
)

$appPath = appdir $App $Global
if (Test-Path "$appPath\current") {
$currentVersion = (installed_manifest $App 'current' $Global).version
} else {
$installedVersion = Get-InstalledVersion -App $App -Global:$Global
if ($installedVersion) {
$currentVersion = $installedVersion[-1]
} else {
$currentVersion = $null
}
}
return $currentVersion
}

function version($ver) {
$ver -split '[\.-]' | ForEach-Object {
$num = $_ -as [int]
if($num) { $num } else { $_ }
function Get-InstalledVersion {
<#
.SYNOPSIS
Get installed version of app
.DESCRIPTION
Get all installed version of app, by checking version directories' 'install.json'
#>
param (
[String]
# App's name
$App,
[Switch]
# If global installed
$Global
)

$appPath = appdir $App $Global
if (!(Test-Path $appPath)) {
return @()
} else {
return @((Get-ChildItem "$appPath\*\install.json" | Sort-Object -Property LastWriteTimeUtc).Directory.Name) -ne 'current'
}

# Deprecated
# sort_versions (Get-ChildItem $appPath -dir -attr !reparsePoint | Where-Object { $null -ne $(Get-ChildItem $_.FullName) } | ForEach-Object { $_.Name })
}
function compare_versions($a, $b) {
$ver_a = @(version $a)
$ver_b = @(version $b)

for($i=0;$i -lt $ver_a.length;$i++) {
if($i -gt $ver_b.length) { return 1; }
function Compare-Version {
<#
.SYNOPSIS
Compare versions
.DESCRIPTION
Compare versions, mainly according to SemVer's rules
#>
[OutputType('System.Int32')]
[CmdletBinding()]
param (
[Parameter(Position = 0)]
[String]
# Specifies a version used as a reference for comparison.
$ReferenceVersion,
[Parameter(Position = 1)]
[String]
# Specifies the version that are compared to the reference version.
$DifferenceVersion,
[String]
# Specifies the delimiter of versions
$Delimiter = '-'
)

# 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])"
}
# Use '+' sign as post-release, see https://github.com/lukesampson/scoop/pull/3721#issuecomment-553718093
$ReferenceVersion = $ReferenceVersion -replace '\+', '-'
$DifferenceVersion = $DifferenceVersion -replace '\+', '-'

if($ver_a[$i] -gt $ver_b[$i]) { return 1; }
if($ver_a[$i] -lt $ver_b[$i]) { return -1; }
if ($DifferenceVersion -eq $ReferenceVersion) {
return 0
}
if($ver_b.length -gt $ver_a.length) { return -1 }
return 0
}

function qsort($ary, $fn) {
if($null -eq $ary) { return @() }
if(!($ary -is [array])) { return @($ary) }
$splitReferenceVersion = @($ReferenceVersion -split $Delimiter | ForEach-Object { if ($_ -match "^\d+$") { [Long]$_ } else { ($_ -replace '[a-zA-Z]+', '.$&.').Replace('..', '.').Trim('.') } })
$splitDifferenceVersion = @($DifferenceVersion -split $Delimiter | ForEach-Object { if ($_ -match "^\d+$") { [Long]$_ } else { ($_ -replace '[a-zA-Z]+', '.$&.').Replace('..', '.').Trim('.') } })

$pivot = $ary[0]
$rem = $ary[1..($ary.length-1)]
if ($splitReferenceVersion[0] -eq 'nightly' -and $splitDifferenceVersion[0] -eq 'nightly') {
return 0
}

$lesser = qsort ($rem | Where-Object { (& $fn $_ $pivot) -lt 0 }) $fn
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
}
}

$greater = qsort ($rem | Where-Object { (& $fn $_ $pivot) -ge 0 }) $fn
if (($splitReferenceVersion[$i] -match "\.") -or ($splitDifferenceVersion[$i] -match "\.")) {
$Result = Compare-Version $splitReferenceVersion[$i] $splitDifferenceVersion[$i] -Delimiter '\.'
if ($Result -ne 0) {
return $Result
} else {
continue
}
}

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])"
}
}

return @() + $lesser + @($pivot) + $greater
if ($splitDifferenceVersion[$i] -gt $splitReferenceVersion[$i]) { return 1 }
if ($splitDifferenceVersion[$i] -lt $splitReferenceVersion[$i]) { return -1 }
}

return 0
}
function sort_versions($versions) { qsort $versions compare_versions }

# Deprecated
# function qsort($ary, $fn) {
# if($null -eq $ary) { return @() }
# if(!($ary -is [array])) { return @($ary) }
#
# $pivot = $ary[0]
# $rem = $ary[1..($ary.length-1)]
#
# $lesser = qsort ($rem | Where-Object { (& $fn $pivot $_) -lt 0 }) $fn
#
# $greater = qsort ($rem | Where-Object { (& $fn $pivot $_) -ge 0 }) $fn
#
# return @() + $lesser + @($pivot) + $greater
# }
#
# function sort_versions($versions) { qsort $versions Compare-Version }
4 changes: 2 additions & 2 deletions libexec/scoop-cleanup.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,11 @@ if ($global -and !(is_admin)) {
}

function cleanup($app, $global, $verbose, $cache) {
$current_version = current_version $app $global
$current_version = Select-CurrentVersion -App $app -Global:$global
if ($cache) {
Remove-Item "$cachedir\$app#*" -Exclude "$app#$current_version#*"
}
$versions = versions $app $global | Where-Object { $_ -ne $current_version -and $_ -ne 'current' }
$versions = Get-InstalledVersion -App $app -Global:$global | Where-Object { $_ -ne $current_version -and $_ -ne 'current' }
if (!$versions) {
if ($verbose) { success "$app is already clean" }
return
Expand Down
2 changes: 1 addition & 1 deletion libexec/scoop-export.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ if($apps) {
$apps | Sort-Object { $_.name } | Where-Object { !$query -or ($_.name -match $query) } | ForEach-Object {
$app = $_.name
$global = $_.global
$ver = current_version $app $global
$ver = Select-CurrentVersion -App $app -Global:$global
$global_display = $null; if($global) { $global_display = ' *global*'}

$install_info = install_info $app $ver $global
Expand Down
2 changes: 1 addition & 1 deletion libexec/scoop-info.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ Write-Output "Manifest:`n $manifest_file"
if($status.installed) {
# Show installed versions
Write-Output "Installed:"
$versions = versions $app $global
$versions = Get-InstalledVersion -App $app -Global:$global
$versions | ForEach-Object {
$dir = versiondir $app $_ $global
if($global) { $dir += " *global*" }
Expand Down
4 changes: 2 additions & 2 deletions libexec/scoop-install.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ function is_installed($app, $global) {
if (installed $app $global) {
function gf($g) { if ($g) { ' --global' } }

$version = @(versions $app $global)[-1]
$version = Select-CurrentVersion -App $app -Global:$global
if (!(install_info $app $version $global)) {
error "It looks like a previous installation of $app failed.`nRun 'scoop uninstall $app$(gf $global)' before retrying the install."
}
Expand Down Expand Up @@ -114,7 +114,7 @@ $apps, $skip = prune_installed $apps $global

$skip | Where-Object { $explicit_apps -contains $_ } | ForEach-Object {
$app, $null, $null = parse_app $_
$version = @(versions $app $global)[-1]
$version = Select-CurrentVersion -App $app -Global:$global
warn "'$app' ($version) is already installed. Skipping."
}

Expand Down
2 changes: 1 addition & 1 deletion libexec/scoop-list.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ if($apps) {
$apps | Sort-Object { $_.name } | Where-Object { !$query -or ($_.name -match $query) } | ForEach-Object {
$app = $_.name
$global = $_.global
$ver = current_version $app $global
$ver = Select-CurrentVersion -App $app -Global:$global

$install_info = install_info $app $ver $global
write-host " $app " -NoNewline
Expand Down
2 changes: 1 addition & 1 deletion libexec/scoop-reset.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ $apps | ForEach-Object {
}

if ($null -eq $version) {
$version = current_version $app $global
$version = Select-CurrentVersion -App $app -Global:$global
}

$manifest = installed_manifest $app $version $global
Expand Down
2 changes: 1 addition & 1 deletion libexec/scoop-search.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ function search_bucket($bucket, $query) {
}
}
}
$apps | ForEach-Object { $_.version = (latest_version $_.name $bucket); $_ }
$apps | ForEach-Object { $_.version = (Get-LatestVersion $_.name $bucket); $_ }
}

function download_json($url) {
Expand Down
6 changes: 3 additions & 3 deletions libexec/scoop-uninstall.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ if (!$apps) { exit 0 }
:app_loop foreach ($_ in $apps) {
($app, $global) = $_

$version = current_version $app $global
$version = Select-CurrentVersion -App $app -Global:$global
Write-Host "Uninstalling '$app' ($version)."

$dir = versiondir $app $version $global
Expand Down Expand Up @@ -101,7 +101,7 @@ if (!$apps) { exit 0 }
}

# remove older versions
$old = @(versions $app $global)
$old = Get-InstalledVersion -App $app -Global:$global
foreach ($oldver in $old) {
Write-Host "Removing older version ($oldver)."
$dir = versiondir $app $oldver $global
Expand All @@ -115,7 +115,7 @@ if (!$apps) { exit 0 }
}
}

if (@(versions $app $global).length -eq 0) {
if ((Get-InstalledVersion -App $app -Global:$global).length -eq 0) {
$appdir = appdir $app $global
try {
# if last install failed, the directory seems to be locked and this
Expand Down
4 changes: 2 additions & 2 deletions libexec/scoop-update.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ function update_scoop() {
}

function update($app, $global, $quiet = $false, $independent, $suggested, $use_cache = $true, $check_hash = $true) {
$old_version = current_version $app $global
$old_version = Select-CurrentVersion -App $app -Global:$global
$old_manifest = installed_manifest $app $old_version $global
$install = install_info $app $old_version $global

Expand All @@ -180,7 +180,7 @@ function update($app, $global, $quiet = $false, $independent, $suggested, $use_c
$deps | ForEach-Object { install_app $_ $architecture $global $suggested $use_cache $check_hash }
}

$version = latest_version $app $bucket $url
$version = Get-LatestVersion $app $bucket $url
$is_nightly = $version -eq 'nightly'
if ($is_nightly) {
$version = nightly_version $(get-date) $quiet
Expand Down
Loading