You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

169 lines
7.1 KiB

#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
#check if git available
#if not, check/install winget, winget git
$git_upstream = "https://gitea1.intx.com.au/jn/punkshell.git"
$launchdir = Get-Location #store original CWD
$scriptfolder = Resolve-Path (Split-Path -Path $PSCommandPath -Parent)
$punkfolder = ""
$scriptroot = "$([System.IO.Path]::GetFileNameWithoutExtension($PSCommandPath))"
$env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User")
if (-not (Get-Command "git" -ErrorAction SilentlyContinue)) {
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-PSResource/Install-PSResource: only available in newer pwsh etc?
$wgclient = Get-Module -ListAvailable -Name Microsoft.WinGet.Client
if (${wgclient}.Length -eq 0) {
Write-Host "Microsoft.WinGet.Client module not installed.. will try to install."
Install-PackageProvider -Name NuGet -Force
$psgallery_existing_policy = (Get-PSRepository -Name PSGallery).InstallationPolicy
if ($psgallery_existing_policy -eq "Untrusted") {
#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
Set-PSRepository -Name PSGallery -InstallationPolicy Trusted
}
Install-Module -Scope CurrentUser -Name Microsoft.Winget.Client -Force -Repository PSGallery
Repair-WinGetPackageManager
import-module -name Microsoft.Winget.client
if ($psgallery_existing_policy -eq "Untrusted") {
Set-PSRepository -Name PSGallery -InstallationPolicy Untrusted
}
} else {
Write-Host "Microsoft.WinGet.Client is available"
}
$gitversion = (Find-WinGetPackage Git.Git).Version
if ($gitversion) {
Write-Host "Installing git version: ${gitversion}"
Install-WinGetPackage -Id "Git.Git"
} else {
Write-Host "Failed to find git using winget"
exit
}
#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")
if (Get-Command "git" -ErrorAction SilentlyContinue) {
Write-Host "git is now available"
} else {
Write-Host "git is still not available"
Write-HOst "Please install Git or relaunch your terminal and check it is available on the path."
exit
}
}
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."
$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") {
$punkfolder = $launchdir
} elseif ($answer -match "n") {
$punkfolder = $scriptfolder
} else {
exit 1
}
} else {
$punkfolder = $scriptfolder
}
$punkfoldercontents = Get-ChildItem -Path $punkfolder -Force #include possibly hidden items such as .git folder
$contentcount = ( $punkfoldercontents | Measure-Object).Count
$effectively_empty = 0
if ($contentcount -eq 0) {
$effectively_empty = 1
} elseif ($punkfolder -eq $scriptfolder -and $contentcount -lt 10) {
#treat as empty if we have only a few files matching script root name
$scriptlike = get-childitem -Path $punkfolder | Where-Object {$_.name -like "${scriptroot}.*"}
if ($scriptlike.Count -eq $contentcount) {
$effectively_empty = 1
}
}
if (-not($effectively_empty)) {
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 "Please place this script in an empty folder which is to be the punkshell base folder."
exit
} else {
$repo_origin = git remote get-url origin
if ($repo_origin -ne $git_upstream) {
Write-Host "The current repository origin '$repo_origin' is not the expected upstream '${git_upstream}'"
$answer = Read-Host "Continue anyway? (Y|N)"
if (-not($answer -match "y")) {
exit 1
}
}
}
} else {
#punkfolder is empty, or has just the current script
}
Set-Location -Path $punkfolder
if (-not(Test-Path -Path (Join-Path -Path $punkfolder -ChildPath ".git") -PathType Container)) {
git init
git remote add origin $git_upstream
}
git fetch origin
if (($launchdir.Path) -eq ($scriptfolder.Path)) {
if (Test-Path -Path "${scriptroot}.cmd") {
#rename-item won't allow overwriting existing target file
Move-Item -Path "${scriptroot}.cmd" -Destination "${scriptroot}.cmd.lastrun" -Force
}
}
git pull $git_upstream master
git checkout "${scriptroot}.cmd"
git branch --set-upstream-to=origin/master master
Set-Location $launchdir #restore original CWD
# Define the necessary Win32 API functions and constants
Add-Type -TypeDefinition @"
using System;
using System.Runtime.InteropServices;
public class WinAPI
{
// Console Input/Output Handles
public const int STD_OUTPUT_HANDLE = -11;
// Console Modes
public const uint ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x0004;
public const uint DISABLE_NEWLINE_AUTO_RETURN = 0x0008;
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr GetStdHandle(int nStdHandle);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool GetConsoleMode(IntPtr hConsoleHandle, out uint lpMode);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool SetConsoleMode(IntPtr hConsoleHandle, uint dwMode);
}
"@
# Get the handle to the console output buffer
$stdoutHandle = [WinAPI]::GetStdHandle([WinAPI]::STD_OUTPUT_HANDLE)
# Get the current console mode
[uint]$currentMode = 0
if (![WinAPI]::GetConsoleMode($stdoutHandle, [ref]$currentMode)) {
Write-Error "Failed to get console mode. Error code: $($LAST_ERROR)"
return
}
# Enable virtual terminal processing
$newMode = $currentMode -bor [WinAPI]::ENABLE_VIRTUAL_TERMINAL_PROCESSING
# Set the new console mode
if (![WinAPI]::SetConsoleMode($stdoutHandle, $newMode)) {
Write-Error "Failed to set console mode. Error code: $($LAST_ERROR)"
return
}
Write-Host "Virtual terminal processing enabled successfully."
write-host "`e[92m getpunk done `e[m"