Don't drop dot-entries for patterns with a literal leading dot - #189
Open
jaideeppyne wants to merge 1 commit into
Open
Don't drop dot-entries for patterns with a literal leading dot#189jaideeppyne wants to merge 1 commit into
jaideeppyne wants to merge 1 commit into
Conversation
`fill_todo` removes every directory entry whose name starts with a `.`
when `require_literal_leading_dot` is set, before the entry is ever
matched against the pattern for that component. That also removes
entries a pattern is supposed to match: `require_literal_leading_dot`
only asks that the `.` appear literally in the pattern, so `.git*`
should still match `.gitignore`.
`Pattern::matches_with` gets this right (it is covered by
`test_pattern_matches_require_literal_leading_dot`), so `glob_with`
disagreed with matching the same component by hand:
// .gitignore exists in the current directory
let opts = MatchOptions {
require_literal_leading_dot: true,
..MatchOptions::new()
};
Pattern::new(".git*").unwrap().matches_with(".gitignore", opts); // true
glob_with(".git*", opts).unwrap().count(); // 0
The filtering is still needed for a recursive `**` component, which
matches directory entries without consulting the pattern at all, so
keep it for every pattern that does not start with a literal `.`.
Reuse the same "starts with a literal dot" test that already guards the
`.` and `..` special entries a few lines below.
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.
glob_withreturns nothing for patterns like.git*whenrequire_literal_leading_dotis set, even though.gitignoreis sitting right there.fill_tododrops every directory entry whose name starts with a.before the entry is ever matched against the pattern for that component. Butrequire_literal_leading_dotonly asks that the.appear literally in the pattern — and in.git*it does.Pattern::matches_withgets this right (test_pattern_matches_require_literal_leading_dotalready coversaaa/bbb/.*vsaaa/bbb/.ccc), so the two APIs disagree about the same component:fnmatch(".git*", ".gitignore", FNM_PERIOD)and the shell both match, soPatternis the one that's right here.The filter still has a job to do: a recursive
**component matches directory entries without consulting the pattern at all, which is what #128 fixed for #67. So I kept it for every pattern that doesn't start with a literal.. A**component always parses to a singleAnyRecursiveSequencetoken, so it can never take the new exemption and #67 stays fixed. The predicate is the same one that already guards the.and..special entries a few lines below, so I hoisted it into a local.Tests in
tests/glob-std.rscover.a*,.?aaand.[ab]bbmatching hidden entries, plus*and?aastill skipping them. I checked the results againstbashon a dot-heavy tree for around 20 patterns and they agree.I left the
.to_str().unwrap()on that line alone since #162 is already dealing with it.Disclosure: this change was written with AI assistance. The bug was found by differential-testing against
fnmatch(3)andbash; I reviewed the diff and reproduced both the bug and the fix locally.