diff --git a/app/src/Factories/FinderFactory.php b/app/src/Factories/FinderFactory.php index 7a5cd3d..aa1d7c3 100644 --- a/app/src/Factories/FinderFactory.php +++ b/app/src/Factories/FinderFactory.php @@ -3,11 +3,11 @@ namespace App\Factories; use App\SortMethods; +use App\Support\Glob; use Closure; use DI\Container; use RuntimeException; use Symfony\Component\Finder\Finder; -use Symfony\Component\Finder\Glob; use Symfony\Component\Finder\SplFileInfo; use Tightenco\Collect\Support\Collection; @@ -81,12 +81,10 @@ class FinderFactory $this->container->get('hidden_files') )->when($this->container->get('hide_app_files'), static function (Collection $collection) { return $collection->merge(self::APP_FILES); - })->map(static function (string $pattern): string { - return DIRECTORY_SEPARATOR . ltrim($pattern, DIRECTORY_SEPARATOR); })->unique(); - return substr_replace(Glob::toRegex( - sprintf('%s{%s}', $this->container->get('base_path'), $collection->implode(',')) - ), '', -2, 1); + return Glob::toRegex( + sprintf('%s/{%s}', $this->container->get('base_path'), $collection->implode(',')) + ); } } diff --git a/app/src/Support/Glob.php b/app/src/Support/Glob.php new file mode 100644 index 0000000..722cc6f --- /dev/null +++ b/app/src/Support/Glob.php @@ -0,0 +1,101 @@ + 0) { + --$characterGroup; + } + + $pattern .= $char; + break; + + case '^': + if ($characterGroup > 0) { + $pattern .= $char; + } else { + $pattern .= '\\' . $char; + } + break; + + case '{': + $pattern .= '('; + ++$patternGroup; + break; + + case '}': + if ($patternGroup > 0) { + $pattern .= ')'; + --$patternGroup; + } else { + $pattern .= $char; + } + break; + + case ',': + if ($patternGroup > 0) { + $pattern .= '|'; + } else { + $pattern .= $char; + } + break; + + default: + if (in_array($char, ['.', '(', ')', '|', '+', '$'])) { + $pattern .= '\\' . $char; + } else { + $pattern .= $char; + } + + break; + } + } + + return sprintf('#^%s#', $pattern); + } +} diff --git a/tests/Support/GlobTest.php b/tests/Support/GlobTest.php new file mode 100644 index 0000000..6a6c8c0 --- /dev/null +++ b/tests/Support/GlobTest.php @@ -0,0 +1,37 @@ +assertSame('#^#', Glob::toRegex('')); + $this->assertSame('#^\\\\#', Glob::toRegex('\\\\')); + $this->assertSame('#^.#', Glob::toRegex('?')); + $this->assertSame('#^[^/]*#', Glob::toRegex('*')); + $this->assertSame('#^.*#', Glob::toRegex('**')); + $this->assertSame('#^\##', Glob::toRegex('#')); + $this->assertSame('#^\\?#', Glob::toRegex('\\?')); + } + + public function test_it_converts_a_glob_pattern_to_a_regular_expression_pattern(): void + { + $this->assertSame('#^foo\.txt#', Glob::toRegex('foo.txt')); + $this->assertSame('#^foo/bar\.txt#', Glob::toRegex('foo/bar.txt')); + $this->assertSame('#^foo\?bar\.txt#', Glob::toRegex('foo\?bar.txt')); + $this->assertSame('#^[^/]*\.txt#', Glob::toRegex('*.txt')); + $this->assertSame('#^.*/[^/]*\.txt#', Glob::toRegex('**/*.txt')); + $this->assertSame('#^([^/]*|.*/[^/]*)\.txt#', Glob::toRegex('{*,**/*}.txt')); + $this->assertSame('#^file\.(yml|yaml)#', Glob::toRegex('file.{yml,yaml}')); + $this->assertSame('#^[fbw]oo\.txt#', Glob::toRegex('[fbw]oo.txt')); + $this->assertSame('#^[^fbw]oo\.txt#', Glob::toRegex('[^fbw]oo.txt')); + $this->assertSame('#^foo}bar\.txt#', Glob::toRegex('foo}bar.txt')); + $this->assertSame('#^foo\^bar\.txt#', Glob::toRegex('foo^bar.txt')); + $this->assertSame('#^foo,bar\.txt#', Glob::toRegex('foo,bar.txt')); + $this->assertSame('#^foo/.*/[^/]*\.txt#', Glob::toRegex('foo/**/*.txt')); + } +}