From 124891bb40a4b295c27618f4612dfd29503e301b Mon Sep 17 00:00:00 2001 From: Aleksei Lebedev <1329824+LastDragon-ru@users.noreply.github.com> Date: Mon, 22 Jul 2024 10:09:33 +0400 Subject: [PATCH] feat(documentator): `Processor` wildcard tasks support. --- .../src/Processor/Contracts/Task.php | 3 +- .../documentator/src/Processor/Executor.php | 11 +- .../documentator/src/Processor/Processor.php | 4 +- .../src/Processor/ProcessorTest.php | 122 ++++++++++++++++++ 4 files changed, 134 insertions(+), 6 deletions(-) diff --git a/packages/documentator/src/Processor/Contracts/Task.php b/packages/documentator/src/Processor/Contracts/Task.php index 39f452ae..a2faf8c9 100644 --- a/packages/documentator/src/Processor/Contracts/Task.php +++ b/packages/documentator/src/Processor/Contracts/Task.php @@ -8,7 +8,8 @@ interface Task { /** - * Returns the file extensions which task is processing. + * Returns the file extensions which task is processing. The `*` can be used + * to process any file. * * @return non-empty-list */ diff --git a/packages/documentator/src/Processor/Executor.php b/packages/documentator/src/Processor/Executor.php index 6eb64bc3..20feb38a 100644 --- a/packages/documentator/src/Processor/Executor.php +++ b/packages/documentator/src/Processor/Executor.php @@ -18,6 +18,7 @@ use LastDragon_ru\LaraASP\Documentator\Processor\FileSystem\FileSystem; use Throwable; +use function array_merge; use function array_values; use function microtime; use function preg_match; @@ -96,7 +97,7 @@ private function runFile(File $file): float { } // Process - $tasks = $this->tasks[$file->getExtension()] ?? []; + $tasks = array_merge($this->tasks[$file->getExtension()] ?? [], $this->tasks['*'] ?? []); $start = microtime(true); $paused = 0; $this->stack[$path] = $file; @@ -208,10 +209,12 @@ private function dispatch(Dependency|File $file, Result $result, float $duration private function isSkipped(File $file): bool { // Tasks? - $tasks = $this->tasks[$file->getExtension()] ?? []; + if (!isset($this->tasks['*'])) { + $tasks = $this->tasks[$file->getExtension()] ?? []; - if (!$tasks) { - return true; + if (!$tasks) { + return true; + } } // Outside? diff --git a/packages/documentator/src/Processor/Processor.php b/packages/documentator/src/Processor/Processor.php index e577b43f..5fe5b524 100644 --- a/packages/documentator/src/Processor/Processor.php +++ b/packages/documentator/src/Processor/Processor.php @@ -47,7 +47,9 @@ public function task(Task $task): static { */ public function run(string $path, array|string|null $exclude = null, ?Closure $listener = null): float { $start = microtime(true); - $extensions = array_map(static fn ($e) => "*.{$e}", array_keys($this->tasks)); + $extensions = !isset($this->tasks['*']) + ? array_map(static fn ($e) => "*.{$e}", array_keys($this->tasks)) + : null; $exclude = array_map(Glob::toRegex(...), (array) $exclude); $root = new Directory($path, true); $fs = new FileSystem(); diff --git a/packages/documentator/src/Processor/ProcessorTest.php b/packages/documentator/src/Processor/ProcessorTest.php index 223b4952..0a99befe 100644 --- a/packages/documentator/src/Processor/ProcessorTest.php +++ b/packages/documentator/src/Processor/ProcessorTest.php @@ -295,6 +295,128 @@ static function (string $path, Result $result) use (&$count, &$events): void { ); } + public function testRunWildcard(): void { + $taskA = new class() implements Task { + /** + * @var array + */ + public array $processed = []; + + /** + * @inheritDoc + */ + #[Override] + public function getExtensions(): array { + return ['html']; + } + + /** + * @return Generator, mixed, bool> + */ + #[Override] + public function __invoke(Directory $root, File $file): Generator { + $dependencies = match ($file->getName()) { + 'b.html' => [ + '../../../../README.md', + '../a/excluded.txt', + ], + default => [ + // empty + ], + }; + + foreach ($dependencies as $dependency) { + yield new FileReference($dependency); + } + + $this->processed[] = $file->getRelativePath($root); + + return true; + } + }; + $taskB = new class() implements Task { + /** + * @var array + */ + public array $processed = []; + + /** + * @inheritDoc + */ + #[Override] + public function getExtensions(): array { + return ['*']; + } + + #[Override] + public function __invoke(Directory $root, File $file): bool { + $this->processed[] = $file->getRelativePath($root); + + return true; + } + }; + + $root = Path::normalize(self::getTestData()->path('')); + $count = 0; + $events = []; + + (new Processor()) + ->task($taskA) + ->task($taskB) + ->run( + $root, + ['excluded.txt', '**/**/excluded.txt'], + static function (string $path, Result $result) use (&$count, &$events): void { + $events[$path] = $result; + $count++; + }, + ); + + self::assertEquals( + [ + 'b/a/ba.txt' => Result::Success, + 'c.txt' => Result::Success, + 'b/b/bb.txt' => Result::Success, + 'a/a.txt' => Result::Success, + 'a/a/aa.txt' => Result::Success, + 'a/b/ab.txt' => Result::Success, + 'b/b.txt' => Result::Success, + 'c.htm' => Result::Success, + 'c.html' => Result::Success, + 'a/excluded.txt' => Result::Skipped, + '../../../README.md' => Result::Skipped, + 'a/a.html' => Result::Success, + 'b/b.html' => Result::Success, + ], + $events, + ); + self::assertCount($count, $events); + self::assertEquals( + [ + 'a/a.html', + 'b/b.html', + 'c.html', + ], + $taskA->processed, + ); + self::assertEquals( + [ + 'a/a.html', + 'a/a.txt', + 'a/a/aa.txt', + 'a/b/ab.txt', + 'b/a/ba.txt', + 'b/b.html', + 'b/b.txt', + 'b/b/bb.txt', + 'c.htm', + 'c.html', + 'c.txt', + ], + $taskB->processed, + ); + } + public function testRunFileNotFound(): void { $task = new class() implements Task { /**