9 changed files with 1545 additions and 1258 deletions
@ -1,269 +1,374 @@ |
|||||||
|
|
||||||
#launch example |
#launch example |
||||||
#powershell -Command "Invoke-WebRequest -Uri 'https://www.gitea1.intx.com.au/jn/punkshell/raw/branch/master/bin/getzig.cmd' -OutFile 'getzig.cmd'; Start-Process 'cmd.exe' -ArgumentList @('/c', 'getzig.cmd') -NoNewWindow -Wait" |
#powershell -Command "Invoke-WebRequest -Uri 'https://www.gitea1.intx.com.au/jn/punkshell/raw/branch/master/bin/getzig.cmd' -OutFile 'getzig.cmd'; Start-Process 'cmd.exe' -ArgumentList @('/c', 'getzig.cmd') -NoNewWindow -Wait" |
||||||
#powershell -Command "Invoke-WebRequest -Uri 'https://www.gitea1.intx.com.au/jn/punkshell/raw/branch/master/bin/getzig.cmd' -OutFile 'getzig.cmd'; Start-Process 'getzig.cmd' -NoNewWindow -Wait" |
#powershell -Command "Invoke-WebRequest -Uri 'https://www.gitea1.intx.com.au/jn/punkshell/raw/branch/master/bin/getzig.cmd' -OutFile 'getzig.cmd'; Start-Process 'getzig.cmd' -NoNewWindow -Wait" |
||||||
|
|
||||||
#Join-Path using verbose method to support powershell 5? |
#Join-Path using verbose method to support powershell 5? |
||||||
#$outbase = Join-Path -Path $PSScriptRoot -ChildPath "../.." |
#$outbase = Join-Path -Path $PSScriptRoot -ChildPath "../.." |
||||||
$outbase = $PSScriptRoot |
$outbase = $PSScriptRoot |
||||||
$outbase = Resolve-Path -Path $outbase |
$outbase = Resolve-Path -Path $outbase |
||||||
Write-host "Base folder: $outbase" |
Write-host "Base folder: $outbase" |
||||||
$toolsfolder = Join-Path -Path $outbase -ChildPath "tools" |
$toolsfolder = Join-Path -Path $outbase -ChildPath "tools" |
||||||
if (-not(Test-Path -Path $toolsfolder -PathType Container)) { |
if (-not(Test-Path -Path $toolsfolder -PathType Container)) { |
||||||
#create folder - (can include missing intermediaries) |
#create folder - (can include missing intermediaries) |
||||||
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 |
||||||
Write-Output "powershell version: $($PSVersionTable.PSVersion)" |
$releasearchive = "zig-x86_64-windows-0.16.0-dev.254+6dd0270a1.zip" |
||||||
|
Write-Output "powershell version: $($PSVersionTable.PSVersion)" |
||||||
if (Get-Command $zigexe -ErrorAction SilentlyContinue) { |
|
||||||
Write-Host "zig.exe is installed in tools/zig" |
if (Get-Command $zigexe -ErrorAction SilentlyContinue) { |
||||||
$zigv = tools/zig/zig.exe version 2>&1 |
$relative_zigfolder = Resolve-Path -Path $zigfolder -RelativeBasePath $outbase -Relative |
||||||
$stdout = $zigv | Where-Object {$_ -is [string]} |
Write-Host "zig.exe is installed in $relative_zigfolder" |
||||||
$stderr = $zigv | Where-Object {$_ -is [System.Management.Automation.ErrorRecord]} |
$zigv = & $zigexe version 2>&1 |
||||||
if ($stderr) { |
$stdout = $zigv | Where-Object {$_ -is [string]} |
||||||
Write-Host "Unexpected output from tools/zig/zig.exe: $stderr" |
$stderr = $zigv | Where-Object {$_ -is [System.Management.Automation.ErrorRecord]} |
||||||
Write-Host "Consider deleting tools/zig and re-downloading" |
if ($stderr) { |
||||||
} else { |
Write-Host "Unexpected output from ${zigexe}: $stderr" |
||||||
Write-Host "tools/zig/zig.exe version is: $stdout" |
Write-Host "Consider deleting $zigexe and re-downloading" |
||||||
} |
} else { |
||||||
exit |
Write-Host "$zigexe version is: $stdout" |
||||||
} |
} |
||||||
|
exit |
||||||
if (Get-Command "minisign" -ErrorAction SilentlyContinue) { |
} |
||||||
Write-Host "minisign is available" |
|
||||||
} else { |
if (Get-Command "minisign" -ErrorAction SilentlyContinue) { |
||||||
Write-Host "minisign is missing. Will attempt to install using winget." |
Write-Host "minisign is available" |
||||||
#Find-Module/Install-Module: older mechanism, available in powershell |
} else { |
||||||
#Find-PSResource/Install-PSResource: only available in newer pwsh etc? |
Write-Host "minisign is missing. Will attempt to install using winget." |
||||||
$wgclient = Get-Module -ListAvailable -Name Microsoft.WinGet.Client |
#Find-Module/Install-Module: older mechanism, available in powershell |
||||||
if (${wgclient}.Length -eq 0) { |
#Find-PSResource/Install-PSResource: only available in newer pwsh etc? |
||||||
Write-Host "Microsoft.WinGet.Client module not installed.. will try to install." |
$wgclient = Get-Module -ListAvailable -Name Microsoft.WinGet.Client |
||||||
Install-PackageProvider -Name NuGet -Force |
if (${wgclient}.Length -eq 0) { |
||||||
$psgallery_existing_policy = (Get-PSRepository -Name PSGallery).InstallationPolicy |
Write-Host "Microsoft.WinGet.Client module not installed.. will try to install." |
||||||
if ($psgallery_existing_policy -eq "Untrusted") { |
Install-PackageProvider -Scope CurrentUser -Name NuGet -Force |
||||||
#Applies to all versions of PowerShell for the user, and is persistent for current user. |
$psgallery_existing_policy = (Get-PSRepository -Name PSGallery).InstallationPolicy |
||||||
#This has risks in that a powershell session started after this call, and before we reset it, will treat PSGallery as trusted |
if ($psgallery_existing_policy -eq "Untrusted") { |
||||||
Set-PSRepository -Name PSGallery -InstallationPolicy Trusted |
#Applies to all versions of PowerShell for the user, and is persistent for current user. |
||||||
} |
#This has risks in that a powershell session started after this call, and before we reset it, will treat PSGallery as trusted |
||||||
Install-Module -Scope CurrentUser -Name Microsoft.Winget.Client -Force -Repository PSGallery |
Set-PSRepository -Name PSGallery -InstallationPolicy Trusted |
||||||
Repair-WinGetPackageManager |
} |
||||||
import-module -name Microsoft.Winget.client |
Install-Module -Scope CurrentUser -Name Microsoft.Winget.Client -Force -Repository PSGallery |
||||||
|
Repair-WinGetPackageManager |
||||||
if ($psgallery_existing_policy -eq "Untrusted") { |
import-module -name Microsoft.Winget.client |
||||||
Set-PSRepository -Name PSGallery -InstallationPolicy Untrusted |
|
||||||
} |
if ($psgallery_existing_policy -eq "Untrusted") { |
||||||
} else { |
Set-PSRepository -Name PSGallery -InstallationPolicy Untrusted |
||||||
Write-Host "Microsoft.WinGet.Client is available" |
} |
||||||
} |
} else { |
||||||
$wingetversion = (Find-WinGetPackage jedisct1.minisign).Version |
Write-Host "Microsoft.WinGet.Client is available" |
||||||
if ($wingetversion) { |
} |
||||||
Write-Host "Installing minisign version: ${wingetversion}" |
$wingetversion = (Find-WinGetPackage jedisct1.minisign).Version |
||||||
Install-WinGetPackage -Id "jedisct1.minisign" |
if ($wingetversion) { |
||||||
} else { |
Write-Host "Installing minisign version: ${wingetversion}" |
||||||
Write-Host "Failed to find minisign using winget" |
Install-WinGetPackage -Id "jedisct1.minisign" |
||||||
exit |
} else { |
||||||
} |
Write-Host "Failed to find minisign using winget" |
||||||
#refreshing the current session's path should make the new command available (required for powershell 5 at least) |
exit |
||||||
$env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User") |
} |
||||||
if (Get-Command "minisign" -ErrorAction SilentlyContinue) { |
#refreshing the current session's path should make the new command available (required for powershell 5 at least) |
||||||
Write-Host "minisign is now available" |
$env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User") |
||||||
} else { |
if (Get-Command "minisign" -ErrorAction SilentlyContinue) { |
||||||
Write-Host "minisign is still not available" |
Write-Host "minisign is now available" |
||||||
#if we automatically relaunch - we could get stuck in a loop - ask user. |
} else { |
||||||
$response = read-host -Prompt "Relaunching process may make minizip available. Relaunch? Y|N" |
Write-Host "minisign is still not available" |
||||||
#if ($PSVersionTable.PSEdition -eq "Desktop") { |
#if we automatically relaunch - we could get stuck in a loop - ask user. |
||||||
#powershell.exe |
$response = read-host -Prompt "Relaunching process may make minizip available. Relaunch? Y|N" |
||||||
#} else { |
#if ($PSVersionTable.PSEdition -eq "Desktop") { |
||||||
#pwsh.exe |
#powershell.exe |
||||||
#} |
#} else { |
||||||
if ($response -ieq "y") { |
#pwsh.exe |
||||||
Start-Process 'getzig.cmd' -NoNewWindow -Wait |
#} |
||||||
} |
if ($response -ieq "y") { |
||||||
exit |
Start-Process 'getzig.cmd' -NoNewWindow -Wait |
||||||
} |
} |
||||||
} |
exit |
||||||
|
} |
||||||
$zigpubkey = "RWSGOq2NVecA2UPNdBUZykf1CCb147pkmdtYxgb3Ti+JO/wCYvhbAb/U" |
} |
||||||
$mirrors_url = "https://ziglang.org/download/community-mirrors.txt" |
|
||||||
$mirrors_response = $(Invoke-WebRequest -Uri $mirrors_url) |
#extract_zip to be called only after sig verified |
||||||
if ($mirrors_response.StatusCode -eq 200) { |
; |
||||||
#https://www.gitea1.intx.com.au/jn/punkbin/raw/branch/master/win32-x86_64/tools/zig-x86_64-windows-0.15.1.zip |
function extractZip { |
||||||
$mirror_array = @("https://gitea1.intx.com.au/jn/punkbin/raw/branch/master/win32-x86_64/tools") |
[CmdletBinding()] |
||||||
$mirror_array += $mirrors_response.Content.TrimEnd("`r`n") -split "`r`n|`n" |
param( |
||||||
#$mirror_array += "https://bogusxxx.org" #test behaviour of a bogus/down entry |
[Parameter(Mandatory=$true, Position = 0)][string] $releasearchive, |
||||||
$mirror_array += "https://ziglang.org" #main site |
[Parameter(Mandatory=$true, Position = 1)] [string] $toolsfolder |
||||||
|
) |
||||||
$dict_mirrors = [ordered]@{} |
Add-Type -Assembly "System.IO.Compression.Filesystem" |
||||||
$host_list = @() #same ordering as dict_mirrors |
$outfile = Join-Path $toolsfolder -ChildPath $releasearchive |
||||||
foreach ($mirror in $mirror_array) { |
|
||||||
$uri = New-Object System.Uri($mirror) |
$zip_rootname = [System.IO.Path]::GetFileNameWithoutExtension($releasearchive) |
||||||
$hostname = $uri.Host |
if (-not ($zip_rootname.Contains("zig"))) { |
||||||
$dict_mirrors[$hostname] = @{} |
write-host "sanity check on zip_rootname '$zip_rootname' failed - aborting" |
||||||
$dict_mirrors[$hostname]["uri"] = $mirror |
exit 1 |
||||||
$dict_mirrors[$hostname]["latency"] = 888888 ;#default |
} |
||||||
$host_list += $hostname |
$zip_extraction_folder = Join-Path -Path $toolsfolder -ChildPath $zip_rootname |
||||||
#write-host "Host name: $hostname" |
if (Test-Path -Path $zip_extraction_folder -PathType Container) { |
||||||
} |
write-host "Existing folder found at $zip_extraction_folder - removing folder prior to extraction" |
||||||
#write-host "dict: $($dict_mirrors | out-String)" |
Remove-Item -Path $zip_extraction_folder -Recurse -Force -ErrorAction SilentlyContinue |
||||||
write-host "host_list: $host_list" |
} |
||||||
$automation_name = "punkshell+julian@precisium.com.au_target_by_latency" |
#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) |
||||||
#test-netconnection progressbar seems not-so-well-behaved (prog bar lingers) |
Write-Host " - archive extracted." |
||||||
#test-netconnection a function not cmdlet? Seems to need setting at global level |
if (-not (Test-Path -Path $zip_extraction_folder -PathType Container)) { |
||||||
$OriginalProgressPreference = $Global:ProgressPreference |
write-host "Failed to verify extraction as folder at $zip_extraction_folder" |
||||||
$Global:ProgressPreference = 'SilentlyContinue' |
exit 1 |
||||||
#temporary dev download source |
} |
||||||
$ihost = "10.30.30.107" |
|
||||||
$imirror = "http://10.30.30.107/jn/punkbin/raw/branch/master/win32-x86_64/tools" |
|
||||||
$itrace = test-netconnection $ihost -Hops 6 -TraceRoute -ErrorAction Ignore |
$zigfolder = Join-Path $toolsfolder -ChildPath "zig" |
||||||
if ((${itrace}.PingSucceeded) -and (${itrace}.TraceRoute.Count -lt 5)) { |
$zigexe = Join-Path $zigfolder -ChildPath "zig.exe" |
||||||
$host_list += $ihost |
|
||||||
$dict_mirrors[$ihost] = @{} |
$retries = 10 |
||||||
$dict_mirrors[$ihost]["latency"] = 1 |
$exe_missing = $true #missing until tested as a found leaf |
||||||
$dict_mirrors[$ihost]["uri"] = $imirror |
$sleep_time = 2 |
||||||
} |
while (($retries -gt 0) -and $exe_missing) { |
||||||
$trace = test-netconnection gitea1.intx.com.au -Hops 6 -TraceRoute -ErrorAction Ignore |
$retries -= 1 |
||||||
$Global:ProgressPreference = $OriginalProgressPreference |
#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) |
||||||
if ((${trace}.PingSucceeded) -and (${trace}.TraceRoute.Count -lt 5)) { |
#https://stackoverflow.com/questions/74582293/file-lock-issues-on-zip-file-after-io-compression-zipfileextracttodirectory |
||||||
$dict_mirrors["gitea1.intx.com.au"]["latency"] = 2 |
|
||||||
#short-circuit for hosts very near gitea1.intx.com.au |
#In some cases just the GC was enough.. but in other cases even sleep 3 seconds + GC didn't work |
||||||
#don't even test others. This is primarily for hosts at intx.com.au and associated entities - which are more likely to use punkshell than anyone else. |
#sleep of 5 seems more reliable - but the size of the required delay may depend on what is running on the system, |
||||||
} else { |
# and the size of the extracted folder etc. |
||||||
if ($PSVersionTable.PSEdition -eq "Desktop") { |
#Rather than use a large sleep to cover all cases - we use a limited retry loop with a somewhat shorter sleep e.g 2 |
||||||
#powershell.exe |
Write-Host "waiting $sleep_time seconds and also running GC to allow locks to clear. Max remaining retries: $retries" |
||||||
#we seem to need -ErrorAction Ignore for bad/unresponsive host entries - but unlike with pwsh, we don't get any corresponding entry in the test_results, and -Quiet doesn't seem to give us results either REVIEW |
start-sleep -Seconds $sleep_time |
||||||
$test_results = Test-Connection $host_list -Count 1 -ErrorAction Ignore |
|
||||||
for ($i = 0; $i -lt $test_results.Count; $i++) { |
[GC]::Collect() |
||||||
$result = $test_results[$i] |
[GC]::WaitForPendingFinalizers() |
||||||
if ($result) { |
# ------------------------------------- |
||||||
$targethost = $result.Address |
#Remove-Item -Path "$outfile" |
||||||
if ($result.StatusCode -eq 0) { |
#write-host "zip_rootname: $zip_rootname" |
||||||
$dict_mirrors[$targethost]["latency"] = $result.ResponseTime |
write-host "Attempting to move $zip_extraction_folder to ${zigfolder}" |
||||||
} else { |
Rename-Item -Path $(Join-Path -Path $toolsfolder -ChildPath $zip_rootname) -NewName $zigfolder -ErrorAction SilentlyContinue |
||||||
$dict_mirrors[$targethost]["latency"] = 999999 |
if (-not $?) { |
||||||
} |
write-host "Renaming extracted folder into place at $zigfolder failed" |
||||||
} else { |
write-host " - error message: $($error[0].Exception.Message)" |
||||||
$targethost = $host_list[$i] |
} |
||||||
$dict_mirrors[$targethost]["latency"] = 999999 |
if (Test-Path -Path $zigexe -PathType leaf) { |
||||||
} |
$exe_missing = $false |
||||||
} |
} |
||||||
} else { |
} |
||||||
#pwsh.exe |
|
||||||
$test_results = Test-Connection -TargetName $host_list -Count 1 -Ipv4 -Detailed -TcpPort 443 -Quiet |
if (Test-Path -Path $zigexe -PathType leaf) { |
||||||
for ($i = 0; $i -lt $test_results.Count; $i++) { |
Write-Host "Zig installed in ${zigfolder}" |
||||||
$result = $test_results[$i] |
return $true |
||||||
if ($result) { |
} else { |
||||||
$targethost = $result.Target |
Write-Host "Failed to install as $zigexe" |
||||||
if ($result.Status -eq "Success") { |
return $false |
||||||
$dict_mirrors[$targethost]["latency"] = $result.Latency |
} |
||||||
} else { |
} |
||||||
$dict_mirrors[$targethost]["latency"] = 999999 |
|
||||||
} |
|
||||||
} else { |
$zigpubkey = "RWSGOq2NVecA2UPNdBUZykf1CCb147pkmdtYxgb3Ti+JO/wCYvhbAb/U" |
||||||
$targethost = $host_list[$i] |
|
||||||
$dict_mirrors[$targethost]["latency"] = 999999 |
$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 |
||||||
$list_mirror_dicts = @() |
$stdout = $sigresult | Where-Object {$_ -is [string]} |
||||||
#write-host "dict tested: $($dict_mirrors | Out-String)" |
$stderr = $sigresult | Where-Object {$_ -is [System.Management.Automation.ErrorRecord]} |
||||||
foreach ($key in $dict_mirrors.Keys) { |
$is_valid = $false |
||||||
$list_mirror_dicts += $($dict_mirrors[$key]) |
if ($stderr) { |
||||||
} |
write-host "Signature validation failed with message: $stderr" |
||||||
#need to ensure latency cast to integer (on powershell 5 at least) |
} else { |
||||||
$sorted_mirror_dicts = $list_mirror_dicts | Sort-Object -Property { [int]$_.latency } |
if (($stdout | Out-String).Contains("signature verified")) { |
||||||
#Write-Host "Sorted by latency: $($sorted_mirror_dicts | Format-Table -AutoSize | Out-String)" |
write-host $stdout |
||||||
Write-Host "Sorted by latency: $($sorted_mirror_dicts | Out-String)" |
$is_valid = $true |
||||||
|
} else { |
||||||
foreach ($hostinfo in $sorted_mirror_dicts) { |
write-host "Unexpected output from minisign: $stdout" |
||||||
$uristring = $hostinfo.uri |
write-host "Did not contain 'signature verified'" |
||||||
if ($uristring -eq "https://ziglang.org") { |
} |
||||||
$full_uristring = "${uristring}/download/0.15.1/${releasearchive}?source=${automation_name}" |
} |
||||||
$sig_uristring = "${uristring}/download/0.15.1/${releasearchive}.minisig?source=${automation_name}" |
if (-not($is_valid)) { |
||||||
} else { |
write-Host "Couldn't verify signature of existing $outfile with $outfile.minisig" |
||||||
$full_uristring = "${uristring}/${releasearchive}?source=${automation_name}" |
Remove-Item -Path $outfile -ErrorAction SilentlyContinue |
||||||
$sig_uristring = "${uristring}/${releasearchive}.minisig?source=${automation_name}" |
Remove-Item -Path "${outfile}.minisig" -ErrorAction SilentlyContinue |
||||||
} |
} else { |
||||||
Write-Host "Downloading zig from $full_uristring" |
$download_required = $false |
||||||
#$uriobj = [uri]$full_uristring |
} |
||||||
#$lastSegment = $uriobj.Segments[-1] |
} |
||||||
#$outfile = Join-Path $toolsfolder -ChildPath $lastSegment |
} |
||||||
$outfile = Join-Path $toolsfolder -ChildPath $releasearchive |
if (-not $download_required) { |
||||||
Write-Host "Download to: $outfile" |
write-host "Existing zip and zip.minisig ok - download not required" |
||||||
Invoke-WebRequest -Uri $full_uristring -OutFile $outfile |
Write-Host "Signature OK - extracting existing archive ..." |
||||||
|
$null = extractZip $releasearchive $toolsfolder |
||||||
if (-not(Test-Path -Path $outfile -PathType Leaf)) { |
|
||||||
write-Host "Failed to download zig package from $full_uristring to ${outfile} .. aborting download from $uristring" |
$zigexe = Join-Path $zigfolder -ChildPath "zig.exe" |
||||||
continue |
$v = Invoke-Expression "$zigexe version" |
||||||
} |
Write-Host "ZIG VERSION: ${v}" |
||||||
Write-Host "Downloading minisig signature from $sig_uristring" |
exit 0 |
||||||
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" |
$mirrors_url = "https://ziglang.org/download/community-mirrors.txt" |
||||||
continue |
$mirrors_response = $(Invoke-WebRequest -Uri $mirrors_url) |
||||||
} |
if ($mirrors_response.StatusCode -eq 200) { |
||||||
|
#https://www.gitea1.intx.com.au/jn/punkbin/raw/branch/master/win32-x86_64/tools/zig-x86_64-windows-0.15.1.zip |
||||||
write-host "downloaded $outfile and ${outfile}.minisig - validating signature..." |
$mirror_array = @("https://gitea1.intx.com.au/jn/punkbin/raw/branch/master/win32-x86_64/tools") |
||||||
#validate releasearchive (tarball/zip) |
$mirror_array += $mirrors_response.Content.TrimEnd("`r`n") -split "`r`n|`n" |
||||||
$sigresult = minisign -V -P $zigpubkey -m $outfile 2>&1 |
#$mirror_array += "https://bogusxxx.org" #test behaviour of a bogus/down entry |
||||||
$stdout = $sigresult | Where-Object {$_ -is [string]} |
$mirror_array += "https://ziglang.org" #main site |
||||||
$stderr = $sigresult | Where-Object {$_ -is [System.Management.Automation.ErrorRecord]} |
|
||||||
$is_valid = $false |
$dict_mirrors = [ordered]@{} |
||||||
if ($stderr) { |
$host_list = @() #same ordering as dict_mirrors |
||||||
write-host "Signature validation failed with message: $stderr" |
foreach ($mirror in $mirror_array) { |
||||||
} else { |
$uri = New-Object System.Uri($mirror) |
||||||
if (($stdout | Out-String).Contains("signature verified")) { |
$hostname = $uri.Host |
||||||
write-host $stdout |
$dict_mirrors[$hostname] = @{} |
||||||
$is_valid = $true |
$dict_mirrors[$hostname]["uri"] = $mirror |
||||||
} else { |
$dict_mirrors[$hostname]["latency"] = 888888 ;#default |
||||||
write-host "Unexpected output from minisign: $stdout" |
$host_list += $hostname |
||||||
write-host "Did not contain 'signature verified'" |
#write-host "Host name: $hostname" |
||||||
} |
} |
||||||
} |
#write-host "dict: $($dict_mirrors | out-String)" |
||||||
if (-not($is_valid)) { |
write-host "host_list: $host_list" |
||||||
write-Host "Couldn't verify signature from download site $uristring" |
$automation_name = "punkshell+julian@precisium.com.au_target_by_latency" |
||||||
Remove-Item -Path $outfile -ErrorAction SilentlyContinue |
|
||||||
Remove-Item -Path "${outfile}.minisig" -ErrorAction SilentlyContinue |
|
||||||
continue |
#test-netconnection progressbar seems not-so-well-behaved (prog bar lingers) |
||||||
} |
#test-netconnection a function not cmdlet? Seems to need setting at global level |
||||||
|
$OriginalProgressPreference = $Global:ProgressPreference |
||||||
Write-Host "Signature OK - extracting archive ..." |
$Global:ProgressPreference = '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. |
#temporary dev download source |
||||||
# ------------------------------------- |
$ihost = "10.30.30.107" |
||||||
Add-Type -Assembly "System.IO.Compression.Filesystem" |
$imirror = "http://10.30.30.107/jn/punkbin/raw/branch/master/win32-x86_64/tools" |
||||||
[System.IO.Compression.Zipfile]::ExtractToDirectory($outfile, $toolsfolder) |
$itrace = test-netconnection $ihost -Hops 6 -TraceRoute -ErrorAction Ignore |
||||||
Write-Host " - archive extracted." |
if ((${itrace}.PingSucceeded) -and (${itrace}.TraceRoute.Count -lt 5)) { |
||||||
#We *intermittently* get permission errors when trying to rename the resulting folder (possibly also if we try to delete the zip file immediately) |
$host_list += $ihost |
||||||
#There seems to be some sort of lock held after ExtractToDirectory (possibly AV related) |
$dict_mirrors[$ihost] = @{} |
||||||
#https://stackoverflow.com/questions/74582293/file-lock-issues-on-zip-file-after-io-compression-zipfileextracttodirectory |
$dict_mirrors[$ihost]["latency"] = 1 |
||||||
[GC]::Collect() |
$dict_mirrors[$ihost]["uri"] = $imirror |
||||||
[GC]::WaitForPendingFinalizers() |
} |
||||||
# ------------------------------------- |
$trace = test-netconnection gitea1.intx.com.au -Hops 6 -TraceRoute -ErrorAction Ignore |
||||||
|
$Global:ProgressPreference = $OriginalProgressPreference |
||||||
#Remove-Item -Path "$outfile" |
|
||||||
$zip_rootname = [System.IO.Path]::GetFileNameWithoutExtension($releasearchive) |
if ((${trace}.PingSucceeded) -and (${trace}.TraceRoute.Count -lt 5)) { |
||||||
#Rename-Item -Path |
$dict_mirrors["gitea1.intx.com.au"]["latency"] = 2 |
||||||
#write-host "zip_rootname: $zip_rootname" |
#short-circuit for hosts very near gitea1.intx.com.au |
||||||
write-host "moving $(Join-Path -Path $toolsfolder -ChildPath $zip_rootname) to ${zigfolder}" |
#don't even test others. This is primarily for hosts at intx.com.au and associated entities - which are more likely to use punkshell than anyone else. |
||||||
Rename-Item -Path $(Join-Path -Path $toolsfolder -ChildPath $zip_rootname) -NewName $zigfolder |
} else { |
||||||
Write-Host "Zig installed in ${zigfolder}" |
if ($PSVersionTable.PSEdition -eq "Desktop") { |
||||||
$zigexe = Join-Path $zigfolder -ChildPath "zig.exe" |
#powershell.exe |
||||||
$v = Invoke-Expression "$zigexe version" |
#we seem to need -ErrorAction Ignore for bad/unresponsive host entries - but unlike with pwsh, we don't get any corresponding entry in the test_results, and -Quiet doesn't seem to give us results either REVIEW |
||||||
Write-Host "ZIG VERSION: ${v}" |
$test_results = Test-Connection $host_list -Count 1 -ErrorAction Ignore |
||||||
$test_ok = 1 ;#todo |
for ($i = 0; $i -lt $test_results.Count; $i++) { |
||||||
if ($test_ok) { |
$result = $test_results[$i] |
||||||
break |
if ($result) { |
||||||
} |
$targethost = $result.Address |
||||||
} |
if ($result.StatusCode -eq 0) { |
||||||
|
$dict_mirrors[$targethost]["latency"] = $result.ResponseTime |
||||||
} else { |
} else { |
||||||
Write-Host "Unable to retrieve list of zig community mirrors from $mirrors_url" |
$dict_mirrors[$targethost]["latency"] = 999999 |
||||||
} |
} |
||||||
|
} else { |
||||||
|
$targethost = $host_list[$i] |
||||||
|
$dict_mirrors[$targethost]["latency"] = 999999 |
||||||
|
} |
||||||
|
} |
||||||
|
} else { |
||||||
|
#pwsh.exe |
||||||
|
$test_results = Test-Connection -TargetName $host_list -Count 1 -Ipv4 -Detailed -TcpPort 443 -Quiet |
||||||
|
for ($i = 0; $i -lt $test_results.Count; $i++) { |
||||||
|
$result = $test_results[$i] |
||||||
|
if ($result) { |
||||||
|
$targethost = $result.Target |
||||||
|
if ($result.Status -eq "Success") { |
||||||
|
$dict_mirrors[$targethost]["latency"] = $result.Latency |
||||||
|
} else { |
||||||
|
$dict_mirrors[$targethost]["latency"] = 999999 |
||||||
|
} |
||||||
|
} else { |
||||||
|
$targethost = $host_list[$i] |
||||||
|
$dict_mirrors[$targethost]["latency"] = 999999 |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
$list_mirror_dicts = @() |
||||||
|
#write-host "dict tested: $($dict_mirrors | Out-String)" |
||||||
|
foreach ($key in $dict_mirrors.Keys) { |
||||||
|
$list_mirror_dicts += $($dict_mirrors[$key]) |
||||||
|
} |
||||||
|
#need to ensure latency cast to integer (on powershell 5 at least) |
||||||
|
$sorted_mirror_dicts = $list_mirror_dicts | Sort-Object -Property { [int]$_.latency } |
||||||
|
#Write-Host "Sorted by latency: $($sorted_mirror_dicts | Format-Table -AutoSize | Out-String)" |
||||||
|
Write-Host "Sorted by latency: $($sorted_mirror_dicts | Out-String)" |
||||||
|
|
||||||
|
foreach ($hostinfo in $sorted_mirror_dicts) { |
||||||
|
$uristring = $hostinfo.uri |
||||||
|
if ($uristring -eq "https://ziglang.org") { |
||||||
|
$full_uristring = "${uristring}/download/0.15.1/${releasearchive}?source=${automation_name}" |
||||||
|
$sig_uristring = "${uristring}/download/0.15.1/${releasearchive}.minisig?source=${automation_name}" |
||||||
|
} else { |
||||||
|
$full_uristring = "${uristring}/${releasearchive}?source=${automation_name}" |
||||||
|
$sig_uristring = "${uristring}/${releasearchive}.minisig?source=${automation_name}" |
||||||
|
} |
||||||
|
#download the minisig first - because if that fails, we should move on without trying the larger download |
||||||
|
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 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" |
||||||
|
Invoke-WebRequest -Uri $full_uristring -OutFile $outfile |
||||||
|
|
||||||
|
if (-not(Test-Path -Path $outfile -PathType Leaf)) { |
||||||
|
write-Host "Failed to download zig package from $full_uristring to ${outfile} .. aborting download from $uristring" |
||||||
|
continue |
||||||
|
} |
||||||
|
|
||||||
|
write-host "downloaded $outfile and ${outfile}.minisig - validating signature..." |
||||||
|
#validate releasearchive (tarball/zip) |
||||||
|
$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 from download site $uristring" |
||||||
|
Remove-Item -Path $outfile -ErrorAction SilentlyContinue |
||||||
|
Remove-Item -Path "${outfile}.minisig" -ErrorAction SilentlyContinue |
||||||
|
continue |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# ----------------------------------------------------- |
||||||
|
Write-Host "Signature OK - extracting downloaded archive ..." |
||||||
|
$null = extractZip $releasearchive $toolsfolder |
||||||
|
|
||||||
|
$zigexe = Join-Path $zigfolder -ChildPath "zig.exe" |
||||||
|
$v = Invoke-Expression "$zigexe version" |
||||||
|
Write-Host "ZIG VERSION: ${v}" |
||||||
|
|
||||||
|
$test_ok = 1 ;#todo |
||||||
|
if ($test_ok) { |
||||||
|
break |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} else { |
||||||
|
Write-Host "Unable to retrieve list of zig community mirrors from $mirrors_url" |
||||||
|
} |
||||||
@ -1,18 +1,18 @@ |
|||||||
|
|
||||||
#!/bin/sh |
#!/bin/sh |
||||||
echo `# <#` |
echo `# <#` |
||||||
mkdir -p ./zig |
mkdir -p ./zig |
||||||
wget https://ziglang.org/download/0.10.1/zig-linux-x86_64-0.10.1.tar.xz -O ./zig/zig-linux-x86_64-0.10.1.tar.xz |
wget https://ziglang.org/download/0.10.1/zig-linux-x86_64-0.10.1.tar.xz -O ./zig/zig-linux-x86_64-0.10.1.tar.xz |
||||||
tar -xf ./zig/zig-linux-x86_64-0.10.1.tar.xz -C ./zig --strip-components=1 |
tar -xf ./zig/zig-linux-x86_64-0.10.1.tar.xz -C ./zig --strip-components=1 |
||||||
rm ./zig/zig-linux-x86_64-0.10.1.tar.xz |
rm ./zig/zig-linux-x86_64-0.10.1.tar.xz |
||||||
echo "Zig installed." |
echo "Zig installed." |
||||||
./zig/zig version |
./zig/zig version |
||||||
exit |
exit |
||||||
#> > $null |
#> > $null |
||||||
|
|
||||||
Invoke-WebRequest -Uri "https://ziglang.org/download/0.10.1/zig-windows-x86_64-0.10.1.zip" -OutFile ".\zig-windows-x86_64-0.10.1.zip" |
Invoke-WebRequest -Uri "https://ziglang.org/download/0.10.1/zig-windows-x86_64-0.10.1.zip" -OutFile ".\zig-windows-x86_64-0.10.1.zip" |
||||||
Expand-Archive -Path ".\zig-windows-x86_64-0.10.1.zip" -DestinationPath ".\" -Force |
Expand-Archive -Path ".\zig-windows-x86_64-0.10.1.zip" -DestinationPath ".\" -Force |
||||||
Remove-Item -Path " .\zig-windows-x86_64-0.10.1.zip" |
Remove-Item -Path " .\zig-windows-x86_64-0.10.1.zip" |
||||||
Rename-Item -Path ".\zig-windows-x86_64-0.10.1" -NewName ".\zig" |
Rename-Item -Path ".\zig-windows-x86_64-0.10.1" -NewName ".\zig" |
||||||
Write-Host "Zig installed." |
Write-Host "Zig installed." |
||||||
./zig/zig.exe version |
./zig/zig.exe version |
||||||
@ -1,21 +1,21 @@ |
|||||||
|
|
||||||
|
|
||||||
[application] |
[application] |
||||||
template="punk.multishell.cmd" |
template="punk.multishell.cmd" |
||||||
as_admin=false |
as_admin=false |
||||||
|
|
||||||
scripts=[ |
scripts=[ |
||||||
"getzig.ps1", |
"getzig.ps1", |
||||||
"getzig.bash" |
"getzig.bash" |
||||||
] |
] |
||||||
|
|
||||||
default_outputfile="getzig.cmd" |
default_outputfile="getzig.cmd" |
||||||
default_nextshellpath="/usr/bin/env bash" |
default_nextshellpath="/usr/bin/env bash" |
||||||
default_nextshelltype="bash" |
default_nextshelltype="bash" |
||||||
|
|
||||||
#valid nextshelltype entries are: tcl perl pwsh powershell bash. |
#valid nextshelltype entries are: tcl perl pwsh powershell bash. |
||||||
#nextshellpath entries must be 64 characters or less. |
#nextshellpath entries must be 64 characters or less. |
||||||
|
|
||||||
win32.nextshellpath="pwsh -nop -nol -ExecutionPolicy bypass -c" |
win32.nextshellpath="pwsh -nop -nol -ExecutionPolicy bypass -c" |
||||||
win32.nextshelltype="pwsh" |
win32.nextshelltype="pwsh" |
||||||
win32.outputfile="getzig.cmd" |
win32.outputfile="getzig.cmd" |
||||||
@ -1,176 +1,176 @@ |
|||||||
|
|
||||||
#powershell -Command "Invoke-WebRequest -Uri 'https://www.gitea1.intx.com.au/jn/punkshell/raw/branch/master/getpunk.cmd' -OutFile 'getpunk.cmd'; Start-Process 'getpunk.cmd' -NoNewWindow -Wait" |
#powershell -Command "Invoke-WebRequest -Uri 'https://www.gitea1.intx.com.au/jn/punkshell/raw/branch/master/getpunk.cmd' -OutFile 'getpunk.cmd'; Start-Process 'getpunk.cmd' -NoNewWindow -Wait" |
||||||
|
|
||||||
#todo - support either fossil or git |
#todo - support either fossil or git |
||||||
|
|
||||||
#check if git available |
#check if git available |
||||||
#if not, check/install winget, winget git |
#if not, check/install winget, winget git |
||||||
|
|
||||||
$git_upstream = "https://gitea1.intx.com.au/jn/punkshell.git" |
$git_upstream = "https://gitea1.intx.com.au/jn/punkshell.git" |
||||||
$launchdir = Get-Location #store original CWD |
$launchdir = Get-Location #store original CWD |
||||||
$scriptfolder = Resolve-Path (Split-Path -Path $PSCommandPath -Parent) |
$scriptfolder = Resolve-Path (Split-Path -Path $PSCommandPath -Parent) |
||||||
$punkfolder = "" |
$punkfolder = "" |
||||||
$scriptroot = "$([System.IO.Path]::GetFileNameWithoutExtension($PSCommandPath))" |
$scriptroot = "$([System.IO.Path]::GetFileNameWithoutExtension($PSCommandPath))" |
||||||
$env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User") |
$env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User") |
||||||
|
|
||||||
if (-not (Get-Command "git" -ErrorAction SilentlyContinue)) { |
if (-not (Get-Command "git" -ErrorAction SilentlyContinue)) { |
||||||
Write-Host "The git command doesn't seem to be available. Will attempt to install using winget." |
Write-Host "The git command doesn't seem to be available. Will attempt to install using winget." |
||||||
#Find-Module/Install-Module: older mechanism, available in powershell |
#Find-Module/Install-Module: older mechanism, available in powershell |
||||||
#Find-PSResource/Install-PSResource: only available in newer pwsh etc? |
#Find-PSResource/Install-PSResource: only available in newer pwsh etc? |
||||||
$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 -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. |
||||||
#This has risks in that a powershell session started after this call, and before we reset it, will treat PSGallery as trusted |
#This has risks in that a powershell session started after this call, and before we reset it, will treat PSGallery as trusted |
||||||
Set-PSRepository -Name PSGallery -InstallationPolicy Trusted |
Set-PSRepository -Name PSGallery -InstallationPolicy Trusted |
||||||
} |
} |
||||||
Install-Module -Scope CurrentUser -Name Microsoft.Winget.Client -Force -Repository PSGallery |
Install-Module -Scope CurrentUser -Name Microsoft.Winget.Client -Force -Repository PSGallery |
||||||
Repair-WinGetPackageManager |
Repair-WinGetPackageManager |
||||||
import-module -name Microsoft.Winget.client |
import-module -name Microsoft.Winget.client |
||||||
|
|
||||||
if ($psgallery_existing_policy -eq "Untrusted") { |
if ($psgallery_existing_policy -eq "Untrusted") { |
||||||
Set-PSRepository -Name PSGallery -InstallationPolicy Untrusted |
Set-PSRepository -Name PSGallery -InstallationPolicy Untrusted |
||||||
} |
} |
||||||
} else { |
} else { |
||||||
Write-Host "Microsoft.WinGet.Client is available" |
Write-Host "Microsoft.WinGet.Client is available" |
||||||
} |
} |
||||||
$gitversion = (Find-WinGetPackage Git.Git).Version |
$gitversion = (Find-WinGetPackage Git.Git).Version |
||||||
if ($gitversion) { |
if ($gitversion) { |
||||||
Write-Host "Installing git version: ${gitversion}" |
Write-Host "Installing git version: ${gitversion}" |
||||||
Install-WinGetPackage -Id "Git.Git" |
Install-WinGetPackage -Id "Git.Git" |
||||||
} else { |
} else { |
||||||
Write-Host "Failed to find git using winget" |
Write-Host "Failed to find git using winget" |
||||||
exit |
exit |
||||||
} |
} |
||||||
#refreshing the current session's path should make the new command available (required for powershell 5 at least) |
#refreshing the current session's path should make the new command available (required for powershell 5 at least) |
||||||
$env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User") |
$env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User") |
||||||
if (Get-Command "git" -ErrorAction SilentlyContinue) { |
if (Get-Command "git" -ErrorAction SilentlyContinue) { |
||||||
Write-Host "git is now available" |
Write-Host "git is now available" |
||||||
} else { |
} else { |
||||||
Write-Host "git is still not available" |
Write-Host "git is still not available" |
||||||
Write-HOst "Please install Git or relaunch your terminal and check it is available on the path." |
Write-HOst "Please install Git or relaunch your terminal and check it is available on the path." |
||||||
exit |
exit |
||||||
} |
} |
||||||
} |
} |
||||||
|
|
||||||
if (($launchdir.Path) -ne ($scriptfolder.Path)) { |
if (($launchdir.Path) -ne ($scriptfolder.Path)) { |
||||||
Write-Host "The current directory does not seem to be the folder in which the getpunk script is located." |
Write-Host "The current directory does not seem to be the folder in which the getpunk script is located." |
||||||
$answer = Read-Host "Do you want to use the current directory '$($launchdir.Path) as the location for punkshell? Y|N`n Y to use launchdir '$($launchdir.Path)'`n 'N' to use script folder '$($scriptfolder.Path)`n Any other value to abort: " |
$answer = Read-Host "Do you want to use the current directory '$($launchdir.Path) as the location for punkshell? Y|N`n Y to use launchdir '$($launchdir.Path)'`n 'N' to use script folder '$($scriptfolder.Path)`n Any other value to abort: " |
||||||
if ($answer -match "y") { |
if ($answer -match "y") { |
||||||
$punkfolder = $launchdir |
$punkfolder = $launchdir |
||||||
} elseif ($answer -match "n") { |
} elseif ($answer -match "n") { |
||||||
$punkfolder = $scriptfolder |
$punkfolder = $scriptfolder |
||||||
} else { |
} else { |
||||||
exit 1 |
exit 1 |
||||||
} |
} |
||||||
|
|
||||||
} else { |
} else { |
||||||
$punkfolder = $scriptfolder |
$punkfolder = $scriptfolder |
||||||
} |
} |
||||||
$punkfoldercontents = Get-ChildItem -Path $punkfolder -Force #include possibly hidden items such as .git folder |
$punkfoldercontents = Get-ChildItem -Path $punkfolder -Force #include possibly hidden items such as .git folder |
||||||
$contentcount = ( $punkfoldercontents | Measure-Object).Count |
$contentcount = ( $punkfoldercontents | Measure-Object).Count |
||||||
$effectively_empty = 0 |
$effectively_empty = 0 |
||||||
if ($contentcount -eq 0) { |
if ($contentcount -eq 0) { |
||||||
$effectively_empty = 1 |
$effectively_empty = 1 |
||||||
} elseif ($punkfolder -eq $scriptfolder -and $contentcount -lt 10) { |
} elseif ($punkfolder -eq $scriptfolder -and $contentcount -lt 10) { |
||||||
#treat as empty if we have only a few files matching script root name |
#treat as empty if we have only a few files matching script root name |
||||||
$scriptlike = get-childitem -Path $punkfolder | Where-Object {$_.name -like "${scriptroot}.*"} |
$scriptlike = get-childitem -Path $punkfolder | Where-Object {$_.name -like "${scriptroot}.*"} |
||||||
if ($scriptlike.Count -eq $contentcount) { |
if ($scriptlike.Count -eq $contentcount) { |
||||||
$effectively_empty = 1 |
$effectively_empty = 1 |
||||||
} |
} |
||||||
} |
} |
||||||
if (-not($effectively_empty)) { |
if (-not($effectively_empty)) { |
||||||
if (-not(Test-Path -Path (Join-Path -Path $punkfolder -ChildPath ".git") -PathType Container)) { |
if (-not(Test-Path -Path (Join-Path -Path $punkfolder -ChildPath ".git") -PathType Container)) { |
||||||
Write-Host "The folder $punkfolder contains other items, and it does not appear to be a git project root." |
Write-Host "The folder $punkfolder contains other items, and it does not appear to be a git project root." |
||||||
Write-Host "Please place this script in an empty folder which is to be the punkshell base folder." |
Write-Host "Please place this script in an empty folder which is to be the punkshell base folder." |
||||||
exit |
exit |
||||||
} else { |
} else { |
||||||
$repo_origin = git remote get-url origin |
$repo_origin = git remote get-url origin |
||||||
if ($repo_origin -ne $git_upstream) { |
if ($repo_origin -ne $git_upstream) { |
||||||
Write-Host "The current repository origin '$repo_origin' is not the expected upstream '${git_upstream}'" |
Write-Host "The current repository origin '$repo_origin' is not the expected upstream '${git_upstream}'" |
||||||
$answer = Read-Host "Continue anyway? (Y|N)" |
$answer = Read-Host "Continue anyway? (Y|N)" |
||||||
if (-not($answer -match "y")) { |
if (-not($answer -match "y")) { |
||||||
exit 1 |
exit 1 |
||||||
} |
} |
||||||
} |
} |
||||||
} |
} |
||||||
} else { |
} else { |
||||||
#punkfolder is empty, or has just the current script |
#punkfolder is empty, or has just the current script |
||||||
} |
} |
||||||
Set-Location -Path $punkfolder |
Set-Location -Path $punkfolder |
||||||
|
|
||||||
|
|
||||||
if (-not(Test-Path -Path (Join-Path -Path $punkfolder -ChildPath ".git") -PathType Container)) { |
if (-not(Test-Path -Path (Join-Path -Path $punkfolder -ChildPath ".git") -PathType Container)) { |
||||||
git init |
git init |
||||||
git remote add origin $git_upstream |
git remote add origin $git_upstream |
||||||
} |
} |
||||||
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 |
||||||
} |
} |
||||||
} |
} |
||||||
git pull $git_upstream master |
git pull $git_upstream master |
||||||
git checkout "${scriptroot}.cmd" |
git checkout "${scriptroot}.cmd" |
||||||
git branch --set-upstream-to=origin/master master |
git branch --set-upstream-to=origin/master master |
||||||
|
|
||||||
Set-Location $launchdir #restore original CWD |
Set-Location $launchdir #restore original CWD |
||||||
#see also: https://github.com/jdhitsolutions/WTToolbox |
#see also: https://github.com/jdhitsolutions/WTToolbox |
||||||
|
|
||||||
# Define the necessary Win32 API functions and constants |
# Define the necessary Win32 API functions and constants |
||||||
Add-Type -TypeDefinition @" |
Add-Type -TypeDefinition @" |
||||||
using System; |
using System; |
||||||
using System.Runtime.InteropServices; |
using System.Runtime.InteropServices; |
||||||
|
|
||||||
public class WinAPI |
public class WinAPI |
||||||
{ |
{ |
||||||
// Console Input/Output Handles |
// Console Input/Output Handles |
||||||
public const int STD_OUTPUT_HANDLE = -11; |
public const int STD_OUTPUT_HANDLE = -11; |
||||||
public const uint ENABLE_QUICK_EDIT_MODE = 0x0040; |
public const uint ENABLE_QUICK_EDIT_MODE = 0x0040; |
||||||
public const uint ENABLE_EXTENDED_FLAGS = 0x0080; |
public const uint ENABLE_EXTENDED_FLAGS = 0x0080; |
||||||
public const uint ENABLE_MOUSE_INPUT = 0x0010; |
public const uint ENABLE_MOUSE_INPUT = 0x0010; |
||||||
public const uint ENABLE_WINDOW_INPUT = 0x0008; |
public const uint ENABLE_WINDOW_INPUT = 0x0008; |
||||||
public const uint ENABLE_INSERT_MODE = 0x0020; |
public const uint ENABLE_INSERT_MODE = 0x0020; |
||||||
public const uint ENABLE_LINE_INPUT = 0x0002; |
public const uint ENABLE_LINE_INPUT = 0x0002; |
||||||
public const uint ENABLE_ECHO_INPUT = 0x0004; |
public const uint ENABLE_ECHO_INPUT = 0x0004; |
||||||
public const uint ENABLE_PROCESSED_INPUT = 0x0001; |
public const uint ENABLE_PROCESSED_INPUT = 0x0001; |
||||||
|
|
||||||
// Console Modes |
// Console Modes |
||||||
public const uint ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x0004; |
public const uint ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x0004; |
||||||
public const uint DISABLE_NEWLINE_AUTO_RETURN = 0x0008; |
public const uint DISABLE_NEWLINE_AUTO_RETURN = 0x0008; |
||||||
|
|
||||||
[DllImport("kernel32.dll", SetLastError = true)] |
[DllImport("kernel32.dll", SetLastError = true)] |
||||||
public static extern IntPtr GetStdHandle(int nStdHandle); |
public static extern IntPtr GetStdHandle(int nStdHandle); |
||||||
[DllImport("kernel32.dll", SetLastError = true)] |
[DllImport("kernel32.dll", SetLastError = true)] |
||||||
public static extern bool GetConsoleMode(IntPtr hConsoleHandle, out uint lpMode); |
public static extern bool GetConsoleMode(IntPtr hConsoleHandle, out uint lpMode); |
||||||
[DllImport("kernel32.dll", SetLastError = true)] |
[DllImport("kernel32.dll", SetLastError = true)] |
||||||
public static extern bool SetConsoleMode(IntPtr hConsoleHandle, uint dwMode); |
public static extern bool SetConsoleMode(IntPtr hConsoleHandle, uint dwMode); |
||||||
} |
} |
||||||
"@ |
"@ |
||||||
|
|
||||||
# Get the handle to the console output buffer |
# Get the handle to the console output buffer |
||||||
$stdoutHandle = [WinAPI]::GetStdHandle([WinAPI]::STD_OUTPUT_HANDLE) |
$stdoutHandle = [WinAPI]::GetStdHandle([WinAPI]::STD_OUTPUT_HANDLE) |
||||||
|
|
||||||
# Get the current console mode |
# Get the current console mode |
||||||
[uint32]$currentMode = 0 |
[uint32]$currentMode = 0 |
||||||
if (![WinAPI]::GetConsoleMode($stdoutHandle, [ref]$currentMode)) { |
if (![WinAPI]::GetConsoleMode($stdoutHandle, [ref]$currentMode)) { |
||||||
Write-Error "Failed to get console mode. Error code: $($LAST_ERROR)" |
Write-Error "Failed to get console mode. Error code: $($LAST_ERROR)" |
||||||
return |
return |
||||||
} |
} |
||||||
|
|
||||||
# Enable virtual terminal processing |
# Enable virtual terminal processing |
||||||
$newMode = $currentMode -bor [WinAPI]::ENABLE_VIRTUAL_TERMINAL_PROCESSING |
$newMode = $currentMode -bor [WinAPI]::ENABLE_VIRTUAL_TERMINAL_PROCESSING |
||||||
|
|
||||||
# Set the new console mode |
# Set the new console mode |
||||||
if (-not [WinAPI]::SetConsoleMode($stdoutHandle, $newMode)) { |
if (-not [WinAPI]::SetConsoleMode($stdoutHandle, $newMode)) { |
||||||
Write-Error "Failed to set console mode. Error code: $($LAST_ERROR)" |
Write-Error "Failed to set console mode. Error code: $($LAST_ERROR)" |
||||||
return |
return |
||||||
} |
} |
||||||
|
|
||||||
Write-Host "Virtual terminal processing enabled successfully." |
Write-Host "Virtual terminal processing enabled successfully." |
||||||
|
|
||||||
write-host "`e[92m getpunk done `e[m" |
write-host "`e[92m getpunk done `e[m" |
||||||
|
|||||||
@ -1,23 +1,23 @@ |
|||||||
|
|
||||||
[application] |
[application] |
||||||
template="punk.multishell.cmd" |
template="punk.multishell.cmd" |
||||||
as_admin=false |
as_admin=false |
||||||
|
|
||||||
scripts=[ |
scripts=[ |
||||||
"getpunk.ps1", |
"getpunk.ps1", |
||||||
"getpunk.bash" |
"getpunk.bash" |
||||||
] |
] |
||||||
|
|
||||||
default_outputfile="getpunk.cmd" |
default_outputfile="getpunk.cmd" |
||||||
default_nextshellpath="/usr/bin/env bash" |
default_nextshellpath="/usr/bin/env bash" |
||||||
default_nextshelltype="bash" |
default_nextshelltype="bash" |
||||||
|
|
||||||
#valid nextshelltype entries are: tcl perl powershell bash. |
#valid nextshelltype entries are: tcl perl powershell bash. |
||||||
#nextshellpath entries must be 128 characters or less. |
#nextshellpath entries must be 128 characters or less. |
||||||
|
|
||||||
#win32.nextshellpath="pwsh -nop -nol -ExecutionPolicy bypass -File" |
#win32.nextshellpath="pwsh -nop -nol -ExecutionPolicy bypass -File" |
||||||
#win32.nextshelltype="pwsh" |
#win32.nextshelltype="pwsh" |
||||||
|
|
||||||
win32.nextshellpath="cmd.exe /c powershell -nop -nol -ExecutionPolicy ByPass -File" |
win32.nextshellpath="cmd.exe /c powershell -nop -nol -ExecutionPolicy ByPass -File" |
||||||
win32.nextshelltype="powershell" |
win32.nextshelltype="powershell" |
||||||
win32.outputfile="getpunk.cmd" |
win32.outputfile="getpunk.cmd" |
||||||
|
|||||||
@ -1,416 +1,416 @@ |
|||||||
|
|
||||||
|
|
||||||
function GetDynamicParamDictionary { |
function GetDynamicParamDictionary { |
||||||
[CmdletBinding()] |
[CmdletBinding()] |
||||||
param( |
param( |
||||||
[Parameter(ValueFromPipeline=$true, Mandatory=$true)] |
[Parameter(ValueFromPipeline=$true, Mandatory=$true)] |
||||||
[string] $CommandName |
[string] $CommandName |
||||||
) |
) |
||||||
|
|
||||||
begin { |
begin { |
||||||
# Get a list of params that should be ignored (they're common to all advanced functions) |
# Get a list of params that should be ignored (they're common to all advanced functions) |
||||||
$CommonParameterNames = [System.Runtime.Serialization.FormatterServices]::GetUninitializedObject([type] [System.Management.Automation.Internal.CommonParameters]) | |
$CommonParameterNames = [System.Runtime.Serialization.FormatterServices]::GetUninitializedObject([type] [System.Management.Automation.Internal.CommonParameters]) | |
||||||
Get-Member -MemberType Properties | |
Get-Member -MemberType Properties | |
||||||
Select-Object -ExpandProperty Name |
Select-Object -ExpandProperty Name |
||||||
} |
} |
||||||
|
|
||||||
process { |
process { |
||||||
# Create the dictionary that this scriptblock will return: |
# Create the dictionary that this scriptblock will return: |
||||||
$DynParamDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary |
$DynParamDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary |
||||||
|
|
||||||
# Convert to object array and get rid of Common params: |
# Convert to object array and get rid of Common params: |
||||||
(Get-Command $CommandName | Select-Object -exp Parameters).GetEnumerator() | |
(Get-Command $CommandName | Select-Object -exp Parameters).GetEnumerator() | |
||||||
Where-Object { $CommonParameterNames -notcontains $_.Key } | |
Where-Object { $CommonParameterNames -notcontains $_.Key } | |
||||||
ForEach-Object { |
ForEach-Object { |
||||||
$DynamicParameter = New-Object System.Management.Automation.RuntimeDefinedParameter ( |
$DynamicParameter = New-Object System.Management.Automation.RuntimeDefinedParameter ( |
||||||
$_.Key, |
$_.Key, |
||||||
$_.Value.ParameterType, |
$_.Value.ParameterType, |
||||||
$_.Value.Attributes |
$_.Value.Attributes |
||||||
) |
) |
||||||
$DynParamDictionary.Add($_.Key, $DynamicParameter) |
$DynParamDictionary.Add($_.Key, $DynamicParameter) |
||||||
} |
} |
||||||
|
|
||||||
# Return the dynamic parameters |
# Return the dynamic parameters |
||||||
return $DynParamDictionary |
return $DynParamDictionary |
||||||
} |
} |
||||||
} |
} |
||||||
function ParameterDefinitions { |
function ParameterDefinitions { |
||||||
param( |
param( |
||||||
[Parameter(ValueFromRemainingArguments=$true,Position = 1)][string[]] $opts |
[Parameter(ValueFromRemainingArguments=$true,Position = 1)][string[]] $opts |
||||||
) |
) |
||||||
} |
} |
||||||
|
|
||||||
function psmain { |
function psmain { |
||||||
[CmdletBinding()] |
[CmdletBinding()] |
||||||
#Empty param block (extra params can be added) |
#Empty param block (extra params can be added) |
||||||
param( |
param( |
||||||
[Parameter(Mandatory=$false, Position = 0)][string] $action = "" |
[Parameter(Mandatory=$false, Position = 0)][string] $action = "" |
||||||
) |
) |
||||||
dynamicparam { |
dynamicparam { |
||||||
if ($action -eq 'list') { |
if ($action -eq 'list') { |
||||||
$parameterAttribute = [System.Management.Automation.ParameterAttribute]@{ |
$parameterAttribute = [System.Management.Automation.ParameterAttribute]@{ |
||||||
ParameterSetName = "listruntime" |
ParameterSetName = "listruntime" |
||||||
Mandatory = $false |
Mandatory = $false |
||||||
} |
} |
||||||
$attributeCollection = [System.Collections.ObjectModel.Collection[System.Attribute]]::new() |
$attributeCollection = [System.Collections.ObjectModel.Collection[System.Attribute]]::new() |
||||||
$attributeCollection.Add($parameterAttribute) |
$attributeCollection.Add($parameterAttribute) |
||||||
$dynParam1 = [System.Management.Automation.RuntimeDefinedParameter]::new( |
$dynParam1 = [System.Management.Automation.RuntimeDefinedParameter]::new( |
||||||
'remote', [switch], $attributeCollection |
'remote', [switch], $attributeCollection |
||||||
) |
) |
||||||
$paramDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new() |
$paramDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new() |
||||||
$paramDictionary.Add('remote', $dynParam1) |
$paramDictionary.Add('remote', $dynParam1) |
||||||
return $paramDictionary |
return $paramDictionary |
||||||
} elseif ($action -eq 'fetch') { |
} elseif ($action -eq 'fetch') { |
||||||
#GetDynamicParamDictionary ParameterDefinitions |
#GetDynamicParamDictionary ParameterDefinitions |
||||||
$parameterAttribute = [System.Management.Automation.ParameterAttribute]@{ |
$parameterAttribute = [System.Management.Automation.ParameterAttribute]@{ |
||||||
ParameterSetName = "fetchruntime" |
ParameterSetName = "fetchruntime" |
||||||
Mandatory = $false |
Mandatory = $false |
||||||
Position = 1 |
Position = 1 |
||||||
} |
} |
||||||
$attributeCollection = [System.Collections.ObjectModel.Collection[System.Attribute]]::new() |
$attributeCollection = [System.Collections.ObjectModel.Collection[System.Attribute]]::new() |
||||||
$attributeCollection.Add($parameterAttribute) |
$attributeCollection.Add($parameterAttribute) |
||||||
|
|
||||||
$dynParam1 = [System.Management.Automation.RuntimeDefinedParameter]::new( |
$dynParam1 = [System.Management.Automation.RuntimeDefinedParameter]::new( |
||||||
'runtime', [string], $attributeCollection |
'runtime', [string], $attributeCollection |
||||||
) |
) |
||||||
|
|
||||||
$paramDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new() |
$paramDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new() |
||||||
$paramDictionary.Add('runtime', $dynParam1) |
$paramDictionary.Add('runtime', $dynParam1) |
||||||
return $paramDictionary |
return $paramDictionary |
||||||
} elseif ($action -eq 'run') { |
} elseif ($action -eq 'run') { |
||||||
#GetDynamicParamDictionary ParameterDefinitions |
#GetDynamicParamDictionary ParameterDefinitions |
||||||
$parameterAttribute = [System.Management.Automation.ParameterAttribute]@{ |
$parameterAttribute = [System.Management.Automation.ParameterAttribute]@{ |
||||||
ParameterSetName = "runargs" |
ParameterSetName = "runargs" |
||||||
Mandatory = $false |
Mandatory = $false |
||||||
ValueFromRemainingArguments = $true |
ValueFromRemainingArguments = $true |
||||||
} |
} |
||||||
$attributeCollection = [System.Collections.ObjectModel.Collection[System.Attribute]]::new() |
$attributeCollection = [System.Collections.ObjectModel.Collection[System.Attribute]]::new() |
||||||
$attributeCollection.Add($parameterAttribute) |
$attributeCollection.Add($parameterAttribute) |
||||||
|
|
||||||
$dynParam1 = [System.Management.Automation.RuntimeDefinedParameter]::new( |
$dynParam1 = [System.Management.Automation.RuntimeDefinedParameter]::new( |
||||||
'opts', [string[]], $attributeCollection |
'opts', [string[]], $attributeCollection |
||||||
) |
) |
||||||
|
|
||||||
$paramDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new() |
$paramDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new() |
||||||
$paramDictionary.Add('opts', $dynParam1) |
$paramDictionary.Add('opts', $dynParam1) |
||||||
return $paramDictionary |
return $paramDictionary |
||||||
} else { |
} else { |
||||||
#accept all args when action is unrecognised - so we can go to help anyway |
#accept all args when action is unrecognised - so we can go to help anyway |
||||||
$parameterAttribute = [System.Management.Automation.ParameterAttribute]@{ |
$parameterAttribute = [System.Management.Automation.ParameterAttribute]@{ |
||||||
ParameterSetName = "invalidaction" |
ParameterSetName = "invalidaction" |
||||||
Mandatory = $false |
Mandatory = $false |
||||||
ValueFromRemainingArguments = $true |
ValueFromRemainingArguments = $true |
||||||
} |
} |
||||||
$attributeCollection = [System.Collections.ObjectModel.Collection[System.Attribute]]::new() |
$attributeCollection = [System.Collections.ObjectModel.Collection[System.Attribute]]::new() |
||||||
$attributeCollection.Add($parameterAttribute) |
$attributeCollection.Add($parameterAttribute) |
||||||
|
|
||||||
$dynParam1 = [System.Management.Automation.RuntimeDefinedParameter]::new( |
$dynParam1 = [System.Management.Automation.RuntimeDefinedParameter]::new( |
||||||
'opts', [string[]], $attributeCollection |
'opts', [string[]], $attributeCollection |
||||||
) |
) |
||||||
|
|
||||||
$paramDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new() |
$paramDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new() |
||||||
$paramDictionary.Add('opts', $dynParam1) |
$paramDictionary.Add('opts', $dynParam1) |
||||||
return $paramDictionary |
return $paramDictionary |
||||||
} |
} |
||||||
} |
} |
||||||
process { |
process { |
||||||
#Called once - we get a single item being our PSBoundParameters dictionary |
#Called once - we get a single item being our PSBoundParameters dictionary |
||||||
#write-host "Bound Parameters:$($PSBoundParameters.Keys)" |
#write-host "Bound Parameters:$($PSBoundParameters.Keys)" |
||||||
switch ($PSBoundParameters.keys) { |
switch ($PSBoundParameters.keys) { |
||||||
'action' { |
'action' { |
||||||
write-host "got action " $PSBoundParameters.action |
write-host "got action " $PSBoundParameters.action |
||||||
Set-Variable -Name $_ -Value $PSBoundParameters."$_" |
Set-Variable -Name $_ -Value $PSBoundParameters."$_" |
||||||
$known_actions = @("fetch", "list", "run") |
$known_actions = @("fetch", "list", "run") |
||||||
if (-not($known_actions -contains $action)) { |
if (-not($known_actions -contains $action)) { |
||||||
write-host "fetch '$action' not understood. Known_actions: $known_actions" |
write-host "fetch '$action' not understood. Known_actions: $known_actions" |
||||||
exit 1 |
exit 1 |
||||||
} |
} |
||||||
} |
} |
||||||
'opts' { |
'opts' { |
||||||
# write-warning "Unused parameters: $($PSBoundParameters.$_)" |
# write-warning "Unused parameters: $($PSBoundParameters.$_)" |
||||||
} |
} |
||||||
Default { |
Default { |
||||||
# write-warning "Unhandled parameter -> [$($_)]" |
# write-warning "Unhandled parameter -> [$($_)]" |
||||||
} |
} |
||||||
} |
} |
||||||
#foreach ($boundparam in $PSBoundParameters.Keys) { |
#foreach ($boundparam in $PSBoundParameters.Keys) { |
||||||
# write-host "k: $boundparam" |
# write-host "k: $boundparam" |
||||||
#} |
#} |
||||||
} |
} |
||||||
end { |
end { |
||||||
# PSBoundParameters |
# PSBoundParameters |
||||||
#write-host "action:'$action'" |
#write-host "action:'$action'" |
||||||
$outbase = $PSScriptRoot |
$outbase = $PSScriptRoot |
||||||
$outbase = Resolve-Path -Path $outbase |
$outbase = Resolve-Path -Path $outbase |
||||||
#expected script location is the bin folder of a punk project |
#expected script location is the bin folder of a punk project |
||||||
$rtfolder = Join-Path -Path $outbase -ChildPath "runtime" |
$rtfolder = Join-Path -Path $outbase -ChildPath "runtime" |
||||||
#Binary artifact server url. (git is not ideal for this - but will do for now - todo - use artifact system within gitea?) |
#Binary artifact server url. (git is not ideal for this - but will do for now - todo - use artifact system within gitea?) |
||||||
$artifacturl = "https://www.gitea1.intx.com.au/jn/punkbin/raw/branch/master" |
$artifacturl = "https://www.gitea1.intx.com.au/jn/punkbin/raw/branch/master" |
||||||
switch ($action) { |
switch ($action) { |
||||||
'fetch' { |
'fetch' { |
||||||
$arch = "win32-x86_64" |
$arch = "win32-x86_64" |
||||||
$archfolder = Join-Path -Path $rtfolder -ChildPath "$arch" |
$archfolder = Join-Path -Path $rtfolder -ChildPath "$arch" |
||||||
$archurl = "$artifacturl/$arch" |
$archurl = "$artifacturl/$arch" |
||||||
$sha1url = "$archurl/sha1sums.txt" |
$sha1url = "$archurl/sha1sums.txt" |
||||||
$runtime = "tclsh902z.exe" |
$runtime = "tclsh902z.exe" |
||||||
foreach ($boundparam in $PSBoundParameters.Keys) { |
foreach ($boundparam in $PSBoundParameters.Keys) { |
||||||
write-host "fetchopt: $boundparam $($PSBoundParameters[$boundparam])" |
write-host "fetchopt: $boundparam $($PSBoundParameters[$boundparam])" |
||||||
} |
} |
||||||
if ( $PSBoundParameters["runtime"].Length ) { |
if ( $PSBoundParameters["runtime"].Length ) { |
||||||
$runtime = $PSBoundParameters["runtime"] |
$runtime = $PSBoundParameters["runtime"] |
||||||
} |
} |
||||||
$fileurl = "$archurl/$runtime" |
$fileurl = "$archurl/$runtime" |
||||||
|
|
||||||
$output = join-path -Path $archfolder -ChildPath $runtime |
$output = join-path -Path $archfolder -ChildPath $runtime |
||||||
$sha1local = join-path -Path $archfolder -ChildPath "sha1sums.txt" |
$sha1local = join-path -Path $archfolder -ChildPath "sha1sums.txt" |
||||||
|
|
||||||
$container = split-path -Path $output -Parent |
$container = split-path -Path $output -Parent |
||||||
new-item -Path $container -ItemType Directory -force #create with intermediary folders if not already present |
new-item -Path $container -ItemType Directory -force #create with intermediary folders if not already present |
||||||
|
|
||||||
try { |
try { |
||||||
Write-Host "Fetching $sha1url" |
Write-Host "Fetching $sha1url" |
||||||
Invoke-WebRequest -Uri $sha1url -OutFile $sha1local -ErrorAction Stop |
Invoke-WebRequest -Uri $sha1url -OutFile $sha1local -ErrorAction Stop |
||||||
Write-Host "sha1 saved at $sha1local" |
Write-Host "sha1 saved at $sha1local" |
||||||
} catch { |
} catch { |
||||||
Write-Host "An error occurred while downloading ${sha1url}: $($_.Exception.Message)" |
Write-Host "An error occurred while downloading ${sha1url}: $($_.Exception.Message)" |
||||||
if ($_.Exception.Response) { |
if ($_.Exception.Response) { |
||||||
Write-Host "HTTP Status code: $($_.Exception.Response.StatusCode)" |
Write-Host "HTTP Status code: $($_.Exception.Response.StatusCode)" |
||||||
} |
} |
||||||
} |
} |
||||||
if (Test-Path -Path $sha1local -PathType Leaf) { |
if (Test-Path -Path $sha1local -PathType Leaf) { |
||||||
$sha1Content = Get-Content -Path $sha1local |
$sha1Content = Get-Content -Path $sha1local |
||||||
$stored_sha1 = "" |
$stored_sha1 = "" |
||||||
foreach ($line in $sha1Content) { |
foreach ($line in $sha1Content) { |
||||||
#all sha1sums have * (binary indicator) - review |
#all sha1sums have * (binary indicator) - review |
||||||
$match = [regex]::Match($line,"(.*) [*]${runtime}$") |
$match = [regex]::Match($line,"(.*) [*]${runtime}$") |
||||||
if ($match.Success) { |
if ($match.Success) { |
||||||
$stored_sha1 = $match.Groups[1].Value |
$stored_sha1 = $match.Groups[1].Value |
||||||
Write-host "stored hash from sha1sums.txt: $storedhash" |
Write-host "stored hash from sha1sums.txt: $storedhash" |
||||||
break |
break |
||||||
} |
} |
||||||
} |
} |
||||||
if ($stored_sha1 -eq "") { |
if ($stored_sha1 -eq "") { |
||||||
Write-Host "Unable to locate hash for $runtime in $sha1local - Aborting" |
Write-Host "Unable to locate hash for $runtime in $sha1local - Aborting" |
||||||
Write-Host "Please download and verify manually" |
Write-Host "Please download and verify manually" |
||||||
return |
return |
||||||
} |
} |
||||||
|
|
||||||
$need_download = $false |
$need_download = $false |
||||||
if (Test-Path -Path $output -PathType Leaf) { |
if (Test-Path -Path $output -PathType Leaf) { |
||||||
Write-Host "Runtime already found at $output" |
Write-Host "Runtime already found at $output" |
||||||
Write-Host "Checking sha1 checksum of local file versus sha1 of server file" |
Write-Host "Checking sha1 checksum of local file versus sha1 of server file" |
||||||
$file_sha1 = Get-FileHash -Path "$output" -Algorithm SHA1 |
$file_sha1 = Get-FileHash -Path "$output" -Algorithm SHA1 |
||||||
if (${file_sha1}.Hash -ne $stored_sha1) { |
if (${file_sha1}.Hash -ne $stored_sha1) { |
||||||
Write-Host "$runtime on server has different sha1 hash - Download required" |
Write-Host "$runtime on server has different sha1 hash - Download required" |
||||||
$need_download = $true |
$need_download = $true |
||||||
} |
} |
||||||
} else { |
} else { |
||||||
Write-Host "$runtime not found locally - Download required" |
Write-Host "$runtime not found locally - Download required" |
||||||
$need_download = $true |
$need_download = $true |
||||||
} |
} |
||||||
|
|
||||||
if ($need_download) { |
if ($need_download) { |
||||||
Write-Host "Downloading from $fileurl ..." |
Write-Host "Downloading from $fileurl ..." |
||||||
try { |
try { |
||||||
Invoke-WebRequest -Uri $fileurl -OutFile "${output}.tmp" -ErrorAction Stop |
Invoke-WebRequest -Uri $fileurl -OutFile "${output}.tmp" -ErrorAction Stop |
||||||
Write-Host "Runtime saved at $output.tmp" |
Write-Host "Runtime saved at $output.tmp" |
||||||
} |
} |
||||||
catch { |
catch { |
||||||
Write-Host "An error occurred while downloading $fileurl $($_.Exception.Message)" |
Write-Host "An error occurred while downloading $fileurl $($_.Exception.Message)" |
||||||
if ($_.Exception.Response) { |
if ($_.Exception.Response) { |
||||||
Write-Host "HTTP Status code: $($_.Exception.Response.StatusCode)" |
Write-Host "HTTP Status code: $($_.Exception.Response.StatusCode)" |
||||||
} |
} |
||||||
return |
return |
||||||
} |
} |
||||||
Write-Host "comparing sha1 checksum of downloaded file with data in sha1sums.txt" |
Write-Host "comparing sha1 checksum of downloaded file with data in sha1sums.txt" |
||||||
Start-Sleep -Seconds 1 #REVIEW - give at least some time for windows to do its thing? (av filters?) |
Start-Sleep -Seconds 1 #REVIEW - give at least some time for windows to do its thing? (av filters?) |
||||||
$newfile_sha1 = Get-FileHash -Path "${output}.tmp" -Algorithm SHA1 |
$newfile_sha1 = Get-FileHash -Path "${output}.tmp" -Algorithm SHA1 |
||||||
if (${newfile_sha1}.Hash -eq $stored_sha1) { |
if (${newfile_sha1}.Hash -eq $stored_sha1) { |
||||||
Write-Host "sha1 checksum ok" |
Write-Host "sha1 checksum ok" |
||||||
Move-Item -Path "${output}.tmp" -Destination "${output}" -Force |
Move-Item -Path "${output}.tmp" -Destination "${output}" -Force |
||||||
Write-Host "Runtime is available at ${output}" |
Write-Host "Runtime is available at ${output}" |
||||||
} else { |
} else { |
||||||
Write-Host "WARNING! sha1 of downloaded file at $output.tmp does not match stored sha1 from sha1sums.txt" |
Write-Host "WARNING! sha1 of downloaded file at $output.tmp does not match stored sha1 from sha1sums.txt" |
||||||
return |
return |
||||||
} |
} |
||||||
} else { |
} else { |
||||||
Write-Host "Local copy of runtime at $output seems to match sha1 checksum of file on server." |
Write-Host "Local copy of runtime at $output seems to match sha1 checksum of file on server." |
||||||
Write-Host "No download required" |
Write-Host "No download required" |
||||||
} |
} |
||||||
} else { |
} else { |
||||||
Write-Host "Unable to consult local copy of sha1sums.txt at $sha1local" |
Write-Host "Unable to consult local copy of sha1sums.txt at $sha1local" |
||||||
if (Test-Path -Path $output -PathType Leaf) { |
if (Test-Path -Path $output -PathType Leaf) { |
||||||
Write-Host "A runtime is available at $output - but we failed to retrieve the list of sha1sums from the server" |
Write-Host "A runtime is available at $output - but we failed to retrieve the list of sha1sums from the server" |
||||||
Write-Host "Unable to check for updated version at this time." |
Write-Host "Unable to check for updated version at this time." |
||||||
} else { |
} else { |
||||||
Write-Host "Please retry - or manually download a runtime from $archurl and verify checksums" |
Write-Host "Please retry - or manually download a runtime from $archurl and verify checksums" |
||||||
} |
} |
||||||
} |
} |
||||||
} |
} |
||||||
'run' { |
'run' { |
||||||
#select first (or configured default) runtime and launch, passing arguments |
#select first (or configured default) runtime and launch, passing arguments |
||||||
$arch = "win32-x86_64" |
$arch = "win32-x86_64" |
||||||
$archfolder = Join-Path -Path $rtfolder -ChildPath "$arch" |
$archfolder = Join-Path -Path $rtfolder -ChildPath "$arch" |
||||||
if (-not(Test-Path -Path $archfolder -PathType Container)) { |
if (-not(Test-Path -Path $archfolder -PathType Container)) { |
||||||
write-host "No runtimes seem to be installed for $arch`nPlease use 'runtime.cmd fetch' to install" |
write-host "No runtimes seem to be installed for $arch`nPlease use 'runtime.cmd fetch' to install" |
||||||
} else { |
} else { |
||||||
$dircontents = (get-childItem -Path $archfolder -File | Sort-Object Name) |
$dircontents = (get-childItem -Path $archfolder -File | Sort-Object Name) |
||||||
if ($dircontents.Count -gt 0) { |
if ($dircontents.Count -gt 0) { |
||||||
#write-host "run.." |
#write-host "run.." |
||||||
write-host "num params: $($PSBoundParameters.opts.count)" |
write-host "num params: $($PSBoundParameters.opts.count)" |
||||||
|
|
||||||
#todo - use 'active' runtime - need to lookup (PSToml?) |
#todo - use 'active' runtime - need to lookup (PSToml?) |
||||||
#when no 'active' runtime for this os-arch - use last item (sorted in dictionary order) |
#when no 'active' runtime for this os-arch - use last item (sorted in dictionary order) |
||||||
$active = $dircontents[-1].FullName |
$active = $dircontents[-1].FullName |
||||||
write-host "using: $active" |
write-host "using: $active" |
||||||
if ($PSBoundParameters.opts.Length -gt 0) { |
if ($PSBoundParameters.opts.Length -gt 0) { |
||||||
$optsType = $PSBoundParameters.opts.GetType() #method can only be called if .opts is not null |
$optsType = $PSBoundParameters.opts.GetType() #method can only be called if .opts is not null |
||||||
write-host "type of opts: $($optsType.FullName)" |
write-host "type of opts: $($optsType.FullName)" |
||||||
foreach ($boundparam in $PSBoundParameters.opts) { |
foreach ($boundparam in $PSBoundParameters.opts) { |
||||||
write-host $boundparam |
write-host $boundparam |
||||||
} |
} |
||||||
Write-Host "opts: $($PSBoundParameters.opts)" |
Write-Host "opts: $($PSBoundParameters.opts)" |
||||||
Write-Host "args: $args" |
Write-Host "args: $args" |
||||||
Write-HOst "argscount: $($args.Count)" |
Write-HOst "argscount: $($args.Count)" |
||||||
$arglist = @() |
$arglist = @() |
||||||
foreach ($o in $PSBoundParameters.opts) { |
foreach ($o in $PSBoundParameters.opts) { |
||||||
$oquoted = $o -replace '"', "`\`"" |
$oquoted = $o -replace '"', "`\`"" |
||||||
#$oquoted = $oquoted -replace "'", "`'" |
#$oquoted = $oquoted -replace "'", "`'" |
||||||
if ($oquoted -match "\s") { |
if ($oquoted -match "\s") { |
||||||
$oquoted = "`"$oquoted`"" |
$oquoted = "`"$oquoted`"" |
||||||
} |
} |
||||||
$arglist += @($oquoted) |
$arglist += @($oquoted) |
||||||
} |
} |
||||||
$arglist = $arglist.TrimEnd(' ') |
$arglist = $arglist.TrimEnd(' ') |
||||||
write-host "arglist: $arglist" |
write-host "arglist: $arglist" |
||||||
#$arglist = $PSBoundParameters.opts |
#$arglist = $PSBoundParameters.opts |
||||||
Start-Process -FilePath $active -ArgumentList $arglist -NoNewWindow -Wait |
Start-Process -FilePath $active -ArgumentList $arglist -NoNewWindow -Wait |
||||||
} else { |
} else { |
||||||
#powershell 5.1 and earlier can't accept an empty -ArgumentList value :/ !! |
#powershell 5.1 and earlier can't accept an empty -ArgumentList value :/ !! |
||||||
#$arglist = @() |
#$arglist = @() |
||||||
#Start-Process -FilePath $active -ArgumentList $arglist -NoNewWindow -Wait |
#Start-Process -FilePath $active -ArgumentList $arglist -NoNewWindow -Wait |
||||||
#Start-Process -FilePath $active -ArgumentList "" -NoNewWindow -Wait |
#Start-Process -FilePath $active -ArgumentList "" -NoNewWindow -Wait |
||||||
Start-Process -FilePath $active -NoNewWindow -Wait |
Start-Process -FilePath $active -NoNewWindow -Wait |
||||||
} |
} |
||||||
} else { |
} else { |
||||||
write-host "No files found in $archfolder" |
write-host "No files found in $archfolder" |
||||||
write-host "No runtimes seem to be installed for $arch`nPlease use 'runtime.cmd fetch' to install." |
write-host "No runtimes seem to be installed for $arch`nPlease use 'runtime.cmd fetch' to install." |
||||||
} |
} |
||||||
} |
} |
||||||
} |
} |
||||||
'list' { |
'list' { |
||||||
#todo - option to list for other os-arch |
#todo - option to list for other os-arch |
||||||
$arch = 'win32-x86_64' |
$arch = 'win32-x86_64' |
||||||
$archfolder = Join-Path -Path $rtfolder -ChildPath "$arch" |
$archfolder = Join-Path -Path $rtfolder -ChildPath "$arch" |
||||||
$sha1local = join-path -Path $archfolder -ChildPath "sha1sums.txt" |
$sha1local = join-path -Path $archfolder -ChildPath "sha1sums.txt" |
||||||
$archurl = "$artifacturl/$arch" |
$archurl = "$artifacturl/$arch" |
||||||
$sha1url = "$archurl/sha1sums.txt" |
$sha1url = "$archurl/sha1sums.txt" |
||||||
if ( $PSBoundParameters.ContainsKey('remote') ) { |
if ( $PSBoundParameters.ContainsKey('remote') ) { |
||||||
if (-not (test-path -Path $archfolder -Type Container)) { |
if (-not (test-path -Path $archfolder -Type Container)) { |
||||||
new-item -Path $container -ItemType Directory -force #create with intermediary folders if not already present |
new-item -Path $container -ItemType Directory -force #create with intermediary folders if not already present |
||||||
} |
} |
||||||
write-host "Checking for available remote runtimes for" |
write-host "Checking for available remote runtimes for" |
||||||
Write-Host "Fetching $sha1url" |
Write-Host "Fetching $sha1url" |
||||||
Invoke-WebRequest -Uri $sha1url -OutFile $sha1local -ErrorAction Stop |
Invoke-WebRequest -Uri $sha1url -OutFile $sha1local -ErrorAction Stop |
||||||
Write-Host "sha1 saved at $sha1local" |
Write-Host "sha1 saved at $sha1local" |
||||||
$sha1Content = Get-Content -Path $sha1local |
$sha1Content = Get-Content -Path $sha1local |
||||||
$remotedict = @{} |
$remotedict = @{} |
||||||
foreach ($line in $sha1Content) { |
foreach ($line in $sha1Content) { |
||||||
#all sha1sums have * (binary indicator) - review |
#all sha1sums have * (binary indicator) - review |
||||||
$match = [regex]::Match($line,"(.*) [*](.*)$") |
$match = [regex]::Match($line,"(.*) [*](.*)$") |
||||||
if ($match.Success) { |
if ($match.Success) { |
||||||
$server_sha1 = $match.Groups[1].Value |
$server_sha1 = $match.Groups[1].Value |
||||||
$server_rt = $match.Groups[2].Value |
$server_rt = $match.Groups[2].Value |
||||||
$remotedict[$server_rt] = $server_sha1 |
$remotedict[$server_rt] = $server_sha1 |
||||||
} |
} |
||||||
} |
} |
||||||
|
|
||||||
$localdict = @{} |
$localdict = @{} |
||||||
if (test-path -Path $archfolder -Type Container) { |
if (test-path -Path $archfolder -Type Container) { |
||||||
$dircontents = (get-childItem -Path $archfolder -File | Where-object {-not ($(".txt",".tm") -contains $_.Extension) }) |
$dircontents = (get-childItem -Path $archfolder -File | Where-object {-not ($(".txt",".tm") -contains $_.Extension) }) |
||||||
foreach ($f in $dircontents) { |
foreach ($f in $dircontents) { |
||||||
$local_sha1 = Get-FileHash -Path $(${f}.FullName) -Algorithm SHA1 |
$local_sha1 = Get-FileHash -Path $(${f}.FullName) -Algorithm SHA1 |
||||||
$localdict[$f.Name] = ${local_sha1}.Hash |
$localdict[$f.Name] = ${local_sha1}.Hash |
||||||
} |
} |
||||||
} |
} |
||||||
|
|
||||||
Write-host "-----------------------------------------------------------------------" |
Write-host "-----------------------------------------------------------------------" |
||||||
Write-host "Runtimes for $arch" |
Write-host "Runtimes for $arch" |
||||||
Write-host "Local $archfolder" |
Write-host "Local $archfolder" |
||||||
Write-host "Remote $archurl" |
Write-host "Remote $archurl" |
||||||
Write-host "-----------------------------------------------------------------------" |
Write-host "-----------------------------------------------------------------------" |
||||||
Write-host "Local Remote" |
Write-host "Local Remote" |
||||||
Write-host "-----------------------------------------------------------------------" |
Write-host "-----------------------------------------------------------------------" |
||||||
# 12345678910234567892023456789302345 |
# 12345678910234567892023456789302345 |
||||||
$G = "`e[32m" #Green |
$G = "`e[32m" #Green |
||||||
$Y = "`e[33m" #Yellow |
$Y = "`e[33m" #Yellow |
||||||
$R = "`e[31m" #Red |
$R = "`e[31m" #Red |
||||||
$RST = "`e[m" |
$RST = "`e[m" |
||||||
foreach ($key in $localdict.Keys) { |
foreach ($key in $localdict.Keys) { |
||||||
$local_sha1 = $($localdict[$key]) |
$local_sha1 = $($localdict[$key]) |
||||||
if ($remotedict.ContainsKey($key)) { |
if ($remotedict.ContainsKey($key)) { |
||||||
if ($local_sha1 -eq $remotedict[$key]) { |
if ($local_sha1 -eq $remotedict[$key]) { |
||||||
$rhs = "Same version" |
$rhs = "Same version" |
||||||
$C = $G |
$C = $G |
||||||
} else { |
} else { |
||||||
$rhs = "UPDATE AVAILABLE" |
$rhs = "UPDATE AVAILABLE" |
||||||
$C = $Y |
$C = $Y |
||||||
} |
} |
||||||
} else { |
} else { |
||||||
$C = $R |
$C = $R |
||||||
$rhs = "(not listed on server)" |
$rhs = "(not listed on server)" |
||||||
} |
} |
||||||
#ansi problems from cmd.exe not in windows terminal - review |
#ansi problems from cmd.exe not in windows terminal - review |
||||||
$C = "" |
$C = "" |
||||||
$RST = "" |
$RST = "" |
||||||
$lhs = "$key".PadRight(35, ' ') |
$lhs = "$key".PadRight(35, ' ') |
||||||
write-host -nonewline "${C}${lhs}${RST}" |
write-host -nonewline "${C}${lhs}${RST}" |
||||||
write-host $rhs |
write-host $rhs |
||||||
} |
} |
||||||
$lhs_missing = "-".PadRight(35, ' ') |
$lhs_missing = "-".PadRight(35, ' ') |
||||||
foreach ($key in $remotedict.Keys) { |
foreach ($key in $remotedict.Keys) { |
||||||
if (-not ($localdict.ContainsKey($key))) { |
if (-not ($localdict.ContainsKey($key))) { |
||||||
write-host -nonewline $lhs_missing |
write-host -nonewline $lhs_missing |
||||||
write-host $key |
write-host $key |
||||||
} |
} |
||||||
} |
} |
||||||
Write-host "-----------------------------------------------------------------------" |
Write-host "-----------------------------------------------------------------------" |
||||||
|
|
||||||
} else { |
} else { |
||||||
if (test-path -Path $archfolder -Type Container) { |
if (test-path -Path $archfolder -Type Container) { |
||||||
Write-host "-----------------------------------------------------------------------" |
Write-host "-----------------------------------------------------------------------" |
||||||
Write-Host "Local runtimes for $arch" |
Write-Host "Local runtimes for $arch" |
||||||
$dircontents = (get-childItem -Path $archfolder -File | Where-object {-not ($(".txt",".tm") -contains $_.Extension) }) |
$dircontents = (get-childItem -Path $archfolder -File | Where-object {-not ($(".txt",".tm") -contains $_.Extension) }) |
||||||
write-host "$(${dircontents}.count) files in $archfolder" |
write-host "$(${dircontents}.count) files in $archfolder" |
||||||
Write-host "-----------------------------------------------------------------------" |
Write-host "-----------------------------------------------------------------------" |
||||||
foreach ($f in $dircontents) { |
foreach ($f in $dircontents) { |
||||||
write-host $f.Name |
write-host $f.Name |
||||||
} |
} |
||||||
Write-host "-----------------------------------------------------------------------" |
Write-host "-----------------------------------------------------------------------" |
||||||
Write-host "Use: 'list -remote' to compare local runtimes with those available on the artifact server" |
Write-host "Use: 'list -remote' to compare local runtimes with those available on the artifact server" |
||||||
} else { |
} else { |
||||||
write-host "No runtimes seem to be installed for $arch in $archfolder`nPlease use 'runtime.cmd fetch' to install." |
write-host "No runtimes seem to be installed for $arch in $archfolder`nPlease use 'runtime.cmd fetch' to install." |
||||||
write-host "Use 'runtime.cmd list -remote' to see available runtimes for $arch" |
write-host "Use 'runtime.cmd list -remote' to see available runtimes for $arch" |
||||||
} |
} |
||||||
} |
} |
||||||
} |
} |
||||||
default { |
default { |
||||||
$actions = @("fetch", "list", "run") |
$actions = @("fetch", "list", "run") |
||||||
write-host "Available actions: $actions" |
write-host "Available actions: $actions" |
||||||
write-host "received" |
write-host "received" |
||||||
foreach ($boundparam in $PSBoundParameters.opts) { |
foreach ($boundparam in $PSBoundParameters.opts) { |
||||||
write-host $boundparam |
write-host $boundparam |
||||||
} |
} |
||||||
} |
} |
||||||
} |
} |
||||||
|
|
||||||
return $PSBoundParameters |
return $PSBoundParameters |
||||||
} |
} |
||||||
} |
} |
||||||
#write-host (psmain @args) |
#write-host (psmain @args) |
||||||
#$returnvalue = psmain @args |
#$returnvalue = psmain @args |
||||||
#Write-Host "Function Returned $returnvalue" -ForegroundColor Cyan |
#Write-Host "Function Returned $returnvalue" -ForegroundColor Cyan |
||||||
#return $returnvalue |
#return $returnvalue |
||||||
psmain @args | out-null |
psmain @args | out-null |
||||||
exit 0 |
exit 0 |
||||||
|
|
||||||
|
|||||||
@ -1,27 +1,27 @@ |
|||||||
|
|
||||||
[application] |
[application] |
||||||
template="punk.multishell.cmd" |
template="punk.multishell.cmd" |
||||||
as_admin=false |
as_admin=false |
||||||
|
|
||||||
scripts=[ |
scripts=[ |
||||||
"runtime.ps1", |
"runtime.ps1", |
||||||
"runtime.bash" |
"runtime.bash" |
||||||
] |
] |
||||||
|
|
||||||
default_outputfile="runtime.cmd" |
default_outputfile="runtime.cmd" |
||||||
default_nextshellpath="/usr/bin/env bash" |
default_nextshellpath="/usr/bin/env bash" |
||||||
default_nextshelltype="bash" |
default_nextshelltype="bash" |
||||||
|
|
||||||
#valid nextshelltype entries are: tcl perl powershell bash. |
#valid nextshelltype entries are: tcl perl powershell bash. |
||||||
#nextshellpath entries must be 64 characters or less. |
#nextshellpath entries must be 64 characters or less. |
||||||
|
|
||||||
#don't use -c for launching - or in old powershell, arguments such as "a b" will become 2 arguments a b |
#don't use -c for launching - or in old powershell, arguments such as "a b" will become 2 arguments a b |
||||||
#do use -File (even though pwsh doesn't require it) |
#do use -File (even though pwsh doesn't require it) |
||||||
#win32.nextshellpath="pwsh -nop -nol -ExecutionPolicy bypass -File" |
#win32.nextshellpath="pwsh -nop -nol -ExecutionPolicy bypass -File" |
||||||
#win32.nextshelltype="pwsh" |
#win32.nextshelltype="pwsh" |
||||||
|
|
||||||
#powershell needs cmd.exe to preserve spaced args |
#powershell needs cmd.exe to preserve spaced args |
||||||
win32.nextshellpath="cmd.exe /c powershell -nop -nol -ExecutionPolicy bypass -File" |
win32.nextshellpath="cmd.exe /c powershell -nop -nol -ExecutionPolicy bypass -File" |
||||||
win32.nextshelltype="powershell" |
win32.nextshelltype="powershell" |
||||||
|
|
||||||
win32.outputfile="runtime.cmd" |
win32.outputfile="runtime.cmd" |
||||||
|
|||||||
Loading…
Reference in new issue