Skip to content

Commit 2282d53

Browse files
committed
Merge pull request #164 from PowerShell/BugFixes
Bug fixes
2 parents 2260344 + 039e46c commit 2282d53

17 files changed

+126
-45
lines changed

Engine/Commands/GetScriptAnalyzerRuleCommand.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ protected override void ProcessRecord()
142142
{
143143
if (severity != null)
144144
{
145-
var ruleSeverity = severity.Select(item => Enum.Parse(typeof (RuleSeverity), item));
145+
var ruleSeverity = severity.Select(item => Enum.Parse(typeof (RuleSeverity), item, true));
146146
rules = rules.Where(item => ruleSeverity.Contains(item.GetSeverity())).ToList();
147147
}
148148

Engine/Commands/InvokeScriptAnalyzerCommand.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -581,7 +581,7 @@ private void AnalyzeFile(string filePath)
581581

582582
if (severity != null)
583583
{
584-
var diagSeverity = severity.Select(item => Enum.Parse(typeof(DiagnosticSeverity), item));
584+
var diagSeverity = severity.Select(item => Enum.Parse(typeof(DiagnosticSeverity), item, true));
585585
diagnostics = diagnostics.Where(item => diagSeverity.Contains(item.Severity)).ToList();
586586
}
587587

Engine/SpecialVars.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ static SpecialVars()
9191
internal const string WhatIfPreference = "WhatIfPreference";
9292
internal const string WarningPreference = "WarningPreference";
9393
internal const string ConfirmPreference = "ConfirmPreference";
94+
internal const string ProgressPreference = "ProgressPreference";
9495

9596
internal static readonly string[] PreferenceVariables = new string[]
9697
{
@@ -99,7 +100,8 @@ static SpecialVars()
99100
ErrorActionPreference,
100101
WhatIfPreference,
101102
WarningPreference,
102-
ConfirmPreference,
103+
ConfirmPreference,
104+
ProgressPreference
103105
};
104106

105107
internal static readonly Type[] PreferenceVariableTypes = new Type[]
@@ -109,7 +111,8 @@ static SpecialVars()
109111
/* ErrorPreference */ typeof(ActionPreference),
110112
/* WhatIfPreference */ typeof(SwitchParameter),
111113
/* WarningPreference */ typeof(ActionPreference),
112-
/* ConfirmPreference */ typeof(ConfirmImpact),
114+
/* ConfirmPreference */ typeof(ConfirmImpact),
115+
/* ProgressPreference */ typeof(Enum),
113116
};
114117

115118
internal enum AutomaticVariable

Engine/VariableAnalysis.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,8 @@ public bool IsUninitialized(VariableExpressionAst varTarget)
339339
}
340340

341341
return analysis.DefinedBlock == null
342-
&& !SpecialVars.InitializedVariables.Contains(analysis.Name, StringComparer.OrdinalIgnoreCase)
342+
&& !(SpecialVars.InitializedVariables.Contains(analysis.Name, StringComparer.OrdinalIgnoreCase) ||
343+
SpecialVars.InitializedVariables.Contains(analysis.RealName, StringComparer.OrdinalIgnoreCase))
343344
&& !IsGlobalOrEnvironment(varTarget);
344345
}
345346

