Add Matches(pattern) for pattern matching without touching the file system - #162
Merged
Merged
Conversation
Adds ChainablePathGlobbingExtensions.Matches(string) and Matches(params string[]) to Pathy.Globbing, letting a ChainablePath be tested against one or more glob patterns without touching the file system (the path does not need to exist). Implementation uses Matcher.Match(root, file), which performs a pure in-memory string match via InMemoryDirectoryInfo and never enumerates or reads from disk. Rooted paths are matched relative to their drive/volume root so patterns like `src/**/*.cs` match regardless of where on that drive the path lives; relative paths fall back to the current working directory, consistent with GlobFiles. Matching uses the same StringComparison.OrdinalIgnoreCase as GlobFiles. This delivers the capability requested (but not shipped as public API) in the closed issue #35, using the plural-safe name Matches with a multi-pattern overload that returns true if any pattern matches. Fixes #142 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
This was referenced Aug 17, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #142
Summary
Adds
Matches(this ChainablePath path, string globPattern)andMatches(this ChainablePath path, params string[] globPatterns)toPathy.Globbing(ChainablePathGlobbingExtensions), next to the existingGlobFiles. This lets you test a path against one or more glob patterns without any file-system access — the path does not need to exist, and no directory is enumerated.Note on base branch
CONTRIBUTING.md says PRs should target
develop, but that branch does not currently exist in this repository, and all recent merged PRs targetmain. I opened this againstmainto match actual practice — happy to retarget if adevelopbranch gets created.No file-system access — how I verified it
I read the
Microsoft.Extensions.FileSystemGlobbingsource (Matcher,MatcherExtensions,InMemoryDirectoryInfo) rather than assuming behavior:MatcherExtensions.Match(this Matcher, string root, string file)executes the matcher against anInMemoryDirectoryInfo, which only does pure string operations (Path.GetFullPath,Path.IsPathRooted, etc.) on the given file path — it never enumerates a real directory or hits disk, even for a rooted/absolute path.Match(string file)overload just forwards to the two-arg one usingDirectory.GetCurrentDirectory()as root — but that only works correctly whenfileis actually under the current working directory (MatcherContextwalks from the root down, so a file outside the root is silently never matched). SinceChainablePathvalues are typically absolute and unrelated to CWD, I did not use that overload directly.Matchescomputes the root itself: for a rooted path it usesPath.GetPathRoot(file)(the drive/volume root, e.g.C:\), guaranteeing the file is always "under" the root so patterns likesrc/**/*.csmatch anywhere on that drive. For a relative path it falls back toDirectory.GetCurrentDirectory(), matchingGlobFiles's existing behavior.Path.GetPathRoot/Path.IsPathRootedare pure string operations, so this remains fully I/O-free.Matches_does_not_require_the_path_to_exist_on_disk).Case sensitivity
Uses the same
new Matcher(StringComparison.OrdinalIgnoreCase)construction asGlobFiles, for consistency. Covered by aMatches_is_case_insensitivetest.Relationship to closed issue #35
#35 requested a
Match(wildcard)method and was closed without a public API being approved/shipped. This PR delivers that capability, but:Matches(plural-safe) instead ofMatch, with a companionparams string[]overload that returnstrueif any pattern matchesPathy.Globbing(not corePathy), since it depends onMicrosoft.Extensions.FileSystemGlobbing, same asGlobFilesThis is called out in the XML doc comments on both new members.
Changes
Pathy.Globbing/PathyGlobbing.cs: newMatchesoverloads, same argument validation asGlobFiles(throwsArgumentExceptionfor missing/null/empty patterns)Pathy.Specs/ChainablePathSpecs.cs: new specs — suffix match, unrelated pattern no-match, non-existent path, multi-pattern any-match / no-match, case-insensitivity, argument validationPathy.ApiVerificationTests/ApprovedApi/pathy.globbing.*.verified.txt: updated approved public API surface viaAcceptApiChanges.ps1README.md: documentedMatchesunder the Globbing sectionTesting
dotnet test Pathy.Specs— 119/119 passingdotnet test Pathy.ApiVerificationTests— 8/8 passingdotnet build(full solution) — 0 warnings, 0 errorsNote on process
This issue is labeled
enhancementonly (noapi-approvedlabel), and CONTRIBUTING.md normally requires that label before opening a PR for an API change. The repo owner explicitly asked for this PR to be opened directly, so I'm proceeding, but flagging it here for visibility: this implements an as-yet-unapproved API proposal.