Skip to content

Commit

Permalink
decompress.ps1: Refactored (w/ install.ps1, core.ps1)
Browse files Browse the repository at this point in the history
  • Loading branch information
niheaven committed Feb 25, 2019
1 parent 6c037af commit c86ed93
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 111 deletions.
53 changes: 0 additions & 53 deletions lib/core.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -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]
}
Expand Down
98 changes: 88 additions & 10 deletions lib/decompress.ps1
Original file line number Diff line number Diff line change
@@ -1,31 +1,109 @@
function requires_7zip($manifest, $architecture) {
foreach($dlurl in @(url $manifest $architecture)) {
if(file_requires_7zip $dlurl) { return $true }
foreach ($dlurl in @(url $manifest $architecture)) {
if (file_requires_7zip $dlurl) { return $true }
}
}

function requires_lessmsi ($manifest, $architecture) {
$useLessMsi = get_config MSIEXTRACT_USE_LESSMSI
if (!$useLessMsi) { return $false }

$(url $manifest $architecture | Where-Object {
$_ -match '\.(msi)$'
} | Measure-Object | Select-Object -exp count) -gt 0
$_ -match '\.(msi)$'
} | Measure-Object | Select-Object -exp count) -gt 0
}

function file_requires_7zip($fname) {
$fname -match '\.((gz)|(tar)|(tgz)|(lzma)|(bz)|(bz2)|(7z)|(rar)|(iso)|(xz)|(lzh)|(nupkg))$'
}

function extract_7zip($path, $to, $recurse) {
$output = 7z x "$path" -o"$to" -y
if($lastexitcode -ne 0) { abort "Exit code was $lastexitcode." }
$output = &(file_path 7zip 7z.exe) x "$path" -o"$to" -y
if ($lastexitcode -ne 0) { abort "Exit code was $lastexitcode." }

# check for tar
$tar = (split-path $path -leaf) -replace '\.[^\.]*$', ''
if($tar -match '\.tar$') {
if(test-path "$to\$tar") { extract_7zip "$to\$tar" $to $true }
if ($tar -match '\.tar$') {
if (test-path "$to\$tar") { extract_7zip "$to\$tar" $to $true }
}

if($recurse) { Remove-Item $path } # clean up intermediate files
if ($recurse) { Remove-Item $path -Force } # clean up intermediate files
}

function extract_msi($path, $to, $recurse) {
$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 }
if ($recurse) { Remove-Item $path -Force }
}

function extract_lessmsi($path, $to, $recurse) {
&(file_path lessmsi lessmsi.exe) x "$path" "$to\"
Move-Item "$to\SourceDir\*" "$to" -Force
Remove-Item "$to\SourceDir" -Force
if ($recurse) { Remove-Item $path -Force }
}

function extract_inno($path, $to, $recurse) {
$logfile = "$(split-path $path)\innounp.log"
&(file_path innounp innounp.exe) -x -d"$to" -c"{app}" "$path" > "$logfile"
if ($lastexitcode -ne 0) {
abort "Failed to extract files from $path.`nLog file:`n $(friendly_path $logfile)"
}
if (test-path $logfile) { Remove-Item $logfile }
if ($recurse) { Remove-Item $path -Force }
}

function extract_zip($path, $to, $recurse) {
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: $_"
}
if ($recurse) { Remove-Item $path -Force }
}

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
}
4 changes: 1 addition & 3 deletions lib/depends.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,7 @@ function runtime_deps($manifest) {
function install_deps($manifest, $arch) {
$deps = @()

if((requires_7zip $manifest $arch) -and !(7zip_installed)) {
$deps += '7zip'
}
if(requires_7zip $manifest $arch) { $deps += '7zip' }
if(requires_lessmsi $manifest $arch) { $deps += 'lessmsi' }
if($manifest.innosetup) { $deps += 'innounp' }

Expand Down
50 changes: 5 additions & 45 deletions lib/install.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ function install_app($app, $architecture, $global, $suggested, $use_cache = $tru
$persist_dir = persistdir $app $global

$fname = dl_urls $app $version $manifest $bucket $architecture $dir $use_cache $check_hash
unpack_inno $fname $manifest $dir
pre_install $manifest $architecture
run_installer $fname $manifest $architecture $dir $global
ensure_install_dir_not_in_path $dir $global
Expand Down Expand Up @@ -529,15 +528,17 @@ function dl_urls($app, $version, $manifest, $bucket, $architecture, $dir, $use_c

# work out extraction method, if applicable
$extract_fn = $null
if($fname -match '\.zip$') {
if ($manifest.innosetup) {
$extract_fn = 'extract_inno'
} elseif($fname -match '\.zip$') {
$extract_fn = 'extract_zip'
} elseif($fname -match '\.msi$') {
# check manifest doesn't use deprecated install method
$msi = msi $manifest $architecture
if(!$msi) {
$useLessMsi = get_config MSIEXTRACT_USE_LESSMSI
if ($useLessMsi -eq $true) {
$extract_fn, $extract_dir = lessmsi_config $extract_dir
$extract_fn = 'extract_lessmsi'
}
else {
$extract_fn = 'extract_msi'
Expand All @@ -558,8 +559,7 @@ function dl_urls($app, $version, $manifest, $bucket, $architecture, $dir, $use_c
Write-Host $fname -f Cyan -NoNewline
Write-Host " ... " -NoNewline
$null = mkdir "$dir\_tmp"
& $extract_fn "$dir\$fname" "$dir\_tmp"
Remove-Item "$dir\$fname"
& $extract_fn "$dir\$fname" "$dir\_tmp" $true
if ($extract_to) {
$null = mkdir "$dir\$extract_to" -force
}
Expand Down Expand Up @@ -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 }

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit c86ed93

Please sign in to comment.