Skip to content

Commit

Permalink
Option interface refactoring (microsoft#2598)
Browse files Browse the repository at this point in the history
  • Loading branch information
BernieWhite authored Nov 11, 2024
1 parent d1a3bdc commit b176840
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 46 deletions.
8 changes: 3 additions & 5 deletions src/PSRule.Types/Options/BaselineOption.cs
Original file line number Diff line number Diff line change
Expand Up @@ -89,12 +89,10 @@ internal void Load()
Group = group;
}

/// <summary>
/// Load from a dictionary.
/// </summary>
internal void Load(Dictionary<string, object> index)
/// <inheritdoc/>
public void Import(IDictionary<string, object> dictionary)
{
if (index.TryPopStringArrayMap("Baseline.Group", out var group))
if (dictionary.TryPopStringArrayMap("Baseline.Group", out var group))
Group = group;
}
}
32 changes: 15 additions & 17 deletions src/PSRule.Types/Options/ExecutionOption.cs
Original file line number Diff line number Diff line change
Expand Up @@ -351,48 +351,46 @@ internal void Load()
UnprocessedObject = unprocessedObject;
}

/// <summary>
/// Load from dictionary.
/// </summary>
internal void Load(Dictionary<string, object> index)
/// <inheritdoc/>
public void Import(IDictionary<string, object> dictionary)
{
if (index.TryPopEnum("Execution.Break", out BreakLevel @break))
if (dictionary.TryPopEnum("Execution.Break", out BreakLevel @break))
Break = @break;

if (index.TryPopEnum("Execution.HashAlgorithm", out HashAlgorithm hashAlgorithm))
if (dictionary.TryPopEnum("Execution.HashAlgorithm", out HashAlgorithm hashAlgorithm))
HashAlgorithm = hashAlgorithm;

if (index.TryPopEnum("Execution.DuplicateResourceId", out ExecutionActionPreference duplicateResourceId))
if (dictionary.TryPopEnum("Execution.DuplicateResourceId", out ExecutionActionPreference duplicateResourceId))
DuplicateResourceId = duplicateResourceId;

if (index.TryPopEnum("Execution.LanguageMode", out LanguageMode languageMode))
if (dictionary.TryPopEnum("Execution.LanguageMode", out LanguageMode languageMode))
LanguageMode = languageMode;

if (index.TryPopEnum("Execution.InitialSessionState", out SessionState initialSessionState))
if (dictionary.TryPopEnum("Execution.InitialSessionState", out SessionState initialSessionState))
InitialSessionState = initialSessionState;

if (index.TryPopEnum("Execution.RestrictScriptSource", out RestrictScriptSource restrictScriptSource))
if (dictionary.TryPopEnum("Execution.RestrictScriptSource", out RestrictScriptSource restrictScriptSource))
RestrictScriptSource = restrictScriptSource;

if (index.TryPopEnum("Execution.SuppressionGroupExpired", out ExecutionActionPreference suppressionGroupExpired))
if (dictionary.TryPopEnum("Execution.SuppressionGroupExpired", out ExecutionActionPreference suppressionGroupExpired))
SuppressionGroupExpired = suppressionGroupExpired;

if (index.TryPopEnum("Execution.RuleExcluded", out ExecutionActionPreference ruleExcluded))
if (dictionary.TryPopEnum("Execution.RuleExcluded", out ExecutionActionPreference ruleExcluded))
RuleExcluded = ruleExcluded;

if (index.TryPopEnum("Execution.RuleSuppressed", out ExecutionActionPreference ruleSuppressed))
if (dictionary.TryPopEnum("Execution.RuleSuppressed", out ExecutionActionPreference ruleSuppressed))
RuleSuppressed = ruleSuppressed;

if (index.TryPopEnum("Execution.AliasReference", out ExecutionActionPreference aliasReference))
if (dictionary.TryPopEnum("Execution.AliasReference", out ExecutionActionPreference aliasReference))
AliasReference = aliasReference;

if (index.TryPopEnum("Execution.RuleInconclusive", out ExecutionActionPreference ruleInconclusive))
if (dictionary.TryPopEnum("Execution.RuleInconclusive", out ExecutionActionPreference ruleInconclusive))
RuleInconclusive = ruleInconclusive;

if (index.TryPopEnum("Execution.InvariantCulture", out ExecutionActionPreference invariantCulture))
if (dictionary.TryPopEnum("Execution.InvariantCulture", out ExecutionActionPreference invariantCulture))
InvariantCulture = invariantCulture;

if (index.TryPopEnum("Execution.UnprocessedObject", out ExecutionActionPreference unprocessedObject))
if (dictionary.TryPopEnum("Execution.UnprocessedObject", out ExecutionActionPreference unprocessedObject))
UnprocessedObject = unprocessedObject;
}
}
5 changes: 5 additions & 0 deletions src/PSRule.Types/Options/IOption.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,9 @@ namespace PSRule.Options;
/// </summary>
public interface IOption
{
/// <summary>
/// Import from a dictionary index by a string key.
/// </summary>
/// <param name="dictionary">A dictionary of key value pairs to load the option from.</param>
void Import(IDictionary<string, object> dictionary);
}
20 changes: 9 additions & 11 deletions src/PSRule/Configuration/BindingOption.cs
Original file line number Diff line number Diff line change
Expand Up @@ -203,30 +203,28 @@ internal void Load()
UseQualifiedName = useQualifiedName;
}

