Skip to content

Match the empty remainder with a trailing whole-segment ** [patch] - #192

Open
matt-edmondson wants to merge 2 commits into
mainfrom
fix/191-trailing-globstar
Open

matt-edmondson wants to merge 2 commits into
mainfrom
fix/191-trailing-globstar

Conversation

@matt-edmondson

@matt-edmondson matt-edmondson commented Nov 6, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #191

What was wrong

ExpandGlobStarSegments only rewrote a ** followed by a separator. A trailing **, as in src/**, reached DotNet.Glob unchanged. Once the separator was masked, DotNet.Glob read it as ** joined to a literal, and that form needs at least one more character. As a result:

  • src/** missed src/, though src/* matched it.
  • -build/** left build/ visible.
  • a/**/b/** missed a/b/, and /** missed /.

Change

After the **/ expansion, a trailing ** that starts the token or follows a separator is written as *. Under the masked semantics * already crosses separators, so the pattern still matches deeper paths and now also matches the empty remainder.

A ** joined to a literal (foo**) or to another * is left as it was. That case is #135.

This branch also carries #186's one commit, which changes only ReadmeTests.cs. It fixes EveryMethodInTheReadmeApiReferenceExistsWithItsDocumentedDefaults, a test that already fails on main, so CI here can go green before #186 merges. If #186 merges first, that change drops out of the squash.

Tests

  • TrailingGlobStarSegmentMatchesTheEmptyRemainder covers the issue's cases and the fuzzer's (*/**, ?/**, b-/**), plus a backslash separator. Each runs under ByWholeString and under the default options.
  • TrailingGlobStarSegmentStillNeedsItsDirectory checks that src/** still rejects src and docs/a.cs, and foo** still rejects foo.
  • TrailingGlobStarSegmentFiltersLikeASingleStar covers the issue's Filter repro:
    • src/** returns src/, src/a.cs and src/lib/b.cs, the same as src/*.
    • -build/** hides build/.
  • With the TextFilter.cs change reverted, all 8 new positive cases fail. With it, the full suite passes: 281/281 locally and on the ubuntu, windows and macos CI legs.
  • The SonarCloud quality gate fails on code this PR doesn't touch, and it fails the same way on Keep case-sensitive globs off DotNet.Glob's global default [patch] #189. Details are in the PR comments.

🤖 Generated with Claude Code

https://claude.ai/code/session_017vfJW3JF2xHwwm6qrw3Bh7

ExpandGlobStarSegments only rewrote a "**" followed by a separator, so a
trailing "**" (as in "src/**") reached DotNet.Glob as "**" joined to the
masked separator, which needs at least one more character. "src/**" then
missed "src/" though "src/*" matched it, and "-build/**" left "build/"
visible.

A trailing "**" that starts the token or follows a separator is now written
as "*", which already crosses the masked separator and also matches nothing.

Fixes #191

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017vfJW3JF2xHwwm6qrw3Bh7
…patch]

The README API test required every overload's same-named parameter to carry
the documented default. The binary-compatibility overloads from #166 have no
defaults by design, so main has been red since #178. They are marked
[EditorBrowsable(Never)] and are not what the README documents, so the default
check now skips them. A wrong default on a visible overload still fails.

Fixes #183

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017vfJW6FzBtSrY5LKUuDYce

Copy link
Copy Markdown
Contributor Author

ci / .NET / Test on ubuntu-latest failed on 1549673. 280 of 281 tests passed. The one failure is ReadmeTests.EveryMethodInTheReadmeApiReferenceExistsWithItsDocumentedDefaults, and it isn't caused by this PR: it fails the same way on main (5f420d9), and this diff doesn't touch the README or any public method signature.

Open PR #186 already fixes it, so I cherry-picked its one commit, which changes only ReadmeTests.cs, onto this branch as 0f17af1. That keeps this PR from staying red while it waits for #186. When #186 merges first, the duplicate change drops out of the squash. Locally the full suite now passes, 281/281.


Generated by Claude Code

@sonarqubecloud

sonarqubecloud Bot commented Nov 6, 2026

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
C Maintainability Rating on New Code (required ≥ A)

See analysis details on SonarQube Cloud

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE

Copy link
Copy Markdown
Contributor Author

SonarCloud Code Analysis fails the quality gate on 0f17af1 with "C Maintainability Rating on New Code". The findings behind that rating aren't from this PR:

  • The four S3427 blockers sit on DoesMatchGlob, AnyTokenMatchesGlobFilter, AllTokensMatchGlobFilter and DoesMatchRegex (TextFilter.cs 337/411/428/731). Each overlaps its binary-compatibility overload, and none of them is touched here.
  • The S3776 critical (cognitive complexity 16/15) is on ExpandGlobClasses (TextFilter.cs 528). It comes from 5485dfb and isn't touched here either.
  • The same gate fails on open PR Keep case-sensitive globs off DotNet.Glob's global default [patch] #189 for the same code, so it fails for the repository, not for this change.

This diff's only own findings are three INFO-level MSTEST0068 hints in the new test (prefer Assert.AreSequenceEqual over CollectionAssert.AreEqual). Those match the style of the tests around them and don't affect the rating. Fixing the gate needs a decision on the binary-compatibility overloads and a refactor of ExpandGlobClasses, which are both outside this PR's scope, so I'm leaving that to a separate change.


Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Glob "src/**" doesn't match "src/" though "src/*" does, so "-build/**" leaves the build/ entry visible

2 participants