Repository: phpactor/phpactor (php)

Issue:
IndexCleanCommand uses symfony/finder when is not declared as dependency
I discovered there is a command to clean the index cache but trying to use gave m the error
```
PHP Fatal error:  Uncaught Error: Class "Symfony\Component\Finder\Finder" not found
```
I required the package in my root composer.json but I think it is an undeclared dependency of phpactor.

Pull request:
Gh 2304: remove finder dep
Fixes #2304 

Patch:
diff --git a/lib/Amp/Mod.php b/lib/Amp/Mod.php
new file mode 100644
index 00000000..e69de29b
diff --git a/lib/Indexer/Adapter/Php/PhpIndexerLister.php b/lib/Indexer/Adapter/Php/PhpIndexerLister.php
new file mode 100644
index 00000000..ed05b7a9
--- /dev/null
+++ b/lib/Indexer/Adapter/Php/PhpIndexerLister.php
@@ -0,0 +1,33 @@
+<?php
+
+namespace Phpactor\Indexer\Adapter\Php;
+
+use Generator;
+use Phpactor\Indexer\Model\IndexInfo;
+use Phpactor\Indexer\Model\IndexLister;
+use SplFileInfo;
+use Symfony\Component\Filesystem\Path;
+
+class PhpIndexerLister implements IndexLister
+{
+    public function __construct(private string $indexDirectory)
+    {
+    }
+    public function list(): Generator
+    {
+        $indexes = array_filter(array_map(
+            fn (string|false $name) => $name ? Path::join($this->indexDirectory, $name) : '',
+            array_filter(
+                (array)scandir($this->indexDirectory),
+                fn (string|false $name) => !in_array($name, ['.', '..'])
+            ),
+        ), fn (string $indexPath) => is_dir($indexPath));
+
+        foreach ($indexes as $indexPath) {
+            $info = IndexInfo::fromSplFileInfo(new SplFileInfo($indexPath));
+            // warmup the size
+            $info->size();
+            yield $info;
+        }
+    }
+}
diff --git a/lib/Indexer/Extension/Command/IndexCleanCommand.php b/lib/Indexer/Extension/Command/IndexCleanCommand.php
index 40408c86..50179a9d 100644
--- a/lib/Indexer/Extension/Command/IndexCleanCommand.php
+++ b/lib/Indexer/Extension/Command/IndexCleanCommand.php
@@ -5,6 +5,7 @@ namespace Phpactor\Indexer\Extension\Command;
 use Exception;
 use Phpactor\Indexer\Model\IndexInfo;
 use Phpactor\Indexer\Model\IndexInfos;
+use Phpactor\Indexer\Model\IndexLister;
 use Phpactor\Indexer\Util\Filesystem as PhpactorFilesystem;
 use RuntimeException;
 use Symfony\Component\Console\Command\Command;
@@ -18,14 +19,13 @@ use Symfony\Component\Console\Output\ConsoleOutput;
 use Symfony\Component\Console\Output\OutputInterface;
 use Symfony\Component\Console\Question\Question;
 use Symfony\Component\Filesystem\Filesystem;
