Skip to content

Commit

Permalink
feature #22239 [Finder] Glob wildcard while using double-star without…
Browse files Browse the repository at this point in the history
… ending slash (sroze)

This PR was squashed before being merged into the 3.3-dev branch (closes #22239).

Discussion
----------

[Finder] Glob wildcard while using double-star without ending slash

| Q             | A
| ------------- | ---
| Branch?       | master
| Bug fix?      | no
| New feature?  | yes
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | ø
| License       | MIT
| Doc PR        | ø

This PR allows to use the `Glob::toRegex` method to dump a glob that will match "everything after" while using the double-star without leading slash. `/foo/**` will therefore match `/foo/a` or `/foo/a/b/c` or even `/foo/a/b/c/d.e`.

The use-case for this change is an application allowing its users to match a list of files/folders from such glob pattern.

Happy to add a line in the CHANGELOG and documentation if you feel that would make sense.

Commits
-------

170b0ac [Finder] Glob wildcard while using double-star without ending slash
  • Loading branch information
fabpot committed Apr 10, 2017
2 parents f7debe8 + 170b0ac commit bbb0d5e
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 3 deletions.
16 changes: 13 additions & 3 deletions src/Symfony/Component/Finder/Glob.php
Expand Up @@ -60,9 +60,19 @@ public static function toRegex($glob, $strictLeadingDot = true, $strictWildcardS

$firstByte = '/' === $car;

if ($firstByte && $strictWildcardSlash && isset($glob[$i + 3]) && '**/' === $glob[$i + 1].$glob[$i + 2].$glob[$i + 3]) {
$car = $strictLeadingDot ? '/(?:(?=[^\.])[^/]++/)*' : '/(?:[^/]++/)*';
$i += 3;
if ($firstByte && $strictWildcardSlash && isset($glob[$i + 2]) && '**' === $glob[$i + 1].$glob[$i + 2] && (!isset($glob[$i + 3]) || '/' === $glob[$i + 3])) {
$car = '[^/]++/';
if (!isset($glob[$i + 3])) {
$car .= '?';
}

if ($strictLeadingDot) {
$car = '(?=[^\.])'.$car;
}

$car = '/(?:'.$car.')*';
$i += 2 + isset($glob[$i + 3]);

if ('/' === $delimiter) {
$car = str_replace('/', '\\/', $car);
}
Expand Down
1 change: 1 addition & 0 deletions src/Symfony/Component/Finder/Tests/Fixtures/one/.dot
@@ -0,0 +1 @@
.dot
34 changes: 34 additions & 0 deletions src/Symfony/Component/Finder/Tests/GlobTest.php
Expand Up @@ -58,4 +58,38 @@ public function testGlobToRegexDoubleStarNonStrictDots()

$this->assertSame(array('.dot/b/c.neon', '.dot/b/d.neon', 'one/b/c.neon', 'one/b/d.neon'), $match);
}

public function testGlobToRegexDoubleStarWithoutLeadingSlash()
{
$finder = new Finder();
$finder->ignoreDotFiles(false);
$regex = Glob::toRegex('/Fixtures/one/**');

foreach ($finder->in(__DIR__) as $k => $v) {
$k = str_replace(DIRECTORY_SEPARATOR, '/', $k);
if (preg_match($regex, substr($k, strlen(__DIR__)))) {
$match[] = substr($k, 10 + strlen(__DIR__));
}
}
sort($match);

$this->assertSame(array('one/a', 'one/b', 'one/b/c.neon', 'one/b/d.neon'), $match);
}

public function testGlobToRegexDoubleStarWithoutLeadingSlashNotStrictLeadingDot()
{
$finder = new Finder();
$finder->ignoreDotFiles(false);
$regex = Glob::toRegex('/Fixtures/one/**', false);

foreach ($finder->in(__DIR__) as $k => $v) {
$k = str_replace(DIRECTORY_SEPARATOR, '/', $k);
if (preg_match($regex, substr($k, strlen(__DIR__)))) {
$match[] = substr($k, 10 + strlen(__DIR__));
}
}
sort($match);

$this->assertSame(array('one/.dot', 'one/a', 'one/b', 'one/b/c.neon', 'one/b/d.neon'), $match);
}
}

0 comments on commit bbb0d5e

Please sign in to comment.