Pulled int phlak/glob library for glob pattern matching

This commit is contained in:
Chris Kankiewicz
2020-04-30 22:33:39 -07:00
parent 65154d9fe6
commit edad886359
5 changed files with 59 additions and 142 deletions

View File

@@ -3,9 +3,9 @@
namespace App\Factories;
use App\SortMethods;
use App\Support\Glob;
use Closure;
use DI\Container;
use PHLAK\Utilities\Glob;
use RuntimeException;
use Symfony\Component\Finder\Finder;
use Symfony\Component\Finder\SplFileInfo;
@@ -51,9 +51,9 @@ class FinderFactory
if ($this->hiddenFiles()->isNotEmpty()) {
$finder->filter(function (SplFileInfo $file): bool {
return (bool) ! preg_match(Glob::toRegex(
return (bool) ! Glob::pattern(
sprintf('%s/{%s}', $this->container->get('base_path'), $this->hiddenFiles()->implode(','))
), $file->getRealPath());
)->matchStart($file->getRealPath());
});
}

View File

@@ -1,101 +0,0 @@
<?php
namespace App\Support;
class Glob
{
/**
* Convert a glob pattern to a regular expression pattern.
*
* @param string $glob
*
* @return string
*/
public static function toRegex(string $glob): string
{
$pattern = '';
$characterGroup = 0;
$patternGroup = 0;
for ($i = 0; $i < strlen($glob); ++$i) {
$char = $glob[$i];
switch ($char) {
case '\\':
$pattern .= '\\' . $glob[++$i];
break;
case '?':
$pattern .= '.';
break;
case '*':
if (isset($glob[$i + 1]) && $glob[$i + 1] === '*') {
$pattern .= '.*';
++$i;
} else {
$pattern .= '[^/]*';
}
break;
case '#':
$pattern .= '\#';
break;
case '[':
$pattern .= $char;
++$characterGroup;
break;
case ']':
if ($characterGroup > 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);
}
}

View File

@@ -17,6 +17,7 @@
"erusev/parsedown-extra": "^0.8.1",
"filp/whoops": "^2.7",
"middlewares/cache": "^2.0",
"phlak/glob": "^1.0",
"php-di/php-di": "^6.0",
"php-di/slim-bridge": "^3.0",
"psr/http-message": "^1.0.1",

56
composer.lock generated
View File

@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "97cdefd2e4480748bbb183e286dc6640",
"content-hash": "e2699e8d103e85fea1e80125c6e9aa12",
"packages": [
{
"name": "erusev/parsedown",
@@ -523,6 +523,60 @@
],
"time": "2020-04-10T16:34:50+00:00"
},
{
"name": "phlak/glob",
"version": "1.0.0",
"source": {
"type": "git",
"url": "https://github.com/PHLAK/Glob.git",
"reference": "6a58c5157b518d44da235dee8dda0bc8a038cf0b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/PHLAK/Glob/zipball/6a58c5157b518d44da235dee8dda0bc8a038cf0b",
"reference": "6a58c5157b518d44da235dee8dda0bc8a038cf0b",
"shasum": ""
},
"require": {
"php": ">=7.0"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^2.10",
"php": ">=7.2",
"phpunit/phpunit": "^8.0 || ^9.0",
"psy/psysh": "^0.10",
"symfony/var-dumper": "^5.0",
"vimeo/psalm": "^3.8"
},
"type": "library",
"autoload": {
"psr-4": {
"PHLAK\\Utilities\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Chris Kankiewicz",
"email": "Chris@ChrisKankiewicz.com"
}
],
"description": "Glob-like pattern matching and utilities",
"funding": [
{
"url": "https://github.com/sponsors/PHLAK",
"type": "github"
},
{
"url": "https://paypal.me/ChrisKankiewicz",
"type": "paypal"
}
],
"time": "2020-05-01T05:12:53+00:00"
},
{
"name": "php-di/invoker",
"version": "2.0.0",

View File

@@ -1,37 +0,0 @@
<?php
namespace Tests\Support;
use App\Support\Glob;
use Tests\TestCase;
class GlobTest extends TestCase
{
public function test_it_converts_glob_pattern_special_characters_to_a_regular_expression(): void
{
$this->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'));
}
}