Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 13 additions & 11 deletions src/Console/GenerateCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Butschster\ContextGenerator\Application\AppScope;
use Butschster\ContextGenerator\Config\ConfigurationProvider;
use Butschster\ContextGenerator\Config\Exception\ConfigLoaderException;
use Butschster\ContextGenerator\Console\Renderer\GenerateCommandRenderer;
use Butschster\ContextGenerator\DirectoriesInterface;
use Butschster\ContextGenerator\Document\Compiler\DocumentCompiler;
use Spiral\Console\Attribute\Option;
Expand Down Expand Up @@ -64,13 +65,13 @@ public function __invoke(Container $container, DirectoriesInterface $dirs): int
try {
// Get the appropriate loader based on options provided
if ($this->inlineJson !== null) {
$this->output->info('Using inline JSON configuration...');
$this->logger->info('Using inline JSON configuration...');
$loader = $configProvider->fromString($this->inlineJson);
} elseif ($this->configPath !== null) {
$this->output->info(\sprintf('Loading configuration from %s...', $this->configPath));
$this->logger->info(\sprintf('Loading configuration from %s...', $this->configPath));
$loader = $configProvider->fromPath($this->configPath);
} else {
$this->output->info('Loading configuration from default location...');
$this->logger->info('Loading configuration from default location...');
$loader = $configProvider->fromDefaultLocation();
}
} catch (ConfigLoaderException $e) {
Expand All @@ -83,19 +84,20 @@ public function __invoke(Container $container, DirectoriesInterface $dirs): int
return Command::FAILURE;
}

// Create the renderer for consistent output formatting
$renderer = new GenerateCommandRenderer($this->output);

// Display summary header
$this->output->writeln('');

foreach ($loader->load()->getItems() as $document) {
$this->output->info(\sprintf('Compiling %s...', $document->description));
$this->logger->info(\sprintf('Compiling %s...', $document->description));

$compiledDocument = $compiler->compile($document);
if (!$compiledDocument->errors->hasErrors()) {
$this->output->success(\sprintf('Document compiled into %s', $document->outputPath));
continue;
}

$this->output->warning(\sprintf('Document compiled into %s with errors', $document->outputPath));
$this->output->listing(\iterator_to_array($compiledDocument->errors));
$renderer->renderCompilationResult($document, $compiledDocument);
}

$this->output->writeln('');
return Command::SUCCESS;
},
);
Expand Down
105 changes: 105 additions & 0 deletions src/Console/Renderer/GenerateCommandRenderer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
<?php

declare(strict_types=1);

namespace Butschster\ContextGenerator\Console\Renderer;

use Butschster\ContextGenerator\Document\Compiler\CompiledDocument;
use Butschster\ContextGenerator\Document\Document;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;

/**
* Renderer for the generate command output
*/
final readonly class GenerateCommandRenderer
{
/**
* Maximum line width for consistent display
*/
private const int MAX_LINE_WIDTH = 120;

/**
* Success indicator symbol
*/
private const string SUCCESS_SYMBOL = '✓';

/**
* Warning indicator symbol
*/
private const string WARNING_SYMBOL = '!';

/**
* Error indicator symbol
*/
private const string ERROR_SYMBOL = '✗';

public function __construct(
private OutputInterface $output,
) {}

/**
* Render the compilation result for a document
*/
public function renderCompilationResult(Document $document, CompiledDocument $compiledDocument): void
{
\assert($this->output instanceof SymfonyStyle);

$hasErrors = $compiledDocument->errors->hasErrors();
$description = $document->description;
$outputPath = $document->outputPath;

// Calculate padding to align the document descriptions
$padding = $this->calculatePadding($description, $outputPath);

if ($hasErrors) {
// Render warning line with document info
$this->output->writeln(
\sprintf(
' <fg=yellow>%s</> %s <fg=yellow>[%s]</><fg=gray>%s</>',
$this->padRight(self::WARNING_SYMBOL, 1),
$description,
$outputPath,
$padding,
),
);

// Render errors
foreach ($compiledDocument->errors as $error) {
$this->output->writeln(\sprintf(' <fg=red>%s</> %s', self::ERROR_SYMBOL, $error));
}

$this->output->newLine();
} else {
// Render success line with document info
$this->output->writeln(
\sprintf(
' <fg=green>%s</> %s <fg=cyan>[%s]</><fg=gray>%s</>',
$this->padRight(self::SUCCESS_SYMBOL, 2),
$description,
$outputPath,
$padding,
),
);
}
}

/**
* Calculate padding to align the document information
*/
private function calculatePadding(string $description, string $outputPath): string
{
$totalLength = \strlen($description) + \strlen($outputPath) + 5; // 5 accounts for spaces and brackets
$padding = \max(0, self::MAX_LINE_WIDTH - $totalLength);

return \str_repeat('.', $padding);
}

/**
* Pad a string on the right with spaces
*/
private function padRight(string $text, int $length): string
{
return \str_pad($text, $length, ' ', \STR_PAD_RIGHT);
}
}
Loading