Skip to content

Commit

Permalink
Refactor to improve maintainability (microsoft#1881)
Browse files Browse the repository at this point in the history
  • Loading branch information
BernieWhite authored Jul 28, 2024
1 parent 60f7f7d commit f9f67f5
Show file tree
Hide file tree
Showing 30 changed files with 312 additions and 255 deletions.
2 changes: 2 additions & 0 deletions src/PSRule.Types/Definitions/ResourceHelper.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using PSRule.Definitions.Rules;

namespace PSRule.Definitions;

internal static class ResourceHelper
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

namespace PSRule.Definitions;
namespace PSRule.Definitions.Rules;

/// <summary>
/// If the rule fails, how serious is the result.
Expand Down
2 changes: 1 addition & 1 deletion src/PSRule/Common/ReasonExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ internal static class ReasonExtensions
internal static string[] GetStrings(this IList<ResultReason> reason)
{
if (reason == null || reason.Count == 0)
return Array.Empty<string>();
return [];

var result = new string[reason.Count];
for (var i = 0; i < reason.Count; i++)
Expand Down
2 changes: 1 addition & 1 deletion src/PSRule/Common/SeverityLevelExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using PSRule.Definitions;
using PSRule.Definitions.Rules;

namespace PSRule;

Expand Down
17 changes: 17 additions & 0 deletions src/PSRule/Data/IInputFileInfoCollection.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

namespace PSRule.Data;

/// <summary>
/// A collection of <see cref="InputFileInfo"/>.
/// </summary>
public interface IInputFileInfoCollection : IEnumerable<InputFileInfo>
{
/// <summary>
/// Filters the collection to only include <see cref="InputFileInfo"/> with a specific file extension.
/// </summary>
/// <param name="extension">A file extension to filter the collection to.</param>
/// <returns>A filtered collection.</returns>
IInputFileInfoCollection WithExtension(string extension);
}
45 changes: 0 additions & 45 deletions src/PSRule/Data/ITargetIssueCollection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,48 +22,3 @@ public interface ITargetIssueCollection
/// <returns>Returns <c>true</c> if any the collection contains any issues matching the specified <paramref name="type"/>.</returns>
bool Any(string type = null);
}

/// <summary>
/// A collection of issues reported by a downstream tool.
/// </summary>
internal sealed class TargetIssueCollection : ITargetIssueCollection
{
private List<TargetIssueInfo> _Items;

internal TargetIssueCollection() { }

/// <inheritdoc/>
public bool Any(string type = null)
{
return Get(type).Length > 0;
}

/// <inheritdoc/>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE0046:Convert to conditional expression", Justification = "Avoid nested conditional expressions that increase complexity.")]
public TargetIssueInfo[] Get(string type = null)
{
if (_Items == null)
return Array.Empty<TargetIssueInfo>();

return type == null ? _Items.ToArray() : _Items.Where(i => StringComparer.OrdinalIgnoreCase.Equals(i.Type, type)).ToArray();
}

/// <summary>
/// Add one or more issues into the collection.
/// </summary>
/// <param name="issueInfo">An array of <see cref="TargetIssueInfo"/> instance to add to the collection.</param>
internal void AddRange(TargetIssueInfo[] issueInfo)
{
for (var i = 0; issueInfo != null && i < issueInfo.Length; i++)
Add(issueInfo[i]);
}

private void Add(TargetIssueInfo issueInfo)
{
if (issueInfo == null || string.IsNullOrEmpty(issueInfo.Type))
return;

_Items ??= new List<TargetIssueInfo>();
_Items.Add(issueInfo);
}
}
13 changes: 0 additions & 13 deletions src/PSRule/Data/InputFileInfoCollection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,6 @@

namespace PSRule.Data;

/// <summary>
/// A collection of <see cref="InputFileInfo"/>.
/// </summary>
public interface IInputFileInfoCollection : IEnumerable<InputFileInfo>
{
/// <summary>
/// Filters the collection to only include <see cref="InputFileInfo"/> with a specific file extension.
/// </summary>
/// <param name="extension">A file extension to filter the collection to.</param>
/// <returns>A filtered collection.</returns>
IInputFileInfoCollection WithExtension(string extension);
}

/// <summary>
/// A collection of <see cref="InputFileInfo"/>.
/// </summary>
Expand Down
49 changes: 49 additions & 0 deletions src/PSRule/Data/TargetIssueCollection.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

namespace PSRule.Data;

/// <summary>
/// A collection of issues reported by a downstream tool.
/// </summary>
internal sealed class TargetIssueCollection : ITargetIssueCollection
{
private List<TargetIssueInfo> _Items;

internal TargetIssueCollection() { }

/// <inheritdoc/>
public bool Any(string type = null)
{
return Get(type).Length > 0;
}

/// <inheritdoc/>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE0046:Convert to conditional expression", Justification = "Avoid nested conditional expressions that increase complexity.")]
public TargetIssueInfo[] Get(string type = null)
{
if (_Items == null)
return Array.Empty<TargetIssueInfo>();

return type == null ? _Items.ToArray() : _Items.Where(i => StringComparer.OrdinalIgnoreCase.Equals(i.Type, type)).ToArray();
}

/// <summary>
/// Add one or more issues into the collection.
/// </summary>
/// <param name="issueInfo">An array of <see cref="TargetIssueInfo"/> instance to add to the collection.</param>
internal void AddRange(TargetIssueInfo[] issueInfo)
{
for (var i = 0; issueInfo != null && i < issueInfo.Length; i++)
Add(issueInfo[i]);
}

private void Add(TargetIssueInfo issueInfo)
{
if (issueInfo == null || string.IsNullOrEmpty(issueInfo.Type))
return;

_Items ??= new List<TargetIssueInfo>();
_Items.Add(issueInfo);
}
}
89 changes: 0 additions & 89 deletions src/PSRule/Definitions/Baselines/Baseline.cs
Original file line number Diff line number Diff line change
@@ -1,41 +1,12 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using System.Management.Automation;
using Newtonsoft.Json;
using PSRule.Configuration;
using PSRule.Pipeline;
using PSRule.Resources;
using YamlDotNet.Serialization;

namespace PSRule.Definitions.Baselines;

/// <summary>
/// A specification for a V1 baseline resource.
/// </summary>
internal interface IBaselineV1Spec
{
/// <summary>
/// Options that affect property binding.
/// </summary>
BindingOption Binding { get; set; }

/// <summary>
/// Allows configuration key/ values to be specified that can be used within rule definitions.
/// </summary>
ConfigurationOption Configuration { get; set; }

/// <summary>
/// Options that configure conventions.
/// </summary>
ConventionOption Convention { get; set; }

/// <summary>
/// Options for that affect which rules are executed by including and filtering discovered rules.
/// </summary>
RuleOption Rule { get; set; }
}

/// <summary>
/// A baseline resource V1.
/// </summary>
Expand All @@ -61,63 +32,3 @@ public Baseline(string apiVersion, SourceFile source, ResourceMetadata metadata,
[YamlIgnore]
public string Synopsis => Info.Synopsis.Text;
}

/// <summary>
/// A specification for a V1 baseline resource.
/// </summary>
public sealed class BaselineSpec : Spec, IBaselineV1Spec
{
/// <inheritdoc/>
public BindingOption Binding { get; set; }

/// <inheritdoc/>
public ConfigurationOption Configuration { get; set; }

/// <inheritdoc/>
public ConventionOption Convention { get; set; }

/// <inheritdoc/>
public RuleOption Rule { get; set; }
}

internal sealed class BaselineFilter : IResourceFilter
{
private readonly HashSet<string> _Include;
private readonly WildcardPattern _WildcardMatch;

public BaselineFilter(string[] include)
{
_Include = include == null || include.Length == 0 ? null : new HashSet<string>(include, StringComparer.OrdinalIgnoreCase);
_WildcardMatch = null;
if (include != null && include.Length > 0 && WildcardPattern.ContainsWildcardCharacters(include[0]))
{
if (include.Length > 1)
throw new NotSupportedException(PSRuleResources.MatchSingleName);

_WildcardMatch = new WildcardPattern(include[0]);
}
}

ResourceKind IResourceFilter.Kind => ResourceKind.Baseline;

public bool Match(IResource resource)
{
return _Include == null || _Include.Contains(resource.Name) || MatchWildcard(resource.Name);
}

private bool MatchWildcard(string name)
{
return _WildcardMatch != null && _WildcardMatch.IsMatch(name);
}
}

internal sealed class BaselineRef : ResourceRef
{
public readonly ScopeType Type;

public BaselineRef(string id, ScopeType scopeType)
: base(id, ResourceKind.Baseline)
{
Type = scopeType;
}
}
38 changes: 38 additions & 0 deletions src/PSRule/Definitions/Baselines/BaselineFilter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using System.Management.Automation;
using PSRule.Resources;

namespace PSRule.Definitions.Baselines;

internal sealed class BaselineFilter : IResourceFilter
{
private readonly HashSet<string> _Include;
private readonly WildcardPattern _WildcardMatch;

public BaselineFilter(string[] include)
{
_Include = include == null || include.Length == 0 ? null : new HashSet<string>(include, StringComparer.OrdinalIgnoreCase);
_WildcardMatch = null;
if (include != null && include.Length > 0 && WildcardPattern.ContainsWildcardCharacters(include[0]))
{
if (include.Length > 1)
throw new NotSupportedException(PSRuleResources.MatchSingleName);

_WildcardMatch = new WildcardPattern(include[0]);
}
}

ResourceKind IResourceFilter.Kind => ResourceKind.Baseline;

public bool Match(IResource resource)
{
return _Include == null || _Include.Contains(resource.Name) || MatchWildcard(resource.Name);
}

private bool MatchWildcard(string name)
{
return _WildcardMatch != null && _WildcardMatch.IsMatch(name);
}
}
17 changes: 17 additions & 0 deletions src/PSRule/Definitions/Baselines/BaselineRef.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using PSRule.Pipeline;

namespace PSRule.Definitions.Baselines;

internal sealed class BaselineRef : ResourceRef
{
public readonly ScopeType Type;

public BaselineRef(string id, ScopeType scopeType)
: base(id, ResourceKind.Baseline)
{
Type = scopeType;
}
}
24 changes: 24 additions & 0 deletions src/PSRule/Definitions/Baselines/BaselineSpec.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using PSRule.Configuration;

namespace PSRule.Definitions.Baselines;

/// <summary>
/// A specification for a V1 baseline resource.
/// </summary>
public sealed class BaselineSpec : Spec, IBaselineV1Spec
{
/// <inheritdoc/>
public BindingOption Binding { get; set; }

/// <inheritdoc/>
public ConfigurationOption Configuration { get; set; }

/// <inheritdoc/>
public ConventionOption Convention { get; set; }

/// <inheritdoc/>
public RuleOption Rule { get; set; }
}
32 changes: 32 additions & 0 deletions src/PSRule/Definitions/Baselines/IBaselineV1Spec.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using PSRule.Configuration;

namespace PSRule.Definitions.Baselines;

/// <summary>
/// A specification for a V1 baseline resource.
/// </summary>
internal interface IBaselineV1Spec
{
/// <summary>
/// Options that affect property binding.
/// </summary>
BindingOption Binding { get; set; }

/// <summary>
/// Allows configuration key/ values to be specified that can be used within rule definitions.
/// </summary>
ConfigurationOption Configuration { get; set; }

/// <summary>
/// Options that configure conventions.
/// </summary>
ConventionOption Convention { get; set; }

/// <summary>
/// Options for that affect which rules are executed by including and filtering discovered rules.
/// </summary>
RuleOption Rule { get; set; }
}
Loading

0 comments on commit f9f67f5

Please sign in to comment.