Skip to content

Commit

Permalink
[TASK] Improve progress bar
Browse files Browse the repository at this point in the history
* Display a progress bar during parsing
* Display one progress bar per renderer
* Introduce an event once the files have been collected for parsing

This gives me progress bars like this after rendering:

Parsing: 16/16 [============================] 100% Parsed 16 files in 0.98 seconds
Rendering: 16/16 [============================] 100% Output format html: Rendered 16 documents in 0.71 seconds
Rendering: 16/16 [============================] 100% Output format interlink: Rendered 16 documents in 0.00 seconds

During rendering and during parsing the currently handled file is displayed.
  • Loading branch information
linawolf committed Dec 31, 2023
1 parent 9d860d2 commit 243d49b
Show file tree
Hide file tree
Showing 7 changed files with 156 additions and 19 deletions.
97 changes: 87 additions & 10 deletions packages/guides-cli/src/Command/Run.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,14 @@
use Monolog\Logger;
use phpDocumentor\Guides\Cli\Logger\SpyProcessor;
use phpDocumentor\Guides\Compiler\CompilerContext;
use phpDocumentor\Guides\Event\PostCollectFilesForParsingEvent;
use phpDocumentor\Guides\Event\PostParseDocument;
use phpDocumentor\Guides\Event\PostParseProcess;
use phpDocumentor\Guides\Event\PostRenderDocument;
use phpDocumentor\Guides\Event\PostRenderProcess;
use phpDocumentor\Guides\Event\PreParseDocument;
use phpDocumentor\Guides\Event\PreRenderDocument;
use phpDocumentor\Guides\Event\PreRenderProcess;
use phpDocumentor\Guides\Handlers\CompileDocumentsCommand;
use phpDocumentor\Guides\Handlers\ParseDirectoryCommand;
use phpDocumentor\Guides\Handlers\ParseFileCommand;
Expand All @@ -39,6 +46,7 @@
use function implode;
use function is_countable;
use function is_dir;
use function microtime;
use function pathinfo;
use function realpath;
use function sprintf;
Expand Down Expand Up @@ -117,6 +125,80 @@ public function __construct(
);
}

public function registerProgressBar(ConsoleOutputInterface $output): void
{
$parsingProgressBar = new ProgressBar($output->section());
$parsingProgressBar->setFormat('Parsing: %current%/%max% [%bar%] %percent:3s%% %message%');
$parsingStartTime = microtime(true);
$this->eventDispatcher->addListener(
PostCollectFilesForParsingEvent::class,
static function (PostCollectFilesForParsingEvent $event) use ($parsingProgressBar, &$parsingStartTime): void {
// Each File needs to be first parsed then rendered
$parsingStartTime = microtime(true);
$parsingProgressBar->setMaxSteps(count($event->getFiles()));
},
);
$this->eventDispatcher->addListener(
PreParseDocument::class,
static function (PreParseDocument $event) use ($parsingProgressBar): void {
$parsingProgressBar->setMessage('Parsing file: ' . $event->getFileName());
$parsingProgressBar->display();
},
);
$this->eventDispatcher->addListener(
PostParseDocument::class,
static function (PostParseDocument $event) use ($parsingProgressBar): void {
$parsingProgressBar->advance();
},
);
$this->eventDispatcher->addListener(
PostParseProcess::class,
static function (PostParseProcess $event) use ($parsingProgressBar, $parsingStartTime): void {
$parsingTimeElapsed = microtime(true) - $parsingStartTime;
$parsingProgressBar->setMessage(sprintf(
'Parsed %s files in %.2f seconds',
$parsingProgressBar->getMaxSteps(),
$parsingTimeElapsed,
));
$parsingProgressBar->finish();
},
);
$that = $this;
$this->eventDispatcher->addListener(
PreRenderProcess::class,
static function (PreRenderProcess $event) use ($that, $output): void {
$renderingProgressBar = new ProgressBar($output->section(), count($event->getCommand()->getDocumentArray()));
$renderingProgressBar->setFormat('Rendering: %current%/%max% [%bar%] %percent:3s%% Output format ' . $event->getCommand()->getOutputFormat() . ': %message%');
$renderingStartTime = microtime(true);
$that->eventDispatcher->addListener(
PreRenderDocument::class,
static function (PreRenderDocument $event) use ($renderingProgressBar): void {
$renderingProgressBar->setMessage('Rendering: ' . $event->getCommand()->getFileDestination());
$renderingProgressBar->display();
},
);
$that->eventDispatcher->addListener(
PostRenderDocument::class,
static function (PostRenderDocument $event) use ($renderingProgressBar): void {
$renderingProgressBar->advance();
},
);
$that->eventDispatcher->addListener(
PostRenderProcess::class,
static function (PostRenderProcess $event) use ($renderingProgressBar, $renderingStartTime): void {
$renderingElapsedTime = microtime(true) - $renderingStartTime;
$renderingProgressBar->setMessage(sprintf(
'Rendered %s documents in %.2f seconds',
$renderingProgressBar->getMaxSteps(),
$renderingElapsedTime,
));
$renderingProgressBar->finish();
},
);
},
);
}

