Skip to content

Commit

Permalink
refactor(install): Separate archive extraction from downloader
Browse files Browse the repository at this point in the history
  • Loading branch information
niheaven committed May 9, 2024
1 parent 776135e commit 80cf9a0
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 50 deletions.
68 changes: 68 additions & 0 deletions lib/decompress.ps1
Original file line number Diff line number Diff line change
@@ -1,3 +1,71 @@
# Description: Functions for decompressing archives or installers

function Invoke-Extraction {
param (
[string]
$Path,
[string[]]
$Name,
[psobject]
$Manifest,
[Alias('Arch', 'Architecture')]
[string]
$ProcessorArchitecture
)

# 'url', 'extract_dir' and 'extract_to' are paired
$uri = @(url $Manifest $ProcessorArchitecture)
$extractDir = @(extract_dir $Manifest $ProcessorArchitecture)
$extractTo = @(extract_to $Manifest $ProcessorArchitecture)

for ($i = 0; $i -lt $Name.Length; $i++) {
$fnArgs = @{
Path = Join-Path $Path $Name[$i]
DestinationPath = Join-Path $Path $extractTo[$i]
ExtractDir = $extractDir[$i]
}
# work out extraction method, if applicable
$extractFn = $null
switch -regex ($fnArgs.Path) {
'\.zip$' {
if ((Test-HelperInstalled -Helper 7zip) -or ((get_config 7ZIPEXTRACT_USE_EXTERNAL) -and (Test-CommandAvailable 7z))) {
$extractFn = 'Expand-7zipArchive'
} else {
$extractFn = 'Expand-ZipArchive'
}
continue
}
'\.msi$' {
$extractFn = 'Expand-MsiArchive'
continue
}
'\.exe$' {
if ($Manifest.innosetup) {
$extractFn = 'Expand-InnoArchive'
}
continue
}
{ Test-ZstdRequirement -Uri $_ } {
# Check Zstd first
$extractFn = 'Expand-ZstdArchive'
continue
}
{ Test-7zipRequirement -Uri $_ } {
# Then check 7zip
$extractFn = 'Expand-7zipArchive'
continue
}
}
if ($extractFn) {
Write-Host 'Extracting ' -NoNewline
Write-Host $(url_remote_filename $uri[$i]) -ForegroundColor Cyan -NoNewline
Write-Host ' ... ' -NoNewline
& $extractFn @fnArgs -Removal
Write-Host 'done.' -ForegroundColor Green
}
}
}

function Expand-7zipArchive {
[CmdletBinding()]
param (
Expand Down
55 changes: 5 additions & 50 deletions lib/install.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,10 @@ function install_app($app, $architecture, $global, $suggested, $use_cache = $tru
$persist_dir = persistdir $app $global

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

run_installer $fname $manifest $architecture $dir $global
run_installer $fname[-1] $manifest $architecture $dir $global
ensure_install_dir_not_in_path $dir $global
$dir = link_current $dir
create_shims $manifest $dir $global $architecture
Expand Down Expand Up @@ -539,21 +540,12 @@ function Invoke-ScoopDownload ($app, $version, $manifest, $bucket, $architecture
# we only want to show this warning once
if (!$use_cache) { warn 'Cache is being ignored.' }

# can be multiple urls: if there are, then installer should go last,
# so that $fname is set properly
# can be multiple urls: if there are, then installer should go last to make 'installer.args' section work
$urls = @(script:url $manifest $architecture)

# can be multiple cookies: they will be used for all HTTP requests.
$cookies = $manifest.cookie

$fname = $null

# extract_dir and extract_to in manifest are like queues: for each url that
# needs to be extracted, will get the next dir from the queue
$extract_dirs = @(extract_dir $manifest $architecture)
$extract_tos = @(extract_to $manifest $architecture)
$extracted = 0

# download first
if (Test-Aria2Enabled) {
Invoke-CachedAria2Download $app $version $manifest $architecture $dir $cookies $use_cache $check_hash
Expand Down Expand Up @@ -587,44 +579,7 @@ function Invoke-ScoopDownload ($app, $version, $manifest, $bucket, $architecture
}
}

foreach ($url in $urls) {
$fname = url_filename $url

$extract_dir = $extract_dirs[$extracted]
$extract_to = $extract_tos[$extracted]

# work out extraction method, if applicable
$extract_fn = $null
if ($manifest.innosetup) {
$extract_fn = 'Expand-InnoArchive'
} elseif ($fname -match '\.zip$') {
# Use 7zip when available (more fast)
if (((get_config USE_EXTERNAL_7ZIP) -and (Test-CommandAvailable 7z)) -or (Test-HelperInstalled -Helper 7zip)) {
$extract_fn = 'Expand-7zipArchive'
} else {
$extract_fn = 'Expand-ZipArchive'
}
} elseif ($fname -match '\.msi$') {
$extract_fn = 'Expand-MsiArchive'
} elseif (Test-ZstdRequirement -Uri $fname) {
# Zstd first
$extract_fn = 'Expand-ZstdArchive'
} elseif (Test-7zipRequirement -Uri $fname) {
# 7zip
$extract_fn = 'Expand-7zipArchive'
}

if ($extract_fn) {
Write-Host 'Extracting ' -NoNewline
Write-Host $fname -f Cyan -NoNewline
Write-Host ' ... ' -NoNewline
& $extract_fn -Path "$dir\$fname" -DestinationPath "$dir\$extract_to" -ExtractDir $extract_dir -Removal
Write-Host 'done.' -f Green
$extracted++
}
}

$fname # returns the last downloaded file
return $urls.ForEach({ url_filename $_ })
}

function cookie_header($cookies) {
Expand Down Expand Up @@ -710,7 +665,7 @@ function run_installer($fname, $manifest, $architecture, $dir, $global) {
return
}
if ($installer) {
$prog = "$dir\$(coalesce $installer.file "$fname")"
$prog = "$dir\$(coalesce $installer.file $fname)"
if (!(is_in_dir $dir $prog)) {
abort "Error in manifest: Installer $prog is outside the app directory."
}
Expand Down

0 comments on commit 80cf9a0

Please sign in to comment.