Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 9b95ed0

Browse files
committed
fix: fix logic error for file finder
1 parent de25967 commit 9b95ed0

File tree

2 files changed

+86
-45
lines changed

2 files changed

+86
-45
lines changed

‎src/FileFinder.php‎

Lines changed: 74 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
use RecursiveIteratorIterator;
2626
use RuntimeException;
2727
use SplFileInfo;
28+
use Toolkit\Stdlib\Str;
2829
use Traversable;
2930
use UnexpectedValueException;
3031
use function array_flip;
@@ -34,6 +35,7 @@
3435
use function fnmatch;
3536
use function get_object_vars;
3637
use function is_iterable;
38+
use function is_string;
3739
use function iterator_count;
3840
use function str_contains;
3941
use function stream_get_meta_data;
@@ -78,16 +80,14 @@ final class FileFinder implements IteratorAggregate, Countable
7880
/** @var bool */
7981
private bool $ignoreVcsAdded = false;
8082

81-
/**
82-
* @var bool
83-
*/
83+
/** @var bool */
8484
private bool $skipUnreadableDirs = true;
8585

8686
/** @var array */
8787
private array $dirs = [];
8888

8989
/**
90-
* File,dir name match.
90+
* add include file,dir name match.
9191
*
9292
* eg: '.php' '*.php' 'test.php'
9393
*
@@ -96,26 +96,28 @@ final class FileFinder implements IteratorAggregate, Countable
9696
private array $names = [];
9797

9898
/**
99-
* File,dir name exclude
99+
* add exclude file,dir name patterns
100100
*
101101
* eg: '.php' '*.php' 'test.php'
102102
*
103103
* @var array
104104
*/
105105
private array $notNames = [];
106106

107-
/** @var array */
107+
/** @var array<string> include paths pattern. */
108108
private array $paths = [];
109109

110-
/** @var array */
110+
/** @var array<string> exclude paths pattern */
111111
private array $notPaths = [];
112112

113-
/**
114-
* @var array exclude directories
115-
*/
113+
/** @var array<string> exclude directory names */
116114
private array $excludes = [];
117115

118-
/** @var array */
116+
/**
117+
* path filters. each filter like: `Closure(SplFileInfo):bool`, return FALSE to exclude.
118+
*
119+
* @var array
120+
*/
119121
private array $filters = [];
120122

121123
/** @var array */
@@ -213,6 +215,8 @@ public function onlyFiles(): self
213215
}
214216

215217
/**
218+
* add include file,dir name match pattern.
219+
*
216220
* $finder->name('*.php')
217221
* $finder->name('test.php')
218222
*
@@ -222,28 +226,29 @@ public function onlyFiles(): self
222226
*/
223227
public function name(string $pattern): self
224228
{
225-
if ($pattern) {
226-
$this->names[] = $pattern;
227-
}
228-
229-
return $this;
229+
return $this->addNames($pattern);
230230
}
231231

232232
/**
233+
* add include file,dir name match pattern.
234+
*
233235
* @param array|string $patterns
234236
*
235237
* @return FileFinder
236238
*/
237239
public function addNames(array|string $patterns): self
238240
{
239241
if ($patterns) {
240-
$this->names = array_merge($this->names, (array)$patterns);
242+
$patterns = is_string($patterns) ? Str::splitTrimmed($patterns) : $patterns;
243+
// append
244+
$this->names = array_merge($this->names, $patterns);
241245
}
242-
243246
return $this;
244247
}
245248

246249
/**
250+
* add exclude file,dir name patterns
251+
*
247252
* @param string $pattern
248253
*
249254
* @return FileFinder
@@ -255,20 +260,25 @@ public function notName(string $pattern): self
255260
}
256261

257262
/**
263+
* add exclude file,dir name patterns
264+
*
258265
* @param array|string $patterns
259266
*
260267
* @return FileFinder
261268
*/
262269
public function notNames(array|string $patterns): self
263270
{
264271
if ($patterns) {
265-
$this->notNames = array_merge($this->notNames, (array)$patterns);
272+
$patterns = is_string($patterns) ? Str::splitTrimmed($patterns) : $patterns;
273+
// append
274+
$this->notNames = array_merge($this->notNames, $patterns);
266275
}
267-
268276
return $this;
269277
}
270278

