diff --git a/portable/advanced/Check-PowerShell.ps1 b/portable/advanced/Check-PowerShell.ps1 new file mode 100644 index 0000000..e4ed7e9 --- /dev/null +++ b/portable/advanced/Check-PowerShell.ps1 @@ -0,0 +1,52 @@ +# Parses every .ps1 in the repository and reports syntax errors. +# +# Why this exists: most of this project's PowerShell was written on a Mac, where +# no parser is available. "It looks right" is not a check — a single stray +# character stops the Windows installer from running at all, and there is no way +# to find that out except on Windows. +# +# Run from the repository root: +# powershell -ExecutionPolicy Bypass -File portable\advanced\Check-PowerShell.ps1 +# +# Exit code is the number of files with errors, so CI can use it too. + +$ErrorActionPreference = 'Stop' +$root = Split-Path -Parent (Split-Path -Parent $PSScriptRoot) +$failed = 0 +$checked = 0 + +Write-Host "" +Write-Host " Parsing every .ps1 under $root" -ForegroundColor Cyan +Write-Host "" + +Get-ChildItem -Path $root -Recurse -Filter *.ps1 -File | + Where-Object { $_.FullName -notmatch '\\node_modules\\|\\app\\|\\\.git\\' } | + Sort-Object FullName | + ForEach-Object { + $checked++ + $errors = $null + $relative = $_.FullName.Substring($root.Length).TrimStart('\') + [void][System.Management.Automation.Language.Parser]::ParseFile($_.FullName, [ref]$null, [ref]$errors) + + if ($errors -and $errors.Count -gt 0) { + $failed++ + Write-Host (" FAIL " + $relative) -ForegroundColor Red + foreach ($e in $errors) { + $line = $e.Extent.StartLineNumber + Write-Host (" line " + $line + ": " + $e.Message) -ForegroundColor Red + } + } else { + Write-Host (" ok " + $relative) -ForegroundColor Green + } + } + +Write-Host "" +if ($failed -eq 0) { + Write-Host " $checked file(s) parsed, no syntax errors." -ForegroundColor Green +} else { + Write-Host " $failed of $checked file(s) have syntax errors." -ForegroundColor Red + Write-Host " Send the red lines above to whoever wrote them." -ForegroundColor Yellow +} +Write-Host "" + +exit $failed