diff --git a/.editorconfig b/.editorconfig
index 78906e8269..d39f0b9771 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -28,6 +28,10 @@ dotnet_style_readonly_field = true:suggestion
csharp_style_namespace_declarations = file_scoped:error
dotnet_diagnostic.IDE0005.severity = error
+# Compiler warnings
+dotnet_diagnostic.CS0472.severity = error
+dotnet_diagnostic.CS0436.severity = error
+
# License header
file_header_template = Copyright (c) Microsoft Corporation.\nLicensed under the MIT License.
dotnet_diagnostic.IDE0073.severity = error
diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml
index c5ce8362bc..2461a7537a 100644
--- a/.github/workflows/build.yaml
+++ b/.github/workflows/build.yaml
@@ -42,7 +42,7 @@ jobs:
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
- dotnet-version: 8.x
+ global-json-file: global.json
- name: Install dependencies
shell: pwsh
@@ -115,7 +115,7 @@ jobs:
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
- dotnet-version: 8.x
+ global-json-file: global.json
- if: ${{ matrix.shell == 'pwsh' }}
name: Install dependencies (PowerShell)
@@ -166,7 +166,7 @@ jobs:
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
- dotnet-version: 8.x
+ global-json-file: global.json
- name: Install dependencies
timeout-minutes: 3
@@ -214,6 +214,11 @@ jobs:
with:
node-version: 20
+ - name: Setup .NET
+ uses: actions/setup-dotnet@v4
+ with:
+ global-json-file: global.json
+
- name: Install dependencies
timeout-minutes: 3
run: |
diff --git a/docs/hooks/old_hooks.py b/docs/hooks/maml_formatting.py
similarity index 63%
rename from docs/hooks/old_hooks.py
rename to docs/hooks/maml_formatting.py
index 47d89e3ab2..9ab5bff264 100644
--- a/docs/hooks/old_hooks.py
+++ b/docs/hooks/maml_formatting.py
@@ -11,10 +11,11 @@
import mkdocs.structure.pages
log = logging.getLogger(f"mkdocs.plugins.{__name__}")
-rulesItem: mkdocs.structure.nav.Section = mkdocs.structure.nav.Section("Rules", [])
# Replace MAML headers
def on_page_markdown(markdown: str, page: mkdocs.structure.nav.Page, config: mkdocs.config.Config, files: mkdocs.structure.files.Files) -> str:
+ '''Hook on_page_markdown event.'''
+
markdown = markdown.replace("## about_PSRule_Assert", "")
markdown = markdown.replace("## about_PSRule_Baseline", "")
markdown = markdown.replace("## about_PSRule_Badges", "")
@@ -59,44 +60,3 @@ def on_page_markdown(markdown: str, page: mkdocs.structure.nav.Page, config: mkd
markdown = re.sub(r"\@([\w-]*)", r"[@\g<1>](https://github.com/\g<1>)", markdown)
return markdown
-
-# Dynamically build reference nav
-def build_reference_nav(nav: mkdocs.structure.nav.Navigation, config: mkdocs.config.Config, files: mkdocs.structure.files.Files) -> mkdocs.structure.nav.Navigation:
- build_rule_nav(nav, config, files)
- build_baseline_nav(nav, config, files)
- return nav
-
-# Build Rules list
-def build_rule_nav(nav: mkdocs.structure.nav.Navigation, config: mkdocs.config.Config, files: mkdocs.structure.files.Files):
- children = []
- item: mkdocs.structure.nav.Section = mkdocs.structure.nav.Section("Rules", children)
-
- for f in files:
- if not f.is_documentation_page():
- continue
-
- if not f._get_stem().startswith("Azure."):
- continue
-
- if f._get_dest_path(False).__contains__("/rules/"):
- children.append(mkdocs.structure.pages.Page(f._get_stem(), f, config))
-
- referenceItem: mkdocs.structure.nav.Section = next(x for x in nav if x.title == "Reference")
- referenceItem.children.append(item)
- mkdocs.structure.nav._add_parent_links(nav)
-
-# Build Baselines list
-def build_baseline_nav(nav: mkdocs.structure.nav.Navigation, config: mkdocs.config.Config, files: mkdocs.structure.files.Files):
- children = []
- item: mkdocs.structure.nav.Section = mkdocs.structure.nav.Section("Baselines", children)
-
- for f in files:
- if not f.is_documentation_page():
- continue
-
- if f._get_dest_path(False).__contains__("/baselines/"):
- children.append(mkdocs.structure.pages.Page(f._get_stem(), f, config))
-
- referenceItem: mkdocs.structure.nav.Section = next(x for x in nav if x.title == "Reference")
- referenceItem.children.append(item)
- mkdocs.structure.nav._add_parent_links(nav)
diff --git a/mkdocs.yml b/mkdocs.yml
index 3826133c82..4bf763c8dc 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -166,7 +166,7 @@ plugins:
'changelog.md': 'CHANGELOG-v3.md'
hooks:
- - docs/hooks/old_hooks.py
+ - docs/hooks/maml_formatting.py
# watch:
# - includes
diff --git a/ps-rule-ci.yaml b/ps-rule-ci.yaml
index 9dc0c31f5e..33cd571300 100644
--- a/ps-rule-ci.yaml
+++ b/ps-rule-ci.yaml
@@ -30,3 +30,4 @@ input:
- '!**/*.psd1'
- '!**/*.psm1'
- '*.Designer.cs'
+ - '*.csproj'
diff --git a/src/PSRule.Benchmark/packages.lock.json b/src/PSRule.Benchmark/packages.lock.json
index 858dd42753..dc5a172a3b 100644
--- a/src/PSRule.Benchmark/packages.lock.json
+++ b/src/PSRule.Benchmark/packages.lock.json
@@ -1986,8 +1986,8 @@
},
"YamlDotNet": {
"type": "Transitive",
- "resolved": "16.2.1",
- "contentHash": "im6zTVgesjcfTRfuMpnx51Rg2svWenp/3q5XBfcIzgj8PNIkkSD2xEl9HWcVi2SaJPP9XcXUdzed9gSDEuf1TA=="
+ "resolved": "16.3.0",
+ "contentHash": "SgMOdxbz8X65z8hraIs6hOEdnkH6hESTAIUa7viEngHOYaH+6q5XJmwr1+yb9vJpNQ19hCQY69xbFsLtXpobQA=="
},
"Microsoft.PSRule.Badges": {
"type": "Project",
@@ -2012,7 +2012,7 @@
"type": "Project",
"dependencies": {
"Newtonsoft.Json": "[13.0.3, )",
- "YamlDotNet": "[16.2.1, )"
+ "YamlDotNet": "[16.3.0, )"
}
}
}
diff --git a/src/PSRule.CommandLine/packages.lock.json b/src/PSRule.CommandLine/packages.lock.json
index c7dd8484f5..cf5ed29d8a 100644
--- a/src/PSRule.CommandLine/packages.lock.json
+++ b/src/PSRule.CommandLine/packages.lock.json
@@ -1636,8 +1636,8 @@
},
"YamlDotNet": {
"type": "Transitive",
- "resolved": "16.2.1",
- "contentHash": "im6zTVgesjcfTRfuMpnx51Rg2svWenp/3q5XBfcIzgj8PNIkkSD2xEl9HWcVi2SaJPP9XcXUdzed9gSDEuf1TA=="
+ "resolved": "16.3.0",
+ "contentHash": "SgMOdxbz8X65z8hraIs6hOEdnkH6hESTAIUa7viEngHOYaH+6q5XJmwr1+yb9vJpNQ19hCQY69xbFsLtXpobQA=="
},
"Microsoft.PSRule.Badges": {
"type": "Project",
@@ -1668,7 +1668,7 @@
"type": "Project",
"dependencies": {
"Newtonsoft.Json": "[13.0.3, )",
- "YamlDotNet": "[16.2.1, )"
+ "YamlDotNet": "[16.3.0, )"
}
}
}
diff --git a/src/PSRule.EditorServices/packages.lock.json b/src/PSRule.EditorServices/packages.lock.json
index 845c1f833c..bbe19f1fd8 100644
--- a/src/PSRule.EditorServices/packages.lock.json
+++ b/src/PSRule.EditorServices/packages.lock.json
@@ -1635,8 +1635,8 @@
},
"YamlDotNet": {
"type": "Transitive",
- "resolved": "16.2.1",
- "contentHash": "im6zTVgesjcfTRfuMpnx51Rg2svWenp/3q5XBfcIzgj8PNIkkSD2xEl9HWcVi2SaJPP9XcXUdzed9gSDEuf1TA=="
+ "resolved": "16.3.0",
+ "contentHash": "SgMOdxbz8X65z8hraIs6hOEdnkH6hESTAIUa7viEngHOYaH+6q5XJmwr1+yb9vJpNQ19hCQY69xbFsLtXpobQA=="
},
"Microsoft.PSRule.Badges": {
"type": "Project",
@@ -1676,7 +1676,7 @@
"type": "Project",
"dependencies": {
"Newtonsoft.Json": "[13.0.3, )",
- "YamlDotNet": "[16.2.1, )"
+ "YamlDotNet": "[16.3.0, )"
}
}
}
diff --git a/src/PSRule.SDK/packages.lock.json b/src/PSRule.SDK/packages.lock.json
index 8008adb433..a659e2da51 100644
--- a/src/PSRule.SDK/packages.lock.json
+++ b/src/PSRule.SDK/packages.lock.json
@@ -1033,8 +1033,8 @@
},
"YamlDotNet": {
"type": "Transitive",
- "resolved": "16.2.1",
- "contentHash": "im6zTVgesjcfTRfuMpnx51Rg2svWenp/3q5XBfcIzgj8PNIkkSD2xEl9HWcVi2SaJPP9XcXUdzed9gSDEuf1TA=="
+ "resolved": "16.3.0",
+ "contentHash": "SgMOdxbz8X65z8hraIs6hOEdnkH6hESTAIUa7viEngHOYaH+6q5XJmwr1+yb9vJpNQ19hCQY69xbFsLtXpobQA=="
},
"Microsoft.PSRule.Badges": {
"type": "Project",
@@ -1059,7 +1059,7 @@
"type": "Project",
"dependencies": {
"Newtonsoft.Json": "[13.0.3, )",
- "YamlDotNet": "[16.2.1, )"
+ "YamlDotNet": "[16.3.0, )"
}
}
}
diff --git a/src/PSRule.Tool/packages.lock.json b/src/PSRule.Tool/packages.lock.json
index 9f4cf995e8..85789e2e69 100644
--- a/src/PSRule.Tool/packages.lock.json
+++ b/src/PSRule.Tool/packages.lock.json
@@ -1633,8 +1633,8 @@
},
"YamlDotNet": {
"type": "Transitive",
- "resolved": "16.2.1",
- "contentHash": "im6zTVgesjcfTRfuMpnx51Rg2svWenp/3q5XBfcIzgj8PNIkkSD2xEl9HWcVi2SaJPP9XcXUdzed9gSDEuf1TA=="
+ "resolved": "16.3.0",
+ "contentHash": "SgMOdxbz8X65z8hraIs6hOEdnkH6hESTAIUa7viEngHOYaH+6q5XJmwr1+yb9vJpNQ19hCQY69xbFsLtXpobQA=="
},
"Microsoft.PSRule.Badges": {
"type": "Project",
@@ -1674,7 +1674,7 @@
"type": "Project",
"dependencies": {
"Newtonsoft.Json": "[13.0.3, )",
- "YamlDotNet": "[16.2.1, )"
+ "YamlDotNet": "[16.3.0, )"
}
}
},
diff --git a/src/PSRule.Types/Definitions/IResource.cs b/src/PSRule.Types/Definitions/IResource.cs
index b47a310a54..ab023a0a37 100644
--- a/src/PSRule.Types/Definitions/IResource.cs
+++ b/src/PSRule.Types/Definitions/IResource.cs
@@ -51,7 +51,7 @@ public interface IResource : ILanguageBlock
///
/// The source location of the resource.
///
- ISourceExtent Extent { get; }
+ ISourceExtent? Extent { get; }
///
/// Additional information about the resource.
diff --git a/src/PSRule.Types/Emitters/InternalFileStream.cs b/src/PSRule.Types/Emitters/InternalFileStream.cs
deleted file mode 100644
index 42510e4925..0000000000
--- a/src/PSRule.Types/Emitters/InternalFileStream.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright (c) Microsoft Corporation.
-// Licensed under the MIT License.
-
-namespace PSRule.Emitters;
-
-internal class InternalFileStream
-{
- public InternalFileStream()
- {
- }
-}
diff --git a/src/PSRule.Types/Options/BaselineOption.cs b/src/PSRule.Types/Options/BaselineOption.cs
index 817280fdcb..2feacea32b 100644
--- a/src/PSRule.Types/Options/BaselineOption.cs
+++ b/src/PSRule.Types/Options/BaselineOption.cs
@@ -30,7 +30,7 @@ public BaselineOption()
/// Create an option instance based on an existing object.
///
/// The existing object to copy.
- public BaselineOption(BaselineOption option)
+ public BaselineOption(BaselineOption? option)
{
if (option == null)
return;
@@ -67,7 +67,7 @@ public override int GetHashCode()
/// The new instance uses any non-null values from .
/// Any null values from are replaced with .
///
- public static BaselineOption Combine(BaselineOption o1, BaselineOption o2)
+ public static BaselineOption Combine(BaselineOption? o1, BaselineOption? o2)
{
var result = new BaselineOption(o1)
{
diff --git a/src/PSRule.Types/Options/ExecutionOption.cs b/src/PSRule.Types/Options/ExecutionOption.cs
index a0d5b0e5ec..d9a8c62a72 100644
--- a/src/PSRule.Types/Options/ExecutionOption.cs
+++ b/src/PSRule.Types/Options/ExecutionOption.cs
@@ -71,7 +71,7 @@ public ExecutionOption()
/// Creates a execution option by copying an existing instance.
///
/// The option instance to copy.
- public ExecutionOption(ExecutionOption option)
+ public ExecutionOption(ExecutionOption? option)
{
if (option == null)
return;
@@ -143,7 +143,7 @@ public override int GetHashCode()
/// Merge two option instances by replacing any unset properties from with values.
/// Values from that are set are not overridden.
///
- internal static ExecutionOption Combine(ExecutionOption o1, ExecutionOption o2)
+ internal static ExecutionOption Combine(ExecutionOption? o1, ExecutionOption? o2)
{
var result = new ExecutionOption(o1)
{
diff --git a/src/PSRule.Types/Options/OverrideOption.cs b/src/PSRule.Types/Options/OverrideOption.cs
index 3a83c203b2..da23d4fe09 100644
--- a/src/PSRule.Types/Options/OverrideOption.cs
+++ b/src/PSRule.Types/Options/OverrideOption.cs
@@ -34,7 +34,7 @@ public OverrideOption()
/// Create an option instance based on an existing object.
///
/// The existing object to copy.
- public OverrideOption(OverrideOption option)
+ public OverrideOption(OverrideOption? option)
{
if (option == null)
return;
@@ -71,7 +71,7 @@ public override int GetHashCode()
/// The new instance uses any non-null values from .
/// Any null values from are replaced with .
///
- public static OverrideOption Combine(OverrideOption o1, OverrideOption o2)
+ public static OverrideOption Combine(OverrideOption? o1, OverrideOption? o2)
{
var result = new OverrideOption(o1)
{
diff --git a/src/PSRule/Commands/ExportConventionCommand.cs b/src/PSRule/Commands/ExportConventionCommand.cs
index f0f0988cd1..c56c186225 100644
--- a/src/PSRule/Commands/ExportConventionCommand.cs
+++ b/src/PSRule/Commands/ExportConventionCommand.cs
@@ -70,7 +70,7 @@ protected override void ProcessRecord()
var context = RunspaceContext.CurrentThread;
if (context == null) return;
- var source = context.Source;
+ var source = context.Source!;
var errorPreference = GetErrorActionPreference();
var commentMetadata = GetCommentMetadata(source, MyInvocation.ScriptLineNumber, MyInvocation.OffsetInLine);
var metadata = new ResourceMetadata
diff --git a/src/PSRule/Common/HashSetExtensions.cs b/src/PSRule/Common/HashSetExtensions.cs
index c9ecd3104a..ab5f14e31a 100644
--- a/src/PSRule/Common/HashSetExtensions.cs
+++ b/src/PSRule/Common/HashSetExtensions.cs
@@ -7,25 +7,25 @@ namespace PSRule;
internal static class HashSetExtensions
{
- internal static bool ContainsIds(this HashSet hashset, ResourceId id, ResourceId? @ref, ResourceId[] aliases, out ResourceId? duplicate)
+ internal static bool ContainsIds(this HashSet set, ResourceId id, ResourceId? @ref, ResourceId[] aliases, out ResourceId? duplicate)
{
duplicate = null;
- if (hashset == null || hashset.Count == 0)
+ if (set == null || set.Count == 0)
return false;
- if (hashset.Contains(id))
+ if (set.Contains(id))
{
duplicate = id;
return true;
}
- if (@ref.HasValue && hashset.Contains(@ref.Value))
+ if (@ref.HasValue && set.Contains(@ref.Value))
{
duplicate = @ref.Value;
return true;
}
for (var i = 0; aliases != null && i < aliases.Length; i++)
{
- if (hashset.Contains(aliases[i]))
+ if (set.Contains(aliases[i]))
{
duplicate = aliases[i];
return true;
@@ -34,25 +34,25 @@ internal static bool ContainsIds(this HashSet hashset, ResourceId id
return false;
}
- internal static bool ContainsNames(this HashSet hashset, ResourceId id, ResourceId? @ref, ResourceId[] aliases, out string duplicate)
+ internal static bool ContainsNames(this HashSet set, ResourceId id, ResourceId? @ref, ResourceId[] aliases, out string duplicate)
{
duplicate = null;
- if (hashset == null || hashset.Count == 0)
+ if (set == null || set.Count == 0)
return false;
- if (hashset.Contains(id.Name))
+ if (set.Contains(id.Name))
{
duplicate = id.Name;
return true;
}
- if (@ref.HasValue && hashset.Contains(@ref.Value.Name))
+ if (@ref.HasValue && set.Contains(@ref.Value.Name))
{
duplicate = @ref.Value.Name;
return true;
}
for (var i = 0; aliases != null && i < aliases.Length; i++)
{
- if (hashset.Contains(aliases[i].Name))
+ if (set.Contains(aliases[i].Name))
{
duplicate = aliases[i].Name;
return true;
@@ -61,35 +61,35 @@ internal static bool ContainsNames(this HashSet hashset, ResourceId id,
return false;
}
- internal static void AddIds(this HashSet hashset, ResourceId id, ResourceId? @ref, ResourceId[] aliases)
+ internal static void AddIds(this HashSet set, ResourceId id, ResourceId? @ref, ResourceId[] aliases)
{
- if (hashset == null)
+ if (set == null)
return;
- if (!hashset.Contains(id))
- hashset.Add(id);
+ if (!set.Contains(id))
+ set.Add(id);
- if (@ref.HasValue && !hashset.Contains(@ref.Value))
- hashset.Add(@ref.Value);
+ if (@ref.HasValue && !set.Contains(@ref.Value))
+ set.Add(@ref.Value);
for (var i = 0; aliases != null && i < aliases.Length; i++)
- if (!hashset.Contains(aliases[i]))
- hashset.Add(aliases[i]);
+ if (!set.Contains(aliases[i]))
+ set.Add(aliases[i]);
}
- internal static void AddNames(this HashSet hashset, ResourceId id, ResourceId? @ref, ResourceId[] aliases)
+ internal static void AddNames(this HashSet set, ResourceId id, ResourceId? @ref, ResourceId[] aliases)
{
- if (hashset == null)
+ if (set == null)
return;
- if (!hashset.Contains(id.Name))
- hashset.Add(id.Name);
+ if (!set.Contains(id.Name))
+ set.Add(id.Name);
- if (@ref.HasValue && !hashset.Contains(@ref.Value.Name))
- hashset.Add(@ref.Value.Name);
+ if (@ref.HasValue && !set.Contains(@ref.Value.Name))
+ set.Add(@ref.Value.Name);
for (var i = 0; aliases != null && i < aliases.Length; i++)
- if (!hashset.Contains(aliases[i].Name))
- hashset.Add(aliases[i].Name);
+ if (!set.Contains(aliases[i].Name))
+ set.Add(aliases[i].Name);
}
}
diff --git a/src/PSRule/Converters/Json/LockEntryIntegrityJsonConverter.cs b/src/PSRule/Converters/Json/LockEntryIntegrityJsonConverter.cs
index 0b2086c474..97cc807d07 100644
--- a/src/PSRule/Converters/Json/LockEntryIntegrityJsonConverter.cs
+++ b/src/PSRule/Converters/Json/LockEntryIntegrityJsonConverter.cs
@@ -19,19 +19,14 @@ internal sealed class LockEntryIntegrityJsonConverter : JsonConverter(parts[0], ignoreCase: true, result: out var algorithm))
- return null;
-
- return new LockEntryIntegrity
- {
- Algorithm = algorithm,
- Hash = parts[1]
- };
+ return Enum.TryParse(parts[0], ignoreCase: true, result: out var algorithm)
+ ? new LockEntryIntegrity(algorithm, hash: parts[1])
+ : null;
}
public override void WriteJson(JsonWriter writer, LockEntryIntegrity? value, JsonSerializer serializer)
{
- if (value == null || value.Algorithm == null || value.Algorithm == IntegrityAlgorithm.Unknown || string.IsNullOrEmpty(value.Hash))
+ if (value == null || value.Algorithm == IntegrityAlgorithm.Unknown || string.IsNullOrEmpty(value.Hash))
return;
var algorithm = Enum.GetName(typeof(IntegrityAlgorithm), value.Algorithm).ToLower();
diff --git a/src/PSRule/Definitions/Conventions/ConventionExtensions.cs b/src/PSRule/Definitions/Conventions/ConventionExtensions.cs
index cd45cfcd27..586fc3ba08 100644
--- a/src/PSRule/Definitions/Conventions/ConventionExtensions.cs
+++ b/src/PSRule/Definitions/Conventions/ConventionExtensions.cs
@@ -49,7 +49,7 @@ private static bool Match(RunspaceContext context, ScriptBlockConvention block)
try
{
context.EnterLanguageScope(block.Source);
- var filter = context.LanguageScope.GetFilter(ResourceKind.Convention);
+ var filter = context.LanguageScope?.GetFilter(ResourceKind.Convention);
return filter == null || filter.Match(block);
}
finally
diff --git a/src/PSRule/Definitions/IDependencyTarget.cs b/src/PSRule/Definitions/IDependencyTarget.cs
index 4acb362d19..4371903fb2 100644
--- a/src/PSRule/Definitions/IDependencyTarget.cs
+++ b/src/PSRule/Definitions/IDependencyTarget.cs
@@ -3,6 +3,8 @@
namespace PSRule.Definitions;
+#nullable enable
+
///
/// An object that relies on a dependency chain.
///
@@ -21,15 +23,17 @@ public interface IDependencyTarget
///
/// Additional aliases for the resource.
///
- ResourceId[] Alias { get; }
+ ResourceId[]? Alias { get; }
///
/// Resources this target depends on.
///
- ResourceId[] DependsOn { get; }
+ ResourceId[]? DependsOn { get; }
///
/// Determines if the source was imported as a dependency.
///
bool Dependency { get; }
}
+
+#nullable restore
diff --git a/src/PSRule/Definitions/Rules/RuleExtensions.cs b/src/PSRule/Definitions/Rules/RuleExtensions.cs
index a73a41a82d..15d048047b 100644
--- a/src/PSRule/Definitions/Rules/RuleExtensions.cs
+++ b/src/PSRule/Definitions/Rules/RuleExtensions.cs
@@ -117,7 +117,7 @@ public static DependencyTargetCollection ToRuleDependencyTargetCollec
// Process from PowerShell
foreach (var block in blocks.OfType())
{
- if (knownRuleIds.ContainsIds(block.Id, block.Ref, block.Alias, out var duplicateId))
+ if (knownRuleIds.ContainsIds(block.Id, block.Ref, block.Alias, out var duplicateId) && duplicateId != null)
{
context.DuplicateResourceId(block.Id, duplicateId.Value);
continue;
@@ -138,7 +138,7 @@ public static DependencyTargetCollection ToRuleDependencyTargetCollec
foreach (var block in blocks.OfType())
{
var ruleName = block.Name;
- if (knownRuleIds.ContainsIds(block.Id, block.Ref, block.Alias, out var duplicateId))
+ if (knownRuleIds.ContainsIds(block.Id, block.Ref, block.Alias, out var duplicateId) && duplicateId != null)
{
context.DuplicateResourceId(block.Id, duplicateId.Value);
continue;
@@ -151,7 +151,7 @@ public static DependencyTargetCollection ToRuleDependencyTargetCollec
}
context.EnterLanguageScope(block.Source);
- context.LanguageScope.TryGetOverride(block.Id, out var propertyOverride);
+ context.LanguageScope!.TryGetOverride(block.Id, out var propertyOverride);
try
{
var info = GetRuleHelpInfo(context, block) ?? new RuleHelpInfo(
diff --git a/src/PSRule/Emitters/EmitterContext.cs b/src/PSRule/Emitters/EmitterContext.cs
index 5c918e6483..f7ad2ca8d4 100644
--- a/src/PSRule/Emitters/EmitterContext.cs
+++ b/src/PSRule/Emitters/EmitterContext.cs
@@ -17,12 +17,12 @@ namespace PSRule.Emitters;
internal sealed class EmitterContext : BaseEmitterContext
{
private readonly ConcurrentQueue _Queue;
- private readonly PathFilter _InputFilter;
+ private readonly PathFilter? _InputFilter;
///
/// Create an instance containing context for an .
///
- internal EmitterContext(ConcurrentQueue queue, PathFilter inputFilter, PSRuleOption? option)
+ internal EmitterContext(ConcurrentQueue queue, PathFilter? inputFilter, PSRuleOption? option)
: base(option?.Input?.Format ?? InputFormat.None, option?.Input?.ObjectPath, option?.Input?.FileObjects ?? false)
{
_Queue = queue;
@@ -32,7 +32,8 @@ internal EmitterContext(ConcurrentQueue queue, PathFilter inputFi
///
protected override void Enqueue(ITargetObject value)
{
- if (!ShouldQueue(value)) return;
+ if (!ShouldQueue(value))
+ return;
_Queue.Enqueue(value);
}
@@ -42,7 +43,8 @@ protected override void Enqueue(ITargetObject value)
///
private bool ShouldQueue(ITargetObject targetObject)
{
- if (_InputFilter == null) return true;
+ if (_InputFilter == null)
+ return true;
foreach (var source in targetObject.Source)
{
diff --git a/src/PSRule/Pipeline/Dependencies/IntegrityBuilder.cs b/src/PSRule/Pipeline/Dependencies/IntegrityBuilder.cs
index 59729bcfe4..70d2a9cc94 100644
--- a/src/PSRule/Pipeline/Dependencies/IntegrityBuilder.cs
+++ b/src/PSRule/Pipeline/Dependencies/IntegrityBuilder.cs
@@ -47,11 +47,7 @@ public static LockEntryIntegrity Build(IntegrityAlgorithm alg, string path)
Formatting = Formatting.None,
});
- return new LockEntryIntegrity
- {
- Algorithm = IntegrityAlgorithm.SHA512,
- Hash = CalculateHashFromContent(alg, content)
- };
+ return new LockEntryIntegrity(IntegrityAlgorithm.SHA512, hash: CalculateHashFromContent(alg, content));
}
private static string CalculateHashFromPath(IntegrityAlgorithm alg, string path)
diff --git a/src/PSRule/Pipeline/Dependencies/LockEntryIntegrity.cs b/src/PSRule/Pipeline/Dependencies/LockEntryIntegrity.cs
index 3aef46a5e6..3ad9841ba1 100644
--- a/src/PSRule/Pipeline/Dependencies/LockEntryIntegrity.cs
+++ b/src/PSRule/Pipeline/Dependencies/LockEntryIntegrity.cs
@@ -10,19 +10,19 @@ namespace PSRule.Pipeline.Dependencies;
///
/// Split out an integrity hash string into the algorithm and hash value.
///
-public sealed class LockEntryIntegrity
+public sealed class LockEntryIntegrity(IntegrityAlgorithm algorithm, string hash)
{
///
/// The algorithm used to generate the hash.
///
[Required]
- public IntegrityAlgorithm Algorithm { get; set; }
+ public IntegrityAlgorithm Algorithm { get; set; } = algorithm;
///
/// The base64 encoded hash value.
///
[Required]
- public string Hash { get; set; }
+ public string Hash { get; set; } = hash;
}
#nullable restore
diff --git a/src/PSRule/Pipeline/HostContext.cs b/src/PSRule/Pipeline/HostContext.cs
index 0e92131ad9..0450e74b49 100644
--- a/src/PSRule/Pipeline/HostContext.cs
+++ b/src/PSRule/Pipeline/HostContext.cs
@@ -42,7 +42,7 @@ public virtual ActionPreference GetPreferenceVariable(string variableName)
}
///
- public virtual T GetVariable(string variableName)
+ public virtual T? GetVariable(string variableName)
{
return default;
}
diff --git a/src/PSRule/Pipeline/IHostContext.cs b/src/PSRule/Pipeline/IHostContext.cs
index 761a0b3407..40154e2225 100644
--- a/src/PSRule/Pipeline/IHostContext.cs
+++ b/src/PSRule/Pipeline/IHostContext.cs
@@ -32,7 +32,7 @@ public interface IHostContext
///
/// Get the value of a named variable.
///
- T GetVariable(string variableName);
+ T? GetVariable(string variableName);
///
/// Set the value of a named variable.
diff --git a/src/PSRule/Pipeline/OptionContext.cs b/src/PSRule/Pipeline/OptionContext.cs
index 0ecb07a35a..44f1e25f74 100644
--- a/src/PSRule/Pipeline/OptionContext.cs
+++ b/src/PSRule/Pipeline/OptionContext.cs
@@ -9,26 +9,18 @@ namespace PSRule.Pipeline;
#nullable enable
-internal sealed class OptionContext
+internal sealed class OptionContext(BindTargetMethod? bindTargetName, BindTargetMethod? bindTargetType, BindTargetMethod? bindField, string[]? inputTargetType)
{
- private ConventionOption _Convention;
- private List _ConventionOrder;
+ private ConventionOption? _Convention;
+ private List? _ConventionOrder;
- public OptionContext(BindTargetMethod bindTargetName, BindTargetMethod bindTargetType, BindTargetMethod bindField, string[] inputTargetType)
- {
- BindTargetName = bindTargetName;
- BindTargetType = bindTargetType;
- BindField = bindField;
- InputTargetType = inputTargetType;
- }
-
- public Options.BaselineOption Baseline { get; set; }
+ public Options.BaselineOption? Baseline { get; set; }
- public BindingOption Binding { get; set; }
+ public BindingOption? Binding { get; set; }
- public ConfigurationOption Configuration { get; set; }
+ public ConfigurationOption? Configuration { get; set; }
- public ConventionOption Convention
+ public ConventionOption? Convention
{
get
{
@@ -41,42 +33,42 @@ public ConventionOption Convention
}
}
- public ExecutionOption Execution { get; set; }
+ public ExecutionOption? Execution { get; set; }
- public IncludeOption Include { get; set; }
+ public IncludeOption? Include { get; set; }
- public InputOption Input { get; set; }
+ public InputOption? Input { get; set; }
- public LoggingOption Logging { get; set; }
+ public LoggingOption? Logging { get; set; }
- public OutputOption Output { get; set; }
+ public OutputOption? Output { get; set; }
- public OverrideOption Override { get; set; }
+ public OverrideOption? Override { get; set; }
- public RepositoryOption Repository { get; set; }
+ public RepositoryOption? Repository { get; set; }
- public RequiresOption Requires { get; set; }
+ public RequiresOption? Requires { get; set; }
- public RuleOption Rule { get; set; }
+ public RuleOption? Rule { get; set; }
- public SuppressionOption Suppression { get; set; }
+ public SuppressionOption? Suppression { get; set; }
- public IResourceFilter ConventionFilter { get; set; }
+ public IResourceFilter? ConventionFilter { get; set; }
- public IResourceFilter RuleFilter { get; set; }
+ public IResourceFilter? RuleFilter { get; set; }
- public BindTargetMethod BindTargetName { get; }
- public BindTargetMethod BindTargetType { get; }
- public BindTargetMethod BindField { get; }
+ public BindTargetMethod? BindTargetName { get; } = bindTargetName;
+ public BindTargetMethod? BindTargetType { get; } = bindTargetType;
+ public BindTargetMethod? BindField { get; } = bindField;
- public string[] InputTargetType { get; }
+ public string[]? InputTargetType { get; } = inputTargetType;
internal int GetConventionOrder(IConventionV1 convention)
{
if (Convention?.Include == null || Convention.Include.Length == 0)
return -1;
- _ConventionOrder ??= new List(Convention.Include);
+ _ConventionOrder ??= [.. Convention.Include];
var index = _ConventionOrder.IndexOf(convention.Id.Value);
if (index == -1)
index = _ConventionOrder.IndexOf(convention.Name);
diff --git a/src/PSRule/Pipeline/OptionContextBuilder.cs b/src/PSRule/Pipeline/OptionContextBuilder.cs
index 7d576ac6b1..d6df68d264 100644
--- a/src/PSRule/Pipeline/OptionContextBuilder.cs
+++ b/src/PSRule/Pipeline/OptionContextBuilder.cs
@@ -63,7 +63,7 @@ internal OptionContextBuilder(PSRuleOption option, string[]? include = null, Has
///
/// Build an .
///
- internal OptionContext Build(string languageScope)
+ internal OptionContext Build(string? languageScope)
{
languageScope = ResourceHelper.NormalizeScope(languageScope);
var context = new OptionContext(_BindTargetName, _BindTargetType, _BindField, _InputTargetType);
@@ -76,7 +76,10 @@ internal OptionContext Build(string languageScope)
Combine(context, _Scopes[i]);
}
//Combine(PSRuleOption.FromDefault());
+ context.Output ??= new();
context.Output.Culture ??= _DefaultCulture;
+
+ context.Rule ??= new();
context.Rule.IncludeLocal = GetIncludeLocal(_Scopes) ?? context.Rule.IncludeLocal ?? true;
context.RuleFilter = GetRuleFilter(context.Rule);
@@ -202,15 +205,15 @@ private static string[] GetConventions(List scopes)
}
include.AddUnique(add);
}
- return include.ToArray();
+ return [.. include];
}
- private bool? GetIncludeLocal(List scopes)
+ private static bool? GetIncludeLocal(List scopes)
{
for (var i = 0; i < scopes.Count; i++)
{
- if (scopes[i].Type == ScopeType.Workspace && scopes[i].Rule != null && scopes[i].Rule.IncludeLocal.HasValue)
- return scopes[i].Rule.IncludeLocal.Value;
+ if (scopes[i].Type == ScopeType.Workspace && scopes[i].Rule != null && scopes[i].Rule.IncludeLocal != default)
+ return scopes[i].Rule.IncludeLocal!.Value;
}
return null;
}
diff --git a/src/PSRule/Pipeline/PipelineContext.cs b/src/PSRule/Pipeline/PipelineContext.cs
index 1277c47ad7..3294e2e7c7 100644
--- a/src/PSRule/Pipeline/PipelineContext.cs
+++ b/src/PSRule/Pipeline/PipelineContext.cs
@@ -43,7 +43,7 @@ internal sealed class PipelineContext : IPipelineContext, IBindingContext
private readonly Dictionary _PathExpressionCache;
// Objects kept for caching and disposal
- private Runspace _Runspace;
+ private Runspace? _Runspace;
// Track whether Dispose has been called.
private bool _Disposed;
@@ -58,7 +58,7 @@ internal sealed class PipelineContext : IPipelineContext, IBindingContext
internal IList SuppressionGroup;
- internal readonly IHostContext HostContext;
+ internal readonly IHostContext? HostContext;
private readonly Func _GetReader;
internal IPipelineReader? Reader { get; private set; }
internal readonly string RunId;
@@ -78,7 +78,7 @@ internal sealed class PipelineContext : IPipelineContext, IBindingContext
///
public ILanguageScopeSet LanguageScope { get; }
- private PipelineContext(PSRuleOption option, IHostContext hostContext, Func reader, IPipelineWriter writer, ILanguageScopeSet languageScope, OptionContextBuilder optionBuilder, ResourceCache resourceCache)
+ private PipelineContext(PSRuleOption option, IHostContext? hostContext, Func reader, IPipelineWriter writer, ILanguageScopeSet languageScope, OptionContextBuilder optionBuilder, ResourceCache resourceCache)
{
Option = option ?? throw new ArgumentNullException(nameof(option));
LanguageScope = languageScope ?? throw new ArgumentNullException(nameof(languageScope));
@@ -100,11 +100,11 @@ private PipelineContext(PSRuleOption option, IHostContext hostContext, Func reader, IPipelineWriter writer, ILanguageScopeSet languageScope, OptionContextBuilder optionBuilder, ResourceCache resourceCache)
+ public static PipelineContext New(PSRuleOption option, IHostContext? hostContext, Func reader, IPipelineWriter writer, ILanguageScopeSet languageScope, OptionContextBuilder optionBuilder, ResourceCache resourceCache)
{
var context = new PipelineContext(option, hostContext, reader, writer, languageScope, optionBuilder, resourceCache);
CurrentThread = context;
diff --git a/src/PSRule/Pipeline/PipelineInputStream.cs b/src/PSRule/Pipeline/PipelineInputStream.cs
index d4ad5471d1..7009abd5ae 100644
--- a/src/PSRule/Pipeline/PipelineInputStream.cs
+++ b/src/PSRule/Pipeline/PipelineInputStream.cs
@@ -17,12 +17,12 @@ namespace PSRule.Pipeline;
///
internal sealed class PipelineInputStream : IPipelineReader
{
- private readonly InputPathBuilder _InputPath;
- private readonly PathFilter _InputFilter;
+ private readonly InputPathBuilder? _InputPath;
+ private readonly PathFilter? _InputFilter;
private readonly ConcurrentQueue _Queue;
private readonly EmitterCollection _EmitterCollection;
- public PipelineInputStream(ILanguageScopeSet? languageScopeSet, InputPathBuilder inputPath, PathFilter inputFilter, PSRuleOption? option)
+ public PipelineInputStream(ILanguageScopeSet? languageScopeSet, InputPathBuilder? inputPath, PathFilter? inputFilter, PSRuleOption? option)
{
_InputPath = inputPath;
_InputFilter = inputFilter;
diff --git a/src/PSRule/Rules/RuleBlock.cs b/src/PSRule/Rules/RuleBlock.cs
index ebe46daff8..c6e658c7f3 100644
--- a/src/PSRule/Rules/RuleBlock.cs
+++ b/src/PSRule/Rules/RuleBlock.cs
@@ -23,7 +23,7 @@ namespace PSRule.Rules;
[DebuggerDisplay("{Id} @{Source.Path}")]
internal sealed class RuleBlock : ILanguageBlock, IDependencyTarget, IDisposable, IResource, IRuleV1
{
- internal RuleBlock(ISourceFile source, ResourceId id, ResourceId? @ref, RuleProperties @default, RuleOverride @override, RuleHelpInfo info, ICondition condition, IResourceTags tag, ResourceId[] alias, ResourceId[] dependsOn, Hashtable configuration, ISourceExtent extent, ResourceFlags flags, IResourceLabels labels)
+ internal RuleBlock(ISourceFile source, ResourceId id, ResourceId? @ref, RuleProperties @default, RuleOverride? @override, RuleHelpInfo info, ICondition condition, IResourceTags tag, ResourceId[] alias, ResourceId[]? dependsOn, Hashtable? configuration, ISourceExtent? extent, ResourceFlags flags, IResourceLabels labels)
{
Source = source;
Name = id.Name;
@@ -77,7 +77,7 @@ internal RuleBlock(ISourceFile source, ResourceId id, ResourceId? @ref, RuleProp
///
/// Other rules that must completed successfully before calling this rule.
///
- public readonly ResourceId[] DependsOn;
+ public readonly ResourceId[]? DependsOn;
///
/// Tags assigned to block. Tags are additional metadata used to select rules to execute and identify results.
@@ -93,7 +93,7 @@ internal RuleBlock(ISourceFile source, ResourceId id, ResourceId? @ref, RuleProp
///
/// These defaults are used when the value does not exist in the baseline configuration.
///
- public readonly Hashtable Configuration;
+ public readonly Hashtable? Configuration;
public readonly RuleHelpInfo Info;
@@ -101,7 +101,7 @@ internal RuleBlock(ISourceFile source, ResourceId id, ResourceId? @ref, RuleProp
public ISourceFile Source { get; }
///
- public ISourceExtent Extent { get; }
+ public ISourceExtent? Extent { get; }
///
[JsonIgnore]
@@ -114,9 +114,9 @@ internal RuleBlock(ISourceFile source, ResourceId id, ResourceId? @ref, RuleProp
[JsonIgnore]
[YamlIgnore]
- public RuleOverride Override { get; }
+ public RuleOverride? Override { get; }
- ResourceId[] IDependencyTarget.DependsOn => DependsOn;
+ ResourceId[]? IDependencyTarget.DependsOn => DependsOn;
bool IDependencyTarget.Dependency => Source.IsDependency();
diff --git a/src/PSRule/Rules/RuleRecord.cs b/src/PSRule/Rules/RuleRecord.cs
index bd994ef462..e8305cdc4c 100644
--- a/src/PSRule/Rules/RuleRecord.cs
+++ b/src/PSRule/Rules/RuleRecord.cs
@@ -27,7 +27,7 @@ public sealed class RuleRecord : IDetailedRuleResultV2
internal readonly ResultDetail _Detail;
- internal RuleRecord(string runId, ResourceId ruleId, string @ref, TargetObject targetObject, string targetName, string targetType, IResourceTags tag, RuleHelpInfo info, Hashtable field, RuleProperties @default, ISourceExtent extent, RuleOutcome outcome = RuleOutcome.None, RuleOutcomeReason reason = RuleOutcomeReason.None, RuleOverride? @override = null)
+ internal RuleRecord(string runId, ResourceId ruleId, string @ref, TargetObject targetObject, string targetName, string targetType, IResourceTags tag, RuleHelpInfo info, Hashtable? field, RuleProperties @default, ISourceExtent? extent, RuleOutcome outcome = RuleOutcome.None, RuleOutcomeReason reason = RuleOutcomeReason.None, RuleOverride? @override = null)
{
_TargetObject = targetObject;
RunId = runId;
@@ -92,7 +92,7 @@ internal RuleRecord(string runId, ResourceId ruleId, string @ref, TargetObject t
///
[JsonIgnore]
[YamlIgnore]
- public ISourceExtent Extent { get; }
+ public ISourceExtent? Extent { get; }
///
/// The outcome after the rule processes an object.
@@ -149,7 +149,7 @@ internal RuleRecord(string runId, ResourceId ruleId, string @ref, TargetObject t
/// A set of custom fields bound for the target object.
///
[JsonProperty(PropertyName = "field")]
- public Hashtable Field { get; }
+ public Hashtable? Field { get; }
///
/// Tags set for the rule.
diff --git a/src/PSRule/Runtime/Binding/TargetBinderBuilder.cs b/src/PSRule/Runtime/Binding/TargetBinderBuilder.cs
index 03ae67170f..a275cabf47 100644
--- a/src/PSRule/Runtime/Binding/TargetBinderBuilder.cs
+++ b/src/PSRule/Runtime/Binding/TargetBinderBuilder.cs
@@ -14,11 +14,11 @@ internal sealed class TargetBinderBuilder
{
private readonly List _BindingContext;
private readonly HashSet? _TypeFilter;
- private readonly BindTargetMethod _BindTargetName;
- private readonly BindTargetMethod _BindTargetType;
- private readonly BindTargetMethod _BindField;
+ private readonly BindTargetMethod? _BindTargetName;
+ private readonly BindTargetMethod? _BindTargetType;
+ private readonly BindTargetMethod? _BindField;
- public TargetBinderBuilder(BindTargetMethod bindTargetName, BindTargetMethod bindTargetType, BindTargetMethod bindField, string[]? typeFilter)
+ public TargetBinderBuilder(BindTargetMethod? bindTargetName, BindTargetMethod? bindTargetType, BindTargetMethod? bindField, string[]? typeFilter)
{
_BindTargetName = bindTargetName;
_BindTargetType = bindTargetType;
diff --git a/src/PSRule/Runtime/Binding/TargetBindingContext.cs b/src/PSRule/Runtime/Binding/TargetBindingContext.cs
index 03997fffc8..436a0f663b 100644
--- a/src/PSRule/Runtime/Binding/TargetBindingContext.cs
+++ b/src/PSRule/Runtime/Binding/TargetBindingContext.cs
@@ -18,12 +18,12 @@ internal sealed class TargetBindingContext : ITargetBindingContext
private readonly string[]? _TargetName;
private readonly string[]? _TargetType;
private readonly string _NameSeparator;
- private readonly BindTargetMethod _BindTargetName;
- private readonly BindTargetMethod _BindTargetType;
- private readonly BindTargetMethod _BindField;
+ private readonly BindTargetMethod? _BindTargetName;
+ private readonly BindTargetMethod? _BindTargetType;
+ private readonly BindTargetMethod? _BindField;
private readonly HashSet? _TypeFilter;
- public TargetBindingContext(BindingOption? bindingOption, BindTargetMethod bindTargetName, BindTargetMethod bindTargetType, BindTargetMethod bindField, HashSet? typeFilter)
+ public TargetBindingContext(BindingOption? bindingOption, BindTargetMethod? bindTargetName, BindTargetMethod? bindTargetType, BindTargetMethod? bindField, HashSet? typeFilter)
{
_PreferTargetInfo = bindingOption?.PreferTargetInfo ?? BindingOption.Default.PreferTargetInfo!.Value;
_IgnoreCase = bindingOption?.IgnoreCase ?? BindingOption.Default.IgnoreCase!.Value;
@@ -84,9 +84,9 @@ private TargetBindingResult Bind(string targetName, string targetNamePath, strin
///
/// Bind additional fields.
///
- private static ImmutableHashtable? BindField(BindTargetMethod bindField, FieldMap?[] map, bool caseSensitive, object o)
+ private static ImmutableHashtable? BindField(BindTargetMethod? bindField, FieldMap?[] map, bool caseSensitive, object o)
{
- if (map == null || map.Length == 0)
+ if (map == null || map.Length == 0 || bindField == null)
return null;
var hashtable = new ImmutableHashtable();
diff --git a/src/PSRule/Runtime/LanguageScope.cs b/src/PSRule/Runtime/LanguageScope.cs
index 3d63561776..a1ab2a5c13 100644
--- a/src/PSRule/Runtime/LanguageScope.cs
+++ b/src/PSRule/Runtime/LanguageScope.cs
@@ -16,29 +16,20 @@ namespace PSRule.Runtime;
#nullable enable
[DebuggerDisplay("{Name}")]
-internal sealed class LanguageScope : ILanguageScope, IRuntimeServiceCollection
+internal sealed class LanguageScope(string name) : ILanguageScope, IRuntimeServiceCollection
{
- private IDictionary? _Configuration;
+ private IDictionary? _Configuration = new Dictionary(StringComparer.OrdinalIgnoreCase);
private WildcardMap? _Override;
- private readonly Dictionary _Service;
- private readonly List _Emitters;
- private readonly Dictionary _Filter;
+ private readonly Dictionary _Service = [];
+ private readonly List _Emitters = [];
+ private readonly Dictionary _Filter = [];
private ITargetBinder? _TargetBinder;
private StringComparer? _BindingComparer;
private bool _Disposed;
- public LanguageScope(string name)
- {
- _Configuration = new Dictionary(StringComparer.OrdinalIgnoreCase);
- Name = ResourceHelper.NormalizeScope(name);
- _Filter = [];
- _Service = [];
- _Emitters = [];
- }
-
///
- public string Name { [DebuggerStepThrough] get; }
+ public string Name { [DebuggerStepThrough] get; } = ResourceHelper.NormalizeScope(name);
///
public string[]? Culture { [DebuggerStepThrough] get; [DebuggerStepThrough] private set; }
@@ -55,14 +46,14 @@ public void Configure(OptionContext context)
WithFilter(context.RuleFilter);
WithFilter(context.ConventionFilter);
_BindingComparer = context.Binding.GetComparer();
- Culture = context.Output.Culture;
+ Culture = context.Output?.Culture;
var builder = new TargetBinderBuilder(context.BindTargetName, context.BindTargetType, context.BindField, context.InputTargetType);
_TargetBinder = builder.Build(context.Binding);
_Override = WithOverride(context.Override);
}
- private static WildcardMap? WithOverride(OverrideOption option)
+ private static WildcardMap? WithOverride(OverrideOption? option)
{
if (option == null || option.Level == null)
return default;
@@ -92,8 +83,11 @@ public bool TryGetOverride(ResourceId id, out RuleOverride? value)
}
///
- public void WithFilter(IResourceFilter resourceFilter)
+ public void WithFilter(IResourceFilter? resourceFilter)
{
+ if (resourceFilter == null)
+ return;
+
_Filter[resourceFilter.Kind] = resourceFilter;
}
diff --git a/src/PSRule/Runtime/PSRule.cs b/src/PSRule/Runtime/PSRule.cs
index c847950bfb..fca0f1a9cc 100644
--- a/src/PSRule/Runtime/PSRule.cs
+++ b/src/PSRule/Runtime/PSRule.cs
@@ -70,7 +70,7 @@ public void Add(string path)
{
var context = GetContext();
context.Writer.VerboseInputAdded(path);
- context.Pipeline.Reader.Add(path);
+ context.Pipeline.Reader?.Add(path);
}
}
@@ -323,7 +323,7 @@ public void ImportWithType(string? type, PSObject[] sourceObject)
if (sourceObject[i] == null)
continue;
- GetContext().Pipeline.Reader.Enqueue(sourceObject[i], targetType: type, skipExpansion: true);
+ GetContext().Pipeline.Reader?.Enqueue(sourceObject[i], targetType: type, skipExpansion: true);
}
}
diff --git a/src/PSRule/Runtime/RunspaceContext.cs b/src/PSRule/Runtime/RunspaceContext.cs
index 79dc61c874..4445124cd8 100644
--- a/src/PSRule/Runtime/RunspaceContext.cs
+++ b/src/PSRule/Runtime/RunspaceContext.cs
@@ -458,8 +458,8 @@ private string GetStackTrace(ErrorRecord record)
Thread.CurrentThread.CurrentCulture,
PSRuleResources.RuleStackTrace,
RuleBlock.Name,
- RuleBlock.Extent.File,
- RuleBlock.Extent.Line)
+ RuleBlock.Extent?.File,
+ RuleBlock.Extent?.Line)
);
}
@@ -593,12 +593,12 @@ public RuleRecord EnterRuleBlock(RuleBlock ruleBlock)
runId: Pipeline.RunId,
ruleId: ruleBlock.Id,
@ref: ruleBlock.Ref.GetValueOrDefault().Name,
- targetObject: TargetObject,
- targetName: Binding?.TargetName,
- targetType: Binding?.TargetType,
+ targetObject: TargetObject!,
+ targetName: Binding?.TargetName!,
+ targetType: Binding?.TargetType!,
tag: ruleBlock.Tag,
info: ruleBlock.Info,
- field: Binding.Field,
+ field: Binding?.Field,
@default: ruleBlock.Default,
extent: ruleBlock.Extent,
@override: ruleBlock.Override
@@ -656,7 +656,7 @@ internal void AddService(string id, object service)
if (LanguageScope == null) throw new InvalidOperationException("Can not call out of scope.");
ResourceHelper.ParseIdString(LanguageScope.Name, id, out var scopeName, out var name);
- return !Pipeline.LanguageScope.TryScope(scopeName, out var scope) || string.IsNullOrEmpty(name) ? null : scope.GetService(name);
+ return scopeName == null || !Pipeline.LanguageScope.TryScope(scopeName, out var scope) || scope == null || name == null || string.IsNullOrEmpty(name) ? null : scope.GetService(name);
}
private void RunConventionInitialize()
@@ -799,7 +799,7 @@ internal bool TryGetConfigurationValue(string name, out object? value)
return false;
// Get from baseline configuration
- if (LanguageScope.TryConfigurationValue(name, out var result))
+ if (LanguageScope != null && LanguageScope.TryConfigurationValue(name, out var result))
{
value = result;
return true;
diff --git a/src/PSRule/packages.lock.json b/src/PSRule/packages.lock.json
index bf9dd93d80..4a88d71c7d 100644
--- a/src/PSRule/packages.lock.json
+++ b/src/PSRule/packages.lock.json
@@ -1051,8 +1051,8 @@
},
"YamlDotNet": {
"type": "Transitive",
- "resolved": "16.2.1",
- "contentHash": "im6zTVgesjcfTRfuMpnx51Rg2svWenp/3q5XBfcIzgj8PNIkkSD2xEl9HWcVi2SaJPP9XcXUdzed9gSDEuf1TA=="
+ "resolved": "16.3.0",
+ "contentHash": "SgMOdxbz8X65z8hraIs6hOEdnkH6hESTAIUa7viEngHOYaH+6q5XJmwr1+yb9vJpNQ19hCQY69xbFsLtXpobQA=="
},
"Microsoft.PSRule.Badges": {
"type": "Project",
@@ -1064,7 +1064,7 @@
"type": "Project",
"dependencies": {
"Newtonsoft.Json": "[13.0.3, )",
- "YamlDotNet": "[16.2.1, )"
+ "YamlDotNet": "[16.3.0, )"
}
}
}