Files
git.stella-ops.org/src/__Libraries/StellaOps.Facet/GlobMatcher.cs

71 lines
2.0 KiB
C#

// <copyright file="GlobMatcher.cs" company="StellaOps">
// Copyright (c) StellaOps. Licensed under BUSL-1.1.
// </copyright>
using DotNet.Globbing;
namespace StellaOps.Facet;
/// <summary>
/// Utility for matching file paths against glob patterns.
/// </summary>
public sealed class GlobMatcher
{
private readonly List<Glob> _globs;
/// <summary>
/// Initializes a new instance of the <see cref="GlobMatcher"/> class.
/// </summary>
/// <param name="patterns">Glob patterns to match against.</param>
public GlobMatcher(IEnumerable<string> patterns)
{
ArgumentNullException.ThrowIfNull(patterns);
_globs = patterns
.Select(p => Glob.Parse(NormalizePattern(p)))
.ToList();
}
/// <summary>
/// Check if a path matches any of the patterns.
/// </summary>
/// <param name="path">The path to check (Unix-style).</param>
/// <returns>True if any pattern matches.</returns>
public bool IsMatch(string path)
{
ArgumentNullException.ThrowIfNull(path);
var normalizedPath = NormalizePath(path);
return _globs.Any(g => g.IsMatch(normalizedPath));
}
/// <summary>
/// Create a matcher for a single facet.
/// </summary>
/// <param name="facet">The facet to create a matcher for.</param>
/// <returns>A GlobMatcher for the facet's selectors.</returns>
public static GlobMatcher ForFacet(IFacet facet)
{
ArgumentNullException.ThrowIfNull(facet);
return new GlobMatcher(facet.Selectors);
}
private static string NormalizePattern(string pattern)
{
// Ensure patterns use forward slashes
return pattern.Replace('\\', '/');
}
private static string NormalizePath(string path)
{
// Ensure paths use forward slashes and are rooted
var normalized = path.Replace('\\', '/');
if (!normalized.StartsWith('/'))
{
normalized = "/" + normalized;
}
return normalized;
}
}