Skip to content
Open
Show file tree
Hide file tree
Changes from 2 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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
- **install:** Add separator at the end of notes, highlight suggestions ([#6418](https://github.com/ScoopInstaller/Scoop/issues/6418))
- **download|scoop-download:** Add GitHub issue prompt when the default downloader fails ([#6539](https://github.com/ScoopInstaller/Scoop/issues/6539))
- **download|scoop-config:** Allow disabling automatic fallback to the default downloader when Aria2c download fails ([#6538](https://github.com/ScoopInstaller/Scoop/issues/6538))
- **scoop-install|update:** Update extraction tools ahead of installs/updates ([#6572](https://github.com/ScoopInstaller/Scoop/issues/6572))

### Bug Fixes

Expand Down
2 changes: 2 additions & 0 deletions lib/core.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -474,12 +474,14 @@ function Get-HelperPath {
'7zip' { $HelperPath = Get-AppFilePath '7zip' '7z.exe' }
'Lessmsi' { $HelperPath = Get-AppFilePath 'lessmsi' 'lessmsi.exe' }
'Innounp' {
# Changes to the extraction tool priority should be synced with the Get-OutdatedHelper function as well.
$HelperPath = Get-AppFilePath 'innounp-unicode' 'innounp.exe'
if ([String]::IsNullOrEmpty($HelperPath)) {
$HelperPath = Get-AppFilePath 'innounp' 'innounp.exe'
}
}
'Dark' {
# Changes to the extraction tool priority should be synced with the Get-OutdatedHelper function as well
$HelperPath = Get-AppFilePath 'wixtoolset' 'wix.exe'
if ([String]::IsNullOrEmpty($HelperPath)) {
$HelperPath = Get-AppFilePath 'dark' 'dark.exe'
Expand Down
94 changes: 94 additions & 0 deletions lib/depends.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -156,3 +156,97 @@ function Test-LessmsiRequirement {
)
return ($Uri | Where-Object { $_ -match '\.msi$' }).Count -gt 0
}

function Get-OutdatedHelper {
<#
.SYNOPSIS
Get outdated installation helpers
.PARAMETER App
App's name
.PARAMETER Global
Whether the app is globally installed
.OUTPUTS
[Object[]]
A list of concrete outdated helper apps, each represented as a PSCustomObject with 'App' and 'Global' properties
#>
[CmdletBinding()]
[OutputType([Object[]])]
param (
[Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
[String]
$App,
[Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
[Boolean]
$Global
)
begin {
$helpers = @()
}

process {
$version = Select-CurrentVersion -AppName $App -Global:$Global

$manifest = if ($version) {
installed_manifest $App $version $Global
} else {
Get-Manifest $App
}
$install = install_info $App $version $Global
$architecture = Format-ArchitectureString $install.architecture

$helpers += Get-InstallationHelper $manifest $architecture -All | Where-Object {
(Test-HelperInstalled -Helper $_) -and ($helpers -notcontains $_)
}
}

end {
$outdated = @()

foreach ($helper in $helpers) {
# Get the concrete app name
$app = switch ($helper) {
'7zip' { '7zip' }
'lessmsi' { 'lessmsi' }
'innounp' { if (installed 'innounp-unicode') { 'innounp-unicode' } else { 'innounp' } }
'dark' { if (installed 'wixtoolset') { 'wixtoolset' } else { 'dark' } }
default { $null }
}

if (-not $app) {
continue
}

$global = installed $app $true
$status = app_status $app $global

if (-not ($status.installed -and $status.outdated)) {
continue
}

info ("Outdated extraction tool '$app' detected: $($status.version) -> $($status.latest_version){0}." -f ('', ' (global)')[$global])

# Filter out outdated helpers that are held
if ($status.hold) {
warn "Skipping update of outdated extraction tool '$app' because it is held at version $($status.version)."
warn ("Outdated extraction tool may cause decompression errors. Please run 'scoop unhold $app{0}' to unhold it." -f ('', ' -g')[$global])
continue
}

# Filter out outdated helpers that are blocked by permission issues
if ((-not (is_admin)) -and $global) {
warn "Skipping update of outdated extraction tool '$app' because it is globally installed."
warn "Outdated extraction tool may cause decompression errors. Please run 'scoop update $app -g' to update it."
continue
}

Write-Host ("$app`: $($status.version) -> $($status.latest_version){0}" -f ('', ' (global)')[$global]) -ForegroundColor Yellow

$outdated += [PSCustomObject]@{
App = $app
Global = $global
}
}

return , $outdated
}
}
2 changes: 1 addition & 1 deletion lib/install.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ function Invoke-Installer {
if ($installer.file -or $installer.args) {
# Installer filename is either explicit defined ('installer.file') or file name in the first URL
if (!$Name) {
$Name = url_filename @(url $manifest $architecture)
$Name = url_filename @(url $manifest $ProcessorArchitecture)
}
$progName = "$Path\$(coalesce $installer.file $Name[0])"
if (!(is_in_dir $Path $progName)) {
Expand Down
126 changes: 126 additions & 0 deletions lib/update.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
function update($app, $global, $force, $quiet = $false, $independent, $suggested, $use_cache = $true, $check_hash = $true) {
$old_version = Select-CurrentVersion -AppName $app -Global:$global
$old_manifest = installed_manifest $app $old_version $global
$install = install_info $app $old_version $global

# re-use architecture, bucket and url from first install
$architecture = Format-ArchitectureString $install.architecture
$bucket = $install.bucket
if ($null -eq $bucket) {
$bucket = 'main'
}
$url = $install.url

$manifest = manifest $app $bucket $url
$version = $manifest.version
$is_nightly = $version -eq 'nightly'
if ($is_nightly) {
$version = nightly_version $quiet
$check_hash = $false
}

if (!$force -and ($old_version -eq $version)) {
if (!$quiet) {
warn "The latest version of '$app' ($version) is already installed."
}
return
}
if (!$version) {
# installed from a custom bucket/no longer supported
error "No manifest available for '$app'."
return
}

Write-Host "Updating '$app' ($old_version -> $version)"

#region Workaround for #2952
if (test_running_process $app $global) {
Write-Host 'Running process detected, skip updating.'
return
}
#endregion Workaround for #2952

# region Workaround
# Workaround for https://github.com/ScoopInstaller/Scoop/issues/2220 until install is refactored
# Remove and replace whole region after proper fix
Write-Host 'Downloading new version'
if (Test-Aria2Enabled) {
Invoke-CachedAria2Download $app $version $manifest $architecture $cachedir $manifest.cookie $true $check_hash
} else {
$urls = script:url $manifest $architecture

foreach ($url in $urls) {
Invoke-CachedDownload $app $version $url $null $manifest.cookie $true

if ($check_hash) {
$manifest_hash = hash_for_url $manifest $url $architecture
$source = cache_path $app $version $url
$ok, $err = check_hash $source $manifest_hash $(show_app $app $bucket)

if (!$ok) {
error $err
if (Test-Path $source) {
# rm cached file
Remove-Item -Force $source
}
if ($url.Contains('sourceforge.net')) {
Write-Host -f yellow 'SourceForge.net is known for causing hash validation fails. Please try again before opening a ticket.'
}
abort $(new_issue_msg $app $bucket 'hash check failed')
}
}
}
}
# There is no need to check hash again while installing
$check_hash = $false
# endregion Workaround

$dir = versiondir $app $old_version $global
$persist_dir = persistdir $app $global

Invoke-HookScript -HookType 'pre_uninstall' -Manifest $old_manifest -Arch $architecture

Write-Host "Uninstalling '$app' ($old_version)"
Invoke-Installer -Path $dir -Manifest $old_manifest -ProcessorArchitecture $architecture -Global:$global -Uninstall
rm_shims $app $old_manifest $global $architecture

# If a junction was used during install, that will have been used
# as the reference directory. Otherwise it will just be the version
# directory.
$refdir = unlink_current $dir
uninstall_psmodule $old_manifest $refdir $global
env_rm_path $old_manifest $refdir $global $architecture
env_rm $old_manifest $global $architecture

if ($force -and ($old_version -eq $version)) {
if (!(Test-Path "$dir/../_$version.old")) {
Move-Item "$dir" "$dir/../_$version.old"
} else {
$i = 1
while (Test-Path "$dir/../_$version.old($i)") {
$i++
}
Move-Item "$dir" "$dir/../_$version.old($i)"
}
}

Invoke-HookScript -HookType 'post_uninstall' -Manifest $old_manifest -Arch $architecture

if ($bucket) {
# add bucket name it was installed from
$app = "$bucket/$app"
}
if ($install.url) {
# use the url of the install json if the application was installed through url
$app = $install.url
}

if ($independent) {
install_app $app $architecture $global $suggested $use_cache $check_hash
} else {
# Also add missing dependencies
$apps = @(Get-Dependency $app $architecture) -ne $app
ensure_none_failed $apps
$apps.Where({ !(installed $_) }) + $app | ForEach-Object { install_app $_ $architecture $global $suggested $use_cache $check_hash }
}
}
8 changes: 7 additions & 1 deletion libexec/scoop-install.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
. "$PSScriptRoot\..\lib\manifest.ps1" # 'generate_user_manifest' 'Get-Manifest' 'Select-CurrentVersion' (indirectly)
. "$PSScriptRoot\..\lib\system.ps1"
. "$PSScriptRoot\..\lib\install.ps1"
. "$PSScriptRoot\..\lib\update.ps1"
. "$PSScriptRoot\..\lib\download.ps1"
. "$PSScriptRoot\..\lib\decompress.ps1"
. "$PSScriptRoot\..\lib\shortcuts.ps1"
Expand Down Expand Up @@ -65,7 +66,7 @@ if ($global -and !(is_admin)) {

if (is_scoop_outdated) {
if ($opt.u -or $opt.'no-update-scoop') {
warn "Scoop is out of date."
warn 'Scoop is out of date.'
} else {
& "$PSScriptRoot\scoop-update.ps1"
}
Expand Down Expand Up @@ -132,6 +133,11 @@ if ((Test-Aria2Enabled) -and (get_config 'aria2-warning-enabled' $true)) {
warn "Should it cause issues, run 'scoop config aria2-enabled false' to disable it."
warn "To disable this warning, run 'scoop config aria2-warning-enabled false'."
}

# Update extraction tools ahead of installs/updates
$outdated_helpers = $apps | ForEach-Object { [PSCustomObject]@{App = $_; Global = $global } } | Get-OutdatedHelper
$outdated_helpers | ForEach-Object { update $_.App $_.Global $false $false $independent $suggested $use_cache $check_hash }

$apps | ForEach-Object { install_app $_ $architecture $global $suggested $use_cache $check_hash }

show_suggestions $suggested
Expand Down
Loading
Loading