Skip to content

Commit 2544745

Browse files
authored
refactor(install): Replace 'run_(un)installer()' with 'Invoke-Installer()' (#5968)
1 parent 5ce70c4 commit 2544745

7 files changed

Lines changed: 78 additions & 89 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
### Code Refactoring
2020

2121
- **install:** Separate archive extraction from downloader ([#5951](https://github.com/ScoopInstaller/Scoop/issues/5951))
22+
- **install:** Replace 'run_(un)installer()' with 'Invoke-Installer()' ([#5968](https://github.com/ScoopInstaller/Scoop/issues/5968))
2223

2324
## [v0.4.1](https://github.com/ScoopInstaller/Scoop/compare/v0.4.0...v0.4.1) - 2024-04-25
2425

bin/uninstall.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ function do_uninstall($app, $global) {
4242
$architecture = $install.architecture
4343

4444
Write-Output "Uninstalling '$app'"
45-
run_uninstaller $manifest $architecture $dir
45+
Invoke-Installer -Path $dir -Manifest $manifest -ProcessorArchitecture $architecture -Uninstall
4646
rm_shims $app $manifest $global $architecture
4747

4848
# If a junction was used during install, that will have been used

lib/core.ps1

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -324,10 +324,6 @@ function Invoke-GitLog {
324324
# helper functions
325325
function coalesce($a, $b) { if($a) { return $a } $b }
326326

327-
function format($str, $hash) {
328-
$hash.keys | ForEach-Object { set-variable $_ $hash[$_] }
329-
$executionContext.invokeCommand.expandString($str)
330-
}
331327
function is_admin {
332328
$admin = [security.principal.windowsbuiltinrole]::administrator
333329
$id = [security.principal.windowsidentity]::getcurrent()

lib/install.ps1

Lines changed: 73 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,9 @@ function install_app($app, $architecture, $global, $suggested, $use_cache = $tru
5151

5252
$fname = Invoke-ScoopDownload $app $version $manifest $bucket $architecture $dir $use_cache $check_hash
5353
Invoke-Extraction -Path $dir -Name $fname -Manifest $manifest -ProcessorArchitecture $architecture
54-
Invoke-HookScript -HookType 'pre_install' -Manifest $manifest -Arch $architecture
54+
Invoke-HookScript -HookType 'pre_install' -Manifest $manifest -ProcessorArchitecture $architecture
5555

56-
run_installer @($fname)[-1] $manifest $architecture $dir $global
56+
Invoke-Installer -Path $dir -Manifest $manifest -ProcessorArchitecture $architecture -AppName $app -Global:$global
5757
ensure_install_dir_not_in_path $dir $global
5858
$dir = link_current $dir
5959
create_shims $manifest $dir $global $architecture
@@ -66,7 +66,7 @@ function install_app($app, $architecture, $global, $suggested, $use_cache = $tru
6666
persist_data $manifest $original_dir $persist_dir
6767
persist_permission $manifest $global
6868

69-
Invoke-HookScript -HookType 'post_install' -Manifest $manifest -Arch $architecture
69+
Invoke-HookScript -HookType 'post_install' -Manifest $manifest -ProcessorArchitecture $architecture
7070

7171
# save info for uninstall
7272
save_installed_manifest $app $bucket $dir $url
@@ -540,7 +540,7 @@ function Invoke-ScoopDownload ($app, $version, $manifest, $bucket, $architecture
540540
# we only want to show this warning once
541541
if (!$use_cache) { warn 'Cache is being ignored.' }
542542

543-
# can be multiple urls: if there are, then installer should go last to make 'installer.args' section work
543+
# can be multiple urls: if there are, then installer should go first to make 'installer.args' section work
544544
$urls = @(script:url $manifest $architecture)
545545

546546
# can be multiple cookies: they will be used for all HTTP requests.
@@ -651,70 +651,84 @@ function check_hash($file, $hash, $app_name) {
651651
return $true, $null
652652
}
653653

654-
# for dealing with installers
655-
function args($config, $dir, $global) {
656-
if ($config) { return $config | ForEach-Object { (format $_ @{'dir' = $dir; 'global' = $global }) } }
657-
@()
658-
}
659-
660-
function run_installer($fname, $manifest, $architecture, $dir, $global) {
661-
$installer = installer $manifest $architecture
662-
if ($installer.script) {
663-
Write-Output 'Running installer script...'
664-
Invoke-Command ([scriptblock]::Create($installer.script -join "`r`n"))
665-
return
666-
}
667-
if ($installer) {
668-
$prog = "$dir\$(coalesce $installer.file $fname)"
669-
if (!(is_in_dir $dir $prog)) {
670-
abort "Error in manifest: Installer $prog is outside the app directory."
654+
function Invoke-Installer {
655+
[CmdletBinding()]
656+
param (
657+
[string]
658+
$Path,
659+
[psobject]
660+
$Manifest,
661+
[Alias('Arch', 'Architecture')]
662+
[ValidateSet('32bit', '64bit', 'arm64')]
663+
[string]
664+
$ProcessorArchitecture,
665+
[string]
666+
$AppName,
667+
[switch]
668+
$Global,
669+
[switch]
670+
$Uninstall
671+
)
672+
$type = if ($Uninstall) { 'uninstaller' } else { 'installer' }
673+
$installer = arch_specific $type $Manifest $ProcessorArchitecture
674+
if ($installer.file -or $installer.args) {
675+
# Installer filename is either explicit defined ('installer.file') or file name in the first URL
676+
$progName = "$Path\$(coalesce $installer.file (url_filename @(url $manifest $architecture)[0]))"
677+
if (!(is_in_dir $Path $progName)) {
678+
abort "Error in manifest: $((Get-Culture).TextInfo.ToTitleCase($type)) $progName is outside the app directory."
679+
} elseif (!(Test-Path $progName)) {
680+
abort "$((Get-Culture).TextInfo.ToTitleCase($type)) $progName is missing."
671681
}
672-
$arg = @(args $installer.args $dir $global)
673-
if ($prog.endswith('.ps1')) {
674-
& $prog @arg
682+
$substitutions = @{
683+
'$dir' = $Path
684+
'$global' = $Global
685+
'$version' = $Manifest.version
686+
}
687+
$fnArgs = substitute $installer.args $substitutions
688+
if ($progName.EndsWith('.ps1')) {
689+
& $progName @fnArgs
675690
} else {
676-
$installed = Invoke-ExternalCommand $prog $arg -Activity 'Running installer...'
677-
if (!$installed) {
678-
abort "Installation aborted. You might need to run 'scoop uninstall $app' before trying again."
691+
$status = Invoke-ExternalCommand $progName -ArgumentList $fnArgs -Activity "Running $type ..."
692+
if (!$status) {
693+
if ($Uninstall) {
694+
abort 'Uninstallation aborted.'
695+
} else {
696+
abort "Installation aborted. You might need to run 'scoop uninstall $AppName' before trying again."
697+
}
679698
}
680699
# Don't remove installer if "keep" flag is set to true
681-
if (!($installer.keep -eq 'true')) {
682-
Remove-Item $prog
700+
if (!$installer.keep) {
701+
Remove-Item $progName
683702
}
684703
}
685704
}
705+
Invoke-HookScript -HookType $type -Manifest $Manifest -ProcessorArchitecture $ProcessorArchitecture
686706
}
687707

688-
function run_uninstaller($manifest, $architecture, $dir) {
689-
$uninstaller = uninstaller $manifest $architecture
690-
$version = $manifest.version
691-
if ($uninstaller.script) {
692-
Write-Output 'Running uninstaller script...'
693-
Invoke-Command ([scriptblock]::Create($uninstaller.script -join "`r`n"))
694-
return
695-
}
696-
697-
if ($uninstaller.file) {
698-
$prog = "$dir\$($uninstaller.file)"
699-
$arg = args $uninstaller.args
700-
if (!(is_in_dir $dir $prog)) {
701-
warn "Error in manifest: Installer $prog is outside the app directory, skipping."
702-
$prog = $null
703-
} elseif (!(Test-Path $prog)) {
704-
warn "Uninstaller $prog is missing, skipping."
705-
$prog = $null
706-
}
708+
function Invoke-HookScript {
709+
[CmdletBinding()]
710+
param(
711+
[Parameter(Mandatory = $true)]
712+
[ValidateSet('installer', 'pre_install', 'post_install', 'uninstaller', 'pre_uninstall', 'post_uninstall')]
713+
[String] $HookType,
714+
[Parameter(Mandatory = $true)]
715+
[ValidateNotNullOrEmpty()]
716+
[PSCustomObject] $Manifest,
717+
[Parameter(Mandatory = $true)]
718+
[Alias('Arch', 'Architecture')]
719+
[ValidateSet('32bit', '64bit', 'arm64')]
720+
[string]
721+
$ProcessorArchitecture
722+
)
707723

708-
if ($prog) {
709-
if ($prog.endswith('.ps1')) {
710-
& $prog @arg
711-
} else {
712-
$uninstalled = Invoke-ExternalCommand $prog $arg -Activity 'Running uninstaller...'
713-
if (!$uninstalled) {
714-
abort 'Uninstallation aborted.'
715-
}
716-
}
717-
}
724+
$script = arch_specific $HookType $Manifest $ProcessorArchitecture
725+
if ($HookType -in @('installer', 'uninstaller')) {
726+
$script = $script.script
727+
}
728+
if ($script) {
729+
Write-Host "Running $HookType script..." -NoNewline
730+
Invoke-Command ([scriptblock]::Create($script -join "`r`n"))
731+
Write-Host 'done.' -ForegroundColor Green
718732
}
719733
}
720734

@@ -884,7 +898,7 @@ function env_set($manifest, $dir, $global, $arch) {
884898
if ($env_set) {
885899
$env_set | Get-Member -Member NoteProperty | ForEach-Object {
886900
$name = $_.name
887-
$val = format $env_set.$($_.name) @{ 'dir' = $dir }
901+
$val = substitute $env_set.$($_.name) @{ '$dir' = $dir }
888902
Set-EnvVar -Name $name -Value $val -Global:$global
889903
Set-Content env:\$name $val
890904
}
@@ -901,28 +915,6 @@ function env_rm($manifest, $global, $arch) {
901915
}
902916
}
903917

904-
function Invoke-HookScript {
905-
[CmdletBinding()]
906-
param(
907-
[Parameter(Mandatory = $true)]
908-
[ValidateSet('pre_install', 'post_install',
909-
'pre_uninstall', 'post_uninstall')]
910-
[String] $HookType,
911-
[Parameter(Mandatory = $true)]
912-
[ValidateNotNullOrEmpty()]
913-
[PSCustomObject] $Manifest,
914-
[Parameter(Mandatory = $true)]
915-
[ValidateSet('32bit', '64bit', 'arm64')]
916-
[String] $Arch
917-
)
918-
919-
$script = arch_specific $HookType $Manifest $Arch
920-
if ($script) {
921-
Write-Output "Running $HookType script..."
922-
Invoke-Command ([scriptblock]::Create($script -join "`r`n"))
923-
}
924-
}
925-
926918
function show_notes($manifest, $dir, $original_dir, $persist_dir) {
927919
if ($manifest.notes) {
928920
Write-Output 'Notes'

libexec/scoop-info.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ $env_set = arch_specific 'env_set' $manifest $install.architecture
210210
if ($env_set) {
211211
$env_vars = @()
212212
$env_set | Get-Member -member noteproperty | ForEach-Object {
213-
$env_vars += "$($_.name) = $(format $env_set.$($_.name) @{ "dir" = $dir })"
213+
$env_vars += "$($_.name) = $(substitute $env_set.$($_.name) @{ '$dir' = $dir })"
214214
}
215215
$item.Environment = $env_vars -join "`n"
216216
}

libexec/scoop-uninstall.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ if (!$apps) { exit 0 }
7474
continue
7575
}
7676

77-
run_uninstaller $manifest $architecture $dir
77+
Invoke-Installer -Path $dir -Manifest $manifest -ProcessorArchitecture $architecture -Uninstall
7878
rm_shims $app $manifest $global $architecture
7979
rm_startmenu_shortcuts $manifest $global $architecture
8080

libexec/scoop-update.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@ function update($app, $global, $quiet = $false, $independent, $suggested, $use_c
340340
Invoke-HookScript -HookType 'pre_uninstall' -Manifest $old_manifest -Arch $architecture
341341

342342
Write-Host "Uninstalling '$app' ($old_version)"
343-
run_uninstaller $old_manifest $architecture $dir
343+
Invoke-Installer -Path $dir -Manifest $old_manifest -ProcessorArchitecture $architecture -Uninstall
344344
rm_shims $app $old_manifest $global $architecture
345345

346346
# If a junction was used during install, that will have been used

0 commit comments

Comments
 (0)