Rules/AvoidDefaultTrueValueSwitchParameter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public IEnumerable<DiagnosticRecord> AnalyzeScript(Ast ast, string fileName)
3939
// Iterrates all ParamAsts and check if any are switch.
4040
foreach (ParameterAst paramAst in paramAsts)
4141
{
42-
if (paramAst.Attributes.Any(attr => String.Equals(attr.TypeName.FullName, "switch", StringComparison.OrdinalIgnoreCase))
42+
if (paramAst.Attributes.Any(attr => string.Equals(attr.TypeName.GetReflectionType().FullName, "system.management.automation.switchparameter", StringComparison.OrdinalIgnoreCase))
4343
&& paramAst.DefaultValue != null && String.Equals(paramAst.DefaultValue.Extent.Text, "$true", StringComparison.OrdinalIgnoreCase))
4444
{
4545
yield return new DiagnosticRecord(

Rules/MissingModuleManifestField.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
using System;
1414
using System.Collections.Generic;
15+
using System.Collections.ObjectModel;
1516
using System.Management.Automation.Language;
1617
using System.Management.Automation;
1718
using Microsoft.Windows.Powershell.ScriptAnalyzer.Generic;
@@ -44,6 +45,10 @@ public IEnumerable<DiagnosticRecord> AnalyzeScript(Ast ast, string fileName)
4445
{
4546
ps.AddCommand("Test-ModuleManifest");
4647
ps.AddParameter("Path", fileName);
48+
49+
// Suppress warnings emitted during the execution of Test-ModuleManifest
50+
// ModuleManifest rule must catch any violations (warnings/errors) and generate DiagnosticRecord(s)
51+
ps.AddParameter("WarningAction", ActionPreference.SilentlyContinue);
4752
ps.Invoke();
4853

4954
} catch { }

Rules/UseOutputTypeCorrectly.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ public override AstVisitAction VisitFunctionDefinition(FunctionDefinitionAst fun
110110
|| String.Equals(typeof(Unreached).FullName, typeName, StringComparison.OrdinalIgnoreCase)
111111
|| String.Equals(typeof(Undetermined).FullName, typeName, StringComparison.OrdinalIgnoreCase)
112112
|| String.Equals(typeof(object).FullName, typeName, StringComparison.OrdinalIgnoreCase)
113+
|| String.Equals(typeof(void).FullName, typeName, StringComparison.OrdinalIgnoreCase)
113114
|| outputTypes.Contains(typeName, StringComparer.OrdinalIgnoreCase))
114115
{
115116
continue;

Rules/UseSingularNouns.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ public IEnumerable<DiagnosticRecord> AnalyzeScript(Ast ast, string fileName) {
4949
String noun = funcNamePieces[1];
5050
var ps = System.Data.Entity.Design.PluralizationServices.PluralizationService.CreateService(CultureInfo.GetCultureInfo("en-us"));
5151

52-
if (ps.IsPlural(noun))
52+
if (!ps.IsSingular(noun))
5353
{
5454
yield return new DiagnosticRecord(string.Format(CultureInfo.CurrentCulture, Strings.UseSingularNounsError, funcAst.Name),
5555
funcAst.Extent, GetName(), DiagnosticSeverity.Warning, fileName);

Tests/Engine/GetScriptAnalyzerRule.tests.ps1

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -113,23 +113,28 @@ Describe "Test RuleExtension" {
113113
Describe "TestSeverity" {
114114
It "filters rules based on the specified rule severity" {
115115
$rules = Get-ScriptAnalyzerRule -Severity Error
116-
$rules.Count | Should be 4
116+
$rules.Count | Should be 6
117117
}
118118

119119
It "filters rules based on multiple severity inputs"{
120120
$rules = Get-ScriptAnalyzerRule -Severity Error,Information
121-
$rules.Count | Should be 8
121+
$rules.Count | Should be 12
122+
}
123+
124+
It "takes lower case inputs" {
125+
$rules = Get-ScriptAnalyzerRule -Severity error
126+
$rules.Count | Should be 6
122127
}
123128
}
124129

125130
Describe "TestWildCard" {
126131
It "filters rules based on the -Name wild card input" {
127132
$rules = Get-ScriptAnalyzerRule -Name PSDSC*
128-
$rules.Count | Should be 4
133+
$rules.Count | Should be 6
129134
}
130135

131136
It "filters rules based on wild card input and severity"{
132137
$rules = Get-ScriptAnalyzerRule -Name PSDSC* -Severity Information
133-
$rules.Count | Should be 2
138+
$rules.Count | Should be 3
134139
}
135140
}

Tests/Engine/InvokeScriptAnalyzer.tests.ps1

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ Describe "Test IncludeRule" {
141141

142142
it "includes 2 wildcardrules" {
143143
$includeWildcard = Invoke-ScriptAnalyzer $directory\..\Rules\BadCmdlet.ps1 -IncludeRule $avoidRules, $useRules
144-
$includeWildcard.Count | Should be 7
144+
$includeWildcard.Count | Should be 9
145145
}
146146
}
147147
}
@@ -169,6 +169,11 @@ Describe "Test Severity" {
169169
$errors = Invoke-ScriptAnalyzer $directory\TestScript.ps1 -Severity Information, Warning
170170
$errors.Count | Should Be 2
171171
}
172+
173+
It "works with lowercase argument"{
174+
$errors = Invoke-ScriptAnalyzer $directory\TestScript.ps1 -Severity information, warning
175+
$errors.Count | Should Be 2
176+
}
172177
}
173178

174179
Context "When used incorrectly" {

Tests/Rules/AvoidDefaultTrueValueSwitchParameter.ps1

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,11 @@
1313

1414
# Param2 help description
1515
[switch]
16-
$switch=$true
16+
$switch=$true,
17+
18+
# Param3 help description
19+
[System.Management.Automation.SwitchParameter]
20+
$switch2 = $true
1721
)
1822

1923
Begin

Tests/Rules/AvoidDefaultTrueValueSwitchParameter.tests.ps1

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ $noViolations = Invoke-ScriptAnalyzer $directory\AvoidDefaultTrueValueSwitchPara
77

88
Describe "AvoidDefaultTrueValueSwitchParameter" {
99
Context "When there are violations" {
10-
It "has 1 avoid using switch parameter default to true violation" {
11-
$violations.Count | Should Be 1
10+
It "has 2 avoid using switch parameter default to true violation" {
11+
$violations.Count | Should Be 2
1212
}
1313

1414
It "has the correct description message" {

Tests/Rules/AvoidGlobalOrUnitializedVarsNoViolations.ps1

Lines changed: 41 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,41 @@
1-
function Test {
2-
$initialized = "Initialized"
3-
$noglobal = "local"
4-
$env:ShouldNotRaiseError
5-
}
6-
7-
$a = 3;
8-
9-
if ($true) {
10-
$a = 4;
11-
$c = 3;
12-
} else {
13-
$b = 5;
14-
$c = 4;
15-
}
16-
17-
$b = 6;
18-
$a;
19-
$b;
20-
21-
stop-process 12,23 -ErrorVariable ev -ErrorAction SilentlyContinue
22-
if($null -ne $ev)
23-
{
24-
Write-host $ev[0]
25-
# no error should be raised here
26-
Invoke-Command {$b}
27-
}
28-
29-
get-process notepad | tee-object -variable proc
30-
$proc[0]
1+
function Test {
2+
$initialized = "Initialized"
3+
$noglobal = "local"
4+
$env:ShouldNotRaiseError
5+
}
6+
7+
$a = 3;
8+
9+
if ($true) {
10+
$a = 4;
11+
$c = 3;
12+
} else {
13+
$b = 5;
14+
$c = 4;
15+
}
16+
17+
$b = 6;
18+
$a;
19+
$b;
20+
21+
stop-process 12,23 -ErrorVariable ev -ErrorAction SilentlyContinue
22+
if($null -ne $ev)
23+
{
24+
Write-host $ev[0]
25+
# no error should be raised here
26+
Invoke-Command {$b}
27+
}
28+
29+
get-process notepad | tee-object -variable proc
30+
$proc[0]
31+
32+
function Test-PreferenceVariable
33+
{
34+
35+
if (-not $PSBoundParameters.ContainsKey('Verbose')) {
36+
$VerbosePreference = $PSCmdlet.GetVariableValue('VerbosePreference') -as
37+
[System.Management.Automation.ActionPreference]
38+
}
39+
40+
$VerbosePreference
41+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
Import-Module PSScriptAnalyzer
2+
$AvoidUninitializedVariable = "PSAvoidUninitializedVariable"
3+
$violationMessage = "Variable 'MyProgressPreference' is not initialized. Non-global variables must be initialized. To fix a violation of this rule, please initialize non-global variables."
4+
$directory = Split-Path -Parent $MyInvocation.MyCommand.Path
5+
$violations = Invoke-ScriptAnalyzer $directory\AvoidUsingUninitializedVariable.ps1 -IncludeRule $AvoidUninitializedVariable
6+
$noViolations = Invoke-ScriptAnalyzer $directory\AvoidUsingUninitializedVariableNoViolations.ps1 -IncludeRule $AvoidUninitializedVariable
7+
8+
Describe "AvoidUsingUninitializedVariable" {
9+
Context "Script uses uninitialized variables - Violation" {
10+
It "Have 3 rule violations" {
11+
$violations.Count | Should Be 3
12+
}
13+
14+
It "has the correct description message for UninitializedVariable rule violation" {
15+
$violations[0].Message | Should Be $violationMessage
16+
}
17+
}
18+
19+
Context "Script uses initialized variables - No violation" {
20+
It "results in no rule violations" {
21+
$noViolations.Count | Should Be 0
22+
}
23+
}
24+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Script has uninitialized variables
2+
# Must result in AvoidUsingUninitializedVariablerule violations along with other violations
3+
4+
function Test-MyPreference
5+
{
6+
Write-Verbose $MyProgressPreference
7+
Write-Verbose $MyVerbosePreference
8+
}
9+
10+
Write-Verbose $MyProgressPreference
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Script uses built-in preference variables
2+
# Must not result in AvoidUsingUninitializedVariablerule violations
3+
# However there are other violations in this script - Write-Verbose is not using positional parameters
4+
5+
function Test-Preference
6+
{
7+
Write-Verbose $ProgressPreference
8+
Write-Verbose $VerbosePreference
9+
}
10+
11+
Write-Verbose $ProgressPreference

Tests/Rules/GoodCmdlet.ps1

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ function Get-File
9191
{
9292
if ($pscmdlet.ShouldContinue("Yes", "No")) {
9393
}
94+
[System.Void] $Param3
9495
}
9596
}
9697

0 commit comments

Comments
 (0)