diff --git a/.github/workflows/test-analysis-failure.yml b/.github/workflows/test-analysis-failure.yml index 1f9453d6..42a3a838 100644 --- a/.github/workflows/test-analysis-failure.yml +++ b/.github/workflows/test-analysis-failure.yml @@ -23,6 +23,9 @@ jobs: PSAvoidUsingLineContinuation: Using backtick (line continuation) makes the code harder to read and maintain. PSUseApprovedVerbs: The cmdlet 'Violate-Analyzers' uses an unapproved verb. PSUseSingularNouns: The cmdlet 'Violate-Analyzers' uses a plural noun. + PSAvoidUsingWriteHost: File 'Violate-Analyzers.ps1' uses Write-Host. + PSUseConsistentIndentation: Indentation not consistent + PSAvoidUsingDoubleQuotesForConstantString: Use single quotes when a string is constant. call-test-analysis-failure-local: name: Test Analysis Failure - Local ProjectReference @@ -39,3 +42,6 @@ jobs: PSAvoidUsingLineContinuation: Using backtick (line continuation) makes the code harder to read and maintain. PSUseApprovedVerbs: The cmdlet 'Violate-Analyzers' uses an unapproved verb. PSUseSingularNouns: The cmdlet 'Violate-Analyzers' uses a plural noun. + PSAvoidUsingWriteHost: File 'Violate-Analyzers.ps1' uses Write-Host. + PSUseConsistentIndentation: Indentation not consistent + PSAvoidUsingDoubleQuotesForConstantString: Use single quotes when a string is constant. diff --git a/Lombiq.Analyzers.PowerShell/Invoke-Analyzer.ps1 b/Lombiq.Analyzers.PowerShell/Invoke-Analyzer.ps1 index 91b65bda..0694d0aa 100644 --- a/Lombiq.Analyzers.PowerShell/Invoke-Analyzer.ps1 +++ b/Lombiq.Analyzers.PowerShell/Invoke-Analyzer.ps1 @@ -57,7 +57,7 @@ function Write-FileError([string] $Message, [string] $Path, [int] $Line = 0, [in } elseif ($ForMsBuild) { - if (-not $Message.Contains(":")) { $Message = ": $Message" } + if (-not $Message.Contains(':')) { $Message = ": $Message" } if ($Path) { @@ -84,7 +84,7 @@ else exit -1 } -$installVersion = "1.20.0" +$installVersion = '1.21.0' if ((Get-InstalledModule PSScriptAnalyzer -ErrorAction SilentlyContinue).Version -ne [Version]$installVersion) { try @@ -94,10 +94,12 @@ if ((Get-InstalledModule PSScriptAnalyzer -ErrorAction SilentlyContinue).Version } catch { - $infoUrl = "https://docs.microsoft.com/en-us/powershell/utility-modules/psscriptanalyzer/overview?view=ps-modules#installing-psscriptanalyzer" - Write-FileError ("Unable to detect Invoke-ScriptAnalyzer and failed to install PSScriptAnalyzer. If you " + - "are on Windows Powershell, open an administrator shell and type `"Install-Module -Name " + - "PSScriptAnalyzer -Force -RequiredVersion $installVersion`". Otherwise see $infoUrl to learn more.") + $infoUrl = 'https://docs.microsoft.com/en-us/powershell/utility-modules/psscriptanalyzer/overview?view=ps-modules#installing-psscriptanalyzer' + @( + 'Unable to detect Invoke-ScriptAnalyzer and failed to install PSScriptAnalyzer. If you are on Windows' + 'Powershell, open an administrator shell and type "Install-Module -Name PSScriptAnalyzer -RequiredVersion' + "$installVersion`". Otherwise see $infoUrl to learn more." + ) -join ' ' | Write-FileError exit -2 } } @@ -109,18 +111,16 @@ $analyzerParameters = @{ IncludeDefaultRules = $true Fix = $Fix } -$results = Find-Recursively -IncludeFile "*.ps1", "*.psm1", "*.psd1" -ExcludeDirectory node_modules | +$results = Find-Recursively -IncludeFile '*.ps1', '*.psm1', '*.psd1' -ExcludeDirectory node_modules | Where-Object { # Exclude /TestSolutions/Violate-Analyzers.ps1 and /TestSolutions/*/Violate-Analyzers.ps1 $IncludeTestSolutions -or -not ( $PSItem.Name -eq 'Violate-Analyzers.ps1' -and ($PSItem.Directory.Name -eq 'TestSolutions' -or $PSItem.Directory.Parent.Name -eq 'TestSolutions')) } | - ForEach-Object { Invoke-ScriptAnalyzer -Path $PSItem.FullName @analyzerParameters } | - # Only Warning and above (ignore "Information" type results). - Where-Object { $PSItem.Severity -ge [Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic.DiagnosticSeverity]::Warning } + ForEach-Object { Invoke-ScriptAnalyzer -Path $PSItem.FullName @analyzerParameters } foreach ($result in $results) { - $message = $result.RuleName + ": " + $result.Message + $message = $result.RuleName + ': ' + $result.Message Write-FileError -Path $result.ScriptPath -Line $result.Line -Column $result.Column $message } diff --git a/Lombiq.Analyzers.PowerShell/PSScriptAnalyzerSettings.psd1 b/Lombiq.Analyzers.PowerShell/PSScriptAnalyzerSettings.psd1 index 39478b29..677a637b 100644 --- a/Lombiq.Analyzers.PowerShell/PSScriptAnalyzerSettings.psd1 +++ b/Lombiq.Analyzers.PowerShell/PSScriptAnalyzerSettings.psd1 @@ -1,8 +1,53 @@ @{ ExcludeRules = @( + 'PSDscExamplesPresent', + 'PSDscTestsPresent', + 'PSReturnCorrectTypesForDSCFunctions', + 'PSProvideCommentHelp', # This rule expects us to implement a feature we will be unlikely to use in the majority of cases. Although # ShouldProcess support should be implemented in cases where it makes sense. 'PSUseShouldProcessForStateChangingFunctions' ) + Rules = @{ + PSAvoidSemicolonsAsLineTerminators = @{ + Enable = $true + } + PSAvoidUsingDoubleQuotesForConstantString = @{ + Enable = $true + } + PSPlaceCloseBrace = @{ + Enable = $true + IgnoreOneLineBlock = $true + NewLineAfter = $true + NoEmptyLineBefore = $false + } + PSPlaceOpenBrace = @{ + Enable = $true + IgnoreOneLineBlock = $true + NewLineAfter = $true + OnSameLine = $false + } + PSUseConsistentIndentation = @{ + Enable = $true + IndentationSize = 4 + PipelineIndentation = 'IncreaseIndentationForFirstPipeline' + Kind = 'space' + } + PSUseConsistentWhitespace = @{ + Enable = $true + CheckInnerBrace = $true + CheckOpenBrace = $true + CheckOpenParen = $true + CheckOperator = $true + CheckPipe = $true + CheckPipeForRedundantWhitespace = $true + CheckSeparator = $true + CheckParameter = $false + IgnoreAssignmentOperatorInsideHashTable = $false + } + PSUseCorrectCasing = @{ + Enable = $true + } + } } diff --git a/Lombiq.Analyzers.PowerShell/Rules/Measure-AutomaticVariableAlias/Measure-AutomaticVariableAlias.psm1 b/Lombiq.Analyzers.PowerShell/Rules/Measure-AutomaticVariableAlias/Measure-AutomaticVariableAlias.psm1 index c0daf0df..ccff0ed0 100644 --- a/Lombiq.Analyzers.PowerShell/Rules/Measure-AutomaticVariableAlias/Measure-AutomaticVariableAlias.psm1 +++ b/Lombiq.Analyzers.PowerShell/Rules/Measure-AutomaticVariableAlias/Measure-AutomaticVariableAlias.psm1 @@ -31,29 +31,31 @@ function Measure-AutomaticVariableAlias try { # Filter down tokens to just variable tokens with the name "_". - foreach ($automaticVariableAliasToken in $Token | Where-Object { $PSItem.GetType().Name -eq "VariableToken" -and $PSItem.Name -eq "_" }) + foreach ($automaticVariableAliasToken in $Token | Where-Object { $PSItem.GetType().Name -eq 'VariableToken' -and $PSItem.Name -eq '_' }) { - $correctionTypeName = "Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic.CorrectionExtent" + $correctionTypeName = 'Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic.CorrectionExtent' $correctionExtent = New-Object -TypeName $correctionTypeName -ArgumentList @( $automaticVariableAliasToken.Extent.StartLineNumber $automaticVariableAliasToken.Extent.EndLineNumber $automaticVariableAliasToken.Extent.StartColumnNumber $automaticVariableAliasToken.Extent.EndColumnNumber '$PSItem' - 'Replaced the usage of the alias of the automatic variable ''$_'' with its full name ''$PSItem''.' + 'Replaced the usage of the alias of the automatic variable "$_" with its full name "$PSItem".' ) $suggestedCorrections = New-Object System.Collections.ObjectModel.Collection[$correctionTypeName] $suggestedCorrections.add($correctionExtent) | Out-Null $results += [Microsoft.Windows.Powershell.ScriptAnalyzer.Generic.DiagnosticRecord]@{ - "Extent" = $automaticVariableAliasToken.Extent - "Message" = '''$_'' is an alias of the automatic variable ''$PSItem''. Please consider using the full name of this' + - ' variable for consistency.' - "RuleName" = "PSAvoidUsingAutomaticVariableAlias" - "RuleSuppressionID" = "PSAvoidUsingAutomaticVariableAlias" - "Severity" = "Warning" - "SuggestedCorrections" = $suggestedCorrections + 'Extent' = $automaticVariableAliasToken.Extent + 'Message' = @( + '"$_" is an alias of the automatic variable "$PSItem". Please use the full name of this' + 'variable for consistency.' + ) -join ' ' + 'RuleName' = 'PSAvoidUsingAutomaticVariableAlias' + 'RuleSuppressionID' = 'PSAvoidUsingAutomaticVariableAlias' + 'Severity' = 'Warning' + 'SuggestedCorrections' = $suggestedCorrections } } diff --git a/Lombiq.Analyzers.PowerShell/Rules/Measure-LineContinuation/Measure-LineContinuation.psm1 b/Lombiq.Analyzers.PowerShell/Rules/Measure-LineContinuation/Measure-LineContinuation.psm1 index 53309e98..34c94188 100644 --- a/Lombiq.Analyzers.PowerShell/Rules/Measure-LineContinuation/Measure-LineContinuation.psm1 +++ b/Lombiq.Analyzers.PowerShell/Rules/Measure-LineContinuation/Measure-LineContinuation.psm1 @@ -38,12 +38,14 @@ function Measure-LineContinuation $PSItem.Kind -eq [System.Management.Automation.Language.TokenKind]::LineContinuation }) { $results += [Microsoft.Windows.Powershell.ScriptAnalyzer.Generic.DiagnosticRecord]@{ - "Extent" = $lineContinuationToken.Extent - "Message" = 'Using backtick (line continuation) makes the code harder to read and' + - ' maintain. Please consider using parameter splatting instead.' - "RuleName" = "PSAvoidUsingLineContinuation" - "RuleSuppressionID" = "PSAvoidUsingLineContinuation" - "Severity" = "Warning" + 'Extent' = $lineContinuationToken.Extent + 'Message' = @( + 'Using backtick (line continuation) makes the code harder to read and maintain. Please use' + 'parameter splatting instead.' + ) -join ' ' + 'RuleName' = 'PSAvoidUsingLineContinuation' + 'RuleSuppressionID' = 'PSAvoidUsingLineContinuation' + 'Severity' = 'Warning' } } diff --git a/TestSolutions/Lombiq.Analyzers.PowerShell.PackageReference/Lombiq.Analyzers.PowerShell.PackageReference.csproj b/TestSolutions/Lombiq.Analyzers.PowerShell.PackageReference/Lombiq.Analyzers.PowerShell.PackageReference.csproj index 724512a8..cb739980 100644 --- a/TestSolutions/Lombiq.Analyzers.PowerShell.PackageReference/Lombiq.Analyzers.PowerShell.PackageReference.csproj +++ b/TestSolutions/Lombiq.Analyzers.PowerShell.PackageReference/Lombiq.Analyzers.PowerShell.PackageReference.csproj @@ -7,7 +7,7 @@ - + diff --git a/TestSolutions/Violate-Analyzers.ps1 b/TestSolutions/Violate-Analyzers.ps1 index 18137174..ba1ce7e6 100644 --- a/TestSolutions/Violate-Analyzers.ps1 +++ b/TestSolutions/Violate-Analyzers.ps1 @@ -1,9 +1,9 @@ function Violate-Analyzers() { - "This file is intended to verify that PSScriptAnalyzer works and contains intentionally bad code." + Write-Host 'This file contains intentionally bad code to verify that PSScriptAnalyzer works correctly.' } try { Violate-Analyzers } catch { } "Lombiq", ` -"Orchard", "Hastlayer" | % { $_ } +'Orchard', 'Hastlayer' | % { $_ }