Skip to content

Integrate Master with BugFixes #236

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 45 commits into from
Jun 2, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
6ea858a
Merge pull request #119 from PowerShell/master
raghushantha May 7, 2015
1f43e97
Merge pull request #129 from PowerShell/BugFixes
raghushantha May 8, 2015
9539455
Merge pull request #170 from PowerShell/master
yutingc May 15, 2015
9f2564c
Added Build status for BugFixes and Development branches
raghushantha May 15, 2015
506da93
Update README.md
raghushantha May 15, 2015
f1b8484
Update README.md
raghushantha May 15, 2015
368309d
Merge pull request #172 from PowerShell/BuildStatusBranch
raghushantha May 15, 2015
44574b5
Add new ProvideDefaultParameterValue rule.
GoodOlClint May 16, 2015
513b04c
Tests for ProvideDefaultParameterValue rule
GoodOlClint May 16, 2015
503d18e
Don't trigger PSAvoidUninitializedVariable on function parameters
GoodOlClint May 16, 2015
2f5480d
Correct PSProvideDefaultParameterValue NoViolations test script
GoodOlClint May 16, 2015
4e9732c
Updated strings for PSProvideDefaultParameterValue
GoodOlClint May 16, 2015
55919be
Updated Tests for PSProvideDefaultParameterValue
GoodOlClint May 16, 2015
94dcf51
Raise PSProvideDefaultParameterValues for parameters outside a param …
GoodOlClint May 16, 2015
fdd1198
Don't raise PSAvoidUninitalizedVariables for parameters outside a par…
GoodOlClint May 16, 2015
67dbc2c
Updated PSProvideDefaultParameterValue Rules
GoodOlClint May 16, 2015
be83037
Do not trigger PSProvideDefaultParameterValue when parameters are use…
GoodOlClint May 16, 2015
ead2e6f
More robust PSProvideDefaultParameterValue tests
GoodOlClint May 16, 2015
18678a3
Correct Engine tests for PSProvideDefaultParameterValue
GoodOlClint May 17, 2015
2528ca6
Remove isDscResourceFile Check from PSAvoidUninitalizedVariables Rule
GoodOlClint May 17, 2015
276f464
Add isDscResourceFile Check to PSProvideDefaultParameterValue
GoodOlClint May 17, 2015
a848091
Merge pull request #174 from GoodOlClint/PSProvideDefaultParameterValue
raghushantha May 18, 2015
d6bde9d
Add rule documentation for ProvideDefaultParameter
yutingc May 18, 2015
8e1b187
Update ProvideDefaultParameterValue.md
yutingc May 18, 2015
b8d4d6b
Merge pull request #175 from PowerShell/NewRuleDocumentation
yutingc May 18, 2015
a22fe8f
Add new rule AvoidUsingDeprecatedManifestFileds
yutingc May 18, 2015
7ce25fd
Edit some fields
yutingc May 18, 2015
eae794c
Update some string format
yutingc May 18, 2015
f949885
Change the string format
yutingc May 18, 2015
3a62693
Add braces for if condition
yutingc May 18, 2015
67fc917
Modify error strings and test file fields
yutingc May 18, 2015
c0e1393
Added null check for BaseObject
yutingc May 18, 2015
a3ec054
Update the error description string
yutingc May 18, 2015
2e27554
Merge pull request #177 from PowerShell/AvoidUsingDeprecatedManifestF…
yutingc May 19, 2015
9704c47
Add rule documentation for new rule
yutingc May 19, 2015
0607a75
Change the formats
yutingc May 19, 2015
e050eb3
Merge pull request #184 from PowerShell/ruleDocumentationForNewRule
yutingc May 19, 2015
2849549
Merge pull request #186 from PowerShell/development
yutingc May 19, 2015
221933f
Merge pull request #185 from PowerShell/BugFixes
yutingc May 19, 2015
2bc754d
Rename License.txt to LICENSE.md
raghushantha May 20, 2015
5f677e9
Rename LICENSE.md to LICENSE
raghushantha May 20, 2015
785e4b8
Merge branch 'BugFixes'
yutingc May 29, 2015
46fcb59
Merge branch 'master' of https://github.com/PowerShell/PSScriptAnalyzer
yutingc May 29, 2015
c4ae0a5
Merge pull request #229 from PowerShell/BugFixes
raghushantha Jun 1, 2015
76200c9
Fix for failing RuleSuppressionID tests
raghushantha Jun 2, 2015
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
File renamed without changes.
15 changes: 6 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
|Master |BugFixes |Development |
|:------:|:------:|:-------:|:-------:|
[![Build status](https://ci.appveyor.com/api/projects/status/h5mot3vqtvxw5d7l/branch/master?svg=true)](https://ci.appveyor.com/project/PowerShell/psscriptanalyzer/branch/master)|[![Build status](https://ci.appveyor.com/api/projects/status/h5mot3vqtvxw5d7l/branch/bugfixes?svg=true)](https://ci.appveyor.com/project/PowerShell/psscriptanalyzer/branch/bugfixes)|[![Build status](https://ci.appveyor.com/api/projects/status/h5mot3vqtvxw5d7l/branch/development?svg=true)](https://ci.appveyor.com/project/PowerShell/psscriptanalyzer/branch/development) |

Introduction


Introduction
============

PSScriptAnalyzer is a static code checker for Windows PowerShell modules and scripts. PSScriptAnalyzer checks the quality of Windows PowerShell code by running a set of rules. The rules are based on PowerShell best practices identified by PowerShell Team and the community. It generates DiagnosticResults (errors and warnings) to inform users about potential code defects and suggests possible solutions for improvements.
Expand Down Expand Up @@ -42,14 +47,6 @@ Use Visual Studio to build "PSScriptAnalyzer.sln". Use ~/PSScriptAnalyzer/ folde
**Note: If there are any build errors, please refer to Requirements section and make sure all dependencies are properly installed**


Build Status
==============

| |Master Branch |
|---------|:------:|:------:|:-------:|:-------:|
|**Debug Version**|[![Build status](https://ci.appveyor.com/api/projects/status/h5mot3vqtvxw5d7l/branch/master?svg=true)](https://ci.appveyor.com/project/PowerShell/psscriptanalyzer/branch/master) |


Running Tests
=============

Expand Down
27 changes: 27 additions & 0 deletions RuleDocumentation/AvoidUsingDeprecatedManifestFields.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#AvoidUsingDeprecatedManifestFields
**Severity Level: Warning**


##Description

PowerShell V5.0 introduced some new fields and replaced some old fields with in module manifest files (.psd1). Therefore, fields such as "ModuleToProcess" is replaced with "RootModule". Using the deprecated manifest fields will result in PSScriptAnalyzer warnings.

##How to Fix

To fix a violation of this, please replace "ModuleToProcess" with "RootModule".

##Example

Wrong:
```
ModuleToProcess ='psscriptanalyzer'

ModuleVersion = '1.0'
```

Correct:
```
RootModule ='psscriptanalyzer'

ModuleVersion = '1.0'
```
30 changes: 30 additions & 0 deletions RuleDocumentation/ProvideDefaultParameterValue.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#ProvideDefaultParameterValue
**Severity Level: Warning**


##Description
Parameters must have a default value as uninitialized parameters will lead to potential bugs in the scripts.

##How to Fix

To fix a violation of this rule, please specify a default value for all parameters.

##Example

Wrong:

```
function Test($Param1)
{
$Param1
}
```

Correct:

```
function Test($Param1 = $null)
{
$Param1
}
```
22 changes: 10 additions & 12 deletions Rules/AvoidUninitializedVariable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,26 +52,24 @@ public IEnumerable<DiagnosticRecord> AnalyzeScript(Ast ast, string fileName)

IEnumerable<Ast> funcAsts = ast.FindAll(item => item is FunctionDefinitionAst, true);
IEnumerable<Ast> funcMemberAsts = ast.FindAll(item => item is FunctionMemberAst, true);

// Checks whether this is a dsc resource file (we don't raise this rule for get, set and test-target resource
bool isDscResourceFile = Helper.Instance.IsDscResourceModule(fileName);

List<string> targetResourcesFunctions = new List<string>( new string[] { "get-targetresource", "set-targetresource", "test-targetresource" });


foreach (FunctionDefinitionAst funcAst in funcAsts)
{
// Finds all VariableExpressionAst.
IEnumerable<Ast> varAsts = funcAst.FindAll(testAst => testAst is VariableExpressionAst, true);

HashSet<string> paramVariables = new HashSet<string>();

if (isDscResourceFile && targetResourcesFunctions.Contains(funcAst.Name, StringComparer.OrdinalIgnoreCase))
// don't raise the rules for variables in the param block.
if (funcAst.Body != null && funcAst.Body.ParamBlock != null && funcAst.Body.ParamBlock.Parameters != null)
{
// don't raise the rules for variables in the param block.
if (funcAst.Body != null && funcAst.Body.ParamBlock != null && funcAst.Body.ParamBlock.Parameters != null)
{
paramVariables.UnionWith(funcAst.Body.ParamBlock.Parameters.Select(paramAst => paramAst.Name.VariablePath.UserPath));
}
paramVariables.UnionWith(funcAst.Body.ParamBlock.Parameters.Select(paramAst => paramAst.Name.VariablePath.UserPath));
}

//don't raise the rules for parameters outside the param block
if(funcAst.Parameters != null)
{
paramVariables.UnionWith(funcAst.Parameters.Select(paramAst => paramAst.Name.VariablePath.UserPath));
}

// Iterates all VariableExpressionAst and check the command name.
Expand Down
132 changes: 132 additions & 0 deletions Rules/AvoidUsingDeprecatedManifestFields.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
//
// Copyright (c) Microsoft Corporation.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//

using System;
using System.Collections.Generic;
using System.Management.Automation.Language;
using System.Management.Automation;
using Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic;
using System.ComponentModel.Composition;
using System.Globalization;

namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.BuiltinRules
{
/// <summary>
/// AvoidUsingDeprecatedManifestFields: Run Test Module Manifest to check that no deprecated fields are being used.
/// </summary>
[Export(typeof(IScriptRule))]
public class AvoidUsingDeprecatedManifestFields : IScriptRule
{
/// <summary>
/// AnalyzeScript: Run Test Module Manifest to check that no deprecated fields are being used.
/// </summary>
/// <param name="ast">The script's ast</param>
/// <param name="fileName">The script's file name</param>
/// <returns>A List of diagnostic results of this rule</returns>
public IEnumerable<DiagnosticRecord> AnalyzeScript(Ast ast, string fileName)
{
if (ast == null)
{
throw new ArgumentNullException(Strings.NullAstErrorMessage);
}

if (String.Equals(System.IO.Path.GetExtension(fileName), ".psd1", StringComparison.OrdinalIgnoreCase))
{
var ps = System.Management.Automation.PowerShell.Create(RunspaceMode.CurrentRunspace);
IEnumerable<PSObject> result = null;
try
{
ps.AddCommand("Test-ModuleManifest");
ps.AddParameter("Path", fileName);

// Suppress warnings emitted during the execution of Test-ModuleManifest
// ModuleManifest rule must catch any violations (warnings/errors) and generate DiagnosticRecord(s)
ps.AddParameter("WarningAction", ActionPreference.SilentlyContinue);
ps.AddParameter("WarningVariable", "Message");
ps.AddScript("$Message");
result = ps.Invoke();

}
catch
{}

if (result != null)
{
foreach (var warning in result)
{
if (warning.BaseObject != null)
{
yield return
new DiagnosticRecord(
String.Format(CultureInfo.CurrentCulture, warning.BaseObject.ToString()), ast.Extent,
GetName(), DiagnosticSeverity.Warning, fileName);
}
}
}

}

}

/// <summary>
/// GetName: Retrieves the name of this rule.
/// </summary>
/// <returns>The name of this rule</returns>
public string GetName()
{
return string.Format(CultureInfo.CurrentCulture, Strings.NameSpaceFormat, GetSourceName(), Strings.AvoidUsingDeprecatedManifestFieldsName);
}

/// <summary>
/// GetCommonName: Retrieves the common name of this rule.
/// </summary>
/// <returns>The common name of this rule</returns>
public string GetCommonName()
{
return String.Format(CultureInfo.CurrentCulture, Strings.AvoidUsingDeprecatedManifestFieldsCommonName);
}

/// <summary>
/// GetDescription: Retrieves the description of this rule.
/// </summary>
/// <returns>The description of this rule</returns>
public string GetDescription()
{
return String.Format(CultureInfo.CurrentCulture, Strings.AvoidUsingDeprecatedManifestFieldsDescription);
}

/// <summary>
/// Method: Retrieves the type of the rule: builtin, managed or module.
/// </summary>
public SourceType GetSourceType()
{
return SourceType.Builtin;
}

/// <summary>
/// GetSeverity: Retrieves the severity of the rule: error, warning of information.
/// </summary>
/// <returns></returns>
public RuleSeverity GetSeverity()
{
return RuleSeverity.Warning;
}

/// <summary>
/// Method: Retrieves the module/assembly name the rule is from.
/// </summary>
public string GetSourceName()
{
return string.Format(CultureInfo.CurrentCulture, Strings.SourceName);
}
}
}
140 changes: 140 additions & 0 deletions Rules/ProvideDefaultParameterValue.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
//
// Copyright (c) Microsoft Corporation.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//

using System;
using System.Linq;
using System.Collections.Generic;
using System.Management.Automation.Language;
using Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic;
using System.ComponentModel.Composition;
using System.Globalization;

namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.BuiltinRules
{
/// <summary>
/// ProvideDefaultParameterValue: Check if any uninitialized variable is used.
/// </summary>
[Export(typeof(IScriptRule))]
public class ProvideDefaultParameterValue : IScriptRule
{
/// <summary>
/// AnalyzeScript: Check if any uninitialized variable is used.
/// </summary>
public IEnumerable<DiagnosticRecord> AnalyzeScript(Ast ast, string fileName)
{
if (ast == null) throw new ArgumentNullException(Strings.NullAstErrorMessage);

// Finds all functionAst
IEnumerable<Ast> functionAsts = ast.FindAll(testAst => testAst is FunctionDefinitionAst, true);

// Checks whether this is a dsc resource file (we don't raise this rule for get, set and test-target resource
bool isDscResourceFile = Helper.Instance.IsDscResourceModule(fileName);

List<string> targetResourcesFunctions = new List<string>(new string[] { "get-targetresource", "set-targetresource", "test-targetresource" });


foreach (FunctionDefinitionAst funcAst in functionAsts)
{
// Finds all ParamAsts.
IEnumerable<Ast> varAsts = funcAst.FindAll(testAst => testAst is VariableExpressionAst, true);

// Iterrates all ParamAsts and check if their names are on the list.

HashSet<string> dscVariables = new HashSet<string>();
if (isDscResourceFile && targetResourcesFunctions.Contains(funcAst.Name, StringComparer.OrdinalIgnoreCase))
{
// don't raise the rules for variables in the param block.
if (funcAst.Body != null && funcAst.Body.ParamBlock != null && funcAst.Body.ParamBlock.Parameters != null)
{
dscVariables.UnionWith(funcAst.Body.ParamBlock.Parameters.Select(paramAst => paramAst.Name.VariablePath.UserPath));
}
}
// only raise the rules for variables in the param block.
if (funcAst.Body != null && funcAst.Body.ParamBlock != null && funcAst.Body.ParamBlock.Parameters != null)
{
foreach (var paramAst in funcAst.Body.ParamBlock.Parameters)
{
if (Helper.Instance.IsUninitialized(paramAst.Name, funcAst) && !dscVariables.Contains(paramAst.Name.VariablePath.UserPath))
{
yield return new DiagnosticRecord(string.Format(CultureInfo.CurrentCulture, Strings.ProvideDefaultParameterValueError, paramAst.Name.VariablePath.UserPath),
paramAst.Name.Extent, GetName(), DiagnosticSeverity.Warning, fileName, paramAst.Name.VariablePath.UserPath);
}
}
}

if (funcAst.Parameters != null)
{
foreach (var paramAst in funcAst.Parameters)
{
if (Helper.Instance.IsUninitialized(paramAst.Name, funcAst) && !dscVariables.Contains(paramAst.Name.VariablePath.UserPath))
{
yield return new DiagnosticRecord(string.Format(CultureInfo.CurrentCulture, Strings.ProvideDefaultParameterValueError, paramAst.Name.VariablePath.UserPath),
paramAst.Name.Extent, GetName(), DiagnosticSeverity.Warning, fileName, paramAst.Name.VariablePath.UserPath);
}
}
}
}
}

/// <summary>
/// GetName: Retrieves the name of this rule.
/// </summary>
/// <returns>The name of this rule</returns>
public string GetName()
{
return string.Format(CultureInfo.CurrentCulture, Strings.NameSpaceFormat, GetSourceName(), Strings.ProvideDefaultParameterValueName);
}

/// <summary>
/// GetCommonName: Retrieves the common name of this rule.
/// </summary>
/// <returns>The common name of this rule</returns>
public string GetCommonName()
{
return string.Format(CultureInfo.CurrentCulture, Strings.ProvideDefaultParameterValueCommonName);
}

/// <summary>
/// GetDescription: Retrieves the description of this rule.
/// </summary>
/// <returns>The description of this rule</returns>
public string GetDescription()
{
return string.Format(CultureInfo.CurrentCulture, Strings.ProvideDefaultParameterValueDescription);
}

/// <summary>
/// Method: Retrieves the type of the rule: builtin, managed or module.
/// </summary>
public SourceType GetSourceType()
{
return SourceType.Builtin;
}

/// <summary>
/// GetSeverity: Retrieves the severity of the rule: error, warning of information.
/// </summary>
/// <returns></returns>
public RuleSeverity GetSeverity()
{
return RuleSeverity.Warning;
}

/// <summary>
/// Method: Retrieves the module/assembly name the rule is from.
/// </summary>
public string GetSourceName()
{
return string.Format(CultureInfo.CurrentCulture, Strings.SourceName);
}
}
}
Loading