Skip to content

Commit

Permalink
Convert UseSingularNouns to configurable rule and add Windows to allo…
Browse files Browse the repository at this point in the history
…wlist (#1858)

* Add Windows to the UseSingularNouns allow list

* Add test case for Windows verb

* Refactor UseSingularNouns to configurable rule and add tests

* Update UseSingularNouns docs with configuration information

* Remove extra test code

---------

Co-authored-by: Christoph Bergmeister <c.bergmeister@gmail.com>
  • Loading branch information
MJVL and bergmeister authored Jan 18, 2024
1 parent 9314e69 commit da64672
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 14 deletions.
26 changes: 14 additions & 12 deletions Rules/UseSingularNouns.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,21 +32,23 @@ 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;
}

/// <summary>
/// Checks that all defined cmdlet use singular noun
/// </summary>
/// <param name="ast"></param>
/// <param name="fileName"></param>
/// <returns></returns>
public IEnumerable<DiagnosticRecord> AnalyzeScript(Ast ast, string fileName)
public override IEnumerable<DiagnosticRecord> AnalyzeScript(Ast ast, string fileName)
{
if (ast == null) throw new ArgumentNullException(Strings.NullCommandInfoError);

Expand All @@ -70,7 +72,7 @@ public IEnumerable<DiagnosticRecord> AnalyzeScript(Ast ast, string fileName)

if (pluralizer.CanOnlyBePlural(noun))
{
if (nounAllowList.Contains(noun, StringComparer.OrdinalIgnoreCase))
if (NounAllowList.Contains(noun, StringComparer.OrdinalIgnoreCase))
{
continue;
}
Expand Down Expand Up @@ -99,7 +101,7 @@ public IEnumerable<DiagnosticRecord> AnalyzeScript(Ast ast, string fileName)
/// GetName: Retrieves the name of this rule.
/// </summary>
/// <returns>The name of this rule</returns>
public string GetName()
public override string GetName()
{
return string.Format(CultureInfo.CurrentCulture, Strings.NameSpaceFormat, GetSourceName(), Strings.UseSingularNounsName);
}
Expand All @@ -108,7 +110,7 @@ public string GetName()
/// GetName: Retrieves the common name of this rule.
/// </summary>
/// <returns>The common name of this rule</returns>
public string GetCommonName()
public override string GetCommonName()
{
return string.Format(CultureInfo.CurrentCulture, Strings.UseSingularNounsCommonName);
}
Expand All @@ -117,15 +119,15 @@ public string GetCommonName()
/// GetDescription: Retrieves the description of this rule.
/// </summary>
/// <returns>The description of this rule</returns>
public string GetDescription()
public override string GetDescription()
{
return string.Format(CultureInfo.CurrentCulture, Strings.UseSingularNounsDescription);
}

/// <summary>
/// GetSourceType: Retrieves the type of the rule: builtin, managed or module.
/// </summary>
public SourceType GetSourceType()
public override SourceType GetSourceType()
{
return SourceType.Builtin;
}
Expand All @@ -134,15 +136,15 @@ public SourceType GetSourceType()
/// GetSeverity: Retrieves the severity of the rule: error, warning of information.
/// </summary>
/// <returns></returns>
public RuleSeverity GetSeverity()
public override RuleSeverity GetSeverity()
{
return RuleSeverity.Warning;
}

/// <summary>
/// GetSourceName: Retrieves the module/assembly name the rule is from.
/// </summary>
public string GetSourceName()
public override string GetSourceName()
{
return string.Format(CultureInfo.CurrentCulture, Strings.SourceName);
}
Expand Down
29 changes: 28 additions & 1 deletion Tests/Rules/UseSingularNounsReservedVerbs.tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand All @@ -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" {
Expand Down
2 changes: 1 addition & 1 deletion docs/Rules/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 | |
Expand Down
21 changes: 21 additions & 0 deletions docs/Rules/UseSingularNouns.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down

0 comments on commit da64672

Please sign in to comment.