Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/PSModuleUtils.psd1
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
@{
RootModule = 'PSModuleUtils.psm1'
ModuleVersion = '3.1.0'
ModuleVersion = '3.2.0'
GUID = '3c63c38f-c32c-4837-a6fa-0b456f4099ce'
Author = ''
CompanyName = ''
Expand Down
34 changes: 28 additions & 6 deletions src/Public/Invoke-PSModuleAnalyzer.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ command needs to process the diagnostics, such as converting them to SARIF.
Analyzes only what SourceDirectory itself matches instead of descending into subdirectories. Use with
a wildcard to keep a subtree with different rules, such as a tests folder, out of the run.

.PARAMETER ErrorOnFinding
Throws when the analyzer reports anything, rather than setting the process exit code. Required to
gate a script that analyzes more than one path: PSScriptAnalyzer's exit code is last-writer-wins and
does not stop the caller, so a clean pass after a failing one leaves the run reporting success.

.OUTPUTS
Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic.DiagnosticRecord

Expand All @@ -33,6 +38,9 @@ Invoke-PSModuleAnalyzer -SourceDirectory $PWD/src -Fix
.EXAMPLE
Invoke-PSModuleAnalyzer -SourceDirectory $PWD/scripts/*.ps1 -NoRecurse

.EXAMPLE
Invoke-PSModuleAnalyzer -SourceDirectory $PWD/tests -ErrorOnFinding

.NOTES
N/A
#>
Expand All @@ -44,15 +52,16 @@ function Invoke-PSModuleAnalyzer {
[String]$Settings = (Get-PSModuleAnalyzerSettingsPath -CallerScriptRoot $PSScriptRoot),
[Switch]$Fix,
[Switch]$NoExit,
[Switch]$NoRecurse
[Switch]$NoRecurse,
[Switch]$ErrorOnFinding
)

$scriptAnalyzerArgs = @{
Path = $SourceDirectory
Settings = $Settings
Recurse = (-not $NoRecurse)
Severity = 'Error', 'Warning', 'Information'
EnableExit = (-not $Fix -and -not $NoExit)
EnableExit = (-not $Fix -and -not $NoExit -and -not $ErrorOnFinding)
ReportSummary = $true
ErrorAction = 'Stop'
}
Expand All @@ -61,8 +70,21 @@ function Invoke-PSModuleAnalyzer {
$scriptAnalyzerArgs.Fix = $true
}

# After PSScriptAnalyzer fixes recursive PSUseCorrectCasing command metadata resolution, uncomment this call
# and remove the private workaround and its tests.
# Invoke-ScriptAnalyzer @scriptAnalyzerArgs
Invoke-PSModuleAnalyzerCasingWorkaround @scriptAnalyzerArgs
# After PSScriptAnalyzer fixes recursive PSUseCorrectCasing command metadata resolution, uncomment
# these calls and remove the private workaround and its tests.
if ($ErrorOnFinding) {
# $diagnostics = @(Invoke-ScriptAnalyzer @scriptAnalyzerArgs)
$diagnostics = @(Invoke-PSModuleAnalyzerCasingWorkaround @scriptAnalyzerArgs)

if ($diagnostics) {
# Written to the host as well as thrown: the throw discards the records, and a count on its
# own does not say what to fix.
Write-Host -Object ($diagnostics | Format-Table -AutoSize | Out-String -Width 200)
throw "$($diagnostics.Count) rule violation(s) found in '$SourceDirectory'."
}
}
else {
# Invoke-ScriptAnalyzer @scriptAnalyzerArgs
Invoke-PSModuleAnalyzerCasingWorkaround @scriptAnalyzerArgs
}
}
26 changes: 26 additions & 0 deletions tests/Invoke-PSModuleAnalyzer.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,32 @@ Describe 'Unit Tests' -Tag 'Unit' {
$topOnlyFindings.ScriptName | Should -Not -Contain 'Alias.ps1'
}

It 'should not set the analyzer exit code when ErrorOnFinding is set' {
Mock Invoke-PSModuleAnalyzerCasingWorkaround {}

Invoke-PSModuleAnalyzer -SourceDirectory $TestDrive -ErrorOnFinding

Should -Invoke Invoke-PSModuleAnalyzerCasingWorkaround -Exactly -Times 1 -ParameterFilter {
$EnableExit -eq $false
}
}

It 'should throw naming the count and the path when ErrorOnFinding finds something' {
$fixtureDir = Join-Path -Path $TestDrive -ChildPath 'ErrorOnFindingFixture'
New-Item -ItemType Directory -Path $fixtureDir -Force | Out-Null
'function Get-Aliased { gci }' | Set-Content -Path "$fixtureDir/Aliased.ps1" -Encoding utf8

{ Invoke-PSModuleAnalyzer -SourceDirectory $fixtureDir -ErrorOnFinding } |
Should -Throw '*rule violation(s) found in*ErrorOnFindingFixture*'
}

It 'should stay silent when ErrorOnFinding has nothing to report' {
$fixtureDir = Join-Path -Path $TestDrive -ChildPath 'ErrorOnFindingCleanFixture'
New-Item -ItemType Directory -Path $fixtureDir -Force | Out-Null

{ Invoke-PSModuleAnalyzer -SourceDirectory $fixtureDir -ErrorOnFinding } | Should -Not -Throw
}

It 'should preserve nested parentheses containing function definitions in fix mode' {
$fixtureDir = Join-Path -Path $TestDrive -ChildPath 'IndentationFixture'
New-Item -ItemType Directory -Path $fixtureDir -Force | Out-Null
Expand Down