Skip to content

Commit

Permalink
Refactoring of language scopes (microsoft#2601)
Browse files Browse the repository at this point in the history
  • Loading branch information
BernieWhite authored Nov 12, 2024
1 parent ea4a77c commit d2c4191
Show file tree
Hide file tree
Showing 12 changed files with 122 additions and 68 deletions.
4 changes: 2 additions & 2 deletions docs/CHANGELOG-v3.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ See [upgrade notes][1] for helpful information when upgrading from previous vers
[#2552](https://github.com/microsoft/PSRule/issues/2552)
- Modules are automatically restored unless `--no-restore` is used with the `run` command.
- Engineering:
- Bump YamlDotNet to v16.1.3.
[#1874](https://github.com/microsoft/PSRule/pull/1874)
- Bump YamlDotNet to v16.2.0.
[#2596](https://github.com/microsoft/PSRule/pull/2596)

## v3.0.0-B0275 (pre-release)

Expand Down
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ nav:
- Index: concepts/cli/index.md
- run: concepts/cli/run.md
- module: concepts/cli/module.md
- restore: concepts/cli/restore.md
- Assertion methods: concepts/PSRule/en-US/about_PSRule_Assert.md
- Baselines: concepts/PSRule/en-US/about_PSRule_Baseline.md
- Badges: concepts/PSRule/en-US/about_PSRule_Badges.md
Expand Down
81 changes: 63 additions & 18 deletions src/PSRule/Host/HostHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -658,8 +658,7 @@ private static Baseline[] ToBaselineV1(IEnumerable<ILanguageBlock> blocks, Runsp

private static SuppressionGroupV1[] ToSuppressionGroupV1(IEnumerable<ILanguageBlock> blocks, RunspaceContext context)
{
if (blocks == null)
return Array.Empty<SuppressionGroupV1>();
if (blocks == null) return [];

// Index suppression groups by Id.
var results = new Dictionary<string, SuppressionGroupV1>(StringComparer.OrdinalIgnoreCase);
Expand All @@ -682,13 +681,12 @@ private static SuppressionGroupV1[] ToSuppressionGroupV1(IEnumerable<ILanguageBl
context.ExitLanguageScope(block.Source);
}
}
return results.Values.ToArray();
return [.. results.Values];
}

private static ModuleConfigV1[] ToModuleConfigV1(IEnumerable<ILanguageBlock> blocks, RunspaceContext context)
{
if (blocks == null)
return Array.Empty<ModuleConfigV1>();
if (blocks == null) return [];

// Index configurations by Name.
var results = new Dictionary<string, ModuleConfigV1>(StringComparer.OrdinalIgnoreCase);
Expand Down Expand Up @@ -766,39 +764,86 @@ private static void Import(IConvention[] blocks, RunspaceContext context)

private static bool Match(RunspaceContext context, RuleBlock resource)
{
var filter = context.LanguageScope.GetFilter(ResourceKind.Rule);
return filter == null || filter.Match(resource);
try
{
context.EnterLanguageScope(resource.Source);
var filter = context.LanguageScope.GetFilter(ResourceKind.Rule);
return filter == null || filter.Match(resource);
}
finally
{
context.ExitLanguageScope(resource.Source);
}
}

private static bool Match(RunspaceContext context, IRuleV1 resource)
{
context.EnterLanguageScope(resource.Source);
var filter = context.LanguageScope.GetFilter(ResourceKind.Rule);
return filter == null || filter.Match(resource);
try
{
context.EnterLanguageScope(resource.Source);
var filter = context.LanguageScope.GetFilter(ResourceKind.Rule);
return filter == null || filter.Match(resource);
}
finally
{
context.ExitLanguageScope(resource.Source);
}
}

private static bool Match(RunspaceContext context, Baseline resource)
{
var filter = context.LanguageScope.GetFilter(ResourceKind.Baseline);
return filter == null || filter.Match(resource);
try
{
context.EnterLanguageScope(resource.Source);
var filter = context.LanguageScope.GetFilter(ResourceKind.Baseline);
return filter == null || filter.Match(resource);
}
finally
{
context.ExitLanguageScope(resource.Source);
}
}

private static bool Match(RunspaceContext context, ScriptBlockConvention block)
{
var filter = context.LanguageScope.GetFilter(ResourceKind.Convention);
return filter == null || filter.Match(block);
try
{
context.EnterLanguageScope(block.Source);
var filter = context.LanguageScope.GetFilter(ResourceKind.Convention);
return filter == null || filter.Match(block);
}
finally
{
context.ExitLanguageScope(block.Source);
}
}

private static bool Match(RunspaceContext context, SelectorV1 resource)
{
var filter = context.LanguageScope.GetFilter(ResourceKind.Selector);
return filter == null || filter.Match(resource);
try
{
context.EnterLanguageScope(resource.Source);
var filter = context.LanguageScope.GetFilter(ResourceKind.Selector);
return filter == null || filter.Match(resource);
}
finally
{
context.ExitLanguageScope(resource.Source);
}
}

private static bool Match(RunspaceContext context, SuppressionGroupV1 suppressionGroup)
{
var filter = context.LanguageScope.GetFilter(ResourceKind.SuppressionGroup);
return filter == null || filter.Match(suppressionGroup);
try
{
context.EnterLanguageScope(suppressionGroup.Source);
var filter = context.LanguageScope.GetFilter(ResourceKind.SuppressionGroup);
return filter == null || filter.Match(suppressionGroup);
}
finally
{
//context.ExitLanguageScope(suppressionGroup.Source);
}
}

private static IConvention[] Sort(RunspaceContext context, IConvention[] conventions)
Expand Down
7 changes: 7 additions & 0 deletions src/PSRule/Pipeline/PipelineContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,11 @@ internal sealed class PipelineContext : IPipelineContext, IBindingContext

public IPipelineWriter Writer { get; }

/// <summary>
/// A collection of languages scopes for this pipeline.
/// </summary>
public ILanguageScopeCollection LanguageScopes { get; }

private PipelineContext(PSRuleOption option, IHostContext hostContext, PipelineInputStream reader, IPipelineWriter writer, OptionContextBuilder optionBuilder, IList<ResourceRef> unresolved)
{
_OptionBuilder = optionBuilder;
Expand All @@ -87,6 +92,7 @@ private PipelineContext(PSRuleOption option, IHostContext hostContext, PipelineI
RunId = Environment.GetRunId() ?? ObjectHashAlgorithm.GetDigest(Guid.NewGuid().ToByteArray());
RunTime = Stopwatch.StartNew();
_DefaultOptionContext = _OptionBuilder?.Build(null);
LanguageScopes = new LanguageScopeSet();
}

public static PipelineContext New(PSRuleOption option, IHostContext hostContext, PipelineInputStream reader, IPipelineWriter writer, OptionContextBuilder optionBuilder, IList<ResourceRef> unresolved)
Expand Down Expand Up @@ -299,6 +305,7 @@ private void Dispose(bool disposing)
ObjectHashAlgorithm?.Dispose();
_Runspace?.Dispose();
_PathExpressionCache.Clear();
LanguageScopes.Dispose();
LocalizedDataCache.Clear();
ExpressionCache.Clear();
ContentCache.Clear();
Expand Down
2 changes: 1 addition & 1 deletion src/PSRule/Runtime/ILanguageScope.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ internal interface ILanguageScope : IDisposable
/// <summary>
/// Get an ordered culture preference list which will be tries for finding help.
/// </summary>
string[] Culture { get; }
string[]? Culture { get; }

void Configure(OptionContext context);

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

namespace PSRule.Runtime;

internal interface ILanguageScopeCollection : IDisposable
{
IEnumerable<ILanguageScope> Get();

bool TryScope(string name, out ILanguageScope scope);

bool Import(string name);
}
14 changes: 8 additions & 6 deletions src/PSRule/Runtime/LanguageScope.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ internal sealed class LanguageScope : ILanguageScope

public LanguageScope(string name)
{
_Configuration = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
Name = ResourceHelper.NormalizeScope(name);
_Filter = [];
_Service = [];
Expand All @@ -33,7 +34,7 @@ public LanguageScope(string name)
public string Name { [DebuggerStepThrough] get; }

/// <inheritdoc/>
public string[] Culture { [DebuggerStepThrough] get; [DebuggerStepThrough] private set; }
public string[]? Culture { [DebuggerStepThrough] get; [DebuggerStepThrough] private set; }

public StringComparer GetBindingComparer() => _BindingComparer ?? StringComparer.OrdinalIgnoreCase;

Expand All @@ -50,6 +51,7 @@ public void Configure(OptionContext context)
if (context == null) throw new ArgumentNullException(nameof(context));

_Configuration = context.Configuration;
_Configuration ??= new Dictionary<string, object>();
WithFilter(context.RuleFilter);
WithFilter(context.ConventionFilter);
_BindingComparer = context.Binding.GetComparer();
Expand All @@ -62,7 +64,7 @@ public void Configure(OptionContext context)
/// <inheritdoc/>
public bool TryConfigurationValue(string key, out object? value)
{
value = null;
value = default;
return !string.IsNullOrEmpty(key) && _Configuration != null && _Configuration.TryGetValue(key, out value);
}

Expand Down Expand Up @@ -113,8 +115,8 @@ public bool TryGetType(object o, out string? type, out string? path)
path = result.TargetTypePath;
return true;
}
type = null;
path = null;
type = default;
path = default;
return false;
}

Expand All @@ -128,8 +130,8 @@ public bool TryGetName(object o, out string? name, out string? path)
path = result.TargetNamePath;
return true;
}
name = null;
path = null;
name = default;
path = default;
return false;
}

Expand Down
34 changes: 7 additions & 27 deletions src/PSRule/Runtime/LanguageScopeSet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace PSRule.Runtime;
/// <summary>
/// A collection of <see cref="ILanguageScope"/>.
/// </summary>
internal sealed class LanguageScopeSet : IDisposable
internal sealed class LanguageScopeSet : ILanguageScopeCollection
{
private readonly Dictionary<string, ILanguageScope> _Scopes;

Expand All @@ -18,15 +18,7 @@ internal sealed class LanguageScopeSet : IDisposable
public LanguageScopeSet()
{
_Scopes = new Dictionary<string, ILanguageScope>(StringComparer.OrdinalIgnoreCase);
Import(null, out _Current);
}

public ILanguageScope Current
{
get
{
return _Current;
}
Import(null);
}

#region IDisposable
Expand Down Expand Up @@ -64,34 +56,22 @@ internal void Add(ILanguageScope languageScope)
_Scopes.Add(languageScope.Name, languageScope);
}

internal IEnumerable<ILanguageScope> Get()
public IEnumerable<ILanguageScope> Get()
{
return _Scopes.Values;
}

/// <summary>
/// Switch to a specific language scope by name.
/// </summary>
/// <param name="name">The name of the language scope to switch to.</param>
internal void UseScope(string name)
{
if (!_Scopes.TryGetValue(GetScopeName(name), out var scope))
throw new Exception($"The specified scope '{name}' was not found.");

_Current = scope;
}

internal bool TryScope(string name, out ILanguageScope scope)
public bool TryScope(string name, out ILanguageScope scope)
{
return _Scopes.TryGetValue(GetScopeName(name), out scope);
}

internal bool Import(string name, out ILanguageScope scope)
public bool Import(string name)
{
if (_Scopes.TryGetValue(GetScopeName(name), out scope))
if (_Scopes.ContainsKey(GetScopeName(name)))
return false;

scope = new LanguageScope(name);
var scope = new LanguageScope(name);
Add(scope);
return true;
}
Expand Down
Loading

0 comments on commit d2c4191

Please sign in to comment.