-
Notifications
You must be signed in to change notification settings - Fork 4.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Ordered evaluation in FileSystemGlobbing Matcher #109408
Comments
Tagging subscribers to this area: @dotnet/area-extensions-filesystem |
Changing the existing functionality would be too risky as it would result in including or excluding files differently from before, which could cause data loss and other serious issues for users. If we wanted to entertain this, it would need to be presented as an
api-suggestion
@PranavSenthilnathan Can you see if there's a way to achieve the desired result with the existing APIs and current functionality? It looks like |
@jeffhandley yI have converted first post to api proposal. please add that label |
The matcher is just a builder that calls into The ordering is a configuration of the Matcher, so logically it should be passed into the Matcher (either in the constructor or as a property/field) instead of as an argument to Proposed APInamespace Microsoft.Extensions.FileSystemGlobbing;
public class Matcher
{
public Matcher() { }
+ public Matcher(bool ordered) { }
} namespace Microsoft.Extensions.FileSystemGlobbing.Internal;
/// <summary>
/// This API supports infrastructure and is not intended to be used
/// directly from your code. This API may change or be removed in future releases.
/// </summary>
public class MatcherContext
+ : MatcherContextBase
{
public MatcherContext(
IEnumerable<IPattern> includePatterns,
IEnumerable<IPattern> excludePatterns,
DirectoryInfoBase directoryInfo,
StringComparison comparison) { }
} namespace Microsoft.Extensions.FileSystemGlobbing.Internal;
public class OrderedMatcherContext
: MatcherContextBase
{
public OrderedMatcherContext(
IEnumerable<SelectionPattern> patterns,
DirectoryInfoBase directoryInfo,
StringComparison comparison) { }
}
public abstract class MatcherContextBase
{
protected abstract PatternTestResult MatchPatternContexts<TFileInfoBase>(
TFileInfoBase fileinfo, Func<IPatternContext, TFileInfoBase, PatternTestResult> test)
}
public struct SelectionPattern
{
public IPattern pattern;
public SelectionType selectionType;
}
public enum SelectionType
{
Include,
Exclude
} Usagevar m = new Matcher(true);
m.AddInclude("**/*");
m.AddExclude("ExcludeMe/**/*");
m.AddInclude("ExcludeMe/ButActuallyIncludeMe/**/*");
var result = m.Execute(new DirectoryInfoWrapper(new DirectoryInfo("root")));
foreach (var file in result.Files)
{
Console.WriteLine(file.Path);
} |
@PranavSenthilnathan I updated the issue description to reflect your revised proposal, and I'm marking this as
api-ready-for-review
|
Background and Motivation
The current
Microsoft.Extensions.FileSystemGlobbing.Matcher
does not evaluate include and exclude patterns in the order they are added, which leads to limitations when trying to achieve more complex file-matching behavior. Specifically, includes added after an exclude do not override the exclude, resulting in unexpected or undesired results.In scenarios where finer control over the inclusion and exclusion of files is needed, the inability to specify an ordered evaluation can prevent the desired matches. Adding an option to allow ordered evaluation of patterns would offer more intuitive control, empowering developers to achieve more precise and flexible file selection.
Originally posted by @Benjin #21362 (comment)
Current Behavior
Consider the following setup in
Matcher
:Given this directory structure:
The output is currently:
root/helloWorld.txt
root/ExcludeMe/ButActuallyIncludeMe/hiEarth.txt
)Expected Behavior
With ordered evaluation, the output would instead be:
root/helloWorld.txt
root/ExcludeMe/ButActuallyIncludeMe/hiEarth.txt
Revised Proposal
The matcher is just a builder that calls into
MatcherContext
internally to do the work. That class takes in the include and exclude patterns separately so change should be made at that level as well.The ordering is a configuration of the Matcher, so logically it should be passed into the Matcher (either in the constructor or as a property/field) instead of as an argument to
Execute
. This is the API I would suggest:Proposed API
Usage
Original Proposal
API Proposal
To introduce ordered evaluation without altering existing behavior by default, we propose adding an optional
ordered
parameter to theExecute
method. This would allow users to explicitly enable ordered evaluation when required.Proposed API Changes
ordered
parameter to theExecute
method, allowing ordered evaluation to be enabled per execution while keeping current behavior as the default.API Usage
Expected output:
root/helloWorld.txt
root/ExcludeMe/ButActuallyIncludeMe/hiEarth.txt
Alternative Designs
Matcher Constructor with Ordered Parameter:
Another approach could be adding an
ordered
parameter to theMatcher
constructor to set the evaluation order for the entire lifecycle of theMatcher
instance, rather than on a per-execution basis:This approach makes
ordered
a property of theMatcher
instance, reducing the need to specify it with each execution. However, this would make it less flexible for scenarios where a developer may want to toggle ordered evaluation for different executions.Separate
ExecuteInOrder
Method:Another alternative is to create a separate method,
ExecuteInOrder
, which explicitly indicates ordered evaluation:This approach would keep
Execute
unchanged and provide a clear distinction in the API. However, it would increase the API surface.Risks
Enabling ordered evaluation may introduce a minor performance cost due to tracking evaluation order. However, this impact is expected to be minimal and only relevant when
ordered
is set totrue
.The text was updated successfully, but these errors were encountered: