diff --git a/Engine/Commands/InvokeScriptAnalyzerCommand.cs b/Engine/Commands/InvokeScriptAnalyzerCommand.cs index 40b8d5cff..4719a51a1 100644 --- a/Engine/Commands/InvokeScriptAnalyzerCommand.cs +++ b/Engine/Commands/InvokeScriptAnalyzerCommand.cs @@ -192,6 +192,17 @@ public SwitchParameter Fix } private bool fix; + /// + /// Sets the exit code to the number of warnings for usage in CI. + /// + [Parameter(Mandatory = false)] + public SwitchParameter EnableExit + { + get { return enableExit; } + set { enableExit = value; } + } + private bool enableExit; + /// /// Returns path to the file that contains user profile or hash table for ScriptAnalyzer /// @@ -418,6 +429,11 @@ private void WriteToOutput(IEnumerable diagnosticRecords) logger.LogObject(diagnostic, this); } } + + if (EnableExit.IsPresent) + { + this.Host.SetShouldExit(diagnosticRecords.Count()); + } } private void ProcessPath() diff --git a/README.md b/README.md index b36790705..3cd91f699 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,7 @@ Usage ``` PowerShell Get-ScriptAnalyzerRule [-CustomizedRulePath ] [-Name ] [] [-Severity ] -Invoke-ScriptAnalyzer [-Path] [-CustomizedRulePath ] [-ExcludeRule ] [-IncludeRule ] [-Severity ] [-Recurse] [-Fix] [] +Invoke-ScriptAnalyzer [-Path] [-CustomizedRulePath ] [-ExcludeRule ] [-IncludeRule ] [-Severity ] [-Recurse] [-EnableExit] [-Fix] [] ``` [Back to ToC](#table-of-contents) diff --git a/Tests/Engine/InvokeScriptAnalyzer.tests.ps1 b/Tests/Engine/InvokeScriptAnalyzer.tests.ps1 index a915bed85..50f2e8a2f 100644 --- a/Tests/Engine/InvokeScriptAnalyzer.tests.ps1 +++ b/Tests/Engine/InvokeScriptAnalyzer.tests.ps1 @@ -497,3 +497,10 @@ Describe "Test -Fix Switch" { $actualScriptContentAfterFix | Should Be $expectedScriptContentAfterFix } } + +Describe "Test -EnableExit Switch" { + It "Returns exit code equivalent to number of warnings" { + powershell -Command 'Import-Module PSScriptAnalyzer; Invoke-ScriptAnalyzer -ScriptDefinition gci -EnableExit' + $LASTEXITCODE | Should Be 1 + } +} diff --git a/Tests/Engine/LibraryUsage.tests.ps1 b/Tests/Engine/LibraryUsage.tests.ps1 index a945fdd02..3bf7890bd 100644 --- a/Tests/Engine/LibraryUsage.tests.ps1 +++ b/Tests/Engine/LibraryUsage.tests.ps1 @@ -51,7 +51,10 @@ function Invoke-ScriptAnalyzer { [switch] $SuppressedOnly, [Parameter(Mandatory = $false)] - [switch] $Fix + [switch] $Fix, + + [Parameter(Mandatory = $false)] + [switch] $EnableExit ) if ($null -eq $CustomRulePath) @@ -77,16 +80,28 @@ function Invoke-ScriptAnalyzer { $SuppressedOnly.IsPresent ); - if ($PSCmdlet.ParameterSetName -eq "File") { - $supportsShouldProcessFunc = [Func[string, string, bool]]{ return $PSCmdlet.Shouldprocess } - if ($Fix.IsPresent) - { - return $scriptAnalyzer.AnalyzeAndFixPath($Path, $supportsShouldProcessFunc, $Recurse.IsPresent); - } - return $scriptAnalyzer.AnalyzePath($Path, $supportsShouldProcessFunc, $Recurse.IsPresent); + if ($PSCmdlet.ParameterSetName -eq "File") + { + $supportsShouldProcessFunc = [Func[string, string, bool]] { return $PSCmdlet.Shouldprocess } + if ($Fix.IsPresent) + { + $results = $scriptAnalyzer.AnalyzeAndFixPath($Path, $supportsShouldProcessFunc, $Recurse.IsPresent); + } + else + { + $results = $scriptAnalyzer.AnalyzePath($Path, $supportsShouldProcessFunc, $Recurse.IsPresent); + } } - else { - return $scriptAnalyzer.AnalyzeScriptDefinition($ScriptDefinition); + else + { + $results = $scriptAnalyzer.AnalyzeScriptDefinition($ScriptDefinition); + } + + $results + + if ($EnableExit.IsPresent -and $null -ne $results) + { + exit $results.Count } } diff --git a/docs/markdown/Invoke-ScriptAnalyzer.md b/docs/markdown/Invoke-ScriptAnalyzer.md index b421ea076..a83634afd 100644 --- a/docs/markdown/Invoke-ScriptAnalyzer.md +++ b/docs/markdown/Invoke-ScriptAnalyzer.md @@ -12,14 +12,14 @@ Evaluates a script or module based on selected best practice rules ### UNNAMED_PARAMETER_SET_1 ``` Invoke-ScriptAnalyzer [-Path] [-CustomRulePath ] [-RecurseCustomRulePath] - [-ExcludeRule ] [-IncludeRule ] [-Severity ] [-Recurse] [-SuppressedOnly] [-Fix] + [-ExcludeRule ] [-IncludeRule ] [-Severity ] [-Recurse] [-SuppressedOnly] [-Fix] [-EnableExit] [-Settings ] ``` ### UNNAMED_PARAMETER_SET_2 ``` Invoke-ScriptAnalyzer [-ScriptDefinition] [-CustomRulePath ] [-RecurseCustomRulePath] - [-ExcludeRule ] [-IncludeRule ] [-Severity ] [-Recurse] [-SuppressedOnly] + [-ExcludeRule ] [-IncludeRule ] [-Severity ] [-Recurse] [-SuppressedOnly] [-EnableExit] [-Settings ] ``` @@ -48,6 +48,7 @@ To get rules that were suppressed, run Invoke-ScriptAnalyzer with the SuppressedOnly parameter. For instructions on suppressing a rule, see the description of the SuppressedOnly parameter. +For usage in CI systems, the -EnableExit exits the shell with an exit code equal to the number of error records. The PSScriptAnalyzer module tests the Windows PowerShell code in a script, module, or DSC resource to determine whether, and to what extent, it fulfils best practice standards. @@ -416,6 +417,21 @@ Accept pipeline input: False Accept wildcard characters: False ``` +### -EnableExit +Exits PowerShell and returns an exit code equal to the number of error records. This can be useful in CI systems. + +```yaml +Type: SwitchParameter +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: False +Accept pipeline input: False +Accept wildcard characters: False +``` + ### -Settings File path that contains user profile or hash table for ScriptAnalyzer