From a22fe8f7aeef6e4666b92328ce79e173cb84fe55 Mon Sep 17 00:00:00 2001 From: Yuting Chen Date: Mon, 18 May 2015 15:14:40 -0700 Subject: [PATCH 1/8] Add new rule AvoidUsingDeprecatedManifestFileds --- Rules/AvoidUsingDeprecatedManifestFields.cs | 123 ++++++++++++++++++ Rules/ScriptAnalyzerBuiltinRules.csproj | 1 + Rules/Strings.Designer.cs | 33 ++++- Rules/Strings.resx | 9 ++ ...oidUsingDeprecatedManifestFields.tests.ps1 | 19 +++ Tests/Rules/TestBadModule/TestBadModule.psd1 | Bin 6564 -> 6598 bytes .../TestDeprecatedManifestFields.psd1 | 120 +++++++++++++++++ 7 files changed, 302 insertions(+), 3 deletions(-) create mode 100644 Rules/AvoidUsingDeprecatedManifestFields.cs create mode 100644 Tests/Rules/AvoidUsingDeprecatedManifestFields.tests.ps1 create mode 100644 Tests/Rules/TestBadModule/TestDeprecatedManifestFields.psd1 diff --git a/Rules/AvoidUsingDeprecatedManifestFields.cs b/Rules/AvoidUsingDeprecatedManifestFields.cs new file mode 100644 index 000000000..76aa39cb2 --- /dev/null +++ b/Rules/AvoidUsingDeprecatedManifestFields.cs @@ -0,0 +1,123 @@ +// +// 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 +{ + /// + /// MissingModuleManifestField: Run Test Module Manifest to check that no deprecated fields are being used. + /// + [Export(typeof(IScriptRule))] + public class AvoidUsingDeprecatedManifestFields : IScriptRule + { + /// + /// AnalyzeScript: Run Test Module Manifest to check that no deprecated fields are being used. + /// + /// The script's ast + /// The script's file name + /// A List of diagnostic results of this rule + public IEnumerable 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 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) + { + yield return new DiagnosticRecord(warning.BaseObject.ToString(), ast.Extent, GetName(), DiagnosticSeverity.Warning, fileName); + } + } + + } + + } + + /// + /// GetName: Retrieves the name of this rule. + /// + /// The name of this rule + public string GetName() + { + return string.Format(CultureInfo.CurrentCulture, Strings.NameSpaceFormat, GetSourceName(), Strings.AvoidUsingDeprecatedManifestFieldsName); + } + + /// + /// GetCommonName: Retrieves the common name of this rule. + /// + /// The common name of this rule + public string GetCommonName() + { + return String.Format(CultureInfo.CurrentCulture, Strings.AvoidUsingDeprecatedManifestFieldsCommonName); + } + + /// + /// GetDescription: Retrieves the description of this rule. + /// + /// The description of this rule + public string GetDescription() + { + return String.Format(CultureInfo.CurrentCulture, Strings.AvoidUsingDeprecatedManifestFieldsDescription); + } + + /// + /// Method: Retrieves the type of the rule: builtin, managed or module. + /// + public SourceType GetSourceType() + { + return SourceType.Builtin; + } + + /// + /// GetSeverity: Retrieves the severity of the rule: error, warning of information. + /// + /// + public RuleSeverity GetSeverity() + { + return RuleSeverity.Warning; + } + + /// + /// Method: Retrieves the module/assembly name the rule is from. + /// + public string GetSourceName() + { + return string.Format(CultureInfo.CurrentCulture, Strings.SourceName); + } + } +} diff --git a/Rules/ScriptAnalyzerBuiltinRules.csproj b/Rules/ScriptAnalyzerBuiltinRules.csproj index 9f553cb06..087930117 100644 --- a/Rules/ScriptAnalyzerBuiltinRules.csproj +++ b/Rules/ScriptAnalyzerBuiltinRules.csproj @@ -59,6 +59,7 @@ + diff --git a/Rules/Strings.Designer.cs b/Rules/Strings.Designer.cs index 3f8180b6c..108a90fce 100644 --- a/Rules/Strings.Designer.cs +++ b/Rules/Strings.Designer.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // // This code was generated by a tool. -// Runtime Version:4.0.30319.34209 +// Runtime Version:4.0.30319.35317 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. @@ -510,6 +510,33 @@ internal static string AvoidUsingConvertToSecureStringWithPlainTextName { } } + /// + /// Looks up a localized string similar to Avoid Using Deprecated Manifest Fields. + /// + internal static string AvoidUsingDeprecatedManifestFieldsCommonName { + get { + return ResourceManager.GetString("AvoidUsingDeprecatedManifestFieldsCommonName", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Some manifest fields are obsolte in the latest PowerShell version. Please update with the latest manifest fields in modules to avoid PowerShell version inconsistency.. + /// + internal static string AvoidUsingDeprecatedManifestFieldsDescription { + get { + return ResourceManager.GetString("AvoidUsingDeprecatedManifestFieldsDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to AvoidUsingDeprecatedManifestFields. + /// + internal static string AvoidUsingDeprecatedManifestFieldsName { + get { + return ResourceManager.GetString("AvoidUsingDeprecatedManifestFieldsName", resourceCulture); + } + } + /// /// Looks up a localized string similar to Avoid Using Empty Catch Block. /// @@ -1114,7 +1141,7 @@ internal static string ProvideDefaultParameterValueCommonName { } /// - /// Looks up a localized string similar to Parameters must have a default value. To fix a violation of this rule, please specify a default value for parameters. + /// Looks up a localized string similar to Parameters must have a default value. To fix a violation of this rule, please specify a default value for all parameters. /// internal static string ProvideDefaultParameterValueDescription { get { @@ -1123,7 +1150,7 @@ internal static string ProvideDefaultParameterValueDescription { } /// - /// Looks up a localized string similar to Parameter '{0}' is not initialized. Parameters must have a default value. To fix a violation of this rule, please specify a default value for parameters. + /// Looks up a localized string similar to Parameter '{0}' is not initialized. Parameters must have a default value. To fix a violation of this rule, please specify a default value for all parameters. /// internal static string ProvideDefaultParameterValueError { get { diff --git a/Rules/Strings.resx b/Rules/Strings.resx index da0010853..edd55e8f4 100644 --- a/Rules/Strings.resx +++ b/Rules/Strings.resx @@ -726,4 +726,13 @@ ProvideDefaultParameterValue + + Avoid Using Deprecated Manifest Fields + + + Some manifest fields are obsolte in the latest PowerShell version. Please update with the latest manifest fields in modules to avoid PowerShell version inconsistency. + + + AvoidUsingDeprecatedManifestFields + \ No newline at end of file diff --git a/Tests/Rules/AvoidUsingDeprecatedManifestFields.tests.ps1 b/Tests/Rules/AvoidUsingDeprecatedManifestFields.tests.ps1 new file mode 100644 index 000000000..f5729024b --- /dev/null +++ b/Tests/Rules/AvoidUsingDeprecatedManifestFields.tests.ps1 @@ -0,0 +1,19 @@ +Import-Module PSScriptAnalyzer +$violationName = "PSAvoidUsingDeprecatedManifestFields" +$directory = Split-Path -Parent $MyInvocation.MyCommand.Path +$violations = Invoke-ScriptAnalyzer $directory\TestBadModule\TestDeprecatedManifestFields.psd1 | Where-Object {$_.RuleName -eq $violationName} +$noViolations = Invoke-ScriptAnalyzer $directory\TestGoodModule\TestGoodModule.psd1 | Where-Object {$_.RuleName -eq $violationName} + +Describe "AvoidUsingDeprecatedManifestFields" { + Context "When there are violations" { + It "has 1 violations" { + $violations.Count | Should Be 1 + } + } + + Context "When there are no violations" { + It "returns no violations" { + $noViolations.Count | Should Be 0 + } + } +} \ No newline at end of file diff --git a/Tests/Rules/TestBadModule/TestBadModule.psd1 b/Tests/Rules/TestBadModule/TestBadModule.psd1 index 44d52f161732f285a76ab619ba67ef98e355ab5b..1a49df3cc4ed031576f1c7983db059a5df666f08 100644 GIT binary patch delta 52 zcmZ2te9U-53FG8%LUPIq47Lmk4C)NU49N^d44DiC3?&SS40%AD!%)dk#gNKSw0Sb4 GpacMOH4NbZ delta 26 icmX?Ryu^4z2_vKO Date: Mon, 18 May 2015 15:17:32 -0700 Subject: [PATCH 2/8] Edit some fields --- .../Rules/TestBadModule/TestDeprecatedManifestFields.psd1 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Tests/Rules/TestBadModule/TestDeprecatedManifestFields.psd1 b/Tests/Rules/TestBadModule/TestDeprecatedManifestFields.psd1 index fd03fbb90..61456462a 100644 --- a/Tests/Rules/TestBadModule/TestDeprecatedManifestFields.psd1 +++ b/Tests/Rules/TestBadModule/TestDeprecatedManifestFields.psd1 @@ -1,7 +1,7 @@ # # Module manifest for module 'Deprecated Module manifest fields" # -# Generated by: yutch +# Generated by: Microsoft PowerShell Team # # Generated on: 5/18/2015 # @@ -18,13 +18,13 @@ ModuleVersion = '1.0' GUID = 'a9f79c02-4503-4300-a022-5e8c01f3449f' # Author of this module -Author = 'quoct' +Author = '' # Company or vendor of this module -CompanyName = 'Unknown' +CompanyName = '' # Copyright statement for this module -Copyright = '(c) 2015 quoct. All rights reserved.' +Copyright = '(c) 2015 Microsoft. All rights reserved.' # Description of the functionality provided by this module # Description = '' From eae794c0f0f152d2ce78867ad18d5ecd40141ef1 Mon Sep 17 00:00:00 2001 From: Yuting Chen Date: Mon, 18 May 2015 15:19:25 -0700 Subject: [PATCH 3/8] Update some string format --- Rules/AvoidUsingDeprecatedManifestFields.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Rules/AvoidUsingDeprecatedManifestFields.cs b/Rules/AvoidUsingDeprecatedManifestFields.cs index 76aa39cb2..d8fa6a2dd 100644 --- a/Rules/AvoidUsingDeprecatedManifestFields.cs +++ b/Rules/AvoidUsingDeprecatedManifestFields.cs @@ -21,7 +21,7 @@ namespace Microsoft.Windows.Powershell.ScriptAnalyzer.BuiltinRules { /// - /// MissingModuleManifestField: Run Test Module Manifest to check that no deprecated fields are being used. + /// AvoidUsingDeprecatedManifestFields: Run Test Module Manifest to check that no deprecated fields are being used. /// [Export(typeof(IScriptRule))] public class AvoidUsingDeprecatedManifestFields : IScriptRule @@ -60,7 +60,7 @@ public IEnumerable AnalyzeScript(Ast ast, string fileName) { foreach (var warning in result) { - yield return new DiagnosticRecord(warning.BaseObject.ToString(), ast.Extent, GetName(), DiagnosticSeverity.Warning, fileName); + yield return new DiagnosticRecord(String.Format((CultureInfo.CurrentCulture, warning.BaseObject.ToString()), ast.Extent, GetName(), DiagnosticSeverity.Warning, fileName); } } From f9498856315005581cb70af70c9ad81811d5834b Mon Sep 17 00:00:00 2001 From: Yuting Chen Date: Mon, 18 May 2015 15:38:30 -0700 Subject: [PATCH 4/8] Change the string format --- Rules/AvoidUsingDeprecatedManifestFields.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Rules/AvoidUsingDeprecatedManifestFields.cs b/Rules/AvoidUsingDeprecatedManifestFields.cs index d8fa6a2dd..2d4263858 100644 --- a/Rules/AvoidUsingDeprecatedManifestFields.cs +++ b/Rules/AvoidUsingDeprecatedManifestFields.cs @@ -60,7 +60,7 @@ public IEnumerable AnalyzeScript(Ast ast, string fileName) { foreach (var warning in result) { - yield return new DiagnosticRecord(String.Format((CultureInfo.CurrentCulture, warning.BaseObject.ToString()), ast.Extent, GetName(), DiagnosticSeverity.Warning, fileName); + yield return new DiagnosticRecord(String.Format(CultureInfo.CurrentCulture, warning.BaseObject.ToString()), ast.Extent, GetName(), DiagnosticSeverity.Warning, fileName); } } From 3a626937dd3baf634b1ce97768499938bd3ff2ff Mon Sep 17 00:00:00 2001 From: Yuting Chen Date: Mon, 18 May 2015 16:00:21 -0700 Subject: [PATCH 5/8] Add braces for if condition --- Rules/AvoidUsingDeprecatedManifestFields.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Rules/AvoidUsingDeprecatedManifestFields.cs b/Rules/AvoidUsingDeprecatedManifestFields.cs index 2d4263858..7f69f874e 100644 --- a/Rules/AvoidUsingDeprecatedManifestFields.cs +++ b/Rules/AvoidUsingDeprecatedManifestFields.cs @@ -34,7 +34,10 @@ public class AvoidUsingDeprecatedManifestFields : IScriptRule /// A List of diagnostic results of this rule public IEnumerable AnalyzeScript(Ast ast, string fileName) { - if (ast == null) throw new ArgumentNullException(Strings.NullAstErrorMessage); + if (ast == null) + { + throw new ArgumentNullException(Strings.NullAstErrorMessage); + } if (String.Equals(System.IO.Path.GetExtension(fileName), ".psd1", StringComparison.OrdinalIgnoreCase)) { From 67fc9170be74611a652505a268a5e4c33fce25fa Mon Sep 17 00:00:00 2001 From: Yuting Chen Date: Mon, 18 May 2015 16:03:48 -0700 Subject: [PATCH 6/8] Modify error strings and test file fields --- Rules/Strings.Designer.cs | 2 +- Rules/Strings.resx | 2 +- Tests/Rules/TestBadModule/TestBadModule.psd1 | Bin 6598 -> 6602 bytes .../TestDeprecatedManifestFields.psd1 | 2 +- 4 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Rules/Strings.Designer.cs b/Rules/Strings.Designer.cs index 108a90fce..9a80ba177 100644 --- a/Rules/Strings.Designer.cs +++ b/Rules/Strings.Designer.cs @@ -520,7 +520,7 @@ internal static string AvoidUsingDeprecatedManifestFieldsCommonName { } /// - /// Looks up a localized string similar to Some manifest fields are obsolte in the latest PowerShell version. Please update with the latest manifest fields in modules to avoid PowerShell version inconsistency.. + /// Looks up a localized string similar to Some manifest fields are obsolete in the latest PowerShell version. Please update with the latest manifest fields in modules to avoid PowerShell version inconsistency.. /// internal static string AvoidUsingDeprecatedManifestFieldsDescription { get { diff --git a/Rules/Strings.resx b/Rules/Strings.resx index edd55e8f4..b6ed8f8c6 100644 --- a/Rules/Strings.resx +++ b/Rules/Strings.resx @@ -730,7 +730,7 @@ Avoid Using Deprecated Manifest Fields - Some manifest fields are obsolte in the latest PowerShell version. Please update with the latest manifest fields in modules to avoid PowerShell version inconsistency. + Some manifest fields are obsolete in the latest PowerShell version. Please update with the latest manifest fields in modules to avoid PowerShell version inconsistency. AvoidUsingDeprecatedManifestFields diff --git a/Tests/Rules/TestBadModule/TestBadModule.psd1 b/Tests/Rules/TestBadModule/TestBadModule.psd1 index 1a49df3cc4ed031576f1c7983db059a5df666f08..b8d7bea6c0af30f4efab05b25b4cefc2b0d6fa26 100644 GIT binary patch delta 16 XcmX?Re9CykEJo%6hT_dL8FeK9IGqK$ delta 12 TcmX?Qe9U;mEXK|A7 Date: Mon, 18 May 2015 16:10:51 -0700 Subject: [PATCH 7/8] Added null check for BaseObject --- Rules/AvoidUsingDeprecatedManifestFields.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Rules/AvoidUsingDeprecatedManifestFields.cs b/Rules/AvoidUsingDeprecatedManifestFields.cs index 7f69f874e..8e20179cd 100644 --- a/Rules/AvoidUsingDeprecatedManifestFields.cs +++ b/Rules/AvoidUsingDeprecatedManifestFields.cs @@ -63,7 +63,13 @@ public IEnumerable AnalyzeScript(Ast ast, string fileName) { foreach (var warning in result) { - yield return new DiagnosticRecord(String.Format(CultureInfo.CurrentCulture, warning.BaseObject.ToString()), ast.Extent, GetName(), DiagnosticSeverity.Warning, fileName); + if (warning.BaseObject != null) + { + yield return + new DiagnosticRecord( + String.Format(CultureInfo.CurrentCulture, warning.BaseObject.ToString()), ast.Extent, + GetName(), DiagnosticSeverity.Warning, fileName); + } } } From a3ec05475bde9ae1034670c753ef13fa3c8b0248 Mon Sep 17 00:00:00 2001 From: Yuting Chen Date: Mon, 18 May 2015 16:29:00 -0700 Subject: [PATCH 8/8] Update the error description string --- Rules/Strings.Designer.cs | 2 +- Rules/Strings.resx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Rules/Strings.Designer.cs b/Rules/Strings.Designer.cs index 9a80ba177..00f24aa6f 100644 --- a/Rules/Strings.Designer.cs +++ b/Rules/Strings.Designer.cs @@ -520,7 +520,7 @@ internal static string AvoidUsingDeprecatedManifestFieldsCommonName { } /// - /// Looks up a localized string similar to Some manifest fields are obsolete in the latest PowerShell version. Please update with the latest manifest fields in modules to avoid PowerShell version inconsistency.. + /// Looks up a localized string similar to "ModuleToProcess" is obsolete in the latest PowerShell version. Please update with the latest field "RootModule" in manifest files to avoid PowerShell version inconsistency.. /// internal static string AvoidUsingDeprecatedManifestFieldsDescription { get { diff --git a/Rules/Strings.resx b/Rules/Strings.resx index b6ed8f8c6..7686518a9 100644 --- a/Rules/Strings.resx +++ b/Rules/Strings.resx @@ -730,7 +730,7 @@ Avoid Using Deprecated Manifest Fields - Some manifest fields are obsolete in the latest PowerShell version. Please update with the latest manifest fields in modules to avoid PowerShell version inconsistency. + "ModuleToProcess" is obsolete in the latest PowerShell version. Please update with the latest field "RootModule" in manifest files to avoid PowerShell version inconsistency. AvoidUsingDeprecatedManifestFields