Use a polyglot BASH/Batch script as a shim for the Git commit hook

This commit is contained in:
YoshiRulz 2024-06-08 13:39:50 +10:00
parent 4a54a99dbb
commit ffa5bb9b74
No known key found for this signature in database
GPG Key ID: C4DE31C245353FB7
3 changed files with 22 additions and 15 deletions

12
Dist/git_hook_shims/commit-msg Executable file
View File

@ -0,0 +1,12 @@
@{a="\"} >$null # " 2>/dev/null || true #" >NUL 2>&1 || TYPE NUL & ECHO OFF
echo \" <<'BATCH_SCRIPT' >/dev/null ">NUL "\"
dotnet pwsh .\Dist\git_hooks\commit-msg.ps1 %*
GOTO :eof
BATCH_SCRIPT
# else this is BASH
# heredoc trick for polyglot taken from https://github.com/llamasoft/polyshell#how-it-works -- this script is basically that sans PowerShell support (since that's not the shell on Windows)
# improved Batch `ECHO OFF` taken from https://github.com/tingstad/polyscript#explanation
dotnet pwsh "./Dist/git_hooks/$(basename "$0").ps1" "$@"
exit $?

View File

@ -1,24 +1,19 @@
$targetDir = "$PSScriptRoot/../.git/hooks"
if (Test-Path $targetDir -PathType Container) { # is Git repo
$magicHeader = '# placed here by BizHawk build scripts and may be updated automatically'
$PSCommandFilename = Split-Path $PSCommandPath -Leaf
foreach ($f in Get-ChildItem "$PSScriptRoot/git_hooks") {
foreach ($f in Get-ChildItem "$PSScriptRoot/git_hook_shims") {
$target = Join-Path $targetDir $f.Name
if (Test-Path $target -PathType Leaf) { # target file exists
if ($(Get-FileHash $target).Hash -ne $(Get-FileHash $f.FullName).Hash) { # files differ
$head = Get-Content $target -TotalCount 3
if ($magicHeader -in $head) {
echo "[$PSCommandFilename] updating existing Git hook $($f.Name)"
Copy-Item $f $target
} else {
echo "[$PSCommandFilename] found existing Git hook $($f.Name), please resolve conflict manually"
# should probably make the scripts extensible then...
exit 1
}
}
} else {
if (!(Test-Path $target -PathType Leaf)) { # target file doesn't exist
echo "[$PSCommandFilename] creating Git hook $($f.Name)"
Copy-Item $f $target
#TODO generate shim? the only difference between different shims would be the filename in the Batch part (and if there was an equivalent to `basename $0` then that would be the same too
#TODO use symlinks on Linux
} elseif ($(Get-FileHash $target).Hash -ne $(Get-FileHash $f.FullName).Hash) { # files differ
$head = Get-Content $target -TotalCount 3
echo "[$PSCommandFilename] found existing Git hook $($f.Name), please resolve conflict manually"
#TODO should REALLY make the scripts extensible then...
exit 1
}
# else no-op
}
}