From b4218791c75c8e0f303cde1687ebeeb2cde307ee Mon Sep 17 00:00:00 2001 From: Hsiao-nan Cheung Date: Tue, 26 Feb 2019 11:21:34 +0800 Subject: [PATCH] decompress.ps1: Refactored (w/ install.ps1, core.ps1) --- lib/core.ps1 | 53 ------------------- lib/decompress.ps1 | 92 +++++++++++++++++++++++++++++++++ lib/install.ps1 | 40 -------------- test/Scoop-Core.Tests.ps1 | 56 -------------------- test/Scoop-Decompress.Tests.ps1 | 62 ++++++++++++++++++++++ 5 files changed, 154 insertions(+), 149 deletions(-) create mode 100644 test/Scoop-Decompress.Tests.ps1 diff --git a/lib/core.ps1 b/lib/core.ps1 index 2aa73a9109..5facc94895 100644 --- a/lib/core.ps1 +++ b/lib/core.ps1 @@ -273,59 +273,6 @@ function isFileLocked([string]$path) { } } -function extract_zip($path, $to) { - if (!(test-path $path)) { abort "can't find $path to unzip"} - try { add-type -assembly "System.IO.Compression.FileSystem" -ea stop } - catch { unzip_old $path $to; return } # for .net earlier than 4.5 - $retries = 0 - while ($retries -le 10) { - if ($retries -eq 10) { - if (7zip_installed) { - extract_7zip $path $to $false - return - } else { - abort "Unzip failed: Windows can't unzip because a process is locking the file.`nRun 'scoop install 7zip' and try again." - } - } - if (isFileLocked $path) { - write-host "Waiting for $path to be unlocked by another process... ($retries/10)" - $retries++ - Start-Sleep -s 2 - } else { - break - } - } - - try { - [io.compression.zipfile]::extracttodirectory($path,$to) - } catch [system.io.pathtoolongexception] { - # try to fall back to 7zip if path is too long - if(7zip_installed) { - extract_7zip $path $to $false - return - } else { - abort "Unzip failed: Windows can't handle the long paths in this zip file.`nRun 'scoop install 7zip' and try again." - } - } catch [system.io.ioexception] { - if (7zip_installed) { - extract_7zip $path $to $false - return - } else { - abort "Unzip failed: Windows can't handle the file names in this zip file.`nRun 'scoop install 7zip' and try again." - } - } catch { - abort "Unzip failed: $_" - } -} - -function unzip_old($path,$to) { - # fallback for .net earlier than 4.5 - $shell = (new-object -com shell.application -strict) - $zipfiles = $shell.namespace("$path").items() - $to = ensure $to - $shell.namespace("$to").copyHere($zipfiles, 4) # 4 = don't show progress dialog -} - function is_directory([String] $path) { return (Test-Path $path) -and (Get-Item $path) -is [System.IO.DirectoryInfo] } diff --git a/lib/decompress.ps1 b/lib/decompress.ps1 index 71144b156b..5411a92a4f 100644 --- a/lib/decompress.ps1 +++ b/lib/decompress.ps1 @@ -29,3 +29,95 @@ function extract_7zip($path, $to, $recurse) { if($recurse) { Remove-Item $path } # clean up intermediate files } + +function unpack_inno($fname, $manifest, $dir) { + if(!$manifest.innosetup) { return } + + write-host "Unpacking innosetup... " -nonewline + innounp -x -d"$dir\_scoop_unpack" "$dir\$fname" > "$dir\innounp.log" + if($lastexitcode -ne 0) { + abort "Failed to unpack innosetup file. See $dir\innounp.log" + } + + Get-ChildItem "$dir\_scoop_unpack\{app}" -r | Move-Item -dest "$dir" -force + + Remove-Item -r -force "$dir\_scoop_unpack" + + Remove-Item "$dir\$fname" + Write-Host "done." -f Green +} + +function extract_msi($path, $to) { + $logfile = "$(split-path $path)\msi.log" + $ok = run 'msiexec' @('/a', "`"$path`"", '/qn', "TARGETDIR=`"$to`"", "/lwe `"$logfile`"") + if(!$ok) { abort "Failed to extract files from $path.`nLog file:`n $(friendly_path $logfile)" } + if(test-path $logfile) { Remove-Item $logfile } +} + +function lessmsi_config ($extract_dir) { + $extract_fn = 'extract_lessmsi' + if ($extract_dir) { + $extract_dir = join-path SourceDir $extract_dir + } else { + $extract_dir = "SourceDir" + } + + $extract_fn, $extract_dir +} + +function extract_lessmsi($path, $to) { + Invoke-Expression "lessmsi x `"$path`" `"$to\`"" +} + +function extract_zip($path, $to) { + if (!(test-path $path)) { abort "can't find $path to unzip"} + try { add-type -assembly "System.IO.Compression.FileSystem" -ea stop } + catch { unzip_old $path $to; return } # for .net earlier than 4.5 + $retries = 0 + while ($retries -le 10) { + if ($retries -eq 10) { + if (7zip_installed) { + extract_7zip $path $to $false + return + } else { + abort "Unzip failed: Windows can't unzip because a process is locking the file.`nRun 'scoop install 7zip' and try again." + } + } + if (isFileLocked $path) { + write-host "Waiting for $path to be unlocked by another process... ($retries/10)" + $retries++ + Start-Sleep -s 2 + } else { + break + } + } + + try { + [io.compression.zipfile]::extracttodirectory($path, $to) + } catch [system.io.pathtoolongexception] { + # try to fall back to 7zip if path is too long + if (7zip_installed) { + extract_7zip $path $to $false + return + } else { + abort "Unzip failed: Windows can't handle the long paths in this zip file.`nRun 'scoop install 7zip' and try again." + } + } catch [system.io.ioexception] { + if (7zip_installed) { + extract_7zip $path $to $false + return + } else { + abort "Unzip failed: Windows can't handle the file names in this zip file.`nRun 'scoop install 7zip' and try again." + } + } catch { + abort "Unzip failed: $_" + } +} + +function unzip_old($path, $to) { + # fallback for .net earlier than 4.5 + $shell = (new-object -com shell.application -strict) + $zipfiles = $shell.namespace("$path").items() + $to = ensure $to + $shell.namespace("$to").copyHere($zipfiles, 4) # 4 = don't show progress dialog +} diff --git a/lib/install.ps1 b/lib/install.ps1 index adc4f6440c..51b930d485 100644 --- a/lib/install.ps1 +++ b/lib/install.ps1 @@ -592,18 +592,6 @@ function dl_urls($app, $version, $manifest, $bucket, $architecture, $dir, $use_c $fname # returns the last downloaded file } -function lessmsi_config ($extract_dir) { - $extract_fn = 'extract_lessmsi' - if ($extract_dir) { - $extract_dir = join-path SourceDir $extract_dir - } - else { - $extract_dir = "SourceDir" - } - - $extract_fn, $extract_dir -} - function cookie_header($cookies) { if(!$cookies) { return } @@ -739,23 +727,6 @@ function run($exe, $arg, $msg, $continue_exit_codes) { return $true } -function unpack_inno($fname, $manifest, $dir) { - if(!$manifest.innosetup) { return } - - write-host "Unpacking innosetup... " -nonewline - innounp -x -d"$dir\_scoop_unpack" "$dir\$fname" > "$dir\innounp.log" - if($lastexitcode -ne 0) { - abort "Failed to unpack innosetup file. See $dir\innounp.log" - } - - Get-ChildItem "$dir\_scoop_unpack\{app}" -r | Move-Item -dest "$dir" -force - - Remove-Item -r -force "$dir\_scoop_unpack" - - Remove-Item "$dir\$fname" - Write-Host "done." -f Green -} - function run_installer($fname, $manifest, $architecture, $dir, $global) { # MSI or other installer $msi = msi $manifest $architecture @@ -800,17 +771,6 @@ function install_msi($fname, $dir, $msi) { Remove-Item $msifile } -function extract_msi($path, $to) { - $logfile = "$(split-path $path)\msi.log" - $ok = run 'msiexec' @('/a', "`"$path`"", '/qn', "TARGETDIR=`"$to`"", "/lwe `"$logfile`"") - if(!$ok) { abort "Failed to extract files from $path.`nLog file:`n $(friendly_path $logfile)" } - if(test-path $logfile) { Remove-Item $logfile } -} - -function extract_lessmsi($path, $to) { - Invoke-Expression "lessmsi x `"$path`" `"$to\`"" -} - # deprecated # get-wmiobject win32_product is slow and checks integrity of each installed program, # so this uses the [wmi] type accelerator instead diff --git a/test/Scoop-Core.Tests.ps1 b/test/Scoop-Core.Tests.ps1 index f68e0ae7ba..01af877cc8 100644 --- a/test/Scoop-Core.Tests.ps1 +++ b/test/Scoop-Core.Tests.ps1 @@ -61,62 +61,6 @@ describe "movedir" -Tag 'Scoop' { } } -describe "unzip_old" -Tag 'Scoop' { - beforeall { - $working_dir = setup_working "unzip_old" - } - - function test-unzip($from) { - $to = strip_ext $from - - if(is_unix) { - unzip_old ($from -replace '\\','/') ($to -replace '\\','/') - } else { - unzip_old ($from -replace '/','\') ($to -replace '/','\') - } - - $to - } - - context "zip file size is zero bytes" { - $zerobyte = "$working_dir\zerobyte.zip" - $zerobyte | should -exist - - it "unzips file with zero bytes without error" -skip:$isUnix { - # some combination of pester, COM (used within unzip_old), and Win10 causes a bugged return value from test-unzip - # `$to = test-unzip $zerobyte` * RETURN_VAL has a leading space and complains of $null usage when used in PoSH functions - $to = ([string](test-unzip $zerobyte)).trimStart() - - $to | should -not -match '^\s' - $to | should -not -benullorempty - - $to | should -exist - - (Get-ChildItem $to).count | should -be 0 - } - } - - context "zip file is small in size" { - $small = "$working_dir\small.zip" - $small | should -exist - - it "unzips file which is small in size" -skip:$isUnix { - # some combination of pester, COM (used within unzip_old), and Win10 causes a bugged return value from test-unzip - # `$to = test-unzip $small` * RETURN_VAL has a leading space and complains of $null usage when used in PoSH functions - $to = ([string](test-unzip $small)).trimStart() - - $to | should -not -match '^\s' - $to | should -not -benullorempty - - $to | should -exist - - # these don't work for some reason on appveyor - #join-path $to "empty" | should -exist - #(gci $to).count | should -be 1 - } - } -} - describe "shim" -Tag 'Scoop' { beforeall { $working_dir = setup_working "shim" diff --git a/test/Scoop-Decompress.Tests.ps1 b/test/Scoop-Decompress.Tests.ps1 new file mode 100644 index 0000000000..566258bd8b --- /dev/null +++ b/test/Scoop-Decompress.Tests.ps1 @@ -0,0 +1,62 @@ +. "$psscriptroot\Scoop-TestLib.ps1" +. "$psscriptroot\..\lib\core.ps1" +. "$psscriptroot\..\lib\decompress.ps1" +. "$psscriptroot\..\lib\unix.ps1" + +$isUnix = is_unix + +describe "unzip_old" -Tag 'Scoop' { + beforeall { + $working_dir = setup_working "unzip_old" + } + + function test-unzip($from) { + $to = strip_ext $from + + if(is_unix) { + unzip_old ($from -replace '\\','/') ($to -replace '\\','/') + } else { + unzip_old ($from -replace '/','\') ($to -replace '/','\') + } + + $to + } + + context "zip file size is zero bytes" { + $zerobyte = "$working_dir\zerobyte.zip" + $zerobyte | should -exist + + it "unzips file with zero bytes without error" -skip:$isUnix { + # some combination of pester, COM (used within unzip_old), and Win10 causes a bugged return value from test-unzip + # `$to = test-unzip $zerobyte` * RETURN_VAL has a leading space and complains of $null usage when used in PoSH functions + $to = ([string](test-unzip $zerobyte)).trimStart() + + $to | should -not -match '^\s' + $to | should -not -benullorempty + + $to | should -exist + + (Get-ChildItem $to).count | should -be 0 + } + } + + context "zip file is small in size" { + $small = "$working_dir\small.zip" + $small | should -exist + + it "unzips file which is small in size" -skip:$isUnix { + # some combination of pester, COM (used within unzip_old), and Win10 causes a bugged return value from test-unzip + # `$to = test-unzip $small` * RETURN_VAL has a leading space and complains of $null usage when used in PoSH functions + $to = ([string](test-unzip $small)).trimStart() + + $to | should -not -match '^\s' + $to | should -not -benullorempty + + $to | should -exist + + # these don't work for some reason on appveyor + #join-path $to "empty" | should -exist + #(gci $to).count | should -be 1 + } + } +}