private function getSettingsOverridenWithInput(InputInterface $input): ProjectSettings
{
$settings = $this->settingsManager->getProjectSettings();
Expand Down Expand Up @@ -200,6 +282,11 @@ protected function execute(InputInterface $input, OutputInterface $output): int

$documents = [];


if ($output instanceof ConsoleOutputInterface && $settings->isShowProgressBar()) {
$this->registerProgressBar($output);
}

if ($settings->getInputFile() === '') {
$documents = $this->commandBus->handle(
new ParseDirectoryCommand(
Expand Down Expand Up @@ -231,16 +318,6 @@ protected function execute(InputInterface $input, OutputInterface $output): int

$outputFormats = $settings->getOutputFormats();

if ($output instanceof ConsoleOutputInterface && $settings->isShowProgressBar()) {
$progressBar = new ProgressBar($output->section(), count($documents));
$this->eventDispatcher->addListener(
PostRenderDocument::class,
static function (PostRenderDocument $event) use ($progressBar): void {
$progressBar->advance();
},
);
}

foreach ($outputFormats as $format) {
$this->commandBus->handle(
new RenderCommand(
Expand Down
38 changes: 38 additions & 0 deletions packages/guides/src/Event/PostCollectFilesForParsingEvent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

declare(strict_types=1);

namespace phpDocumentor\Guides\Event;

use phpDocumentor\Guides\Files;
use phpDocumentor\Guides\Handlers\ParseDirectoryCommand;

/**
* This event is called after all files have been collected for parsing
* But before the actual parsing begins.
*
* It can be used to manipulate the files to be parsed.
*/
final class PostCollectFilesForParsingEvent
{
public function __construct(
private readonly ParseDirectoryCommand $command,
private Files $files,
) {
}

public function getCommand(): ParseDirectoryCommand
{
return $this->command;
}

public function getFiles(): Files
{
return $this->files;
}

public function setFiles(Files $files): void
{
$this->files = $files;
}
}
6 changes: 4 additions & 2 deletions packages/guides/src/Event/PostRenderDocument.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@
final class PostRenderDocument
{
/** @param NodeRenderer<DocumentNode> $renderer */
public function __construct(private readonly NodeRenderer $renderer, private readonly RenderDocumentCommand $command)
{
public function __construct(
private readonly NodeRenderer $renderer,
private readonly RenderDocumentCommand $command,
) {
}

/** @return NodeRenderer<DocumentNode> */
Expand Down
11 changes: 9 additions & 2 deletions packages/guides/src/Event/PreRenderProcess.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@ final class PreRenderProcess
{
private bool $exitRendering = false;

public function __construct(private readonly RenderCommand $command)
{
public function __construct(
private readonly RenderCommand $command,
private readonly int $steps = 1,
) {
}

public function getCommand(): RenderCommand
Expand All @@ -37,4 +39,9 @@ public function setExitRendering(bool $exitRendering): PreRenderProcess

return $this;
}

public function getSteps(): int
{
return $this->steps;
}
}
9 changes: 8 additions & 1 deletion packages/guides/src/Files.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,15 @@
namespace phpDocumentor\Guides;

use ArrayIterator;
use Countable;
use Iterator;
use IteratorAggregate;

use function count;
use function in_array;

/** @implements IteratorAggregate<string> */
final class Files implements IteratorAggregate
final class Files implements IteratorAggregate, Countable
{
/** @var string[] */
private array $files = [];
Expand All @@ -39,4 +41,9 @@ public function getIterator(): Iterator
{
return new ArrayIterator($this->files);
}

public function count(): int
{
return count($this->files);
}
}
12 changes: 9 additions & 3 deletions packages/guides/src/Handlers/ParseDirectoryHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use InvalidArgumentException;
use League\Flysystem\FilesystemInterface;
use League\Tactician\CommandBus;
use phpDocumentor\Guides\Event\PostCollectFilesForParsingEvent;
use phpDocumentor\Guides\Event\PostParseProcess;
use phpDocumentor\Guides\Event\PreParseProcess;
use phpDocumentor\Guides\FileCollector;
Expand Down Expand Up @@ -47,18 +48,23 @@ public function handle(ParseDirectoryCommand $command): array
);

$files = $this->fileCollector->collect($origin, $currentDirectory, $extension);

$postCollectFilesForParsingEvent = $this->eventDispatcher->dispatch(
new PostCollectFilesForParsingEvent($command, $files),
);
assert($postCollectFilesForParsingEvent instanceof PostCollectFilesForParsingEvent);
/** @var DocumentNode[] $documents */
$documents = [];
foreach ($files as $file) {
foreach ($postCollectFilesForParsingEvent->getFiles() as $file) {
$documents[] = $this->commandBus->handle(
new ParseFileCommand($origin, $currentDirectory, $file, $extension, 1, $command->getProjectNode(), $indexName === $file),
);
}

$postParseProcessEvent = $this->eventDispatcher->dispatch(
$postCollectFilesForParsingEvent = $this->eventDispatcher->dispatch(
new PostParseProcess($command, $documents),
);
assert($postParseProcessEvent instanceof PostParseProcess);
assert($postCollectFilesForParsingEvent instanceof PostParseProcess);

return $documents;
}
Expand Down
2 changes: 1 addition & 1 deletion phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ parameters:

-
message: "#^Parameter \\#1 \\$value of function count expects array\\|Countable, mixed given\\.$#"
count: 2
count: 1
path: packages/guides-cli/src/Command/Run.php

-
Expand Down

0 comments on commit 243d49b

Please sign in to comment.