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

Removing persistent data after uninstall app(s) #5711

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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ test/installer/tmp/*
test/tmp/*
*~
TestResults.xml
.vscode
67 changes: 51 additions & 16 deletions lib/core.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,14 @@ function currentdir($app, $global) {
"$(appdir $app $global)\$version"
}

function persistdir($app, $global) { "$(basedir $global)\persist\$app" }
function persistdir($app, $global) {
$persistBaseDir = "$(basedir $global)\persist"
if ($app) {
return Join-Path $persistBaseDir $app
} else {
return $persistBaseDir
}
}
function usermanifestsdir { "$(basedir)\workspace" }
function usermanifest($app) { "$(usermanifestsdir)\$app.json" }
function cache_path($app, $version, $url) { "$cachedir\$app#$version#$($url -replace '[^\w\.\-]+', '_')" }
Expand Down Expand Up @@ -1076,33 +1083,61 @@ function Confirm-InstallationStatus {
)
$Installed = @()
$Apps | Select-Object -Unique | Where-Object { $_ -ne 'scoop' } | ForEach-Object {
$App, $null, $null = parse_app $_
if ($Global) {
if (Test-Path (appdir $App $true)) {
$Installed += , @($App, $true)
} elseif (Test-Path (appdir $App $false)) {
error "'$App' isn't installed globally, but it may be installed locally."
warn "Try again without the --global (or -g) flag instead."
} else {
error "'$App' isn't installed."
}

$Status = Get-AppStatus -App $_ -Global $Global
$App = $Status.App;

if ($Status.Installed -and ($Global -eq $Status.Global)) {
# Add installed
$Installed += , @($App, $Global);
} else {
if (Test-Path (appdir $App $false)) {
$Installed += , @($App, $false)
} elseif (Test-Path (appdir $App $true)) {
error "'$App' isn't installed locally, but it may be installed globally."
warn "Try again with the --global (or -g) flag instead."
if ($Status.Installed) {
if ($Status.Global) {
error "'$App' isn't installed locally, but it may be installed globally."
warn 'Try again with the --global (or -g) flag instead.'
} else {
error "'$App' isn't installed globally, but it may be installed locally."
warn 'Try again without the --global (or -g) flag instead.'
}
} else {
error "'$App' isn't installed."
}
}

if (failed $App $Global) {
error "'$App' isn't installed correctly."
}
}
return , $Installed
}

Function Get-AppStatus {
[OutputType([Object[]])]
param(
[String]$App,
[Switch]$Global
)
$App, $null, $null = parse_app $App
$IsInstalled = Test-Path (appdir $App $Global)

$Status = [PSCustomObject]@{
App = $App
Installed = $IsInstalled
Global = $Global
}

if (!$IsInstalled) {
# Check if installed somewhere else
$Global = !$Global;
$Status.Installed = Test-Path (appdir $App $Global);
if ($Status.Installed) {
$Status.Global = $Global
}
}

return $Status;
}

function strip_path($orig_path, $dir) {
if($null -eq $orig_path) { $orig_path = '' }
$stripped = [string]::join(';', @( $orig_path.split(';') | Where-Object { $_ -and $_ -ne $dir } ))
Expand Down
27 changes: 27 additions & 0 deletions lib/install.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -1203,6 +1203,33 @@ function unlink_persist_data($manifest, $dir) {
}
}

Function Remove-PersistentData {
[CmdletBinding(SupportsShouldProcess = $true)]
param(
[string]$App,
$Global
)

$Status = Get-AppStatus -App $App -Global:$Global
$App = $Status.App;

if (!$Status.Installed) {
# remove persistend data if app not installed
Write-Host 'Removing persisted data.'
$persistDir = persistdir $App $Global

if (Test-Path $persistDir) {
try {
Remove-Item $persistDir -Recurse -Force -ErrorAction Stop
} catch {
error "Couldn't remove '$(friendly_path $persistDir)'; it may be in use."
continue
}
}
}
}


# check whether write permission for Users usergroup is set to global persist dir, if not then set
function persist_permission($manifest, $global) {
if($global -and $manifest.persist -and (is_admin)) {
Expand Down
37 changes: 30 additions & 7 deletions libexec/scoop-cleanup.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,18 @@
# -a, --all Cleanup all apps (alternative to '*')
# -g, --global Cleanup a globally installed app
# -k, --cache Remove outdated download cache
# -p, --purge Remove persistent data

. "$PSScriptRoot\..\lib\getopt.ps1"
. "$PSScriptRoot\..\lib\manifest.ps1" # 'Select-CurrentVersion' (indirectly)
. "$PSScriptRoot\..\lib\versions.ps1" # 'Select-CurrentVersion'
. "$PSScriptRoot\..\lib\install.ps1" # persist related

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

if (!$apps -and !$all) { 'ERROR: <app> missing'; my_usage; exit 1 }
Expand All @@ -27,7 +29,14 @@ if ($global -and !(is_admin)) {
'ERROR: you need admin rights to cleanup global apps'; exit 1
}

function cleanup($app, $global, $verbose, $cache) {
function cleanup {
param(
[String]$app,
$global,
$verbose,
$cache
)

$current_version = Select-CurrentVersion -AppName $app -Global:$global
if ($cache) {
Remove-Item "$cachedir\$app#*" -Exclude "$app#$current_version#*"
Expand Down Expand Up @@ -61,20 +70,34 @@ function cleanup($app, $global, $verbose, $cache) {
Write-Host ''
}

$installedApps = @()
$persistentApps = @()

if ($apps -or $all) {
if ($apps -eq '*' -or $all) {
$verbose = $false
$apps = applist (installed_apps $false) $false
$installedApps = applist (installed_apps $false) $false
$persistentApps = applist (persistent_apps $false) $false
if ($global) {
$apps += applist (installed_apps $true) $true
$installedApps += applist (installed_apps $true) $true
$persistentApps += applist (persistent_apps $true) $true
}
} else {
$verbose = $true
$apps = Confirm-InstallationStatus $apps -Global:$global
$installedApps = Confirm-InstallationStatus $apps -Global:$global
$persistentApps = applist $apps $global
}

# $installedApps is a list of ($app, $global) tuples
foreach ($_ in $installedApps) {
cleanup -app $_[0] -global $_[1] -verbose $verbose -cache $cache -purge $purge
}

# $apps is now a list of ($app, $global) tuples
$apps | ForEach-Object { cleanup @_ $verbose $cache }
if ($purge -and $persistentApps.Count -gt 0) {
foreach ($_ in $persistentApps) {
Remove-PersistentData -App $_[0] -Global $_[1]
}
}

if ($cache) {
Remove-Item "$cachedir\*.download" -ErrorAction Ignore
Expand Down
33 changes: 17 additions & 16 deletions libexec/scoop-uninstall.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,22 @@ if ($apps -eq 'scoop') {
exit
}

$apps = Confirm-InstallationStatus $apps -Global:$global
if (!$apps) { exit 0 }

:app_loop foreach ($_ in $apps) {
$installedApps = Confirm-InstallationStatus $apps -Global:$global
if (!$installedApps) {

if ($purge) {
# make it possible to remove persintent data of already uninstalled apps
:app_loop foreach ($_ in $apps) {
($app, $global) = $_
Remove-PersistentData -App $app -Global:$global
}
}

exit 0
}

:app_loop foreach ($_ in $installedApps) {
($app, $global) = $_

$version = Select-CurrentVersion -AppName $app -Global:$global
Expand All @@ -52,7 +64,6 @@ if (!$apps) { exit 0 }
Write-Host "Uninstalling '$app' ($version)."

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

$manifest = installed_manifest $app $version $global
$install = install_info $app $version $global
Expand Down Expand Up @@ -128,19 +139,9 @@ if (!$apps) { exit 0 }
}
}

# purge persistant data
# purge persistent data
if ($purge) {
Write-Host 'Removing persisted data.'
$persist_dir = persistdir $app $global

if (Test-Path $persist_dir) {
try {
Remove-Item $persist_dir -Recurse -Force -ErrorAction Stop
} catch {
error "Couldn't remove '$(friendly_path $persist_dir)'; it may be in use."
continue
}
}
Remove-PersistentData -App $app -Global $global
}

success "'$app' was uninstalled."
Expand Down