271279
/**
280+
* add exclude file,dir name patterns
281+
*
272282
* @param array|string $patterns
273283
*
274284
* @return FileFinder
@@ -279,6 +289,8 @@ public function addNotNames(array|string $patterns): self
279289
}
280290

281291
/**
292+
* add include paths pattern.
293+
* eg:
282294
* $finder->path('some/special/dir')
283295
*
284296
* @param string $pattern
@@ -292,33 +304,37 @@ public function path(string $pattern): self
292304
}
293305

294306
/**
307+
* add include paths pattern.
308+
*
295309
* @param array|string $patterns
296310
*
297311
* @return FileFinder
298312
*/
299313
public function addPaths(array|string $patterns): self
300314
{
301315
if ($patterns) {
302-
$this->paths = array_merge($this->paths, (array)$patterns);
316+
$patterns = is_string($patterns) ? Str::splitTrimmed($patterns) : $patterns;
317+
// append
318+
$this->paths = array_merge($this->paths, $patterns);
303319
}
304-
305320
return $this;
306321
}
307322

308323
/**
324+
* add exclude paths pattern
325+
*
309326
* @param string $pattern
310327
*
311328
* @return FileFinder
312329
*/
313330
public function notPath(string $pattern): self
314331
{
315-
if ($pattern) {
316-
$this->notPaths[] = $pattern;
317-
}
318-
return $this;
332+
return $this->addNotPaths($pattern);
319333
}
320334

321335
/**
336+
* add exclude paths pattern. alias of addNotPaths()
337+
*
322338
* @param array|string $patterns
323339
*
324340
* @return FileFinder
@@ -329,30 +345,37 @@ public function notPaths(array|string $patterns): self
329345
}
330346

331347
/**
348+
* add exclude paths pattern.
349+
* eg: $finder->addNotPaths(['vendor', 'node_modules', 'bin/'])
350+
*
332351
* @param array|string $patterns
333352
*
334353
* @return FileFinder
335354
*/
336355
public function addNotPaths(array|string $patterns): self
337356
{
338357
if ($patterns) {
339-
$this->notPaths = array_merge($this->notPaths, (array)$patterns);
358+
$patterns = is_string($patterns) ? Str::splitTrimmed($patterns) : $patterns;
359+
// append
360+
$this->notPaths = array_merge($this->notPaths, $patterns);
340361
}
341-
342362
return $this;
343363
}
344364

345365
/**
346-
* @param $dirs
366+
* exclude directory names
367+
*
368+
* @param array|string $dirNames
347369
*
348370
* @return FileFinder
349371
*/
350-
public function exclude($dirs): self
372+
public function exclude(array|string$dirNames): self
351373
{
352-
if ($dirs) {
353-
$this->excludes = array_merge($this->excludes, (array)$dirs);
374+
if ($dirNames) {
375+
$dirNames = is_string($dirNames) ? Str::splitTrimmed($dirNames) : $dirNames;
376+
// append
377+
$this->excludes = array_merge($this->excludes, $dirNames);
354378
}
355-
356379
return $this;
357380
}
358381

@@ -429,14 +452,13 @@ public function followLinks(mixed $followLinks = true): self
429452
}
430453

431454
/**
432-
* @param Closure $closure
455+
* @param Closure(SplFileInfo): bool $closure
433456
*
434457
* @return FileFinder
435458
*/
436459
public function filter(Closure $closure): self
437460
{
438461
$this->filters[] = $closure;
439-
440462
return $this;
441463
}
442464

@@ -460,9 +482,10 @@ public function in(array|string $dirs): self
460482
public function inDir(array|string $dirs): self
461483
{
462484
if ($dirs) {
463-
$this->dirs = array_merge($this->dirs, (array)$dirs);
485+
$dirs = is_string($dirs) ? Str::splitTrimmed($dirs) : $dirs;
486+
// append
487+
$this->dirs = array_merge($this->dirs, $dirs);
464488
}
465-
466489
return $this;
467490
}
468491

@@ -585,7 +608,7 @@ private function findInDirectory(string $dir): Iterator
585608
$flags |= RecursiveDirectoryIterator::FOLLOW_SYMLINKS;
586609
}
587610

