diff --git a/Rules/UseSingularNouns.cs b/Rules/UseSingularNouns.cs index 218537459..21a6afa90 100644 --- a/Rules/UseSingularNouns.cs +++ b/Rules/UseSingularNouns.cs @@ -32,13 +32,15 @@ namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.BuiltinRules #if !CORECLR [Export(typeof(IScriptRule))] #endif - public class CmdletSingularNoun : IScriptRule + public class CmdletSingularNoun : ConfigurableRule { + [ConfigurableRuleProperty(defaultValue: new string[] { "Data", "Windows" })] + public string[] NounAllowList { get; set; } - private readonly string[] nounAllowList = + public CmdletSingularNoun() { - "Data" - }; + Enable = true; + } /// /// Checks that all defined cmdlet use singular noun @@ -46,7 +48,7 @@ public class CmdletSingularNoun : IScriptRule /// /// /// - public IEnumerable AnalyzeScript(Ast ast, string fileName) + public override IEnumerable AnalyzeScript(Ast ast, string fileName) { if (ast == null) throw new ArgumentNullException(Strings.NullCommandInfoError); @@ -70,7 +72,7 @@ public IEnumerable AnalyzeScript(Ast ast, string fileName) if (pluralizer.CanOnlyBePlural(noun)) { - if (nounAllowList.Contains(noun, StringComparer.OrdinalIgnoreCase)) + if (NounAllowList.Contains(noun, StringComparer.OrdinalIgnoreCase)) { continue; } @@ -99,7 +101,7 @@ public IEnumerable AnalyzeScript(Ast ast, string fileName) /// GetName: Retrieves the name of this rule. /// /// The name of this rule - public string GetName() + public override string GetName() { return string.Format(CultureInfo.CurrentCulture, Strings.NameSpaceFormat, GetSourceName(), Strings.UseSingularNounsName); } @@ -108,7 +110,7 @@ public string GetName() /// GetName: Retrieves the common name of this rule. /// /// The common name of this rule - public string GetCommonName() + public override string GetCommonName() { return string.Format(CultureInfo.CurrentCulture, Strings.UseSingularNounsCommonName); } @@ -117,7 +119,7 @@ public string GetCommonName() /// GetDescription: Retrieves the description of this rule. /// /// The description of this rule - public string GetDescription() + public override string GetDescription() { return string.Format(CultureInfo.CurrentCulture, Strings.UseSingularNounsDescription); } @@ -125,7 +127,7 @@ public string GetDescription() /// /// GetSourceType: Retrieves the type of the rule: builtin, managed or module. /// - public SourceType GetSourceType() + public override SourceType GetSourceType() { return SourceType.Builtin; } @@ -134,7 +136,7 @@ public SourceType GetSourceType() /// GetSeverity: Retrieves the severity of the rule: error, warning of information. /// /// - public RuleSeverity GetSeverity() + public override RuleSeverity GetSeverity() { return RuleSeverity.Warning; } @@ -142,7 +144,7 @@ public RuleSeverity GetSeverity() /// /// GetSourceName: Retrieves the module/assembly name the rule is from. /// - public string GetSourceName() + public override string GetSourceName() { return string.Format(CultureInfo.CurrentCulture, Strings.SourceName); } diff --git a/Tests/Rules/UseSingularNounsReservedVerbs.tests.ps1 b/Tests/Rules/UseSingularNounsReservedVerbs.tests.ps1 index db1af36ce..6d4724236 100644 --- a/Tests/Rules/UseSingularNounsReservedVerbs.tests.ps1 +++ b/Tests/Rules/UseSingularNounsReservedVerbs.tests.ps1 @@ -32,7 +32,7 @@ Describe "UseSingularNouns" { Context "When function names have nouns from allowlist" { - It "ignores function name ending with Data" { + It "ignores function name ending with Data by default" { $nounViolationScript = @' Function Add-SomeData { @@ -44,6 +44,33 @@ Write-Output "Adding some data" -OutVariable violations $violations.Count | Should -Be 0 } + + It "ignores function name ending with Windows by default" { + $nounViolationScript = @' +Function Test-Windows +{ +Write-Output "Testing Microsoft Windows" +} +'@ + Invoke-ScriptAnalyzer -ScriptDefinition $nounViolationScript ` + -IncludeRule "PSUseSingularNouns" ` + -OutVariable violations + $violations.Count | Should -Be 0 + } + + It "ignores function names defined in settings" { + $nounViolationScript = @' +Function Get-Bananas +{ +Write-Output "Bananas" +} +'@ + Invoke-ScriptAnalyzer -ScriptDefinition $nounViolationScript -Settings @{ + IncludeRules = @("PSUseSingularNouns") + Rules = @{ PSUseSingularNouns = @{ NounAllowList = "Bananas" } } + } | Should -BeNullOrEmpty + } + } Context "When there are no violations" { diff --git a/docs/Rules/README.md b/docs/Rules/README.md index f5c8d8bd3..42c2003ad 100644 --- a/docs/Rules/README.md +++ b/docs/Rules/README.md @@ -75,7 +75,7 @@ The PSScriptAnalyzer contains the following rule definitions. | [UseProcessBlockForPipelineCommand](./UseProcessBlockForPipelineCommand.md) | Warning | Yes | | | [UsePSCredentialType](./UsePSCredentialType.md) | Warning | Yes | | | [UseShouldProcessForStateChangingFunctions](./UseShouldProcessForStateChangingFunctions.md) | Warning | Yes | | -| [UseSingularNouns](./UseSingularNouns.md) | Warning | Yes | | +| [UseSingularNouns](./UseSingularNouns.md) | Warning | Yes | Yes | | [UseSupportsShouldProcess](./UseSupportsShouldProcess.md) | Warning | Yes | | | [UseToExportFieldsInManifest](./UseToExportFieldsInManifest.md) | Warning | Yes | | | [UseUsingScopeModifierInNewRunspaces](./UseUsingScopeModifierInNewRunspaces.md) | Warning | Yes | | diff --git a/docs/Rules/UseSingularNouns.md b/docs/Rules/UseSingularNouns.md index caf032e03..387d48c2d 100644 --- a/docs/Rules/UseSingularNouns.md +++ b/docs/Rules/UseSingularNouns.md @@ -22,6 +22,27 @@ function Get-Elements { } ``` +## Configuration + +```powershell +Rules = @{ + UseSingularNouns = @{ + NounAllowList = 'Data', 'Windows', 'Foos' + Enable = $true + } +} +``` + +### Parameters + +#### `UseSingularNouns: string[]` (Default value is `{'Data', 'Windows'}`) + +Commands to be excluded from this rule. `Data` and `Windows` are common false positives and are excluded by default + +#### Enable: `bool` (Default value is `$true`) + +Enable or disable the rule during ScriptAnalyzer invocation. + ## How Change plurals to singular.