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

feat(cache): Add "tidy" as older cache removal command #6229

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
## [Unreleased](https://github.com/ScoopInstaller/Scoop/compare/master...develop)

### BREAKING CHANGE

- **scoop-install|update**: `-k`option that skipped cache and forced redownload is replaced by `-d`. `-k` now keeps older cache after app update

### Features

- **scoop-cache|update**: New tidy command that removes older packages from cache. Automatically run it after app update ([#6068](https://github.com/ScoopInstaller/Scoop/issues/6068))

### Bug Fixes

- **scoop-download|install|update:** Fallback to default downloader when aria2 fails ([#4292](https://github.com/ScoopInstaller/Scoop/issues/4292))
Expand Down
35 changes: 35 additions & 0 deletions lib/cache.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Remove older cache of the given app
function tidy_cache([String] $app, [bool] $total_log = $false) {
if ($app -like "*.json") { return }

# Dependencies of the format "bucket/dependency" install in a directory of form
# "dependency". So we need to extract the bucket from the name and only use the app
# name
$app = ($app -split '/|\\')[-1]

$files = @(Get-ChildItem $cachedir | Where-Object -Property Name -Value "^$app#" -Match | Sort-Object LastWriteTime )
if ($files.Count -le 2) {
return
}

# do not remove last two files
$files = $files[0..($files.Count - 3)]
# remove only items more than one month old
$files = $files| Where-Object {$_.LastWriteTime -lt (Get-Date).AddMonths(-1)}
if ($files.Count -le 0) {
if ($total_log) { Write-Host "No old cache to remove" -ForegroundColor Yellow }
return
}
Write-Host -f yellow "Removing older cache for $app`:" -NoNewline

$totalLength = ($files | Measure-Object -Property Length -Sum).Sum
$files | ForEach-Object {
Write-Host " $(($_ -split '#')[1])" -NoNewline
Remove-Item $_.FullName
}

Write-Host ''
if ($total_log) {
Write-Host "Deleted: $($files.Count) $(pluralize $files.Count 'file' 'files'), $(filesize $totalLength)" -ForegroundColor Yellow
}
}
40 changes: 39 additions & 1 deletion libexec/scoop-cache.ps1
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Usage: scoop cache show|rm [app(s)]
# Usage: scoop cache show|rm|tidy [app(s)]
# Summary: Show or clear the download cache
# Help: Scoop caches downloads so you don't need to download the same files
# when you uninstall and re-install the same version of an app.
Expand All @@ -7,13 +7,19 @@
# scoop cache show
# to see what's in the cache, and
# scoop cache rm <app> to remove downloads for a specific app.
# Or to only remove downloads that older,
# scoop cache tidy <app> removes ones older than a month, keeping the two most recent
#
# To clear everything in your cache, use:
# scoop cache rm *
# To remove older items for all apps, use:
# scoop cache tidy *
# You can also use the `-a/--all` switch in place of `*` here

param($cmd)

. "$PSScriptRoot\..\lib\cache.ps1"

function cacheinfo($file) {
$app, $version, $url = $file.Name -split '#'
New-Object PSObject -Property @{ Name = $app; Version = $version; Length = $file.Length }
Expand Down Expand Up @@ -58,10 +64,42 @@ function cacheremove($app) {
Write-Host "Deleted: $($files.Length) $(pluralize $files.Length 'file' 'files'), $(filesize $totalLength)" -ForegroundColor Yellow
}

function cache_remove_older($app) {
if (!$app) {
'ERROR: <app(s)> missing'
my_usage
exit 1
} elseif ($app -eq '*' -or $app -eq '-a' -or $app -eq '--all') {
$files = @(Get-ChildItem $cachedir)
$totalLength = ($files | Measure-Object -Property Length -Sum).Sum
# Get all apps with cache, and remove their older packages
$apps = @()
$files | ForEach-Object {
$apps += ($_ -split '#', 2)[0]
}
$apps = $apps | Select-Object -Unique

$apps | ForEach-Object {
tidy_cache $_
}

$filesAfter = @(Get-ChildItem $cachedir)
$totalLengthAfter = ($filesAfter | Measure-Object -Property Length -Sum).Sum
$filesRemoved = $files.Length - $filesAfter.length
$sizeRemoved = $totalLength - $totalLengthAfter
Write-Host "Deleted: $($filesRemoved) $(pluralize $filesRemoved 'file' 'files'), $(filesize $sizeRemoved)" -ForegroundColor Yellow
} else {
tidy_cache $app $true
}
}

switch($cmd) {
'rm' {
cacheremove $Args
}
'tidy' {
cache_remove_older $Args
}
'show' {
cacheshow $Args
}
Expand Down
4 changes: 2 additions & 2 deletions libexec/scoop-install.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
# Options:
# -g, --global Install the app globally
# -i, --independent Don't install dependencies automatically
# -k, --no-cache Don't use the download cache
# -d, --no-cache Force redownload by not using the download cache
# -s, --skip-hash-check Skip hash validation (use with caution!)
# -u, --no-update-scoop Don't update Scoop before installing if it's outdated
# -a, --arch <32bit|64bit|arm64> Use the specified architecture, if the app supports it
Expand All @@ -49,7 +49,7 @@ if ($err) { "scoop install: $err"; exit 1 }
$global = $opt.g -or $opt.global
$check_hash = !($opt.s -or $opt.'skip-hash-check')
$independent = $opt.i -or $opt.independent
$use_cache = !($opt.k -or $opt.'no-cache')
$use_cache = !($opt.d -or $opt.'no-cache')
$architecture = Get-DefaultArchitecture
try {
$architecture = Format-ArchitectureString ($opt.a + $opt.arch)
Expand Down
18 changes: 13 additions & 5 deletions libexec/scoop-update.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
# -f, --force Force update even when there isn't a newer version
# -g, --global Update a globally installed app
# -i, --independent Don't install dependencies automatically
# -k, --no-cache Don't use the download cache
# -d, --no-cache Force redownload by not using the download cache
# -k, --keep-cache Don't remove older cached install packages
# -s, --skip-hash-check Skip hash validation (use with caution!)
# -q, --quiet Hide extraneous messages
# -a, --all Update all apps (alternative to '*')
Expand All @@ -25,16 +26,18 @@
. "$PSScriptRoot\..\lib\depends.ps1"
. "$PSScriptRoot\..\lib\install.ps1"
. "$PSScriptRoot\..\lib\download.ps1"
. "$PSScriptRoot\..\lib\cache.ps1"
if (get_config USE_SQLITE_CACHE) {
. "$PSScriptRoot\..\lib\database.ps1"
}

$opt, $apps, $err = getopt $args 'gfiksqa' 'global', 'force', 'independent', 'no-cache', 'skip-hash-check', 'quiet', 'all'
$opt, $apps, $err = getopt $args 'gfsdkqia' 'global', 'force', 'skip-hash-check', 'no-cache', 'keep-cache', 'quiet', 'independent', 'all'
if ($err) { "scoop update: $err"; exit 1 }
$global = $opt.g -or $opt.global
$force = $opt.f -or $opt.force
$check_hash = !($opt.s -or $opt.'skip-hash-check')
$use_cache = !($opt.k -or $opt.'no-cache')
$use_cache = !($opt.d -or $opt.'no-cache')
$keep_cache = $use_cache -and ($opt.k -or $opt.'keep-cache')
$quiet = $opt.q -or $opt.quiet
$independent = $opt.i -or $opt.independent
$all = $opt.a -or $opt.all
Expand Down Expand Up @@ -258,7 +261,7 @@ function Sync-Bucket {
}
}

function update($app, $global, $quiet = $false, $independent, $suggested, $use_cache = $true, $check_hash = $true) {
function update($app, $global, $quiet = $false, $independent, $suggested, $use_cache = $true, $keep_cache = $false, $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
Expand Down Expand Up @@ -383,6 +386,11 @@ function update($app, $global, $quiet = $false, $independent, $suggested, $use_c
ensure_none_failed $apps
$apps.Where({ !(installed $_) }) + $app | ForEach-Object { install_app $_ $architecture $global $suggested $use_cache $check_hash }
}

# remove older cache after update
if (!$keep_cache) {
tidy_cache $app $true
}
}

if (-not ($apps -or $all)) {
Expand Down Expand Up @@ -462,7 +470,7 @@ if (-not ($apps -or $all)) {

$suggested = @{}
# $outdated is a list of ($app, $global) tuples
$outdated | ForEach-Object { update @_ $quiet $independent $suggested $use_cache $check_hash }
$outdated | ForEach-Object { update @_ $quiet $independent $suggested $use_cache $keep_cache $check_hash }
}

exit 0