/// <summary>
/// Load from a dictionary.
/// </summary>
internal void Load(Dictionary<string, object> index)
/// <inheritdoc/>
public void Import(IDictionary<string, object> dictionary)
{
if (index.TryPopValue("Binding.Field", out Hashtable map))
if (dictionary.TryPopValue("Binding.Field", out Hashtable map))
Field = new FieldMap(map);

if (index.TryPopBool("Binding.IgnoreCase", out var ignoreCase))
if (dictionary.TryPopBool("Binding.IgnoreCase", out var ignoreCase))
IgnoreCase = ignoreCase;

if (index.TryPopString("Binding.NameSeparator", out var nameSeparator))
if (dictionary.TryPopString("Binding.NameSeparator", out var nameSeparator))
NameSeparator = nameSeparator;

if (index.TryPopBool("Binding.PreferTargetInfo", out var preferTargetInfo))
if (dictionary.TryPopBool("Binding.PreferTargetInfo", out var preferTargetInfo))
PreferTargetInfo = preferTargetInfo;

if (index.TryPopStringArray("Binding.TargetName", out var targetName))
if (dictionary.TryPopStringArray("Binding.TargetName", out var targetName))
TargetName = targetName;

if (index.TryPopStringArray("Binding.TargetType", out var targetType))
if (dictionary.TryPopStringArray("Binding.TargetType", out var targetType))
TargetType = targetType;

if (index.TryPopValue("Binding.UseQualifiedName", out bool useQualifiedName))
if (dictionary.TryPopValue("Binding.UseQualifiedName", out bool useQualifiedName))
UseQualifiedName = useQualifiedName;
}
}
19 changes: 12 additions & 7 deletions src/PSRule/Configuration/PSRuleOption.cs
Original file line number Diff line number Diff line change
Expand Up @@ -160,13 +160,17 @@ public string ToYaml()
var yaml = GetYaml();
return string.IsNullOrEmpty(_SourcePath)
? yaml
: string.Concat(
string.Format(
: string.Concat
(
string.Format
(
Thread.CurrentThread.CurrentCulture,
PSRuleResources.OptionsSourceComment,
_SourcePath),
_SourcePath
),
System.Environment.NewLine,
yaml);
yaml
);
}

/// <summary>
Expand Down Expand Up @@ -354,10 +358,10 @@ public static PSRuleOption FromHashtable(Hashtable hashtable)

// Start loading matching values
var index = BuildIndex(hashtable);
option.Baseline.Load(index);
option.Binding.Load(index);
option.Baseline.Import(index);
option.Binding.Import(index);
option.Convention.Load(index);
option.Execution.Load(index);
option.Execution.Import(index);
option.Include.Load(index);
option.Input.Load(index);
option.Logging.Load(index);
Expand Down Expand Up @@ -526,6 +530,7 @@ private string GetYaml()
.WithTypeConverter(new FieldMapYamlTypeConverter())
.WithTypeConverter(new StringArrayMapConverter())
.Build();

return s.Serialize(this);
}
}
24 changes: 18 additions & 6 deletions src/PSRule/Pipeline/Emitters/EmitterCollection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,15 @@ public EmitterCollection(ServiceProvider serviceProvider, IEmitter[] emitters, I
/// Visit an object with applicable emitters.
/// </summary>
/// <param name="o">The object to visit.</param>
/// <returns>Returns <c>true</c> if the object was processed by any emitter.</returns>
public bool Visit(object? o)
{
if (o == null) return false;

if (TryGetFile(o, out var info) && info != null)
if (TryGetFile(o, out var info, out var exists) && info != null)
{
if (!exists) return false;

if (_ShouldEmitFile && _Context.ShouldQueue(info.Path))
{
// Emit the file.
Expand Down Expand Up @@ -90,23 +93,27 @@ private static object GetBaseObject(object o)
return o is PSObject pso ? pso.BaseObject : o;
}

private static bool TryGetFile(object o, out InternalFileInfo? info)
private static bool TryGetFile(object o, out InternalFileInfo? info, out bool exists)
{
info = null;
exists = false;
o = GetBaseObject(o);
if (o is FileInfo fileInfo && fileInfo.Exists)
if (o is FileInfo fileInfo)
{
info = new InternalFileInfo(fileInfo.FullName, fileInfo.Extension);
exists = fileInfo.Exists;
return true;
}
if (o is InputFileInfo inputFileInfo && inputFileInfo.AsFileInfo().Exists)
if (o is InputFileInfo inputFileInfo)
{
info = new InternalFileInfo(inputFileInfo.FullName, inputFileInfo.Extension);
exists = inputFileInfo.AsFileInfo().Exists;
return true;
}
if (o is InternalFileInfo internalFile && File.Exists(internalFile.Path))
if (o is InternalFileInfo internalFile)
{
info = internalFile;
exists = File.Exists(internalFile.Path);
return true;
}
return false;
Expand Down Expand Up @@ -160,7 +167,12 @@ private static EmitterChain Create(IEmitter e, EmitterChain? next)
{
return next == null ?
(context, o, type) => e.Accepts(context, type) && e.Visit(context, o) :
(context, o, type) => e.Accepts(context, type) && e.Visit(context, o) || next(context, o, type);
(context, o, type) =>
{
var r1 = e.Accepts(context, type) && e.Visit(context, o);
var r2 = next(context, o, type);
return r1 || r2;
};
}
}

Expand Down

0 comments on commit b176840

Please sign in to comment.