Public Access
75 lines
2.4 KiB
Bash
75 lines
2.4 KiB
Bash
#!/usr/bin/env bash
|
|||
|
|
# Pre-commit checks for the PowerShell scripts. Run from the repo root.
|
||
|
|
# Needs pwsh on PATH (see the project notes for how it was installed).
|
||
|
|
set -uo pipefail
|
||
|
|
cd "$(dirname "$0")"
|
||
|
|
fail=0
|
||
|
|
|
||
|
|
echo "== ASCII only =="
|
||
|
|
# Windows PowerShell 5.1 reads a BOM-less .ps1 in the system codepage, which
|
||
|
|
# turns any multi-byte character into mojibake - including quote characters
|
||
|
|
# that break string literals mid-script.
|
||
|
|
for f in *.ps1; do
|
||
|
|
if LC_ALL=C grep -nP '[^\x00-\x7F]' "$f" >/dev/null; then
|
||
|
|
echo " FAIL $f contains non-ASCII:"
|
||
|
|
LC_ALL=C grep -nP '[^\x00-\x7F]' "$f" | head -5
|
||
|
|
fail=1
|
||
|
|
else
|
||
|
|
echo " ok $f"
|
||
|
|
fi
|
||
|
|
done
|
||
|
|
|
||
|
|
echo
|
||
|
|
echo "== \$var? in a string =="
|
||
|
|
# ? is a legal character in an unbraced PowerShell variable name, so "$name?"
|
||
|
|
# looks up a variable called name? and silently renders empty. Use ${name}?.
|
||
|
|
if grep -nP '\$\w+\?' ./*.ps1; then
|
||
|
|
echo " FAIL - wrap those as \${name}? or the text disappears at runtime"
|
||
|
|
fail=1
|
||
|
|
else
|
||
|
|
echo " ok none found"
|
||
|
|
fi
|
||
|
|
|
||
|
|
echo
|
||
|
|
echo "== parse + Windows PowerShell 5.1 compatibility =="
|
||
|
|
pwsh -NoProfile -Command '
|
||
|
|
$bad = 0
|
||
|
|
foreach ($f in Get-ChildItem -Filter *.ps1) {
|
||
|
|
$e = $null
|
||
|
|
[System.Management.Automation.Language.Parser]::ParseFile($f.FullName, [ref]$null, [ref]$e) | Out-Null
|
||
|
|
if ($e.Count) {
|
||
|
|
$bad++
|
||
|
|
Write-Host " FAIL $($f.Name)"
|
||
|
|
$e | ForEach-Object { " line $($_.Extent.StartLineNumber): $($_.Message)" }
|
||
|
|
} else { Write-Host " ok $($f.Name)" }
|
||
|
|
}
|
||
|
|
if (Get-Module -ListAvailable PSScriptAnalyzer) {
|
||
|
|
Import-Module PSScriptAnalyzer
|
||
|
|
$s = @{ Rules = @{ PSUseCompatibleSyntax = @{ Enable = $true; TargetVersions = @("5.1","7.0") } } }
|
||
|
|
$c = Invoke-ScriptAnalyzer -Path . -Recurse -Settings $s -IncludeRule PSUseCompatibleSyntax
|
||
|
|
if ($c) { $bad++; $c | ForEach-Object { " FAIL 5.1: $($_.ScriptName):$($_.Line) $($_.Message)" } }
|
||
|
|
else { Write-Host " ok 5.1 syntax clean" }
|
||
|
|
} else {
|
||
|
|
Write-Host " skip PSScriptAnalyzer not installed"
|
||
|
|
}
|
||
|
|
exit $bad
|
||
|
|
' || fail=1
|
||
|
|
|
||
|
|
echo
|
||
|
|
echo "== JSON templates =="
|
||
|
|
python3 - <<'PY' || fail=1
|
||
|
|
import glob, json, sys
|
||
|
|
bad = 0
|
||
|
|
for f in glob.glob("Entities/**/*.json", recursive=True) + ["settings.json"]:
|
||
|
|
try:
|
||
|
|
json.load(open(f))
|
||
|
|
print(" ok %s" % f)
|
||
|
|
except Exception as e:
|
||
|
|
print(" FAIL %s: %s" % (f, e)); bad = 1
|
||
|
|
sys.exit(bad)
|
||
|
|
PY
|
||
|
|
|
||
|
|
echo
|
||
|
|
if [ "$fail" -eq 0 ]; then echo "ALL CHECKS PASSED"; else echo "CHECKS FAILED"; fi
|
||
|
|
exit $fail
|