Skip to content

Commit

Permalink
feat(scoop-alter): Add scoop alter command to switch shim's target (S…
Browse files Browse the repository at this point in the history
  • Loading branch information
niheaven authored Feb 13, 2022
1 parent f24159c commit c41cb84
Show file tree
Hide file tree
Showing 7 changed files with 90 additions and 10 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
### Features

- **config:** Allow Scoop to ignore running processes during reset/uninstall/update ([#4713](https://github.com/ScoopInstaller/Scoop/issues/4713), [#4731](https://github.com/ScoopInstaller/Scoop/issues/4731))
- **scoop-alter:** Add `scoop alter` command to switch shim's target ([#4727](https://github.com/ScoopInstaller/Scoop/issues/4727))
- **scoop-download:** Add `scoop download` command ([#4621](https://github.com/ScoopInstaller/Scoop/issues/4621))
- **scoop-(install|virustotal):** Allow skipping update check ([#4634](https://github.com/ScoopInstaller/Scoop/issues/4634))
- **scoop-bucket:** List more detailed information for buckets ([#4704](https://github.com/ScoopInstaller/Scoop/pull/4704))
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) {

Write-Output "Uninstalling '$app'"
run_uninstaller $manifest $architecture $dir
rm_shims $manifest $global $architecture
rm_shims $app $manifest $global $architecture

# If a junction was used during install, that will have been used
# as the reference directory. Othewise it will just be the version
Expand Down
7 changes: 6 additions & 1 deletion lib/core.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -585,13 +585,18 @@ function get_app_name_from_shim($shim) {
}

function warn_on_overwrite($shim, $path) {
if (!(Test-Path($shim))) {
if (!(Test-Path $shim)) {
return
}
$shim_app = get_app_name_from_shim $shim
$path_app = get_app_name $path
if ($shim_app -eq $path_app) {
return
} else {
if (Test-Path -Path "$shim.$path_app" -PathType Leaf) {
Remove-Item -Path "$shim.$path_app" -Force
}
Rename-Item -Path $shim -NewName "$shim.$shim_app"
}
$shimname = (fname $shim) -replace '\.shim$', '.exe'
$filename = (fname $path) -replace '\.shim$', '.exe'
Expand Down
26 changes: 20 additions & 6 deletions lib/install.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -877,23 +877,37 @@ function create_shims($manifest, $dir, $global, $arch) {
}
}

function rm_shim($name, $shimdir) {
'', '.exe', '.shim', '.cmd', '.ps1' | ForEach-Object {
if(test-path -Path "$shimdir\$name$_" -PathType leaf) {
function rm_shim($name, $shimdir, $app) {
'', '.shim', '.cmd', '.ps1' | ForEach-Object {
$shimPath = "$shimdir\$name$_"
$altShimPath = "$shimPath.$app"
if ($app -and (Test-Path -Path $altShimPath -PathType Leaf)) {
Write-Output "Removing shim '$name$_.$app'."
Remove-Item $altShimPath
} elseif (Test-Path -Path $shimPath -PathType Leaf) {
Write-Output "Removing shim '$name$_'."
Remove-Item "$shimdir\$name$_"
Remove-Item $shimPath
$oldShims = Get-Item -Path "$shimPath.*" -Exclude '*.shim', '*.cmd', '*.ps1'
if ($null -eq $oldShims) {
if ($_ -eq '.shim') {
Write-Output "Removing shim '$name.exe'."
Remove-Item -Path "$shimdir\$name.exe"
}
} else {
(@($oldShims) | Sort-Object -Property LastWriteTimeUtc)[-1] | Rename-Item -NewName { $_.Name -replace '\.[^.]*$', '' }
}
}
}
}

function rm_shims($manifest, $global, $arch) {
function rm_shims($app, $manifest, $global, $arch) {
$shims = @(arch_specific 'bin' $manifest $arch)

$shims | Where-Object { $_ -ne $null } | ForEach-Object {
$target, $name, $null = shim_def $_
$shimdir = shimdir $global

rm_shim $name $shimdir
rm_shim $name $shimdir $app
}
}

Expand Down
60 changes: 60 additions & 0 deletions libexec/scoop-alter.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# Usage: scoop alter <command>
# Summary: Maintain shims determining default commands (similar to '(update-)alternatives' on Linux)
# Help: Display and maintain alternatives of a shimmed command installed with Scoop (similar to '(update-)alternatives' on Linux)

param($command)
. "$PSScriptRoot\..\lib\core.ps1"
. "$PSScriptRoot\..\lib\help.ps1"

reset_aliases

if (!$command) { 'ERROR: <command> missing'; my_usage; exit 1 }

try {
$gcm = (Get-Command "$command" -ErrorAction Stop).Path.ToString()
} catch {
abort "'$command' not found" 3
}

$path = $gcm -replace '\.exe$', '.shim'
$userShimPath = "$(Resolve-Path $(shimdir $false))"
$globalShimPath = fullpath (shimdir $true) # don't resolve: may not exist

if ($path -like "$userShimPath*" -or $path -like "$globalShimPath*") {
$altShims = Get-Item -Path "$path.*" -Exclude '*.shim', '*.cmd', '*.ps1'
if ($null -eq $altShims) {
Write-Host "No alternatives of '$command' found."
exit 0
}
$app = get_app_name_from_shim $path
$apps = @($app) + ($altShims | ForEach-Object { $_.Extension.Remove(0, 1) } | Select-Object -Unique)
[System.Management.Automation.Host.ChoiceDescription[]]$altApps = 1..$apps.Length | ForEach-Object {
New-Object System.Management.Automation.Host.ChoiceDescription "&$($_)`b$($apps[$_ - 1])", "Sets '$command' shim from $($apps[$_ - 1])."
}
$selected = $Host.UI.PromptForChoice("Alternatives of '$command' command", "Please choose one that provides '$command' as default:", $altApps, 0)
if ($selected -eq 0) {
Write-Host "'$command' is already from '$app', nothing changed."
exit 0
} else {
$newApp = $apps[$selected]
Write-Host "Use '$command' from '$newApp' as default..." -NoNewline
$pathNoExt = strip_ext $path
'', '.shim', '.cmd', '.ps1' | ForEach-Object {
$shimPath = "$pathNoExt$_"
$newShimPath = "$shimPath.$newApp"
if (Test-Path -Path $shimPath -PathType Leaf) {
Rename-Item -Path $shimPath -NewName "$shimPath.$app" -Force
if (Test-Path -Path $newShimPath -PathType Leaf) {
Rename-Item -Path $newShimPath -NewName $shimPath -Force
}
}
}
Write-Host 'done.'
}
} else {
Write-Host 'Not a scoop shim.'
Write-Host "Command path is: $gcm"
exit 2
}

exit 0
2 changes: 1 addition & 1 deletion libexec/scoop-uninstall.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ if (!$apps) { exit 0 }
$architecture = $install.architecture

run_uninstaller $manifest $architecture $dir
rm_shims $manifest $global $architecture
rm_shims $app $manifest $global $architecture
rm_startmenu_shortcuts $manifest $global $architecture

# If a junction was used during install, that will have been used
Expand Down
2 changes: 1 addition & 1 deletion libexec/scoop-update.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ function update($app, $global, $quiet = $false, $independent, $suggested, $use_c

Write-Host "Uninstalling '$app' ($old_version)"
run_uninstaller $old_manifest $architecture $dir
rm_shims $old_manifest $global $architecture
rm_shims $app $old_manifest $global $architecture
env_rm_path $old_manifest $dir $global $architecture
env_rm $old_manifest $global $architecture

Expand Down

0 comments on commit c41cb84

Please sign in to comment.