Skip to content
Merged
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 = '4.0.0'
GUID = '3c63c38f-c32c-4837-a6fa-0b456f4099ce'
Author = ''
CompanyName = ''
Expand Down
31 changes: 23 additions & 8 deletions src/Public/Invoke-PSModuleAnalyzer.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@
Invokes PSScriptAnalyzer on a directory using a more strict set of rules than default.

.DESCRIPTION
Invokes PSScriptAnalyzer on a directory using a more strict set of rules than default.
Invokes PSScriptAnalyzer on a directory using a more strict set of rules than default, and works
around its recursive PSUseCorrectCasing crash by applying that one rule a file at a time.

Returns diagnostics, like Invoke-ScriptAnalyzer does. Decide what a finding means at the call site:
throw to gate a build, pipe to ConvertTo-SARIF to report one, or pass -EnableExit for a CI step that
should fail on its exit code.

.PARAMETER SourceDirectory
The directory to analyze. Also accepts a file path or a wildcard such as scripts/*.ps1, which pairs
Expand All @@ -16,14 +21,15 @@ source checkout and a built module layout.
.PARAMETER Fix
Whether to fix the issues found.

.PARAMETER NoExit
Returns analyzer diagnostics without exiting the caller when violations are found. Use this when another
command needs to process the diagnostics, such as converting them to SARIF.

.PARAMETER NoRecurse
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 EnableExit
Passed through to Invoke-ScriptAnalyzer: asks the host to exit with the diagnostic count once the run
finishes. Suits a CI step that is one analyzer call. It does not stop the caller and the code is
last-writer-wins, so a script analyzing several paths should test the returned diagnostics instead.

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

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

.EXAMPLE
$findings = Invoke-PSModuleAnalyzer -SourceDirectory $PWD/tests
if ($findings) {
throw "$($findings.Count) rule violation(s) in tests."
}

.EXAMPLE
Invoke-PSModuleAnalyzer -SourceDirectory $PWD/src -EnableExit

.NOTES
N/A
#>
Expand All @@ -43,16 +58,16 @@ function Invoke-PSModuleAnalyzer {
[String]$SourceDirectory = "$PWD/src",
[String]$Settings = (Get-PSModuleAnalyzerSettingsPath -CallerScriptRoot $PSScriptRoot),
[Switch]$Fix,
[Switch]$NoExit,
[Switch]$NoRecurse
[Switch]$NoRecurse,
[Switch]$EnableExit
)

$scriptAnalyzerArgs = @{
Path = $SourceDirectory
Settings = $Settings
Recurse = (-not $NoRecurse)
Severity = 'Error', 'Warning', 'Information'
EnableExit = (-not $Fix -and -not $NoExit)
EnableExit = $EnableExit
ReportSummary = $true
ErrorAction = 'Stop'
}
Expand Down
20 changes: 15 additions & 5 deletions tests/Invoke-PSModuleAnalyzer.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ Describe 'Unit Tests' -Tag 'Unit' {
Invoke-PSModuleAnalyzer -SourceDirectory $TestDrive
Should -Invoke Invoke-PSModuleAnalyzerCasingWorkaround -Exactly -Times 1 -ParameterFilter {
-not $PSBoundParameters.ContainsKey('Fix') -and
$EnableExit -eq $true -and
$EnableExit -eq $false -and
$ReportSummary -eq $true -and
$Severity -contains 'Error' -and
$Severity -contains 'Warning' -and
Expand All @@ -71,10 +71,10 @@ Describe 'Unit Tests' -Tag 'Unit' {
$ErrorAction -eq 'Stop'
}

Invoke-PSModuleAnalyzer -SourceDirectory $TestDrive -NoExit
Invoke-PSModuleAnalyzer -SourceDirectory $TestDrive -EnableExit
Should -Invoke Invoke-PSModuleAnalyzerCasingWorkaround -Exactly -Times 1 -ParameterFilter {
-not $Fix -and
$EnableExit -eq $false -and
$EnableExit -eq $true -and
$ReportSummary -eq $true -and
$Severity -contains 'Error' -and
$Severity -contains 'Warning' -and
Expand Down Expand Up @@ -104,14 +104,24 @@ Describe 'Unit Tests' -Tag 'Unit' {
"function Get-Top { 'ok' }" | Set-Content -Path "$fixtureDir/Top.ps1" -Encoding utf8
'function Get-Nested { gci }' | Set-Content -Path "$nestedDir/Alias.ps1" -Encoding utf8

$recursiveFindings = Invoke-PSModuleAnalyzer -SourceDirectory $fixtureDir -NoExit
$topOnlyFindings = Invoke-PSModuleAnalyzer -SourceDirectory "$fixtureDir/*.ps1" -NoRecurse -NoExit
$recursiveFindings = Invoke-PSModuleAnalyzer -SourceDirectory $fixtureDir
$topOnlyFindings = Invoke-PSModuleAnalyzer -SourceDirectory "$fixtureDir/*.ps1" -NoRecurse

$recursiveFindings.ScriptName | Should -Contain 'Alias.ps1'
$topOnlyFindings.ScriptName | Should -Contain 'Top.ps1'
$topOnlyFindings.ScriptName | Should -Not -Contain 'Alias.ps1'
}

It 'should hand a finding back to the caller rather than exiting on it' {
$fixtureDir = Join-Path -Path $TestDrive -ChildPath 'DefaultReturnFixture'
New-Item -ItemType Directory -Path $fixtureDir -Force | Out-Null
'function Get-Aliased { gci }' | Set-Content -Path "$fixtureDir/Aliased.ps1" -Encoding utf8

$findings = Invoke-PSModuleAnalyzer -SourceDirectory $fixtureDir

$findings.RuleName | Should -Contain 'PSAvoidUsingCmdletAliases'
}

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
Loading