diff --git a/src/PSRule.Badges/BadgeException.cs b/src/PSRule.Badges/BadgeException.cs
new file mode 100644
index 0000000000..5b9ccc7441
--- /dev/null
+++ b/src/PSRule.Badges/BadgeException.cs
@@ -0,0 +1,29 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+using System.Runtime.Serialization;
+
+namespace PSRule.Badges;
+
+///
+/// A generic exception for handling of badges.
+///
+[Serializable]
+internal class BadgeException : Exception
+{
+ public BadgeException()
+ {
+ }
+
+ public BadgeException(string message) : base(message)
+ {
+ }
+
+ public BadgeException(string message, Exception innerException) : base(message, innerException)
+ {
+ }
+
+ protected BadgeException(SerializationInfo info, StreamingContext context) : base(info, context)
+ {
+ }
+}
diff --git a/src/PSRule.Badges/BadgeResources.cs b/src/PSRule.Badges/BadgeResources.cs
index fe87f9e6e1..55dbbb5eb6 100644
--- a/src/PSRule.Badges/BadgeResources.cs
+++ b/src/PSRule.Badges/BadgeResources.cs
@@ -1,8 +1,9 @@
-// Copyright (c) Microsoft Corporation.
+// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
using System.Reflection;
using Newtonsoft.Json;
+using PSRule.Badges.Resources;
namespace PSRule.Badges;
@@ -13,8 +14,8 @@ internal static class BadgeResources
{
private const string DEFAULT_CULTURE_RESOURCE = "PSRule.Badges.Resources.en.json";
- private static char[] _Char;
- private static double[] _Width;
+ private static char[]? _Char;
+ private static double[]? _Width;
///
/// Load pre-calculated widths for characters.
@@ -29,6 +30,9 @@ private static void Load()
using var reader = new StreamReader(stream);
var json = reader.ReadToEnd();
var d = JsonConvert.DeserializeObject
private static double Find(char c)
{
+ if (_Char == null || _Width == null) return 0d;
+
var index = Array.BinarySearch(_Char, c);
return index >= 0 ? _Width[index] : 0d;
}
@@ -59,7 +65,7 @@ private static double Find(char c)
public static double Measure(string s)
{
var length = 0d;
- for (var i = 0; i < s.Length; i++)
+ for (var i = 0; s != null && i < s.Length; i++)
length += GetWidth(s[i]);
return length;
diff --git a/src/PSRule.Badges/PSRule.Badges.csproj b/src/PSRule.Badges/PSRule.Badges.csproj
index 4dc36456d2..caba5918ac 100644
--- a/src/PSRule.Badges/PSRule.Badges.csproj
+++ b/src/PSRule.Badges/PSRule.Badges.csproj
@@ -6,6 +6,7 @@
Microsoft.PSRule.Badges
Library
{309bed8b-4e60-4c42-a2b4-37a2e7ebef3f}
+ enable
README.md
True
@@ -22,4 +23,19 @@
+
+
+ Messages.resx
+ True
+ True
+
+
+
+
+
+ Messages.Designer.cs
+ ResXFileCodeGenerator
+
+
+
diff --git a/src/PSRule.Badges/Resources/Messages.Designer.cs b/src/PSRule.Badges/Resources/Messages.Designer.cs
new file mode 100644
index 0000000000..d15641d323
--- /dev/null
+++ b/src/PSRule.Badges/Resources/Messages.Designer.cs
@@ -0,0 +1,72 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.42000
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace PSRule.Badges.Resources {
+ using System;
+
+
+ ///
+ /// A strongly-typed resource class, for looking up localized strings, etc.
+ ///
+ // This class was auto-generated by the StronglyTypedResourceBuilder
+ // class via a tool like ResGen or Visual Studio.
+ // To add or remove a member, edit your .ResX file then rerun ResGen
+ // with the /str option, or rebuild your VS project.
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ internal class Messages {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal Messages() {
+ }
+
+ ///
+ /// Returns the cached ResourceManager instance used by this class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Resources.ResourceManager ResourceManager {
+ get {
+ if (object.ReferenceEquals(resourceMan, null)) {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("PSRule.Badges.Resources.Messages", typeof(Messages).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ ///
+ /// Overrides the current thread's CurrentUICulture property for all
+ /// resource lookups using this strongly typed resource class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Globalization.CultureInfo Culture {
+ get {
+ return resourceCulture;
+ }
+ set {
+ resourceCulture = value;
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Failed to load badge resources..
+ ///
+ internal static string LoadException {
+ get {
+ return ResourceManager.GetString("LoadException", resourceCulture);
+ }
+ }
+ }
+}
diff --git a/src/PSRule.Badges/Resources/Messages.resx b/src/PSRule.Badges/Resources/Messages.resx
new file mode 100644
index 0000000000..f3f958d755
--- /dev/null
+++ b/src/PSRule.Badges/Resources/Messages.resx
@@ -0,0 +1,123 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ Failed to load badge resources.
+
+
\ No newline at end of file
diff --git a/src/PSRule/Pipeline/GetBaselinePipeline.cs b/src/PSRule/Pipeline/GetBaselinePipeline.cs
index 1e7a664c86..27cb9a24c7 100644
--- a/src/PSRule/Pipeline/GetBaselinePipeline.cs
+++ b/src/PSRule/Pipeline/GetBaselinePipeline.cs
@@ -14,7 +14,7 @@ internal sealed class GetBaselinePipeline : RulePipeline
internal GetBaselinePipeline(
PipelineContext pipeline,
Source[] source,
- PipelineReader reader,
+ PipelineInputStream reader,
IPipelineWriter writer,
IResourceFilter filter
)
diff --git a/src/PSRule/Pipeline/GetRuleHelpPipeline.cs b/src/PSRule/Pipeline/GetRuleHelpPipeline.cs
index 4d5bc3f268..3dfe489fcb 100644
--- a/src/PSRule/Pipeline/GetRuleHelpPipeline.cs
+++ b/src/PSRule/Pipeline/GetRuleHelpPipeline.cs
@@ -176,7 +176,7 @@ protected override PipelineWriter PrepareWriter()
internal sealed class GetRuleHelpPipeline : RulePipeline, IPipeline
{
- internal GetRuleHelpPipeline(PipelineContext pipeline, Source[] source, PipelineReader reader, IPipelineWriter writer)
+ internal GetRuleHelpPipeline(PipelineContext pipeline, Source[] source, PipelineInputStream reader, IPipelineWriter writer)
: base(pipeline, source, reader, writer)
{
// Do nothing
diff --git a/src/PSRule/Pipeline/GetRulePipeline.cs b/src/PSRule/Pipeline/GetRulePipeline.cs
index b045c2622a..cc9bdb32df 100644
--- a/src/PSRule/Pipeline/GetRulePipeline.cs
+++ b/src/PSRule/Pipeline/GetRulePipeline.cs
@@ -12,7 +12,7 @@ internal sealed class GetRulePipeline : RulePipeline, IPipeline
internal GetRulePipeline(
PipelineContext pipeline,
Source[] source,
- PipelineReader reader,
+ PipelineInputStream reader,
IPipelineWriter writer,
bool includeDependencies
)
diff --git a/src/PSRule/Pipeline/GetTargetPipeline.cs b/src/PSRule/Pipeline/GetTargetPipeline.cs
index 34723d4ea1..1683ae32a6 100644
--- a/src/PSRule/Pipeline/GetTargetPipeline.cs
+++ b/src/PSRule/Pipeline/GetTargetPipeline.cs
@@ -72,7 +72,7 @@ public override IPipeline Build(IPipelineWriter writer = null)
}
///
- protected override PipelineReader PrepareReader()
+ protected override PipelineInputStream PrepareReader()
{
if (!string.IsNullOrEmpty(Option.Input.ObjectPath))
{
@@ -124,7 +124,7 @@ protected override PipelineReader PrepareReader()
return PipelineReceiverActions.DetectInputFormat(sourceObject, next);
});
}
- return new PipelineReader(VisitTargetObject, _InputPath, GetInputObjectSourceFilter());
+ return new PipelineInputStream(VisitTargetObject, _InputPath, GetInputObjectSourceFilter());
}
}
@@ -133,7 +133,7 @@ protected override PipelineReader PrepareReader()
///
internal sealed class GetTargetPipeline : RulePipeline
{
- internal GetTargetPipeline(PipelineContext context, PipelineReader reader, IPipelineWriter writer)
+ internal GetTargetPipeline(PipelineContext context, PipelineInputStream reader, IPipelineWriter writer)
: base(context, null, reader, writer) { }
public override void Process(PSObject sourceObject)
diff --git a/src/PSRule/Pipeline/InvokePipelineBuilder.cs b/src/PSRule/Pipeline/InvokePipelineBuilder.cs
index 6554ec9c69..3e07256b31 100644
--- a/src/PSRule/Pipeline/InvokePipelineBuilder.cs
+++ b/src/PSRule/Pipeline/InvokePipelineBuilder.cs
@@ -149,7 +149,7 @@ private static bool IsBlocked(string path)
}
}
- protected override PipelineReader PrepareReader()
+ protected override PipelineInputStream PrepareReader()
{
if (!string.IsNullOrEmpty(Option.Input.ObjectPath))
{
@@ -201,7 +201,7 @@ protected override PipelineReader PrepareReader()
return PipelineReceiverActions.DetectInputFormat(sourceObject, next);
});
}
- return new PipelineReader(VisitTargetObject, _InputPath, GetInputObjectSourceFilter());
+ return new PipelineInputStream(VisitTargetObject, _InputPath, GetInputObjectSourceFilter());
}
}
diff --git a/src/PSRule/Pipeline/PipelineBuilder.cs b/src/PSRule/Pipeline/PipelineBuilder.cs
index 31ab502335..e4ee3d3ae2 100644
--- a/src/PSRule/Pipeline/PipelineBuilder.cs
+++ b/src/PSRule/Pipeline/PipelineBuilder.cs
@@ -468,9 +468,9 @@ protected string ResolveBaselineGroup(string name)
return baselines[0];
}
- protected virtual PipelineReader PrepareReader()
+ protected virtual PipelineInputStream PrepareReader()
{
- return new PipelineReader(null, null, GetInputObjectSourceFilter());
+ return new PipelineInputStream(null, null, GetInputObjectSourceFilter());
}
protected virtual PipelineWriter PrepareWriter()
diff --git a/src/PSRule/Pipeline/PipelineContext.cs b/src/PSRule/Pipeline/PipelineContext.cs
index 1e20e2418f..c601b58552 100644
--- a/src/PSRule/Pipeline/PipelineContext.cs
+++ b/src/PSRule/Pipeline/PipelineContext.cs
@@ -53,7 +53,7 @@ internal sealed class PipelineContext : IDisposable, IBindingContext
internal readonly Dictionary Selector;
internal readonly List SuppressionGroup;
internal readonly IHostContext HostContext;
- internal readonly PipelineReader Reader;
+ internal readonly PipelineInputStream Reader;
internal readonly BindTargetMethod BindTargetName;
internal readonly BindTargetMethod BindTargetType;
internal readonly BindTargetMethod BindField;
@@ -65,7 +65,7 @@ internal sealed class PipelineContext : IDisposable, IBindingContext
public System.Security.Cryptography.HashAlgorithm ObjectHashAlgorithm { get; }
- private PipelineContext(PSRuleOption option, IHostContext hostContext, PipelineReader reader, BindTargetMethod bindTargetName, BindTargetMethod bindTargetType, BindTargetMethod bindField, OptionContextBuilder optionBuilder, IList unresolved)
+ private PipelineContext(PSRuleOption option, IHostContext hostContext, PipelineInputStream reader, BindTargetMethod bindTargetName, BindTargetMethod bindTargetType, BindTargetMethod bindField, OptionContextBuilder optionBuilder, IList unresolved)
{
_OptionBuilder = optionBuilder;
Option = option;
@@ -90,7 +90,7 @@ private PipelineContext(PSRuleOption option, IHostContext hostContext, PipelineR
_DefaultOptionContext = _OptionBuilder?.Build(null);
}
- public static PipelineContext New(PSRuleOption option, IHostContext hostContext, PipelineReader reader, BindTargetMethod bindTargetName, BindTargetMethod bindTargetType, BindTargetMethod bindField, OptionContextBuilder optionBuilder, IList unresolved)
+ public static PipelineContext New(PSRuleOption option, IHostContext hostContext, PipelineInputStream reader, BindTargetMethod bindTargetName, BindTargetMethod bindTargetType, BindTargetMethod bindField, OptionContextBuilder optionBuilder, IList unresolved)
{
var context = new PipelineContext(option, hostContext, reader, bindTargetName, bindTargetType, bindField, optionBuilder, unresolved);
CurrentThread = context;
diff --git a/src/PSRule/Pipeline/PipelineReader.cs b/src/PSRule/Pipeline/PipelineInputStream.cs
similarity index 81%
rename from src/PSRule/Pipeline/PipelineReader.cs
rename to src/PSRule/Pipeline/PipelineInputStream.cs
index 0c66466aa3..64497dca61 100644
--- a/src/PSRule/Pipeline/PipelineReader.cs
+++ b/src/PSRule/Pipeline/PipelineInputStream.cs
@@ -6,14 +6,17 @@
namespace PSRule.Pipeline;
-internal sealed class PipelineReader
+///
+/// A stream of input objects that will be evaluated.
+///
+internal sealed class PipelineInputStream
{
private readonly VisitTargetObject _Input;
private readonly InputPathBuilder _InputPath;
private readonly PathFilter _InputFilter;
private readonly ConcurrentQueue _Queue;
- public PipelineReader(VisitTargetObject input, InputPathBuilder inputPath, PathFilter inputFilter)
+ public PipelineInputStream(VisitTargetObject input, InputPathBuilder inputPath, PathFilter inputFilter)
{
_Input = input;
_InputPath = inputPath;
@@ -25,6 +28,12 @@ public PipelineReader(VisitTargetObject input, InputPathBuilder inputPath, PathF
public bool IsEmpty => _Queue.IsEmpty;
+ ///
+ /// Add a new object into the stream.
+ ///
+ /// An object to process.
+ /// A pre-bound type.
+ /// Determines if expansion is skipped.
public void Enqueue(PSObject sourceObject, string targetType = null, bool skipExpansion = false)
{
if (sourceObject == null)
@@ -46,6 +55,9 @@ public void Enqueue(PSObject sourceObject, string targetType = null, bool skipEx
EnqueueInternal(item);
}
+ ///
+ /// Get the next object in the stream.
+ ///
public bool TryDequeue(out TargetObject sourceObject)
{
return _Queue.TryDequeue(out sourceObject);
diff --git a/src/PSRule/Pipeline/RulePipeline.cs b/src/PSRule/Pipeline/RulePipeline.cs
index 207ff27ed0..653c61ea5c 100644
--- a/src/PSRule/Pipeline/RulePipeline.cs
+++ b/src/PSRule/Pipeline/RulePipeline.cs
@@ -11,13 +11,13 @@ internal abstract class RulePipeline : IPipeline
protected readonly PipelineContext Pipeline;
protected readonly RunspaceContext Context;
protected readonly Source[] Source;
- protected readonly PipelineReader Reader;
+ protected readonly PipelineInputStream Reader;
protected readonly IPipelineWriter Writer;
// Track whether Dispose has been called.
private bool _Disposed;
- protected RulePipeline(PipelineContext context, Source[] source, PipelineReader reader, IPipelineWriter writer)
+ protected RulePipeline(PipelineContext context, Source[] source, PipelineInputStream reader, IPipelineWriter writer)
{
Result = new DefaultPipelineResult(writer);
Pipeline = context;
diff --git a/tests/PSRule.Tests/PipelineTests.cs b/tests/PSRule.Tests/PipelineTests.cs
index d02c7b67f7..23a7395ef0 100644
--- a/tests/PSRule.Tests/PipelineTests.cs
+++ b/tests/PSRule.Tests/PipelineTests.cs
@@ -181,7 +181,7 @@ public void PipelineWithInvariantCulture()
Environment.UseCurrentCulture(CultureInfo.InvariantCulture);
var context = PipelineContext.New(GetOption(), null, null, null, null, null, new OptionContextBuilder(), null);
var writer = new TestWriter(GetOption());
- var pipeline = new GetRulePipeline(context, GetSource(), new PipelineReader(null, null, null), writer, false);
+ var pipeline = new GetRulePipeline(context, GetSource(), new PipelineInputStream(null, null, null), writer, false);
try
{
pipeline.Begin();
@@ -203,7 +203,7 @@ public void PipelineWithInvariantCultureDisabled()
option.Execution.InvariantCulture = ExecutionActionPreference.Ignore;
var context = PipelineContext.New(option, null, null, null, null, null, new OptionContextBuilder(), null);
var writer = new TestWriter(option);
- var pipeline = new GetRulePipeline(context, GetSource(), new PipelineReader(null, null, null), writer, false);
+ var pipeline = new GetRulePipeline(context, GetSource(), new PipelineInputStream(null, null, null), writer, false);
try
{
pipeline.Begin();