Browse Source

scriptapps update

master
Julian Noble 4 months ago
parent
commit
929782e083
  1. 334
      bin/getzig.cmd
  2. 0
      src/scriptapps/bin/getzig.bash
  3. 181
      src/scriptapps/bin/getzig.ps1
  4. 0
      src/scriptapps/bin/getzig_original.polyglot
  5. 0
      src/scriptapps/bin/getzig_wrap.toml
  6. 2
      src/scriptapps/getpunk.ps1

334
bin/getzig.cmd

@ -806,7 +806,13 @@ do if not defined param1 set %%~"param1=%2%%~"
rename set ""; rename S set; set k {-- "$@" "a}; if {[info exists ::env($k)]} {unset ::env($k)} ;# tidyup and restore rename set ""; rename S set; set k {-- "$@" "a}; if {[info exists ::env($k)]} {unset ::env($k)} ;# tidyup and restore
Hide :exit_multishell;Hide {<#};Hide '@ Hide :exit_multishell;Hide {<#};Hide '@
#--------------------------------------------------------------------- #---------------------------------------------------------------------
puts "info script : [info script]"
#puts "argcount : $::argc"
#puts "argvalues: $::argv"
#puts "argv0 : $::argv0"
# -- --- --- --- --- --- --- --- --- --- --- ---
#divert to configured nextshell #divert to configured nextshell
set script_as_called [info script]
package require platform package require platform
set plat_full [platform::generic] set plat_full [platform::generic]
set plat [lindex [split $plat_full -] 0] set plat [lindex [split $plat_full -] 0]
@ -819,6 +825,14 @@ set in_data 0
set nextshellpath "" set nextshellpath ""
set nextshelltype "" set nextshelltype ""
puts stderr "PLAT: $plat" puts stderr "PLAT: $plat"
switch -glob -- $plat {
"msys" - "mingw*" {
set os "win32"
}
default {
set os $plat
}
}
foreach ln [split $scriptdata \n] { foreach ln [split $scriptdata \n] {
if {[string trim $ln] eq ""} {continue} if {[string trim $ln] eq ""} {continue}
if {!$in_data} { if {!$in_data} {
@ -826,14 +840,14 @@ foreach ln [split $scriptdata \n] {
set in_data 1 set in_data 1
} }
} else { } else {
if {[string match "*@SET*nextshellpath?${plat}_*" $ln]} { if {[string match "*@SET*nextshellpath?${os}_*" $ln]} {
set lineparts [split $ln =] set lineparts [split $ln =]
set tail [lindex $lineparts 1] set tail [lindex $lineparts 1]
set nextshellpath [string trimright $tail {_"}] set nextshellpath [string trimright $tail {_"}]
if {$nextshellpath ne "" && $nextshelltype ne ""} { if {$nextshellpath ne "" && $nextshelltype ne ""} {
break break
} }
} elseif {[string match "*@SET*nextshelltype?${plat}_*" $ln]} { } elseif {[string match "*@SET*nextshelltype?${os}_*" $ln]} {
set lineparts [split $ln =] set lineparts [split $ln =]
set tail [lindex $lineparts 1] set tail [lindex $lineparts 1]
set nextshelltype [string trimright $tail {_"}] set nextshelltype [string trimright $tail {_"}]
@ -846,7 +860,6 @@ foreach ln [split $scriptdata \n] {
} }
} }
if {$nextshelltype ne "tcl" && $nextshelltype ne "none"} { if {$nextshelltype ne "tcl" && $nextshelltype ne "none"} {
set script_as_called [info script]
set script_rootname [file rootname $script_as_called] set script_rootname [file rootname $script_as_called]
if {$nextshelltype in "pwsh powershell"} { if {$nextshelltype in "pwsh powershell"} {
# experimental # experimental
@ -907,20 +920,52 @@ if {$nextshelltype ne "tcl" && $nextshelltype ne "none"} {
set scrname $script_as_called set scrname $script_as_called
set arglist $::argv set arglist $::argv
} }
puts stdout "tclsh launching subshell of type: $nextshelltype shellpath: $nextshellpath on script $scrname with args: $arglist"
#todo - handle /usr/bin/env #todo - handle /usr/bin/env
#todo - exitcode #todo - exitcode
if {[llength $nextshellpath] == 1 && [string index $nextshellpath 0] eq {"} && [string index $nextshellpath end] eq {"}} { #review - test spaced quoted words in nextshellpath?
set nextshell_words [list $nextshellpath] #
#if {[llength $nextshellpath] == 1 && [string index $nextshellpath 0] eq {"} && [string index $nextshellpath end] eq {"}} {
# set nextshell_words [list $nextshellpath]
#} else {
# set nextshell_words $nextshellpath
#}
#perform any msys argument munging on a cmd/cmd.exe based nextshellpath before we convert the first word to an auto_exec path
switch -glob -- $plat {
"msys" - "mingw*" {
set cmdword [lindex $nextshellpath 0]
#we only act on cmd or cmd.exe - not a full path such as c:/WINDOWS/system32/cmd.exe
#the nextshellpath should generally be configured as cmd /c ... or cmd.exe ... but specifying it as a path could allow bypassing this un-munging.
#The un-munging only applies to msys/mingw, so such bypassing should be unnecessary - review
#maint: keep this munging in sync with zsh/bash and perl blocks which must also do msys mangling
if {[regexp {^cmd$|^cmd[.]exe$} $cmdword]} {
#need to deal with msys argument munging
puts stderr "cmd call via msys detected. performing translation of /c to //C"
#for now we only deal with /C or /c - todo - other cmd.exe flags?
#In this context we would usually only be using cmd.exe /c to launch older 'desktop' powershell to avoid spaced-argument problems - so we aren't expecting other flags
set new_nextshellpath [list $cmdword]
#for now - just do what zsh munging does - bash regex/string/array processing is tedious and footgunny for the unfamiliar (me),
#so determine the minimum viable case for code there, then port behaviour to perl/tcl msys munging sections.
foreach w [lrange $nextshellpath 1 end] {
if {[regexp {^/[Cc]$} $w]} {
lappend new_nextshellpath {//C}
} else { } else {
set nextshell_words $nextshellpath lappend new_nextshellpath $w
}
}
set nextshellpath $new_nextshellpath
}
} }
set ns_firstword [lindex $nextshellpath 0]
if {[string index $ns_firstword 0] eq {"} && [string index $ns_firstword end] eq {"}} {
set ns_firstword [string range $ns_firstword 1 end-1]
} }
if {[string match {/*/env} $ns_firstword] && $::tcl_platform(platform) ne "windows"} { set ns_firstword [lindex $nextshellpath 0]
#review - is this test for extra layer of double quoting on first word really necessary?
#if we are treaing $nextshellpath as a tcl list - the first layer of double quotes will already have disappeared
##if {[string index $ns_firstword 0] eq {"} && [string index $ns_firstword end] eq {"}} {
## set ns_firstword [string range $ns_firstword 1 end-1]
##}
if {$::tcl_platform(platform) ne "windows" && [string match {/*/env} $ns_firstword]} {
set exec_part $nextshellpath set exec_part $nextshellpath
} else { } else {
set epath [auto_execok $ns_firstword] set epath [auto_execok $ns_firstword]
@ -930,6 +975,10 @@ if {$nextshelltype ne "tcl" && $nextshelltype ne "none"} {
set exec_part [list {*}$epath {*}[lrange $nextshellpath 1 end]] set exec_part [list {*}$epath {*}[lrange $nextshellpath 1 end]]
} }
} }
puts stdout "tclsh launching subshell of type: $nextshelltype shellpath: $nextshellpath on script $scrname with args: $arglist"
puts stdout "exec: $exec_part $scrname $arglist"
catch {exec {*}$exec_part $scrname {*}$arglist <@stdin >@stdout 2>@stderr} emsg eopts catch {exec {*}$exec_part $scrname {*}$arglist <@stdin >@stdout 2>@stderr} emsg eopts
if {[dict exists $eopts -errorcode]} { if {[dict exists $eopts -errorcode]} {
@ -973,11 +1022,6 @@ namespace eval ::punk::multishell {
} }
} }
# -- --- --- --- --- --- --- --- --- --- --- --- --- ---begin Tcl Payload # -- --- --- --- --- --- --- --- --- --- --- --- --- ---begin Tcl Payload
#puts "script : [info script]"
#puts "argcount : $::argc"
#puts "argvalues: $::argv"
#puts "argv0 : $::argv0"
# -- --- --- --- --- --- --- --- --- --- --- ---
#<tcl-payload> #<tcl-payload>
puts stderr "No tcl code for this script. Try another program such as zsh or bash or perl" puts stderr "No tcl code for this script. Try another program such as zsh or bash or perl"
@ -1006,7 +1050,7 @@ echo "var0: $0 @: $@"
# use oldschool backticks and sed (posix - lowest common denominator) \ # use oldschool backticks and sed (posix - lowest common denominator) \
# ps_shellname=`ps -p $$ | awk '$1 != "PID" {print $(NF)}' | tr -d '()' | sed -E 's/^.*\/|^-//'` \ # ps_shellname=`ps -p $$ | awk '$1 != "PID" {print $(NF)}' | tr -d '()' | sed -E 's/^.*\/|^-//'` \
# some ps impls will return arguments - so last field not always appropriate \ # some ps impls will return arguments - so last field not always appropriate \
# some ps impls don't have -o (e.g gnu cygwin) so ps_shellname may remain empty and emit an error \ # some ps impls don't have -o (e.g cygwin) so ps_shellname may remain empty and emit an error \
ps_shellname=`ps -o pid,comm -p $$ | awk '$1 != "PID" {print $2}'` ps_shellname=`ps -o pid,comm -p $$ | awk '$1 != "PID" {print $2}'`
# \ # \
echo "shell from ps: $ps_shellname" echo "shell from ps: $ps_shellname"
@ -1061,17 +1105,14 @@ if false==false # else {
then then
: # : #
# zsh/bash \ # zsh/bash \
shift && set -- "${@:1:$((${#@}-1))}" shift && set -- "${@:1:$((${#@}-1))}"
# ## ### ### ### ### ### ### ### ### ### ### ### ### ### # ## ### ### ### ### ### ### ### ### ### ### ### ### ###
# -- sh/bash script section # -- zsh/bash script section
# -- leave as is if all that is required is launching the Tcl payload"
# --
# -- Note that sh/bash script isn't called when running a .bat/.cmd from cmd.exe on windows by default
# -- adjust the %nextshell% value above
# -- if sh/bash scripting needs to run on windows too.
# -- # --
# -- review - for zsh do we want to use: setopt KSH_ARRAYS ?
# -- arrays in bash 0-based vs 1-based in zsh
# -- stick to the @:i:len syntax which is same for both
# ## ### ### ### ### ### ### ### ### ### ### ### ### ### # ## ### ### ### ### ### ### ### ### ### ### ### ### ###
plat=$(uname -s) #platform/system plat=$(uname -s) #platform/system
@ -1094,7 +1135,6 @@ elif [[ "$plat" == "MINGW64"* ]]; then
elif [[ "$plat" == "CYGWIN_NT"* ]]; then elif [[ "$plat" == "CYGWIN_NT"* ]]; then
os="win32" os="win32"
elif [[ "$plat" == "MSYS_NT"* ]]; then elif [[ "$plat" == "MSYS_NT"* ]]; then
echo MSYS
#review.. #review..
#Need to consider the difference between when msys2 was launched (which strips some paths and sets up the environment) #Need to consider the difference between when msys2 was launched (which strips some paths and sets up the environment)
@ -1141,6 +1181,8 @@ elif [[ "$ps_shellname" == "zsh" ]]; then
else else
#fallback - doesn't seem to work in zsh - untested in early bash #fallback - doesn't seem to work in zsh - untested in early bash
IFS=$'\n' arr_oslines=($shellconfiglines) IFS=$'\n' arr_oslines=($shellconfiglines)
IFS=$' \t\n'
# review
fi fi
nextshellpath="" nextshellpath=""
nextshelltype="" nextshelltype=""
@ -1182,23 +1224,33 @@ if [[ "$nextshelltype" != "bash" && "$nextshelltype" != "none" ]]; then
fi fi
if [[ "$plat" == "MSYS_NT"* ]]; then if [[ "$plat" == "MSYS_NT"* ]]; then
#we need to deal with MSYS argument mangling #we need to deal with MSYS argument munging
cmdpattern="^cmd.exe |^cmd " cmdpattern="^cmd.exe |^cmd "
#do not double quote cmdpattern - or it will be treated as literal string #do not double quote cmdpattern - or it will be treated as literal string
if [[ "$nextshellpath" =~ $cmdpattern ]]; then if [[ "$nextshellpath" =~ $cmdpattern ]]; then
#for now - tell the user what's going on #for now - tell the user what's going on
echo "cmd call via msys detected. performing translation of /c to //c and escaping backslashes in script path" echo "cmd call via msys detected. performing translation of /c to //c and escaping backslashes in script path" >&2
#flags to cmd.exe such as /c are interpreted by msys as looking like a unix path #flags to cmd.exe such as /c are interpreted by msys as looking like a unix path
#review - for nextshellpath targets specified in the block for win32 - we don't expect unix paths (?) #review - for nextshellpath targets specified in the block for win32 - we don't expect unix paths (?)
#what about other flags? - can we just double up all forward slashes? #what about other flags? - can we just double up all forward slashes?
nextshellpath="${nextshellpath// \/c / \/\/c }" #maint: keep this munging in sync with the tcl block and perl block which must also do msys munging
echo "new nextshellpath: ${nextshellpath}" nextshellpath="${nextshellpath// \/[cC] / \/\/c }"
# echo "new nextshellpath: ${nextshellpath}"
#review -
#don't double quote this #don't double quote this
script=${script//\\/\\\\} script=${script//\\/\\\\}
fi fi
echo "calling ${nextshellpath} $script $@" echo "calling ${nextshellpath} $script $@"
# eval is required here - but why?
eval ${nextshellpath} "$script" "$@" #load into array
cmd_array=($nextshellpath)
cmd_array+=("$script") #add script, which may contain spaces as a single entry ?
cmd_array+=( "$@" ) #add each element of args to array as a separate entry (equiv ? "${arr[@]}")
# printf "%s\n" "${cmd_array[@]}"
"${cmd_array[@]}"
# this works to make nextshellpath run - but joins $@ members incorrectly
#eval ${nextshellpath} "$script" "$@"
else else
#e.g /usr/bin/env tclsh "$0" "$@" #e.g /usr/bin/env tclsh "$0" "$@"
${nextshellpath} "$script" "$@" ${nextshellpath} "$script" "$@"
@ -1308,8 +1360,33 @@ if 0 {
# -- unbalanced braces { } here *even in comments* will cause problems if there was no Tcl exit or return above # -- unbalanced braces { } here *even in comments* will cause problems if there was no Tcl exit or return above
# -- custom script should generally go below the begin_powershell_payload line # -- custom script should generally go below the begin_powershell_payload line
# ## ### ### ### ### ### ### ### ### ### ### ### ### ### # ## ### ### ### ### ### ### ### ### ### ### ### ### ###
function GetScriptName { $myInvocation.ScriptName } #$MyInvocation.ScriptName should probably be considered deprecated
$scriptname = GetScriptName # https://stackoverflow.com/questions/78511229/how-can-i-choose-between-myinvocation-scriptname-and-myinvocation-pscommandpat
$runningscriptname = $PSCommandPath
if (-not $MyInvocation.PSCommandPath) {
$callingscriptname = ''
} else {
$callingscriptname = $MyInvocation.PSCommandPath
}
#The problem with psmodulepath
#https://github.com/PowerShell/PowerShell/issues/18108
# psmodulepath is shared by powershell and pwsh despite not all ps modules being compatible.
# It is futzed with by powershell/pwsh based on detecting the child process type.
# a psmodulepath that has been futzed with by pwsh will not work for a child powershell 5 process that isn't launched directly
#This is inherently unfriendly to situations where an intervening process may be something else such as cmd.exe,tcl,perl etc
# nevertheless, powershell/pwsh maintainers seem to have taken the MS-centric view of the world that such situations don't exist :/
#
#symptoms of these shenannigans not working include things like Get-FileHash failing in powershell desktop
#
#We don't know if the original console was pwsh/powershell or cmd.exe, and we need to potentially divert to powershell 5 (desktop)
#via tcl or perl etc - or cmd.exe
if ($PSVersionTable.PSVersion.Major -le 5) {
# For Windows PowerShell, we want to remove any PowerShell 7 paths from PSModulePath
#snipped from https://github.com/PowerShell/DSC/pull/777/commits/af9b99a4d38e0cf1e54c4bbd89cbb6a8a8598c4e
#Presumably users are supposed to know not to have custom paths for powershell desktop containing a 'powershell' subfolder??
$env:PSModulePath = ($env:PSModulePath -split ';' | Where-Object { $_ -notlike '*\powershell\*' }) -join ';'
}
function GetDynamicParamDictionary { function GetDynamicParamDictionary {
[CmdletBinding()] [CmdletBinding()]
param( param(
@ -1384,11 +1461,11 @@ function GetDynamicParamDictionary {
#} #}
#psmain @args #psmain @args
#"Timestamp : {0,10:yyyy-MM-dd HH:mm:ss}" -f $(Get-Date) | write-host #"Timestamp : {0,10:yyyy-MM-dd HH:mm:ss}" -f $(Get-Date) | write-host
"Script Name : {0}" -f $scriptname | write-host #"Running Script Name : {0}" -f $runningscriptname | write-host
"Powershell Version: {0}" -f $PSVersionTable.PSVersion.Major | write-host "Powershell Version: {0}" -f $PSVersionTable.PSVersion.Major | write-host
"powershell args : {0}" -f ($args -join ", ") | write-host #"powershell args : {0}" -f ($args -join ", ") | write-host
# -- --- --- --- # -- --- --- ---
$thisfileContent = Get-Content $scriptname -Raw $thisfileContent = Get-Content $runningscriptname -Raw
$startTag = ": <<asadmin_start>>" $startTag = ": <<asadmin_start>>"
$endTag = ": <<asadmin_end>>" $endTag = ": <<asadmin_end>>"
$pattern = "(?s)`n$startTag[^`n]*`n(.*?)`n$endTag" $pattern = "(?s)`n$startTag[^`n]*`n(.*?)`n$endTag"
@ -1487,7 +1564,7 @@ if ($match.Success) {
} }
if (-not (("pwsh", "powershell", "") -contains $nextshell_type)) { if (-not (("pwsh", "powershell", "") -contains $nextshell_type)) {
#nextshell diversion exists for this platform #nextshell diversion exists for this platform
write-host "os: $os pwsh/powershell launching subshell of type: $nextshell_type shellpath: $nextshell_path on script $scriptname" write-host "os: $os pwsh/powershell launching subshell of type: $nextshell_type shellpath: $nextshell_path on script $runningscriptname"
# $arguments = @($($MyInvocation.MyCommand.Path)) # $arguments = @($($MyInvocation.MyCommand.Path))
# $arguments += $args # $arguments += $args
@ -1495,7 +1572,7 @@ if ($match.Success) {
# $process = (Start-Process -FilePath $nextshell_path -ArgumentList $arguments -NoNewWindow -Wait) # $process = (Start-Process -FilePath $nextshell_path -ArgumentList $arguments -NoNewWindow -Wait)
# Exit $process.ExitCode # Exit $process.ExitCode
& $nextshell_path $scriptname $args & $nextshell_path $runningscriptname $args
exit $LASTEXITCODE exit $LASTEXITCODE
} }
} }
@ -1519,20 +1596,22 @@ if (-not(Test-Path -Path $toolsfolder -PathType Container)) {
New-Item -Path $toolsfolder -ItemType Directory New-Item -Path $toolsfolder -ItemType Directory
} }
$zigfolder = Join-Path $toolsfolder -ChildPath "zig" $zigfolder = Join-Path $toolsfolder -ChildPath "zig"
$zigexe = Join-Path $zigfolder "zig.exe" $zigexe = Join-Path $zigfolder -ChildPath "zig.exe"
$releasearchive = "zig-x86_64-windows-0.15.1.zip" ;#zip on windows, tarball on every other platform # $releasearchive = "zig-x86_64-windows-0.15.1.zip" ;#zip on windows, tarball on every other platform
$releasearchive = "zig-x86_64-windows-0.16.0-dev.254+6dd0270a1.zip"
Write-Output "powershell version: $($PSVersionTable.PSVersion)" Write-Output "powershell version: $($PSVersionTable.PSVersion)"
if (Get-Command $zigexe -ErrorAction SilentlyContinue) { if (Get-Command $zigexe -ErrorAction SilentlyContinue) {
Write-Host "zig.exe is installed in tools/zig" $relative_zigfolder = Resolve-Path -Path $zigfolder -RelativeBasePath $outbase -Relative
$zigv = tools/zig/zig.exe version 2>&1 Write-Host "zig.exe is installed in $relative_zigfolder"
$zigv = & $zigexe version 2>&1
$stdout = $zigv | Where-Object {$_ -is [string]} $stdout = $zigv | Where-Object {$_ -is [string]}
$stderr = $zigv | Where-Object {$_ -is [System.Management.Automation.ErrorRecord]} $stderr = $zigv | Where-Object {$_ -is [System.Management.Automation.ErrorRecord]}
if ($stderr) { if ($stderr) {
Write-Host "Unexpected output from tools/zig/zig.exe: $stderr" Write-Host "Unexpected output from ${zigexe}: $stderr"
Write-Host "Consider deleting tools/zig and re-downloading" Write-Host "Consider deleting $zigexe and re-downloading"
} else { } else {
Write-Host "tools/zig/zig.exe version is: $stdout" Write-Host "$zigexe version is: $stdout"
} }
exit exit
} }
@ -1546,7 +1625,7 @@ if (Get-Command "minisign" -ErrorAction SilentlyContinue) {
$wgclient = Get-Module -ListAvailable -Name Microsoft.WinGet.Client $wgclient = Get-Module -ListAvailable -Name Microsoft.WinGet.Client
if (${wgclient}.Length -eq 0) { if (${wgclient}.Length -eq 0) {
Write-Host "Microsoft.WinGet.Client module not installed.. will try to install." Write-Host "Microsoft.WinGet.Client module not installed.. will try to install."
Install-PackageProvider -Name NuGet -Force Install-PackageProvider -Scope CurrentUser -Name NuGet -Force
$psgallery_existing_policy = (Get-PSRepository -Name PSGallery).InstallationPolicy $psgallery_existing_policy = (Get-PSRepository -Name PSGallery).InstallationPolicy
if ($psgallery_existing_policy -eq "Untrusted") { if ($psgallery_existing_policy -eq "Untrusted") {
#Applies to all versions of PowerShell for the user, and is persistent for current user. #Applies to all versions of PowerShell for the user, and is persistent for current user.
@ -1591,7 +1670,125 @@ if (Get-Command "minisign" -ErrorAction SilentlyContinue) {
} }
} }
#extract_zip to be called only after sig verified
;
function extractZip {
[CmdletBinding()]
param(
[Parameter(Mandatory=$true, Position = 0)][string] $releasearchive,
[Parameter(Mandatory=$true, Position = 1)] [string] $toolsfolder
)
Add-Type -Assembly "System.IO.Compression.Filesystem"
$outfile = Join-Path $toolsfolder -ChildPath $releasearchive
$zip_rootname = [System.IO.Path]::GetFileNameWithoutExtension($releasearchive)
if (-not ($zip_rootname.Contains("zig"))) {
write-host "sanity check on zip_rootname '$zip_rootname' failed - aborting"
exit 1
}
$zip_extraction_folder = Join-Path -Path $toolsfolder -ChildPath $zip_rootname
if (Test-Path -Path $zip_extraction_folder -PathType Container) {
write-host "Existing folder found at $zip_extraction_folder - removing folder prior to extraction"
Remove-Item -Path $zip_extraction_folder -Recurse -Force -ErrorAction SilentlyContinue
}
#Expand-Archive -path $outfile -DestinationPath $toolsfolder -Force #This is *insanely* (many minutes vs seconds) slow on powershell 5 at least - we get a progress meter, but it's too high a price to pay.
# -------------------------------------
[System.IO.Compression.Zipfile]::ExtractToDirectory($outfile, $toolsfolder)
Write-Host " - archive extracted."
if (-not (Test-Path -Path $zip_extraction_folder -PathType Container)) {
write-host "Failed to verify extraction as folder at $zip_extraction_folder"
exit 1
}
$zigfolder = Join-Path $toolsfolder -ChildPath "zig"
$zigexe = Join-Path $zigfolder -ChildPath "zig.exe"
$retries = 10
$exe_missing = $true #missing until tested as a found leaf
$sleep_time = 2
while (($retries -gt 0) -and $exe_missing) {
$retries -= 1
#We *intermittently* get permission errors when trying to rename the resulting folder (possibly also if we try to delete the zip file immediately)
#There seems to be some sort of lock held after ExtractToDirectory (possibly AV related)
#https://stackoverflow.com/questions/74582293/file-lock-issues-on-zip-file-after-io-compression-zipfileextracttodirectory
#In some cases just the GC was enough.. but in other cases even sleep 3 seconds + GC didn't work
#sleep of 5 seems more reliable - but the size of the required delay may depend on what is running on the system,
# and the size of the extracted folder etc.
#Rather than use a large sleep to cover all cases - we use a limited retry loop with a somewhat shorter sleep e.g 2
Write-Host "waiting $sleep_time seconds and also running GC to allow locks to clear. Max remaining retries: $retries"
start-sleep -Seconds $sleep_time
[GC]::Collect()
[GC]::WaitForPendingFinalizers()
# -------------------------------------
#Remove-Item -Path "$outfile"
#write-host "zip_rootname: $zip_rootname"
write-host "Attempting to move $zip_extraction_folder to ${zigfolder}"
Rename-Item -Path $(Join-Path -Path $toolsfolder -ChildPath $zip_rootname) -NewName $zigfolder -ErrorAction SilentlyContinue
if (-not $?) {
write-host "Renaming extracted folder into place at $zigfolder failed"
write-host " - error message: $($error[0].Exception.Message)"
}
if (Test-Path -Path $zigexe -PathType leaf) {
$exe_missing = $false
}
}
if (Test-Path -Path $zigexe -PathType leaf) {
Write-Host "Zig installed in ${zigfolder}"
return $true
} else {
Write-Host "Failed to install as $zigexe"
return $false
}
}
$zigpubkey = "RWSGOq2NVecA2UPNdBUZykf1CCb147pkmdtYxgb3Ti+JO/wCYvhbAb/U" $zigpubkey = "RWSGOq2NVecA2UPNdBUZykf1CCb147pkmdtYxgb3Ti+JO/wCYvhbAb/U"
$outfile = Join-Path $toolsfolder -ChildPath $releasearchive
$sigfile = "${outfile}.minisig"
$download_required = $true #default assumption
if (Test-Path -Path $outfile -PathType Leaf) {
if (Test-Path -Path $sigfile) {
write-host "Found existing $outfile and ${outfile}.minisig - validating signature..."
$sigresult = minisign -V -P $zigpubkey -m $outfile 2>&1
$stdout = $sigresult | Where-Object {$_ -is [string]}
$stderr = $sigresult | Where-Object {$_ -is [System.Management.Automation.ErrorRecord]}
$is_valid = $false
if ($stderr) {
write-host "Signature validation failed with message: $stderr"
} else {
if (($stdout | Out-String).Contains("signature verified")) {
write-host $stdout
$is_valid = $true
} else {
write-host "Unexpected output from minisign: $stdout"
write-host "Did not contain 'signature verified'"
}
}
if (-not($is_valid)) {
write-Host "Couldn't verify signature of existing $outfile with $outfile.minisig"
Remove-Item -Path $outfile -ErrorAction SilentlyContinue
Remove-Item -Path "${outfile}.minisig" -ErrorAction SilentlyContinue
} else {
$download_required = $false
}
}
}
if (-not $download_required) {
write-host "Existing zip and zip.minisig ok - download not required"
Write-Host "Signature OK - extracting existing archive ..."
$null = extractZip $releasearchive $toolsfolder
$zigexe = Join-Path $zigfolder -ChildPath "zig.exe"
$v = Invoke-Expression "$zigexe version"
Write-Host "ZIG VERSION: ${v}"
exit 0
}
$mirrors_url = "https://ziglang.org/download/community-mirrors.txt" $mirrors_url = "https://ziglang.org/download/community-mirrors.txt"
$mirrors_response = $(Invoke-WebRequest -Uri $mirrors_url) $mirrors_response = $(Invoke-WebRequest -Uri $mirrors_url)
if ($mirrors_response.StatusCode -eq 200) { if ($mirrors_response.StatusCode -eq 200) {
@ -1697,11 +1894,15 @@ if ($mirrors_response.StatusCode -eq 200) {
$full_uristring = "${uristring}/${releasearchive}?source=${automation_name}" $full_uristring = "${uristring}/${releasearchive}?source=${automation_name}"
$sig_uristring = "${uristring}/${releasearchive}.minisig?source=${automation_name}" $sig_uristring = "${uristring}/${releasearchive}.minisig?source=${automation_name}"
} }
Write-Host "Downloading zig from $full_uristring" #download the minisig first - because if that fails, we should move on without trying the larger download
#$uriobj = [uri]$full_uristring Write-Host "Downloading minisig signature from $sig_uristring"
#$lastSegment = $uriobj.Segments[-1] Invoke-WebRequest -Uri $sig_uristring -Outfile "${outfile}.minisig"
#$outfile = Join-Path $toolsfolder -ChildPath $lastSegment if (-not(Test-Path -Path "${outfile}.minisig" -PathType Leaf)) {
$outfile = Join-Path $toolsfolder -ChildPath $releasearchive write-Host "Failed to download minisig signature from $sig_uristring to ${outfile}.minisig .. aborting download from $uristring"
continue
}
Write-Host "Downloading zig distribution from $full_uristring"
Write-Host "Download to: $outfile" Write-Host "Download to: $outfile"
Invoke-WebRequest -Uri $full_uristring -OutFile $outfile Invoke-WebRequest -Uri $full_uristring -OutFile $outfile
@ -1709,12 +1910,6 @@ if ($mirrors_response.StatusCode -eq 200) {
write-Host "Failed to download zig package from $full_uristring to ${outfile} .. aborting download from $uristring" write-Host "Failed to download zig package from $full_uristring to ${outfile} .. aborting download from $uristring"
continue continue
} }
Write-Host "Downloading minisig signature from $sig_uristring"
Invoke-WebRequest -Uri $sig_uristring -Outfile "${outfile}.minisig"
if (-not(Test-Path -Path "${outfile}.minisig" -PathType Leaf)) {
write-Host "Failed to download minisig from $sig_uristring to ${outfile}.minisig .. aborting download from $uristring"
continue
}
write-host "downloaded $outfile and ${outfile}.minisig - validating signature..." write-host "downloaded $outfile and ${outfile}.minisig - validating signature..."
#validate releasearchive (tarball/zip) #validate releasearchive (tarball/zip)
@ -1740,29 +1935,16 @@ if ($mirrors_response.StatusCode -eq 200) {
continue continue
} }
Write-Host "Signature OK - extracting archive ..."
#Expand-Archive -path $outfile -DestinationPath $toolsfolder -Force #This is *insanely* (many minutes vs seconds) slow on powershell 5 at least - we get a progress meter, but it's too high a price to pay.
# -------------------------------------
Add-Type -Assembly "System.IO.Compression.Filesystem"
[System.IO.Compression.Zipfile]::ExtractToDirectory($outfile, $toolsfolder)
Write-Host " - archive extracted."
#We *intermittently* get permission errors when trying to rename the resulting folder (possibly also if we try to delete the zip file immediately)
#There seems to be some sort of lock held after ExtractToDirectory (possibly AV related)
#https://stackoverflow.com/questions/74582293/file-lock-issues-on-zip-file-after-io-compression-zipfileextracttodirectory
[GC]::Collect()
[GC]::WaitForPendingFinalizers()
# -------------------------------------
#Remove-Item -Path "$outfile"
$zip_rootname = [System.IO.Path]::GetFileNameWithoutExtension($releasearchive) # -----------------------------------------------------
#Rename-Item -Path Write-Host "Signature OK - extracting downloaded archive ..."
#write-host "zip_rootname: $zip_rootname" $null = extractZip $releasearchive $toolsfolder
write-host "moving $(Join-Path -Path $toolsfolder -ChildPath $zip_rootname) to ${zigfolder}"
Rename-Item -Path $(Join-Path -Path $toolsfolder -ChildPath $zip_rootname) -NewName $zigfolder
Write-Host "Zig installed in ${zigfolder}"
$zigexe = Join-Path $zigfolder -ChildPath "zig.exe" $zigexe = Join-Path $zigfolder -ChildPath "zig.exe"
$v = Invoke-Expression "$zigexe version" $v = Invoke-Expression "$zigexe version"
Write-Host "ZIG VERSION: ${v}" Write-Host "ZIG VERSION: ${v}"
$test_ok = 1 ;#todo $test_ok = 1 ;#todo
if ($test_ok) { if ($test_ok) {
break break

0
src/scriptapps/getzig.bash → src/scriptapps/bin/getzig.bash

181
src/scriptapps/getzig.ps1 → src/scriptapps/bin/getzig.ps1

@ -14,20 +14,22 @@ if (-not(Test-Path -Path $toolsfolder -PathType Container)) {
New-Item -Path $toolsfolder -ItemType Directory New-Item -Path $toolsfolder -ItemType Directory
} }
$zigfolder = Join-Path $toolsfolder -ChildPath "zig" $zigfolder = Join-Path $toolsfolder -ChildPath "zig"
$zigexe = Join-Path $zigfolder "zig.exe" $zigexe = Join-Path $zigfolder -ChildPath "zig.exe"
$releasearchive = "zig-x86_64-windows-0.15.1.zip" ;#zip on windows, tarball on every other platform # $releasearchive = "zig-x86_64-windows-0.15.1.zip" ;#zip on windows, tarball on every other platform
$releasearchive = "zig-x86_64-windows-0.16.0-dev.254+6dd0270a1.zip"
Write-Output "powershell version: $($PSVersionTable.PSVersion)" Write-Output "powershell version: $($PSVersionTable.PSVersion)"
if (Get-Command $zigexe -ErrorAction SilentlyContinue) { if (Get-Command $zigexe -ErrorAction SilentlyContinue) {
Write-Host "zig.exe is installed in tools/zig" $relative_zigfolder = Resolve-Path -Path $zigfolder -RelativeBasePath $outbase -Relative
$zigv = tools/zig/zig.exe version 2>&1 Write-Host "zig.exe is installed in $relative_zigfolder"
$zigv = & $zigexe version 2>&1
$stdout = $zigv | Where-Object {$_ -is [string]} $stdout = $zigv | Where-Object {$_ -is [string]}
$stderr = $zigv | Where-Object {$_ -is [System.Management.Automation.ErrorRecord]} $stderr = $zigv | Where-Object {$_ -is [System.Management.Automation.ErrorRecord]}
if ($stderr) { if ($stderr) {
Write-Host "Unexpected output from tools/zig/zig.exe: $stderr" Write-Host "Unexpected output from ${zigexe}: $stderr"
Write-Host "Consider deleting tools/zig and re-downloading" Write-Host "Consider deleting $zigexe and re-downloading"
} else { } else {
Write-Host "tools/zig/zig.exe version is: $stdout" Write-Host "$zigexe version is: $stdout"
} }
exit exit
} }
@ -41,7 +43,7 @@ if (Get-Command "minisign" -ErrorAction SilentlyContinue) {
$wgclient = Get-Module -ListAvailable -Name Microsoft.WinGet.Client $wgclient = Get-Module -ListAvailable -Name Microsoft.WinGet.Client
if (${wgclient}.Length -eq 0) { if (${wgclient}.Length -eq 0) {
Write-Host "Microsoft.WinGet.Client module not installed.. will try to install." Write-Host "Microsoft.WinGet.Client module not installed.. will try to install."
Install-PackageProvider -Name NuGet -Force Install-PackageProvider -Scope CurrentUser -Name NuGet -Force
$psgallery_existing_policy = (Get-PSRepository -Name PSGallery).InstallationPolicy $psgallery_existing_policy = (Get-PSRepository -Name PSGallery).InstallationPolicy
if ($psgallery_existing_policy -eq "Untrusted") { if ($psgallery_existing_policy -eq "Untrusted") {
#Applies to all versions of PowerShell for the user, and is persistent for current user. #Applies to all versions of PowerShell for the user, and is persistent for current user.
@ -86,7 +88,125 @@ if (Get-Command "minisign" -ErrorAction SilentlyContinue) {
} }
} }
#extract_zip to be called only after sig verified
;
function extractZip {
[CmdletBinding()]
param(
[Parameter(Mandatory=$true, Position = 0)][string] $releasearchive,
[Parameter(Mandatory=$true, Position = 1)] [string] $toolsfolder
)
Add-Type -Assembly "System.IO.Compression.Filesystem"
$outfile = Join-Path $toolsfolder -ChildPath $releasearchive
$zip_rootname = [System.IO.Path]::GetFileNameWithoutExtension($releasearchive)
if (-not ($zip_rootname.Contains("zig"))) {
write-host "sanity check on zip_rootname '$zip_rootname' failed - aborting"
exit 1
}
$zip_extraction_folder = Join-Path -Path $toolsfolder -ChildPath $zip_rootname
if (Test-Path -Path $zip_extraction_folder -PathType Container) {
write-host "Existing folder found at $zip_extraction_folder - removing folder prior to extraction"
Remove-Item -Path $zip_extraction_folder -Recurse -Force -ErrorAction SilentlyContinue
}
#Expand-Archive -path $outfile -DestinationPath $toolsfolder -Force #This is *insanely* (many minutes vs seconds) slow on powershell 5 at least - we get a progress meter, but it's too high a price to pay.
# -------------------------------------
[System.IO.Compression.Zipfile]::ExtractToDirectory($outfile, $toolsfolder)
Write-Host " - archive extracted."
if (-not (Test-Path -Path $zip_extraction_folder -PathType Container)) {
write-host "Failed to verify extraction as folder at $zip_extraction_folder"
exit 1
}
$zigfolder = Join-Path $toolsfolder -ChildPath "zig"
$zigexe = Join-Path $zigfolder -ChildPath "zig.exe"
$retries = 10
$exe_missing = $true #missing until tested as a found leaf
$sleep_time = 2
while (($retries -gt 0) -and $exe_missing) {
$retries -= 1
#We *intermittently* get permission errors when trying to rename the resulting folder (possibly also if we try to delete the zip file immediately)
#There seems to be some sort of lock held after ExtractToDirectory (possibly AV related)
#https://stackoverflow.com/questions/74582293/file-lock-issues-on-zip-file-after-io-compression-zipfileextracttodirectory
#In some cases just the GC was enough.. but in other cases even sleep 3 seconds + GC didn't work
#sleep of 5 seems more reliable - but the size of the required delay may depend on what is running on the system,
# and the size of the extracted folder etc.
#Rather than use a large sleep to cover all cases - we use a limited retry loop with a somewhat shorter sleep e.g 2
Write-Host "waiting $sleep_time seconds and also running GC to allow locks to clear. Max remaining retries: $retries"
start-sleep -Seconds $sleep_time
[GC]::Collect()
[GC]::WaitForPendingFinalizers()
# -------------------------------------
#Remove-Item -Path "$outfile"
#write-host "zip_rootname: $zip_rootname"
write-host "Attempting to move $zip_extraction_folder to ${zigfolder}"
Rename-Item -Path $(Join-Path -Path $toolsfolder -ChildPath $zip_rootname) -NewName $zigfolder -ErrorAction SilentlyContinue
if (-not $?) {
write-host "Renaming extracted folder into place at $zigfolder failed"
write-host " - error message: $($error[0].Exception.Message)"
}
if (Test-Path -Path $zigexe -PathType leaf) {
$exe_missing = $false
}
}
if (Test-Path -Path $zigexe -PathType leaf) {
Write-Host "Zig installed in ${zigfolder}"
return $true
} else {
Write-Host "Failed to install as $zigexe"
return $false
}
}
$zigpubkey = "RWSGOq2NVecA2UPNdBUZykf1CCb147pkmdtYxgb3Ti+JO/wCYvhbAb/U" $zigpubkey = "RWSGOq2NVecA2UPNdBUZykf1CCb147pkmdtYxgb3Ti+JO/wCYvhbAb/U"
$outfile = Join-Path $toolsfolder -ChildPath $releasearchive
$sigfile = "${outfile}.minisig"
$download_required = $true #default assumption
if (Test-Path -Path $outfile -PathType Leaf) {
if (Test-Path -Path $sigfile) {
write-host "Found existing $outfile and ${outfile}.minisig - validating signature..."
$sigresult = minisign -V -P $zigpubkey -m $outfile 2>&1
$stdout = $sigresult | Where-Object {$_ -is [string]}
$stderr = $sigresult | Where-Object {$_ -is [System.Management.Automation.ErrorRecord]}
$is_valid = $false
if ($stderr) {
write-host "Signature validation failed with message: $stderr"
} else {
if (($stdout | Out-String).Contains("signature verified")) {
write-host $stdout
$is_valid = $true
} else {
write-host "Unexpected output from minisign: $stdout"
write-host "Did not contain 'signature verified'"
}
}
if (-not($is_valid)) {
write-Host "Couldn't verify signature of existing $outfile with $outfile.minisig"
Remove-Item -Path $outfile -ErrorAction SilentlyContinue
Remove-Item -Path "${outfile}.minisig" -ErrorAction SilentlyContinue
} else {
$download_required = $false
}
}
}
if (-not $download_required) {
write-host "Existing zip and zip.minisig ok - download not required"
Write-Host "Signature OK - extracting existing archive ..."
$null = extractZip $releasearchive $toolsfolder
$zigexe = Join-Path $zigfolder -ChildPath "zig.exe"
$v = Invoke-Expression "$zigexe version"
Write-Host "ZIG VERSION: ${v}"
exit 0
}
$mirrors_url = "https://ziglang.org/download/community-mirrors.txt" $mirrors_url = "https://ziglang.org/download/community-mirrors.txt"
$mirrors_response = $(Invoke-WebRequest -Uri $mirrors_url) $mirrors_response = $(Invoke-WebRequest -Uri $mirrors_url)
if ($mirrors_response.StatusCode -eq 200) { if ($mirrors_response.StatusCode -eq 200) {
@ -192,11 +312,15 @@ if ($mirrors_response.StatusCode -eq 200) {
$full_uristring = "${uristring}/${releasearchive}?source=${automation_name}" $full_uristring = "${uristring}/${releasearchive}?source=${automation_name}"
$sig_uristring = "${uristring}/${releasearchive}.minisig?source=${automation_name}" $sig_uristring = "${uristring}/${releasearchive}.minisig?source=${automation_name}"
} }
Write-Host "Downloading zig from $full_uristring" #download the minisig first - because if that fails, we should move on without trying the larger download
#$uriobj = [uri]$full_uristring Write-Host "Downloading minisig signature from $sig_uristring"
#$lastSegment = $uriobj.Segments[-1] Invoke-WebRequest -Uri $sig_uristring -Outfile "${outfile}.minisig"
#$outfile = Join-Path $toolsfolder -ChildPath $lastSegment if (-not(Test-Path -Path "${outfile}.minisig" -PathType Leaf)) {
$outfile = Join-Path $toolsfolder -ChildPath $releasearchive write-Host "Failed to download minisig signature from $sig_uristring to ${outfile}.minisig .. aborting download from $uristring"
continue
}
Write-Host "Downloading zig distribution from $full_uristring"
Write-Host "Download to: $outfile" Write-Host "Download to: $outfile"
Invoke-WebRequest -Uri $full_uristring -OutFile $outfile Invoke-WebRequest -Uri $full_uristring -OutFile $outfile
@ -204,12 +328,6 @@ if ($mirrors_response.StatusCode -eq 200) {
write-Host "Failed to download zig package from $full_uristring to ${outfile} .. aborting download from $uristring" write-Host "Failed to download zig package from $full_uristring to ${outfile} .. aborting download from $uristring"
continue continue
} }
Write-Host "Downloading minisig signature from $sig_uristring"
Invoke-WebRequest -Uri $sig_uristring -Outfile "${outfile}.minisig"
if (-not(Test-Path -Path "${outfile}.minisig" -PathType Leaf)) {
write-Host "Failed to download minisig from $sig_uristring to ${outfile}.minisig .. aborting download from $uristring"
continue
}
write-host "downloaded $outfile and ${outfile}.minisig - validating signature..." write-host "downloaded $outfile and ${outfile}.minisig - validating signature..."
#validate releasearchive (tarball/zip) #validate releasearchive (tarball/zip)
@ -235,29 +353,16 @@ if ($mirrors_response.StatusCode -eq 200) {
continue continue
} }
Write-Host "Signature OK - extracting archive ..."
#Expand-Archive -path $outfile -DestinationPath $toolsfolder -Force #This is *insanely* (many minutes vs seconds) slow on powershell 5 at least - we get a progress meter, but it's too high a price to pay.
# -------------------------------------
Add-Type -Assembly "System.IO.Compression.Filesystem"
[System.IO.Compression.Zipfile]::ExtractToDirectory($outfile, $toolsfolder)
Write-Host " - archive extracted."
#We *intermittently* get permission errors when trying to rename the resulting folder (possibly also if we try to delete the zip file immediately)
#There seems to be some sort of lock held after ExtractToDirectory (possibly AV related)
#https://stackoverflow.com/questions/74582293/file-lock-issues-on-zip-file-after-io-compression-zipfileextracttodirectory
[GC]::Collect()
[GC]::WaitForPendingFinalizers()
# -------------------------------------
#Remove-Item -Path "$outfile"
$zip_rootname = [System.IO.Path]::GetFileNameWithoutExtension($releasearchive) # -----------------------------------------------------
#Rename-Item -Path Write-Host "Signature OK - extracting downloaded archive ..."
#write-host "zip_rootname: $zip_rootname" $null = extractZip $releasearchive $toolsfolder
write-host "moving $(Join-Path -Path $toolsfolder -ChildPath $zip_rootname) to ${zigfolder}"
Rename-Item -Path $(Join-Path -Path $toolsfolder -ChildPath $zip_rootname) -NewName $zigfolder
Write-Host "Zig installed in ${zigfolder}"
$zigexe = Join-Path $zigfolder -ChildPath "zig.exe" $zigexe = Join-Path $zigfolder -ChildPath "zig.exe"
$v = Invoke-Expression "$zigexe version" $v = Invoke-Expression "$zigexe version"
Write-Host "ZIG VERSION: ${v}" Write-Host "ZIG VERSION: ${v}"
$test_ok = 1 ;#todo $test_ok = 1 ;#todo
if ($test_ok) { if ($test_ok) {
break break

0
src/scriptapps/getzig_original.polyglot → src/scriptapps/bin/getzig_original.polyglot

0
src/scriptapps/getzig_wrap.toml → src/scriptapps/bin/getzig_wrap.toml

2
src/scriptapps/getpunk.ps1

@ -110,7 +110,7 @@ if (-not(Test-Path -Path (Join-Path -Path $punkfolder -ChildPath ".git") -PathTy
git fetch origin git fetch origin
if (($launchdir.Path) -eq ($scriptfolder.Path)) { if (($launchdir.Path) -eq ($scriptfolder.Path)) {
if (Test-Path -Path "${scriptroot}.cmd") { if (Test-Path -Path "${scriptroot}.cmd") {
#rename-item won't allow overwriting existing target file #Rename-Item won't allow overwriting existing target file
Move-Item -Path "${scriptroot}.cmd" -Destination "${scriptroot}.cmd.lastrun" -Force Move-Item -Path "${scriptroot}.cmd" -Destination "${scriptroot}.cmd.lastrun" -Force
} }
} }

Loading…
Cancel
Save