Skip to content

Fix ** glob pattern not matching files in root directory (Fixes #2355) - #2500

Open
amanmaurya92 wants to merge 3 commits into
dart-lang:mainfrom
amanmaurya92:fix-glob-double-star-root
Open

Fix ** glob pattern not matching files in root directory (Fixes #2355)#2500
amanmaurya92 wants to merge 3 commits into
dart-lang:mainfrom
amanmaurya92:fix-glob-double-star-root

Conversation

@amanmaurya92

Copy link
Copy Markdown
Contributor

This fixes issue #2355 by updating the DoubleStarNode regex evaluation to treat a leading or trailing slash as optional when matching zero directories, and flattens AST nodes during list generation.

Fixes #2355.

Changes:

  • Updated SequenceNode._toRegExp() in ast.dart to make the trailing slash following a DoubleStarNode optional ((?:[^]*/)?) when matching zero directories (e.g. allowing **/filename to match filename).
  • Flattened the internal AST node structure in list_tree.dart's _join() method to correctly position adjacent SequenceNode elements so they are processed properly.
  • Added tests in match_test.dart and list_test.dart to ensure **/foo matches foo and correctly evaluates when ** corresponds to 0 directories.

  • I’ve reviewed the contributor guide and applied the relevant portions to this PR.
Contribution guidelines:

Many Dart repos have a weekly cadence for reviewing PRs - please allow for some latency before initial review feedback.

Note: The Dart team is trialing Gemini Code Assist. Don't take its comments as final Dart team feedback. Use the suggestions if they're helpful; otherwise, wait for a human reviewer.

This fixes issue dart-lang#2355 by updating the DoubleStarNode regex evaluation to treat a leading or trailing slash as optional when matching zero directories, and flattens AST nodes during list generation.
@amanmaurya92
amanmaurya92 requested a review from a team as a code owner August 7, 2026 01:49

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request improves glob matching logic to correctly match files in the root directory when using double-star patterns (e.g., **/foo matching foo). It updates SequenceNode._toRegExp() to handle a DoubleStarNode followed by a slash literal, flattens nested SequenceNode instances in _join, and adds corresponding tests. The reviewer pointed out that the substring operation in SequenceNode._toRegExp() assumes the regex always ends with [^]*, which is fragile, and suggested adding a defensive check to ensure it ends with [^]* before performing the substring.

Comment thread pkgs/glob/lib/src/ast.dart Outdated
@mosuem

mosuem commented Aug 7, 2026

Copy link
Copy Markdown
Member

I believe this is missing more edge test cases, for example: a/**/b matching a/b and a/x/b, or foo**/*.dart matching foo/a.dart but not foobar.dart.

@amanmaurya92
amanmaurya92 force-pushed the fix-glob-double-star-root branch from f50176b to 929ae5c Compare August 7, 2026 14:42
@amanmaurya92

Copy link
Copy Markdown
Contributor Author

The previous regex replacement was too loose.

I've updated the logic so the optional slash for ** only applies when it acts as a true directory boundary
(imagine: when it sits at the start of the string or directly follows a separator).

To ensure everything behaves exactly as expected, I've added the following tests now:

  1. expect('a/b', contains(Glob('a/**/b'))); (Matches zero directories bounded by slashes)
  2. expect('a/x/b', contains(Glob('a/**/b'))); (Matches one directory bounded by slashes)
  3. expect('foo/a.dart', contains(Glob('foo**/*.dart'))); (Matches correctly when ** is attached to a literal)
  4. expect('foobar.dart', isNot(contains(Glob('foo**/*.dart')))); (Ensures it doesn't overly aggressively match paths lacking a directory separator)

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

The pattern **/filename does not match the file in the root folder.

2 participants