mirror of
https://github.com/webinstall/webi-installers.git
synced 2026-08-23 22:16:48 +00:00
feat: add PSScriptAnalyzer (pwsh fmt, fix, lint)
This commit is contained in:
@@ -0,0 +1,210 @@
|
||||
---
|
||||
title: PSScriptAnalyzer
|
||||
homepage: https://github.com/PowerShell/PSScriptAnalyzer
|
||||
tagline: |
|
||||
PSScriptAnalyzer is Formatter & Linter for PowerShell.
|
||||
---
|
||||
|
||||
To update or switch versions, run `webi psscriptanalyzer`.
|
||||
|
||||
## Cheat Sheet
|
||||
|
||||
> It's dangerous to go alone! Take _PSScriptAnalyzer_! \
|
||||
> (nothing crazy, just the standard fmt & lint tool you'd expect)
|
||||
|
||||
You'll probably want [pwsh-essentials](../pwsh-essentials) as well.
|
||||
|
||||
### Table of Contents
|
||||
|
||||
- Files
|
||||
- Manual Install
|
||||
- Format
|
||||
- Lint
|
||||
- Vim Config
|
||||
- Beware the BOM!
|
||||
- Check Version
|
||||
|
||||
### Files
|
||||
|
||||
These are the files / directories that are created and/or modified with this
|
||||
install:
|
||||
|
||||
```text
|
||||
~/.local/share/powershell/Modules/PSScriptAnalyzer/
|
||||
```
|
||||
|
||||
### How to Install PSScriptAnalyzer Manually
|
||||
|
||||
It's just a one liner, but... a little harder to remember than the webi version:
|
||||
|
||||
```sh
|
||||
pwsh -Command "Install-Module -Name PSScriptAnalyzer -Scope CurrentUser -AllowClobber"
|
||||
```
|
||||
|
||||
### How to Run the PowerShell Formatter
|
||||
|
||||
**`pwsh-fmt`** from ([pwsh-essentials](../pwsh-essentials/)) is the **easiest
|
||||
way** to run the formatter on a file or directory.
|
||||
|
||||
```sh
|
||||
pwsh-fmt ./script.ps1
|
||||
```
|
||||
|
||||
There is **no built-in one-liner** to do so. You have to do **something like
|
||||
this instead**:
|
||||
|
||||
```pwsh
|
||||
function Format-File($Path) {
|
||||
$WasDirty = $false
|
||||
|
||||
$Original = Get-Content -Path $Path -Raw
|
||||
$Formatted = Invoke-Formatter -ScriptDefinition $Original
|
||||
|
||||
IF ($Original -eq $Formatted) {
|
||||
return $WasDirty
|
||||
}
|
||||
$WasDirty = $true
|
||||
|
||||
# By default Set-Content unconditionally adds an *extra* newline every time
|
||||
# See <https://stackoverflow.com/a/45266681/151312>
|
||||
Set-Content -Path $Path $Formatted -Encoding utf8NoBom -NoNewline
|
||||
|
||||
return $WasDirty
|
||||
}
|
||||
```
|
||||
|
||||
```pwsh
|
||||
$WasDirty = Format-File -Path "./script.ps1"
|
||||
```
|
||||
|
||||
### How to Run the PowerShell Linter
|
||||
|
||||
**`pwsh-lint`** from ([pwsh-essentials](../pwsh-essentials/)) is the **easiest
|
||||
way** to run the linter on a file or directory.
|
||||
|
||||
```sh
|
||||
pwsh-lint ./script.ps1
|
||||
```
|
||||
|
||||
However, this one does have a nice onesliner:
|
||||
|
||||
```pwsh
|
||||
Invoke-ScriptAnalyzer -Path "./script.ps1" -ExcludeRule PSAvoidUsingWriteHost
|
||||
```
|
||||
|
||||
You can also make the output much more readable by using `Format-List`:
|
||||
|
||||
```pwsh
|
||||
$Diags = Invoke-ScriptAnalyzer -Path "./script.ps1" -ExcludeRule PSAvoidUsingWriteHost
|
||||
Write-Host ($Diags | Format-List | Out-String)
|
||||
```
|
||||
|
||||
### How to Run the PowerShell Fixer
|
||||
|
||||
**`pwsh-fix`** from ([pwsh-essentials](../pwsh-essentials/)) is the **easiest
|
||||
way** to run the fixer on a file or directory.
|
||||
|
||||
At first blush the _Fixer_ seems simple - just at `-Fix` to the _Linter_.
|
||||
|
||||
However, it's tricky because it will output a Byte-Order-Marker, which
|
||||
**requires running the _Formatter_** to remove.
|
||||
|
||||
That would look something like this:
|
||||
|
||||
```pwsh
|
||||
function Repair-File($Path) {
|
||||
$WasDirty = $false
|
||||
|
||||
$Original = Get-Content -Path $Path -Raw
|
||||
$Formatted = Invoke-Formatter -ScriptDefinition $Original
|
||||
|
||||
IF ($Original -eq $Formatted) {
|
||||
return $WasDirty
|
||||
}
|
||||
$WasDirty = $true
|
||||
|
||||
# By default Set-Content unconditionally adds an *extra* newline every time
|
||||
# See <https://stackoverflow.com/a/45266681/151312>
|
||||
Set-Content -Path $Path $Formatted -Encoding utf8NoBom -NoNewline
|
||||
|
||||
return $WasDirty
|
||||
}
|
||||
```
|
||||
|
||||
You'll notice this is very similar to the Formatter solution above, with just
|
||||
these changes:
|
||||
|
||||
```diff
|
||||
- $Formatted = Invoke-Formatter -ScriptDefinition $Original
|
||||
+
|
||||
+ Invoke-ScriptAnalyzer -Fix -Path $Path -ExcludeRule PSAvoidUsingWriteHost
|
||||
+ $Fixed = Get-Content -Path $Path -Raw
|
||||
+ $Formatted = Invoke-Formatter -ScriptDefinition $Fixed
|
||||
```
|
||||
|
||||
### How to Configure PSScriptAnalyzer
|
||||
|
||||
There is no standard config location for projects or globally. \
|
||||
(not at the time of this writing at least)
|
||||
|
||||
Instead you'll need to change the config in your editor.
|
||||
|
||||
### How to Configure PSScriptAnalyzer for Vim
|
||||
|
||||
1. You'll need to install [vim-ale](../vim-ale/)
|
||||
```sh
|
||||
webi vim-ale
|
||||
```
|
||||
2. For **Per-User** config, edit `~/.vimrc` and flavor to taste: `~/.vimrc:`
|
||||
```vim
|
||||
" PowerShell settings
|
||||
let g:ale_powershell_psscriptanalyzer_exclusions = "PSAvoidUsingWriteHost"
|
||||
```
|
||||
3. For **Per-Project** config you'll need to edit `~/.vimrc` _AND_
|
||||
`<PROJECT-DIR>/.vimrc`: `~/.vimrc`:
|
||||
```vim
|
||||
" Place these 2 lines at the very END of ~/.vimrc
|
||||
" (this will enable per-directory .vimrc loading)
|
||||
set secure
|
||||
set exrc
|
||||
```
|
||||
`~/PROJECT-NAME/.vimrc`:
|
||||
```sh
|
||||
" PowerShell settings
|
||||
let g:ale_powershell_psscriptanalyzer_exclusions = "PSAvoidUsingWriteHost"
|
||||
```
|
||||
|
||||
### How to Fix Byte-Order-Marker (BOM)
|
||||
|
||||
When you run the _Linter_ with `-Fix` it will sometimes output a UTF
|
||||
Byte-Order-Marker to the file.
|
||||
|
||||
The good news is that the _Formatter_ will remove this.
|
||||
|
||||
So always run the formatter after the linter. 🤷♂️
|
||||
|
||||
```pwsh
|
||||
$Fixed = Get-Content -Path $Path -Raw
|
||||
$Formatted = Invoke-Formatter -ScriptDefinition $Fixed
|
||||
|
||||
# By default Set-Content unconditionally adds an *extra* newline every time
|
||||
# See <https://stackoverflow.com/a/45266681/151312>
|
||||
Set-Content -Path $Path $Formatted -Encoding utf8NoBom -NoNewline
|
||||
```
|
||||
|
||||
## Check the Installed Version
|
||||
|
||||
This will output the module and version, or `$null`.
|
||||
|
||||
```pwsh
|
||||
Get-InstalledModule PSScriptAnalyzer `
|
||||
| Select-Object -Property Name, Version `
|
||||
| Format-List
|
||||
```
|
||||
|
||||
```text
|
||||
|
||||
Name : PSScriptAnalyzer
|
||||
Version : 1.21.0
|
||||
|
||||
```
|
||||
@@ -0,0 +1,41 @@
|
||||
#!/usr/bin/env pwsh
|
||||
|
||||
function Repair-MissingCommand {
|
||||
Param(
|
||||
[string]$Name,
|
||||
[string]$Package,
|
||||
[string]$Command
|
||||
)
|
||||
|
||||
Write-Host " Checking for $Name ..."
|
||||
$HasCommand = Get-Command -Name $Command -ErrorAction Silent
|
||||
IF ($HasCommand) {
|
||||
Return
|
||||
}
|
||||
|
||||
& $HOME\.local\bin\webi-pwsh.ps1 $Package
|
||||
$null = Sync-EnvPath
|
||||
}
|
||||
|
||||
IF ($null -eq $Env:WEBI_HOST -or "" -eq $Env:WEBI_HOST) {
|
||||
$Env:WEBI_HOST = "https://webinstall.dev"
|
||||
}
|
||||
|
||||
function Install-PSScriptAnalyzer {
|
||||
# Fetch PowerShell Core
|
||||
Repair-MissingCommand -Name "PowerShell Core" -Package "pwsh" -Command "pwsh"
|
||||
|
||||
$NeedsTrust = pwsh -Command "Get-PSRepository -Name 'PSGallery' | Where-Object -Property InstallationPolicy -eq 'Untrusted'"
|
||||
IF ($NeedsTrust) {
|
||||
Write-Host " Trusting PSRepository 'PSGallery' ..."
|
||||
pwsh -Command "Set-PSRepository -Name 'PSGallery' -InstallationPolicy Trusted"
|
||||
}
|
||||
|
||||
# TODO use arguments array instead
|
||||
Write-Host " Running 'Install-Module -Name PSScriptAnalyzer' ..."
|
||||
pwsh -Command "Install-Module -Name PSScriptAnalyzer -Repository PSGallery -Scope CurrentUser -AllowClobber"
|
||||
|
||||
pwsh -Command "Get-InstalledModule PSScriptAnalyzer | Select-Object -Property Name, Version"
|
||||
}
|
||||
|
||||
Install-PSScriptAnalyzer
|
||||
@@ -0,0 +1,17 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
set -u
|
||||
|
||||
__install_psscriptanalyzer() {
|
||||
echo "Checking for pwsh (PowerShell Core)..."
|
||||
if ! command -v pwsh > /dev/null; then
|
||||
"$HOME/.local/bin/webi" pwsh
|
||||
export PATH="$HOME/.local/opt/pwsh:$PATH"
|
||||
pwsh -V
|
||||
fi
|
||||
|
||||
pwsh -Command "Install-Module -Name PSScriptAnalyzer -Scope CurrentUser -AllowClobber"
|
||||
pwsh -Command 'Get-InstalledModule -Name PSScriptAnalyzer | Select-Object -Property "Name", "Version" | Format-List'
|
||||
}
|
||||
|
||||
__install_psscriptanalyzer
|
||||
Reference in New Issue
Block a user