From 03a0692c8327efeac494e1ff3a91d384b99d4c16 Mon Sep 17 00:00:00 2001 From: Bernie White Date: Fri, 3 Jan 2025 23:38:08 +1000 Subject: [PATCH] Code clean up (#2692) --- .editorconfig | 4 ++ .github/workflows/build.yaml | 11 +++- .../{old_hooks.py => maml_formatting.py} | 44 +-------------- mkdocs.yml | 2 +- ps-rule-ci.yaml | 1 + src/PSRule.Benchmark/packages.lock.json | 6 +- src/PSRule.CommandLine/packages.lock.json | 6 +- src/PSRule.EditorServices/packages.lock.json | 6 +- src/PSRule.SDK/packages.lock.json | 6 +- src/PSRule.Tool/packages.lock.json | 6 +- src/PSRule.Types/Definitions/IResource.cs | 2 +- .../Emitters/InternalFileStream.cs | 11 ---- src/PSRule.Types/Options/BaselineOption.cs | 4 +- src/PSRule.Types/Options/ExecutionOption.cs | 4 +- src/PSRule.Types/Options/OverrideOption.cs | 4 +- .../Commands/ExportConventionCommand.cs | 2 +- src/PSRule/Common/HashSetExtensions.cs | 52 ++++++++--------- .../Json/LockEntryIntegrityJsonConverter.cs | 13 ++--- .../Conventions/ConventionExtensions.cs | 2 +- src/PSRule/Definitions/IDependencyTarget.cs | 8 ++- .../Definitions/Rules/RuleExtensions.cs | 6 +- src/PSRule/Emitters/EmitterContext.cs | 10 ++-- .../Pipeline/Dependencies/IntegrityBuilder.cs | 6 +- .../Dependencies/LockEntryIntegrity.cs | 6 +- src/PSRule/Pipeline/HostContext.cs | 2 +- src/PSRule/Pipeline/IHostContext.cs | 2 +- src/PSRule/Pipeline/OptionContext.cs | 56 ++++++++----------- src/PSRule/Pipeline/OptionContextBuilder.cs | 13 +++-- src/PSRule/Pipeline/PipelineContext.cs | 10 ++-- src/PSRule/Pipeline/PipelineInputStream.cs | 6 +- src/PSRule/Rules/RuleBlock.cs | 12 ++-- src/PSRule/Rules/RuleRecord.cs | 6 +- .../Runtime/Binding/TargetBinderBuilder.cs | 8 +-- .../Runtime/Binding/TargetBindingContext.cs | 12 ++-- src/PSRule/Runtime/LanguageScope.cs | 30 ++++------ src/PSRule/Runtime/PSRule.cs | 4 +- src/PSRule/Runtime/RunspaceContext.cs | 16 +++--- src/PSRule/packages.lock.json | 6 +- 38 files changed, 175 insertions(+), 230 deletions(-) rename docs/hooks/{old_hooks.py => maml_formatting.py} (63%) delete mode 100644 src/PSRule.Types/Emitters/InternalFileStream.cs 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, )" } } }