Skip to content

Commit cb692d7

Browse files
committed
Allow File::find() to run over multiple directories
1 parent 100c6dc commit cb692d7

File tree

2 files changed

+32
-23
lines changed

2 files changed

+32
-23
lines changed

src/Facade/File.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
* @method static bool isLoaded() True if an underlying Filesystem instance has been loaded
1616
* @method static void unload() Clear the underlying Filesystem instance
1717
* @method static string createTemporaryDirectory() Create a temporary directory
18-
* @method static FluentIteratorInterface<string,SplFileInfo> find(string $directory, string|null $exclude = null, string|null $include = null, array<string,callable(SplFileInfo): bool> $excludeCallbacks = null, array<string,callable(SplFileInfo): bool> $includeCallbacks = null, bool $recursive = true, bool $withDirectories = false, bool $withDirectoriesFirst = true) Iterate over files in a directory (see {@see Filesystem::find()})
18+
* @method static FluentIteratorInterface<string,SplFileInfo> find(string|string[] $directory, string|null $exclude = null, string|null $include = null, array<string,callable(SplFileInfo): bool> $excludeCallbacks = null, array<string,callable(SplFileInfo): bool> $includeCallbacks = null, bool $recursive = true, bool $withDirectories = false, bool $withDirectoriesFirst = true) Iterate over files in a directory (see {@see Filesystem::find()})
1919
* @method static string|null getEol(string $filename) Get the end-of-line sequence used in a file (see {@see Filesystem::getEol()})
2020
* @method static string getStablePath(string $suffix = '', ?string $dir = null) Generate a filename unique to the current user and the path of the running script (see {@see Filesystem::getStablePath()})
2121
* @method static string|null getStreamUri(resource $stream) Get the URI or filename associated with a stream (see {@see Filesystem::getStreamUri()})

src/Utility/Filesystem.php

Lines changed: 31 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@
44

55
use Lkrms\Facade\Compute;
66
use Lkrms\Facade\Console;
7-
use Lkrms\Facade\File;
87
use Lkrms\Facade\Sys;
98
use Lkrms\Support\Iterator\Contract\FluentIteratorInterface;
109
use Lkrms\Utility\Convert;
1110
use Lkrms\Utility\Test;
11+
use AppendIterator;
1212
use CallbackFilterIterator;
1313
use FilesystemIterator;
1414
use LogicException;
@@ -30,6 +30,8 @@ final class Filesystem
3030
*
3131
* Exclusions are applied before inclusions.
3232
*
33+
* @param string|string[] $directory One or multiple directories to iterate
34+
* over.
3335
* @param string|null $exclude A regular expression that specifies paths to
3436
* exclude. No files are excluded if `null`.
3537
*
@@ -54,7 +56,7 @@ final class Filesystem
5456
* @return FluentIteratorInterface<string,SplFileInfo>
5557
*/
5658
public function find(
57-
string $directory,
59+
$directory,
5860
?string $exclude = null,
5961
?string $include = null,
6062
?array $excludeCallbacks = null,
@@ -113,30 +115,37 @@ function (SplFileInfo $current, string $key) use (
113115
return !$include && !$includeCallbacks;
114116
};
115117
}
116-
117-
if ($recursive) {
118-
$iterator = new RecursiveDirectoryIterator($directory, $flags);
119-
if ($callback ?? null) {
120-
$iterator = new RecursiveCallbackFilterIterator($iterator, $callback);
118+
/** @var AppendIterator|null */
119+
$appendIterator = null;
120+
/** @var non-empty-array<string> */
121+
$directories = (array) $directory;
122+
foreach ($directories as $directory) {
123+
if ($recursive) {
124+
$iterator = new RecursiveDirectoryIterator($directory, $flags);
125+
if ($callback ?? null) {
126+
$iterator = new RecursiveCallbackFilterIterator($iterator, $callback);
127+
}
128+
$iterator = new RecursiveIteratorIterator($iterator, $mode);
129+
} else {
130+
$iterator = new FilesystemIterator($directory, $flags);
131+
if ($callback ?? null) {
132+
$iterator = new CallbackFilterIterator($iterator, $callback);
133+
}
134+
if (!$withDirectories) {
135+
$iterator = new CallbackFilterIterator($iterator, fn(SplFileInfo $current) => !$current->isDir());
136+
}
121137
}
122-
$iterator = new RecursiveIteratorIterator($iterator, $mode);
123-
/** @var FluentIteratorInterface<string,SplFileInfo> */
124-
$iterator = new \Lkrms\Support\Iterator\FluentIterator($iterator);
125138

126-
return $iterator;
127-
}
128-
129-
$iterator = new FilesystemIterator($directory, $flags);
130-
if ($callback ?? null) {
131-
$iterator = new CallbackFilterIterator($iterator, $callback);
132-
}
133-
if (!$withDirectories) {
134-
$iterator = new CallbackFilterIterator($iterator, fn(SplFileInfo $current) => !$current->isDir());
139+
if (!$appendIterator) {
140+
if (count($directories) === 1) {
141+
break;
142+
}
143+
$appendIterator = new AppendIterator();
144+
}
145+
$appendIterator->append($iterator);
135146
}
136-
/** @var FluentIteratorInterface<string,SplFileInfo> */
137-
$iterator = new \Lkrms\Support\Iterator\FluentIterator($iterator);
138147

139-
return $iterator;
148+
return new \Lkrms\Support\Iterator\FluentIterator($appendIterator ?? $iterator);
140149
}
141150

142151
/**

0 commit comments

Comments
 (0)