-use Symfony\Component\Finder\Finder;
 
 class IndexCleanCommand extends Command
 {
     public const ARG_INDEX_NAME = 'name';
     public const OPT_CLEAN_ALL = 'all';
 
-    public function __construct(private string $indexDirectory, private Filesystem $filesystem)
+    public function __construct(private IndexLister $indexLister, private Filesystem $filesystem)
     {
         parent::__construct();
     }
@@ -164,21 +164,9 @@ class IndexCleanCommand extends Command
 
     private function getIndicies(OutputInterface $output): IndexInfos
     {
-        $finder = (new Finder())
-           ->directories()
-           ->in([$this->indexDirectory])
-           ->sortByName()
-           ->depth('==0')
-        ;
-        $fileInfos = iterator_to_array($finder);
-        $progress = new ProgressBar($output, count($fileInfos));
-
         $indexes = [];
-        foreach ($fileInfos as $fileInfo) {
-            $info = IndexInfo::fromSplFileInfo($fileInfo);
-
-            // warmup the size
-            $info->size();
+        $progress = new ProgressBar($output);
+        foreach ($this->indexLister->list() as $info) {
             $indexes[] = $info;
             $progress->advance();
         }
diff --git a/lib/Indexer/Extension/IndexerExtension.php b/lib/Indexer/Extension/IndexerExtension.php
index b9b818cb..703a6323 100644
--- a/lib/Indexer/Extension/IndexerExtension.php
+++ b/lib/Indexer/Extension/IndexerExtension.php
@@ -23,6 +23,7 @@ use Phpactor\Extension\Rpc\RpcExtension;
 use Phpactor\Extension\WorseReflection\WorseReflectionExtension;
 use Phpactor\Extension\FilePathResolver\FilePathResolverExtension;
 use Phpactor\FilePathResolver\PathResolver;
+use Phpactor\Indexer\Adapter\Php\PhpIndexerLister;
 use Phpactor\Indexer\Adapter\ReferenceFinder\IndexedNameSearcher;
 use Phpactor\Indexer\Adapter\ReferenceFinder\Util\ContainerTypeResolver;
 use Phpactor\Indexer\Adapter\Worse\IndexerClassSourceLocator;
@@ -175,7 +176,7 @@ class IndexerExtension implements Extension
             )->resolve($container->parameter(self::PARAM_INDEX_PATH)->string());
 
             $indexPath = dirname($indexPath);
-            return new IndexCleanCommand($indexPath, new Filesystem());
+            return new IndexCleanCommand(new PhpIndexerLister($indexPath), new Filesystem());
         }, [ ConsoleExtension::TAG_COMMAND => ['name' => 'index:clean']]);
 
         $container->register(IndexQueryCommand::class, function (Container $container) {
diff --git a/lib/Indexer/Model/IndexInfo.php b/lib/Indexer/Model/IndexInfo.php
index c25ce0b9..25e0aaf6 100644
--- a/lib/Indexer/Model/IndexInfo.php
+++ b/lib/Indexer/Model/IndexInfo.php
@@ -3,8 +3,8 @@
 namespace Phpactor\Indexer\Model;
 
 use Phpactor\Indexer\Util\Filesystem;
+use SplFileInfo;
 use Symfony\Component\Filesystem\Path;
-use Symfony\Component\Finder\SplFileInfo;
 
 class IndexInfo
 {
@@ -23,7 +23,7 @@ class IndexInfo
     {
         return new self(
             $fileInfo->getRealPath(),
-            $fileInfo->getRelativePathname(),
+            basename($fileInfo->getPathname()),
             null,
             $fileInfo->getCTime(),
             (function (SplFileInfo $info) {
diff --git a/lib/Indexer/Model/IndexLister.php b/lib/Indexer/Model/IndexLister.php
new file mode 100644
index 00000000..b39e5f19
--- /dev/null
+++ b/lib/Indexer/Model/IndexLister.php
@@ -0,0 +1,13 @@
+<?php
+
+namespace Phpactor\Indexer\Model;
+
+use Generator;
+
+interface IndexLister
+{
+    /**
+     * @return Generator<IndexInfo>
+     */
+    public function list(): Generator;
+}


Test patch:
diff --git a/lib/Indexer/Tests/Adapter/Php/PhpIndexListerTest.php b/lib/Indexer/Tests/Adapter/Php/PhpIndexListerTest.php
new file mode 100644
index 00000000..0eba464a
--- /dev/null
+++ b/lib/Indexer/Tests/Adapter/Php/PhpIndexListerTest.php
@@ -0,0 +1,31 @@
+<?php
+
+namespace Phpactor\Indexer\Tests\Adapter\Php;
+
+use Phpactor\Indexer\Adapter\Php\PhpIndexerLister;
+use Phpactor\Indexer\Tests\IntegrationTestCase;
+
+class PhpIndexListerTest extends IntegrationTestCase
+{
+    protected function setUp(): void
+    {
+        $this->workspace()->reset();
+    }
+
+    public function testListsIndexes(): void
+    {
+        $this->workspace()->mkdir('index1');
+        $this->workspace()->mkdir('index2');
+        $this->workspace()->put('file1.txt', '');
+
+        $lister = $this->lister();
+
+        $infos = iterator_to_array($lister->list());
+        self::assertCount(2, $infos);
+    }
+
+    private function lister(): PhpIndexerLister
+    {
+        return (new PhpIndexerLister($this->workspace()->path()));
+    }
+}