588-
$iterator = new class($dir, $flags) extends RecursiveDirectoryIterator {
611+
$iterator = new class($dir, $flags, $this->skipUnreadableDirs) extends RecursiveDirectoryIterator {
589612
private string $rootPath;
590613
private string $subPath = '';
591614
private bool|null $rewindable = null;
@@ -610,8 +633,9 @@ public function __construct(string $path, int $flags, bool $skipUnreadableDirs =
610633

611634
public function current(): SplFileInfo
612635
{
636+
// vdump($this->getPathname(), $this);
613637
if (null === $subPathname = $this->subPath) {
614-
$subPathname = $this->subPath = (string)$this->getSubPath();
638+
$subPathname = $this->subPath = $this->getSubPath();
615639
}
616640

617641
if ('' !== $subPathname) {
@@ -620,8 +644,9 @@ public function current(): SplFileInfo
620644

621645
$subPathname .= $this->getFilename();
622646

623-
// $fileInfo = new \SplFileInfo($this->getPathname());
624-
$fileInfo = new SplFileInfo($this->rootPath . $this->directorySep . $subPathname);
647+
$fileInfo = new SplFileInfo($this->getPathname());
648+
// $fileInfo = new SplFileInfo($this->rootPath . $this->directorySep . $subPathname);
649+
// vdump($this->rootPath, $subPathname, $fileInfo);
625650
// add props
626651
$fileInfo->relativePath = $this->subPath;
627652
$fileInfo->relativePathname = $subPathname;
@@ -634,7 +659,7 @@ public function getChildren(): RecursiveDirectoryIterator
634659
try {
635660
$children = parent::getChildren();
636661
if ($children instanceof self) {
637-
$children->rootPath = $this->rootPath;
662+
$children->rootPath = $this->rootPath;
638663
$children->rewindable = &$this->rewindable;
639664
$children->skipUnreadableDirs = $this->skipUnreadableDirs;
640665
}
@@ -680,6 +705,7 @@ public function isRewindable(): ?bool
680705
// exclude directories
681706
if ($this->excludes) {
682707
$iterator = new class($iterator, $this->excludes) extends FilterIterator implements RecursiveIterator {
708+
/** @var array<string, int> */
683709
private array $excludes;
684710

685711
private RecursiveIterator $iterator;
@@ -734,6 +760,7 @@ public function __construct(Iterator $iterator, int $mode)
734760

735761
public function accept(): bool
736762
{
763+
/** @var SplFileInfo $info */
737764
$info = $this->current();
738765
if (FileFinder::ONLY_DIR === $this->mode && $info->isFile()) {
739766
return false;
@@ -796,6 +823,7 @@ public function __construct(Iterator $iterator, array $filters)
796823

797824
public function accept(): bool
798825
{
826+
/** @var SplFileInfo $fileInfo */
799827
$fileInfo = $this->current();
800828
foreach ($this->filters as $filter) {
801829
if (false === $filter($fileInfo)) {
@@ -810,8 +838,9 @@ public function accept(): bool
810838

811839
if ($this->paths || $this->notPaths) {
812840
$iterator = new class($iterator, $this->paths, $this->notPaths) extends FilterIterator {
841+
/** @var array<string> */
813842
private array $paths;
814-
843+
/** @var array<string> */
815844
private array $notPaths;
816845

817846
public function __construct(Iterator $iterator, array $paths, array $notPaths)
@@ -823,7 +852,8 @@ public function __construct(Iterator $iterator, array $paths, array $notPaths)
823852

824853
public function accept(): bool
825854
{
826-
$pathname = $this->current()->relativePathname;
855+
/** @var string $pathname {@see SplFileInfo::getPathname()} */
856+
$pathname = $this->current()->getPathname();
827857
if ('\\' === DIRECTORY_SEPARATOR) {
828858
$pathname = str_replace('\\', '/', $pathname);
829859
}

‎src/Traits/FileSystemFuncTrait.php‎

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@
3434
use function str_replace;
3535
use function stream_get_meta_data;
3636
use function strlen;
37-
use function strpos;
3837
use const DIRECTORY_SEPARATOR;
3938

4039
/**
@@ -228,6 +227,18 @@ public static function chown(Traversable|array|string $files, string $user, bool
228227
}
229228
}
230229

230+
/**
231+
* clear invalid sep and will parse ~ as user home dir.
232+
*
233+
* @param string $path
234+
*
235+
* @return string
236+
*/
237+
public static function expandPath(string $path): string
238+
{
239+
$path = realpath($path);
240+
}
241+
231242
/**
232243
* clear invalid sep and will parse ~ as user home dir.
233244
*

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /