Skip to content

Commit 83779a2

Browse files
author
Kapil Borle
authored
Merge pull request #588 from PowerShell/ExternalRuleSuppression
Suppress external AST based rules
2 parents e8df57e + 51cefbc commit 83779a2

File tree

3 files changed

+63
-13
lines changed

3 files changed

+63
-13
lines changed

Engine/ScriptAnalyzer.cs

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1473,6 +1473,28 @@ private Tuple<List<SuppressedRecord>, List<DiagnosticRecord>> SuppressRule(
14731473
return records;
14741474
}
14751475

1476+
/// <summary>
1477+
/// Wrapper around SuppressRule method.
1478+
///
1479+
/// This enables suppressing external rules (written in PowerShell).
1480+
/// Since there can be an inconsistency between the rule name in
1481+
/// diagnostic record and the actual rule (function) name, we use
1482+
/// the diagnostic record rule name for suppression
1483+
/// </summary>
1484+
/// <param name="ruleSuppressions"></param>
1485+
/// <param name="ruleDiagnosticRecord"></param>
1486+
/// <returns>Returns a tuple of suppressed and diagnostic records</returns>
1487+
private Tuple<List<SuppressedRecord>, List<DiagnosticRecord>> SuppressRule(
1488+
Dictionary<string, List<RuleSuppression>> ruleSuppressions,
1489+
DiagnosticRecord ruleDiagnosticRecord
1490+
)
1491+
{
1492+
return SuppressRule(
1493+
ruleDiagnosticRecord.RuleName,
1494+
ruleSuppressions,
1495+
new List<DiagnosticRecord> { ruleDiagnosticRecord });
1496+
}
1497+
14761498
/// <summary>
14771499
/// Analyzes the syntax tree of a script file that has already been parsed.
14781500
/// </summary>
@@ -1770,13 +1792,21 @@ public IEnumerable<DiagnosticRecord> AnalyzeSyntaxTree(
17701792
}
17711793
}
17721794

1773-
foreach (var record in this.GetExternalRecord(scriptAst, scriptTokens, exRules.ToArray(), fileName))
1795+
foreach (var ruleRecord in this.GetExternalRecord(scriptAst, scriptTokens, exRules.ToArray(), fileName))
17741796
{
1775-
diagnostics.Add(record);
1797+
var records = SuppressRule(ruleSuppressions, ruleRecord);
1798+
foreach (var record in records.Item2)
1799+
{
1800+
diagnostics.Add(record);
1801+
}
1802+
foreach (var suppressedRec in records.Item1)
1803+
{
1804+
suppressed.Add(suppressedRec);
1805+
}
17761806
}
17771807
}
1778-
1779-
#endregion
1808+
1809+
#endregion
17801810

17811811
// Need to reverse the concurrentbag to ensure that results are sorted in the increasing order of line numbers
17821812
IEnumerable<DiagnosticRecord> diagnosticsList = diagnostics.Reverse();

Tests/Engine/RuleSuppression.tests.ps1

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -114,13 +114,29 @@ function SuppressPwdParam()
114114

115115
if (!$testingLibraryUsage)
116116
{
117-
Context "Bad Rule Suppression" {
118-
It "Throws a non-terminating error" {
119-
Invoke-ScriptAnalyzer -ScriptDefinition $ruleSuppressionBad -IncludeRule "PSAvoidUsingUserNameAndPassWordParams" -ErrorVariable errorRecord -ErrorAction SilentlyContinue
120-
$errorRecord.Count | Should Be 1
121-
$errorRecord.FullyQualifiedErrorId | Should match "suppression message attribute error"
122-
}
123-
}
117+
Context "Bad Rule Suppression" {
118+
It "Throws a non-terminating error" {
119+
Invoke-ScriptAnalyzer -ScriptDefinition $ruleSuppressionBad -IncludeRule "PSAvoidUsingUserNameAndPassWordParams" -ErrorVariable errorRecord -ErrorAction SilentlyContinue
120+
$errorRecord.Count | Should Be 1
121+
$errorRecord.FullyQualifiedErrorId | Should match "suppression message attribute error"
122+
}
123+
}
124+
125+
Context "External Rule Suppression" {
126+
$externalRuleSuppression = @'
127+
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('CommunityAnalyzerRules\Measure-WriteHost','')]
128+
param() # without the param block, powershell parser throws up!
129+
Write-Host "write-host"
130+
'@
131+
It "Suppresses violation of an external ast rule" {
132+
Invoke-ScriptAnalyzer `
133+
-ScriptDefinition $externalRuleSuppression `
134+
-CustomRulePath (Join-Path $directory "CommunityAnalyzerRules") `
135+
-OutVariable ruleViolations `
136+
-SuppressedOnly
137+
$ruleViolations.Count | Should Be 1
138+
}
139+
}
124140
}
125141
}
126142

build.ps1

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,12 @@ if ($BuildDocs)
110110
New-ExternalHelp -Path $markdownDocsPath -OutputPath $outputDocsPath -Force -Verbose:$verbosity
111111
}
112112

113-
114-
$moduleRootPath = Join-Path (Split-Path $profile) 'Modules'
113+
# Appveyor errors out due to $profile being null. Hence...
114+
$moduleRootPath = "$HOME/Documents/WindowsPowerShell/Modules"
115+
if ($profile -ne $null)
116+
{
117+
$moduleRootPath = Join-Path (Split-Path $profile) 'Modules'
118+
}
115119
$modulePSSAPath = Join-Path $moduleRootPath 'PSScriptAnalyzer'
116120
if ($Install)
117121
{

0 commit comments

Comments
 (0)