Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
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
23 changes: 23 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,26 @@
## [Unreleased](https://github.com/ScoopInstaller/Scoop/compare/v0.5.3...develop)

### Features

- **scoop-uninstall**: Allow access to `$bucket` in uninstall scripts ([#6380](https://github.com/ScoopInstaller/Scoop/issues/6380))
- **install:** Add separator at the end of notes, highlight suggestions ([#6418](https://github.com/ScoopInstaller/Scoop/issues/6418))

### Bug Fixes

- **scoop-download**: Fix function `nightly_version` not defined error ([#6386](https://github.com/ScoopInstaller/Scoop/issues/6386))
- **scoop-uninstall:**: Correct `-Global` Switch ([#6454](https://github.com/ScoopInstaller/Scoop/issues/6454))
- **scoop-update**: Force sync tags w/ remote branch while scoop update ([#6439](https://github.com/ScoopInstaller/Scoop/issues/6439))
- **autoupdate:** Use origin URL to handle URLs with fragment in GitHub mode ([#6455](https://github.com/ScoopInstaller/Scoop/issues/6455))
- **buckets|scoop-info:** Switch git log date format to ISO 8601 to avoid locale issues ([#6446](https://github.com/ScoopInstaller/Scoop/issues/6446))
- **scoop-version:** Fix logic error caused by missing brackets ([#6463](https://github.com/ScoopInstaller/Scoop/issues/6463))
- **core|manifest:** Avoid error messages when searching non-existent 'deprecated' directory ([#6471](https://github.com/ScoopInstaller/Scoop/issues/6471))
- **checkver:** Allow script to run when URL fetch fails but script exists ([#6490](https://github.com/ScoopInstaller/Scoop/issues/6490))
- **decompress:** Fix `Expand-7zipArchive` won't remove top folder if $ExtractDir depth exceeds 2 ([#6515](https://github.com/ScoopInstaller/Scoop/issues/6515))

### Code Refactoring

- **output**: Replace raw prints with functions for standardized output ([#6449](https://github.com/ScoopInstaller/Scoop/issues/6449))

## [v0.5.3](https://github.com/ScoopInstaller/Scoop/compare/v0.5.2...v0.5.3) - 2025-08-11

### Features
Expand Down
11 changes: 8 additions & 3 deletions bin/checkver.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -281,11 +281,16 @@ while ($in_progress -gt 0) {
}
$err = $ev.SourceEventArgs.Error
if ($err) {
next "$($err.message)`r`nURL $url is not valid"
continue
if (!$script) {
next "$($err.message)`r`nURL $url is not valid"
continue
} else {
# Run script despite URL download failure
Write-Host "$($err.message)`r`nURL $url is not valid. Falling back to checkver.script ..."
}
}

if ($url) {
if ($url -and !$err) {
$ms = New-Object System.IO.MemoryStream
$ms.Write($result, 0, $result.Length)
$ms.Seek(0, 0) | Out-Null
Expand Down
8 changes: 4 additions & 4 deletions bin/scoop.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ switch ($subCommand) {
}
({ $subCommand -in @('-v', '--version') }) {
Write-Host 'Current Scoop version:'
if (Test-GitAvailable -and (Test-Path "$PSScriptRoot\..\.git") -and (get_config SCOOP_BRANCH 'master') -ne 'master') {
Invoke-Git -Path "$PSScriptRoot\.." -ArgumentList @('log', 'HEAD', '-1', '--oneline')
if ((Test-GitAvailable) -and (Test-Path "$PSScriptRoot\..\.git") -and ((get_config SCOOP_BRANCH 'master') -ne 'master')) {
Invoke-Git -Path "$PSScriptRoot\.." -ArgumentList @('--no-pager', 'log', 'HEAD', '-1', '--oneline')
} else {
$version = Select-String -Pattern '^## \[(v[\d.]+)\].*?([\d-]+)$' -Path "$PSScriptRoot\..\CHANGELOG.md"
Write-Host $version.Matches.Groups[1].Value -ForegroundColor Cyan -NoNewline
Expand All @@ -31,9 +31,9 @@ switch ($subCommand) {

Get-LocalBucket | ForEach-Object {
$bucketLoc = Find-BucketDirectory $_ -Root
if (Test-GitAvailable -and (Test-Path "$bucketLoc\.git")) {
if ((Test-GitAvailable) -and (Test-Path "$bucketLoc\.git")) {
Write-Host "'$_' bucket:"
Invoke-Git -Path $bucketLoc -ArgumentList @('log', 'HEAD', '-1', '--oneline')
Invoke-Git -Path $bucketLoc -ArgumentList @('--no-pager', 'log', 'HEAD', '-1', '--oneline')
Write-Host ''
}
}
Expand Down
2 changes: 1 addition & 1 deletion bin/uninstall.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ function do_uninstall($app, $global) {
$architecture = $install.architecture

Write-Output "Uninstalling '$app'"
Invoke-Installer -Path $dir -Manifest $manifest -ProcessorArchitecture $architecture -Uninstall
Invoke-Installer -Path $dir -Manifest $manifest -ProcessorArchitecture $architecture -Global:$global -Uninstall
rm_shims $app $manifest $global $architecture

# If a junction was used during install, that will have been used
Expand Down
11 changes: 7 additions & 4 deletions lib/autoupdate.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
function format_hash([String] $hash) {
$hash = $hash.toLower()

# Workaround for GitHub API:
# `"digest": "sha256:<SHA256_STRING>"`
if ($hash -like 'sha256:*') {
$hash = $hash.Substring(7) # Remove prefix 'sha256:'
}
Expand Down Expand Up @@ -209,13 +211,14 @@ function get_hash_for_app([String] $app, $config, [String] $version, [String] $u
$hash = $null

$hashmode = $config.mode
$originurl = strip_fragment $url
$basename = [System.Web.HttpUtility]::UrlDecode((url_remote_filename($url)))

$substitutions = $substitutions.Clone()
$substitutions.Add('$url', (strip_fragment $url))
$substitutions.Add('$baseurl', (strip_filename (strip_fragment $url)).TrimEnd('/'))
$substitutions.Add('$url', $originurl)
$substitutions.Add('$baseurl', (strip_filename $originurl).TrimEnd('/'))
$substitutions.Add('$basename', $basename)
$substitutions.Add('$urlNoExt', (strip_ext (strip_fragment $url)))
$substitutions.Add('$urlNoExt', (strip_ext $originurl))
$substitutions.Add('$basenameNoExt', (strip_ext $basename))

debug $substitutions
Expand Down Expand Up @@ -297,7 +300,7 @@ function get_hash_for_app([String] $app, $config, [String] $version, [String] $u
}
'github' {
$hashfile_url = "https://api.github.com/repos/$($matches['owner'])/$($matches['repo'])/releases"
$hash = find_hash_in_json $hashfile_url $substitutions ("$..assets[?(@.browser_download_url == '" + $url + "')].digest")
$hash = find_hash_in_json $hashfile_url $substitutions ("$..assets[?(@.browser_download_url == '" + $originurl + "')].digest")
}
}

Expand Down
2 changes: 1 addition & 1 deletion lib/buckets.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ function list_buckets {
$path = Find-BucketDirectory $_ -Root
if ((Test-Path (Join-Path $path '.git')) -and (Get-Command git -ErrorAction SilentlyContinue)) {
$bucket.Source = Invoke-Git -Path $path -ArgumentList @('config', 'remote.origin.url')
$bucket.Updated = Invoke-Git -Path $path -ArgumentList @('log', '--format=%aD', '-n', '1') | Get-Date
$bucket.Updated = Invoke-Git -Path $path -ArgumentList @('log', '--format=%aI', '-n', '1') | Get-Date
} else {
$bucket.Source = friendly_path $path
$bucket.Updated = (Get-Item "$path\bucket" -ErrorAction SilentlyContinue).LastWriteTime
Expand Down
4 changes: 2 additions & 2 deletions lib/core.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ function load_cfg($file) {
$content = [System.IO.File]::ReadAllLines($file)
return ($content | ConvertFrom-Json -ErrorAction Stop)
} catch {
Write-Host "ERROR loading $file`: $($_.exception.message)"
error "loading $file`: $($_.exception.message)"
}
}

Expand Down Expand Up @@ -555,7 +555,7 @@ function app_status($app, $global) {
$status.hold = ($install_info.hold -eq $true)

$deprecated_dir = (Find-BucketDirectory -Name $install_info.bucket -Root) + "\deprecated"
$status.deprecated = (Get-ChildItem $deprecated_dir -Filter "$(sanitary_path $app).json" -Recurse).FullName
$status.deprecated = (Get-ChildItem $deprecated_dir -Filter "$(sanitary_path $app).json" -Recurse -ErrorAction Ignore).FullName

$manifest = manifest $app $install_info.bucket $install_info.url
$status.removed = (!$manifest)
Expand Down
47 changes: 30 additions & 17 deletions lib/decompress.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ function Expand-7zipArchive {
} else {
$7zPath = Get-HelperPath -Helper 7zip
}
$LogPath = "$(Split-Path $Path)\7zip.log"
$LogPath = "$(Split-Path -Path $Path)\7zip.log"
$DestinationPath = $DestinationPath.TrimEnd('\')
$ArgList = @('x', $Path, "-o$DestinationPath", '-xr!*.nsis', '-y')
$IsTar = ((strip_ext $Path) -match '\.tar$') -or ($Path -match '\.t[abgpx]z2?$')
Expand All @@ -106,13 +106,13 @@ function Expand-7zipArchive {
'Skip' { $ArgList += '-aos' }
'Rename' { $ArgList += '-aou' }
}
$Status = Invoke-ExternalCommand $7zPath $ArgList -LogPath $LogPath
if (!$Status) {
abort "Failed to extract files from $Path.`nLog file:`n $(friendly_path $LogPath)`n$(new_issue_msg $app $bucket 'decompress error')"
$Status = Invoke-ExternalCommand -FilePath $7zPath -ArgumentList $ArgList -LogPath $LogPath
if (-not $Status) {
abort "Failed to extract files from $Path.`nLog file:`n $(friendly_path -path $LogPath)`n$(new_issue_msg $app $bucket 'decompress error')"
}
if ($IsTar) {
# Check for tar
$Status = Invoke-ExternalCommand $7zPath @('l', $Path) -LogPath $LogPath
$Status = Invoke-ExternalCommand -FilePath $7zPath -ArgumentList @('l', $Path) -LogPath $LogPath
if ($Status) {
# get inner tar file name
$TarFile = (Select-String -Path $LogPath -Pattern '[^ ]*tar$').Matches.Value
Expand All @@ -121,27 +121,40 @@ function Expand-7zipArchive {
abort "Failed to list files in $Path.`nNot a 7-Zip supported archive file."
}
}
if (!$IsTar -and $ExtractDir) {
movedir "$DestinationPath\$ExtractDir" $DestinationPath | Out-Null
# Remove temporary directory if it is empty
$ExtractDirTopPath = [string] "$DestinationPath\$($ExtractDir -replace '[\\/].*')"
if ((Get-ChildItem -Path $ExtractDirTopPath -Force -ErrorAction Ignore).Count -eq 0) {
Remove-Item -Path $ExtractDirTopPath -Recurse -Force -ErrorAction Ignore
if (-not $IsTar -and $ExtractDir) {
# Move content from $ExtractDir to destination
$null = movedir -from "$DestinationPath\$ExtractDir" -to $DestinationPath
# Remove temporary directories if not empty
$ExtractDirs = [string[]]($ExtractDir -split '[\\/]' | Where-Object -FilterScript { -not [string]::IsNullOrWhiteSpace($_) })
$Depth = [byte] $ExtractDirs.'Count'
do {
$CurrentDir = [string] [System.IO.Path]::Combine(
$DestinationPath, (
($ExtractDirs | Select-Object -First $Depth) -join [System.IO.Path]::DirectorySeparatorChar
)
)
if ((Get-ChildItem -Path $CurrentDir -Force -ErrorAction 'Ignore').'Count' -gt 0) {
$Depth = 0
} else {
Remove-Item -Path $CurrentDir -Recurse -Force -ErrorAction 'Ignore'
}
$Depth--
}
while ($Depth -gt 0)
}
if (Test-Path $LogPath) {
Remove-Item $LogPath -Force
if (Test-Path -Path $LogPath -PathType 'Leaf') {
Remove-Item -Path $LogPath -Force
}
if ($Removal) {
if (($Path -replace '.*\.([^\.]*)$', '$1') -eq '001') {
# Remove splitted 7-zip archive parts
Get-ChildItem "$($Path -replace '\.[^\.]*$', '').???" | Remove-Item -Force
Get-ChildItem -Path "$($Path -replace '\.[^\.]*$', '').???" | Remove-Item -Force
} elseif (($Path -replace '.*\.part(\d+)\.rar$', '$1')[-1] -eq '1') {
# Remove splitted RAR archive parts
Get-ChildItem "$($Path -replace '\.part(\d+)\.rar$', '').part*.rar" | Remove-Item -Force
Get-ChildItem -Path "$($Path -replace '\.part(\d+)\.rar$', '').part*.rar" | Remove-Item -Force
} else {
# Remove original archive file
Remove-Item $Path -Force
Remove-Item -Path $Path -Force
}
}
}
Expand Down Expand Up @@ -248,7 +261,7 @@ function Expand-InnoArchive {
switch -Regex ($ExtractDir) {
'^[^{].*' { $ArgList += "-c{app}\$ExtractDir" }
'^{.*' { $ArgList += "-c$ExtractDir" }
Default { $ArgList += '-c{app}' }
default { $ArgList += '-c{app}' }
}
if ($Switches) {
$ArgList += (-split $Switches)
Expand Down
5 changes: 3 additions & 2 deletions lib/install.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ function ensure_install_dir_not_in_path($dir, $global) {

$fixed, $removed = find_dir_or_subdir $path "$dir"
if ($removed) {
$removed | ForEach-Object { "Installer added '$(friendly_path $_)' to path. Removing." }
$removed | ForEach-Object { Write-Output "Installer added '$(friendly_path $_)' to path. Removing." }
Set-EnvVar -Name 'PATH' -Value $fixed -Global:$global
}

Expand Down Expand Up @@ -359,6 +359,7 @@ function show_notes($manifest, $dir, $original_dir, $persist_dir) {
Write-Output 'Notes'
Write-Output '-----'
Write-Output (wraptext (substitute $manifest.notes @{ '$dir' = $dir; '$original_dir' = $original_dir; '$persist_dir' = $persist_dir }))
Write-Output '-----'
}
}

Expand Down Expand Up @@ -419,7 +420,7 @@ function show_suggestions($suggested) {
}

if (!$fulfilled) {
Write-Host "'$app' suggests installing '$([string]::join("' or '", $feature_suggestions))'."
Write-Host "'$app' suggests installing '$([string]::join("' or '", $feature_suggestions))'." -ForegroundColor DarkYellow
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion lib/manifest.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ function Get-Manifest($app) {
$manifest = manifest $app $bucket
if (!$manifest) {
$deprecated_dir = (Find-BucketDirectory -Name $bucket -Root) + '\deprecated'
$manifest = parse_json (Get-ChildItem $deprecated_dir -Filter "$(sanitary_path $app).json" -Recurse).FullName
$manifest = parse_json (Get-ChildItem $deprecated_dir -Filter "$(sanitary_path $app).json" -Recurse -ErrorAction Ignore).FullName
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion libexec/scoop-alias.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ if ($SubCommand -notin $SubCommands) {
}

$opt, $other, $err = getopt $Args 'v' 'verbose'
if ($err) { "scoop alias: $err"; exit 1 }
if ($err) { error "scoop alias: $err"; exit 1 }

$name, $command, $description = $other
$verbose = $opt.v -or $opt.verbose
Expand Down
8 changes: 4 additions & 4 deletions libexec/scoop-bucket.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,14 @@ $usage_rm = 'usage: scoop bucket rm <name>'
switch ($cmd) {
'add' {
if (!$name) {
'<name> missing'
error '<name> missing'
$usage_add
exit 1
}
if (!$repo) {
$repo = known_bucket_repo $name
if (!$repo) {
"Unknown bucket '$name'. Try specifying <repo>."
error "Unknown bucket '$name'. Try specifying <repo>."
$usage_add
exit 1
}
Expand All @@ -51,7 +51,7 @@ switch ($cmd) {
}
'rm' {
if (!$name) {
'<name> missing'
error '<name> missing'
$usage_rm
exit 1
}
Expand All @@ -73,7 +73,7 @@ switch ($cmd) {
exit 0
}
default {
"scoop bucket: cmd '$cmd' not supported"
error "scoop bucket: cmd '$cmd' not supported"
my_usage
exit 1
}
Expand Down
2 changes: 1 addition & 1 deletion libexec/scoop-cache.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ function cacheshow($app) {

function cacheremove($app) {
if (!$app) {
'ERROR: <app(s)> missing'
error '<app(s)> missing'
my_usage
exit 1
} elseif ($app -eq '*' -or $app -eq '-a' -or $app -eq '--all') {
Expand Down
6 changes: 3 additions & 3 deletions libexec/scoop-cleanup.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@
. "$PSScriptRoot\..\lib\install.ps1" # persist related

$opt, $apps, $err = getopt $args 'agk' 'all', 'global', 'cache'
if ($err) { "scoop cleanup: $err"; exit 1 }
if ($err) { error "scoop cleanup: $err"; exit 1 }
$global = $opt.g -or $opt.global
$cache = $opt.k -or $opt.cache
$all = $opt.a -or $opt.all

if (!$apps -and !$all) { 'ERROR: <app> missing'; my_usage; exit 1 }
if (!$apps -and !$all) { error '<app> missing'; my_usage; exit 1 }

if ($global -and !(is_admin)) {
'ERROR: you need admin rights to cleanup global apps'; exit 1
error 'you need admin rights to cleanup global apps'; exit 1
}

function cleanup($app, $global, $verbose, $cache) {
Expand Down
1 change: 1 addition & 0 deletions libexec/scoop-download.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
. "$PSScriptRoot\..\lib\versions.ps1" # 'Select-CurrentVersion'
. "$PSScriptRoot\..\lib\manifest.ps1" # 'generate_user_manifest' 'Get-Manifest'
. "$PSScriptRoot\..\lib\download.ps1"
. "$PSScriptRoot\..\lib\install.ps1" # 'nightly_version'
if (get_config USE_SQLITE_CACHE) {
. "$PSScriptRoot\..\lib\database.ps1"
}
Expand Down
6 changes: 3 additions & 3 deletions libexec/scoop-help.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,17 @@ function print_summaries {

$commands = commands

if(!($cmd)) {
if (!($cmd)) {
Write-Host "Usage: scoop <command> [<args>]

Available commands are listed below.

Type 'scoop help <command>' to get more help for a specific command."
print_summaries
} elseif($commands -contains $cmd) {
} elseif ($commands -contains $cmd) {
print_help $cmd
} else {
warn "scoop help: no such command '$cmd'"
error "scoop help: no such command '$cmd'"
exit 1
}

Expand Down
2 changes: 1 addition & 1 deletion libexec/scoop-hold.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
. "$PSScriptRoot\..\lib\versions.ps1" # 'Select-CurrentVersion'

$opt, $apps, $err = getopt $args 'g' 'global'
if ($err) { "scoop hold: $err"; exit 1 }
if ($err) { error "scoop hold: $err"; exit 1 }

$global = $opt.g -or $opt.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 @@ -122,7 +122,7 @@ if ($manifest.depends) {

if (Test-Path $manifest_file) {
if (Get-Command git -ErrorAction Ignore) {
$gitinfo = (Invoke-Git -Path (Split-Path $manifest_file) -ArgumentList @('log', '-1', '-s', '--format=%aD#%an', $manifest_file) 2> $null) -Split '#'
$gitinfo = (Invoke-Git -Path (Split-Path $manifest_file) -ArgumentList @('log', '-1', '-s', '--format=%aI#%an', $manifest_file) 2> $null) -Split '#'
}
if ($gitinfo) {
$item.'Updated at' = $gitinfo[0] | Get-Date
Expand Down
2 changes: 1 addition & 1 deletion libexec/scoop-install.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ if (get_config USE_SQLITE_CACHE) {
}

$opt, $apps, $err = getopt $args 'giksua:' 'global', 'independent', 'no-cache', 'skip-hash-check', 'no-update-scoop', 'arch='
if ($err) { "scoop install: $err"; exit 1 }
if ($err) { error "scoop install: $err"; exit 1 }

$global = $opt.g -or $opt.global
$check_hash = !($opt.s -or $opt.'skip-hash-check')
Expand Down
Loading
Loading