-
Notifications
You must be signed in to change notification settings - Fork 0
/
ps.lint.ps1
168 lines (131 loc) · 6.06 KB
/
ps.lint.ps1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
<#PSScriptInfo
.VERSION 1.0
.GUID fe1ffe19-f980-4070-9914-b36cbe58322f
.AUTHOR hrxn.public@gmail.com
.COPYRIGHT (c)Hrxn
.TAGS PowerShell Development Scripting PSScriptAnalyzer Analysis
.LICENSEURI https://github.com/Hrxn/Pwsh/blob/master/LICENSE
.PROJECTURI https://github.com/Hrxn/Pwsh
.EXTERNALMODULEDEPENDENCIES PSScriptAnalyzer
.RELEASENOTES
- 1.0 [2023-08-10] | Initial release
#>
<#
.SYNOPSIS
PSScriptAnalyzer utility script
.DESCRIPTION
Use `Invoke-ScriptAnalyzer` with a predefined set of rules and options.
Dependencies:
1) PSScriptAnalyzer (https://github.com/PowerShell/PSScriptAnalyzer)
.PARAMETER Path
Specifies the path to the scripts or module to be analyzed. Wildcard characters are supported.
Possible are paths to script (.ps1) or module (.psm1) files, or to a directory that contains scripts or modules. Other filetpyes are ignored.
The default value is the current working directory.
.PARAMETER ScriptDefinition
Run the analysis on commands, functions, or expressions represented in a string.
.PARAMETER Preset
Specifies the path to a file containing a user-defined PSScriptAnalyzer profile. A script analyzer profile file describes a predefined set of
rules and rule options to be used for analysis. Rules in the profile take precedence over the same parameters and values specified at the command-line.
If no value is provided for the 'Preset' parameter, analysis will fall back to a default preset that is distributed together with this script
at './Preferences/Fesp.PowerShell.PSScriptAnalyzer.Preset.All.psd1'
.PARAMETER Severity
Only select rule violations with the specified severity.
.PARAMETER Recurse
Runs script analyzer on the files in the 'Path' directory and all subdirectories recursively.
.PARAMETER ReportSummary
Combines all rule violations in a summary.
.PARAMETER SuppressedOnly
Only select rule violations that have been suppressed by using the suppression attribute (SuppressMessageAttribute) in the source code.
.EXAMPLE
ps.lint.ps1 -Path ps.lint.ps1
.EXAMPLE
ps.lint.ps1 .\PowerShell\MyModule
.INPUTS
'Path' or 'ScriptDefinition' as String
.OUTPUTS
Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic.DiagnosticRecord, Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic.SuppressedRecord
.LINK
https://github.com/Hrxn/pwsh
#>
#Requires -Version 7.2
[CmdletBinding(DefaultParameterSetName = 'Path')]
param(
[Parameter(ParameterSetName = 'Path', Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)]
[SupportsWildcards()]
[string[]] $Path = $PWD.Path,
[Parameter(ParameterSetName = 'ScriptDefinition', Position = 0, ValueFromPipelineByPropertyName)]
[string] $ScriptDefinition,
[Parameter(Position = 1)]
[string] $Preset,
[ValidateSet('Warning', 'Error', 'Information', 'ParseError')]
[string[]] $Severity,
[switch] $Recurse,
[switch] $ReportSummary,
[switch] $SuppressedOnly,
[switch] $IncludeSuppressed
)
begin {
function Show-Message ($In) {
Write-Host -Object $In
}
try {
Import-Module -Name 'PSScriptAnalyzer' -Force -ErrorAction Stop
} catch {
Show-Message ("`e[38;5;242m[`e[38;5;196mps.lint`e[38;5;242m]`e[38;5;242m[`e[38;5;196mError`e[38;5;242m] `e[38;5;231m- `e[38;5;196mERROR`e[38;5;231m -`e[0m Unable to imp" +
"ort module `e[38;5;179m'`e[38;5;41mPSScriptAnalyzer`e[38;5;179m'`e[0m, please make sure that it is correctly installed on your system!")
exit 1
}
if ($SuppressedOnly -and $IncludeSuppressed) {
Show-Message ("`e[38;5;242m[`e[38;5;196mps.lint`e[38;5;242m]`e[38;5;242m[`e[38;5;196mError`e[38;5;242m] `e[38;5;231m- `e[38;5;196mERROR`e[38;5;231m -`e[0m Both " +
"`e[38;5;179m'`e[38;5;8m-SuppressedOnly`e[38;5;179m'`e[0m and `e[38;5;179m'`e[38;5;8m-IncludeSuppressed`e[38;5;179m'`e[0m have been specified: " +
'You can only use one of these flags at a time!')
exit 2
}
if ($Preset) {
if ([System.IO.File]::Exists([System.IO.Path]::GetFullPath($Preset, $PWD))) {
$ScriptAnalyzerSettings = [System.IO.Path]::GetFullPath($Preset, $PWD)
} else {
Show-Message ("`e[38;5;242m[`e[38;5;196mps.lint`e[38;5;242m]`e[38;5;242m[`e[38;5;196mError`e[38;5;242m] `e[38;5;231m- `e[38;5;196mERROR`e[38;5;231m -`e[0m Provided " +
"value for the argument `e[38;5;179m'`e[38;5;41mPreset`e[38;5;179m'`e[0m: `e[38;5;179m'{0}`e[38;5;179m'`e[0m is not a preset file that exists!" -f $Preset)
exit 3
}
} else {
$IncludedSettingsPreset = [System.IO.Path]::Join($PSScriptRoot, 'Preferences', 'Fesp.PowerShell.PSScriptAnalyzer.Preset.All.psd1')
if ([System.IO.File]::Exists($IncludedSettingsPreset)) {
$ScriptAnalyzerSettings = $IncludedSettingsPreset
} else {
Show-Message ("`e[38;5;242m[`e[38;5;196mps.lint`e[38;5;242m]`e[38;5;242m[`e[38;5;196mError`e[38;5;242m] `e[38;5;231m- `e[38;5;196mERROR`e[38;5;231m -`e[0m The bundl" +
"ed PSScriptAnalyzer settings preset file was not found at the expected path: `e[38;5;179m'{0}`e[38;5;179m'`e[0m!" -f $IncludedSettingsPreset)
exit 4
}
}
}
process {
$ScriptAnalyzerParams = @{
Settings = $ScriptAnalyzerSettings
ReportSummary = $ReportSummary
}
if ($Severity) {
$ScriptAnalyzerParams += @{ Severity = $Severity }
}
if ($PSCmdlet.ParameterSetName -ceq 'Path') {
foreach ($PathEntry in $Path) {
if ($IncludeSuppressed) {
Invoke-ScriptAnalyzer @ScriptAnalyzerParams -Path $PathEntry -IncludeSuppressed -Recurse:$Recurse
} else {
Invoke-ScriptAnalyzer @ScriptAnalyzerParams -Path $PathEntry -SuppressedOnly:$SuppressedOnly -Recurse:$Recurse
}
}
} else {
if (-not [System.String]::IsNullOrWhiteSpace($ScriptDefinition)) {
if ($IncludeSuppressed) {
Invoke-ScriptAnalyzer @ScriptAnalyzerParams -ScriptDefinition $ScriptDefinition -IncludeSuppressed
} else {
Invoke-ScriptAnalyzer @ScriptAnalyzerParams -ScriptDefinition $ScriptDefinition -SuppressedOnly:$SuppressedOnly
}
} else {
Show-Message ("`e[38;5;242m[`e[38;5;196mps.lint`e[38;5;242m]`e[38;5;242m[`e[38;5;196mError`e[38;5;242m] `e[38;5;231m- `e[38;5;196mERROR`e[38;5;231m -`e[0m Provided " +
"value for the argument `e[38;5;179m'`e[38;5;41mScriptDefinition`e[38;5;179m'`e[0m: `e[38;5;179m'{0}`e[38;5;179m'`e[0m is not valid!" -f $ScriptDefinition)
}
}
}