Skip to content

Commit

Permalink
implement globstar
Browse files Browse the repository at this point in the history
  • Loading branch information
mlebkowski committed Dec 18, 2024
1 parent 502fd07 commit ed2a76d
Show file tree
Hide file tree
Showing 9 changed files with 129 additions and 2 deletions.
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
"php-di/php-di": "^6.4",
"dusank/knapsack": "^10.0",
"php-di/slim-bridge": "^3.4",
"symfony/console": "^5.4"
"symfony/console": "^5.4",
"symfony/finder": "^5.4"
},
"license": "MIT",
"autoload": {
Expand Down
65 changes: 64 additions & 1 deletion composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 19 additions & 0 deletions src/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,30 @@

use DusanKasan\Knapsack\Collection;
use RuntimeException;
use SplFileInfo;
use Symfony\Component\Finder\Finder;

/** @return string[] */
function findFiles(string $root, string ...$patterns): iterable {
$globstar = '**/';

$root = rtrim($root, '/');
foreach ($patterns as $pattern) {
// php glob does not support globstar to match any directory depth. Let’s hack around it
if (str_contains($pattern, $globstar)) {
[$directory, $name] = explode($globstar, $pattern, 2);
$finder = Finder::create()
->in($root.'/'.ltrim($directory, '/'))
->name($name)
->files()
->sortByName();
yield from map(
array_values(iterator_to_array($finder)),
static fn (SplFileInfo $file) => $file->getRealPath(),
);
continue;
}

$result = glob($root.'/'.ltrim($pattern, '/'));
if (false === $result) {
throw new RuntimeException('Invalid pattern: '.$pattern);
Expand Down
1 change: 1 addition & 0 deletions tests/Resources/ServicesBuilder/alpha.php
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<?php
1 change: 1 addition & 0 deletions tests/Resources/ServicesBuilder/bravo.php
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<?php
1 change: 1 addition & 0 deletions tests/Resources/ServicesBuilder/charlie/delta.php
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<?php
1 change: 1 addition & 0 deletions tests/Resources/ServicesBuilder/charlie/echo/foxtrot.php
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<?php
1 change: 1 addition & 0 deletions tests/Resources/ServicesBuilder/composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
39 changes: 39 additions & 0 deletions tests/ServicesBuilderTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php
declare(strict_types=1);

namespace WonderNetwork\SlimKernel;

use PHPUnit\Framework\TestCase;
use function WonderNetwork\SlimKernel\Collection\collection;
use function WonderNetwork\SlimKernel\Collection\map;

final class ServicesBuilderTest extends TestCase {
public function testSimpleGlob(): void {
$this->assertFiles('*.php', ['alpha.php', 'bravo.php']);
}

public function testRecursiveGlob(): void {
$this->assertFiles(
'**/*.php',
[
'alpha.php',
'bravo.php',
'charlie/delta.php',
'charlie/echo/foxtrot.php',
],
);
}

/**
* @param string $pattern
* @param string[] $expected
*/
private function assertFiles(string $pattern, array $expected): void {
$basePath = __DIR__.'/Resources/ServicesBuilder/';
$sut = new ServicesBuilder($basePath);
$actual = collection($sut->glob($pattern))->toArray();
$expected = map($expected, static fn (string $path) => $basePath.$path);

self::assertSame($expected, $actual);
}
}

0 comments on commit ed2a76d

Please sign in to comment.