Skip to content

Commit

Permalink
Refactor to move fancy output logic to realtime compiler class
Browse files Browse the repository at this point in the history
  • Loading branch information
caendesilva committed Nov 9, 2023
1 parent 5acdb3b commit 99ed9c1
Show file tree
Hide file tree
Showing 2 changed files with 129 additions and 99 deletions.
101 changes: 3 additions & 98 deletions packages/framework/src/Console/Commands/ServeCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,12 @@
use Closure;
use Hyde\Hyde;
use Hyde\Facades\Config;
use Illuminate\Support\Str;
use Illuminate\Support\Carbon;
use Hyde\RealtimeCompiler\ConsoleOutput;
use Illuminate\Support\Facades\Process;
use LaravelZero\Framework\Commands\Command;

use function Termwind\{render};
use function sprintf;
use function class_exists;

/**
* Start the realtime compiler server.
Expand Down Expand Up @@ -69,101 +67,10 @@ protected function printStartMessage(): void
if ($this->useBasicOutput()) {
$this->line('<info>Starting the HydeRC server...</info> Press Ctrl+C to stop');
} else {
$title = 'HydePHP Realtime Compiler';
$version = ' v'.Hyde::version();

$url = sprintf('http://%s:%d', $this->getHostSelection(), $this->getPortSelection());

$width = max(strlen("$title $version"), strlen("Listening on $url") + 1) + 1;
$spacing = str_repeat('&nbsp;', $width);
$lines = str_repeat('', $width);

$line1 = '&nbsp;'.sprintf('<span class="text-blue-500">%s</span>&nbsp;<span class="text-gray">%s</span>', $title, $version).str_repeat('&nbsp;', $width - strlen("$title $version"));
$line2 = '&nbsp;'.sprintf('<span class="text-white">Listening on </span>&nbsp;<a href="%s" class="text-yellow-500">%s</a>', $url, $url).str_repeat('&nbsp;', $width - strlen("Listening on $url") - 1);
render(<<<HTML
<div class="text-green-500">
<br>
&nbsp;╭{$lines}╮<br>
&nbsp;│{$spacing}│<br>
&nbsp;│{$line1}│<br>
&nbsp;│{$spacing}│<br>
&nbsp;│{$line2}│<br>
&nbsp;│{$spacing}│<br>
&nbsp;╰{$lines}
<br>
</div>
HTML);
ConsoleOutput::printStartMessage($this->getHostSelection(), $this->getPortSelection());

Check warning on line 70 in packages/framework/src/Console/Commands/ServeCommand.php

View check run for this annotation

Codecov / codecov/patch

packages/framework/src/Console/Commands/ServeCommand.php#L70

Added line #L70 was not covered by tests
}
}

protected function handleOutput(string $buffer): void
{
str($buffer)->trim()->explode("\n")->each(function (string $line): void {
if (str_contains($line, 'Development Server (http:')) {
$line = $this->formatServerStartedLine($line);
} elseif (str_contains($line, ']: ')) {
$line = $this->formatRequestLine($line);
} elseif (str_ends_with(trim($line), 'Accepted') || str_ends_with(trim($line), 'Closing')) {
if ($this->output->isVerbose()) {
$line = $this->formatRequestStatusLine($line);
} else {
return;
}
} else {
$line = $this->formatLine($line, Carbon::now());
}

render($line);
});
}

protected function formatServerStartedLine(string $line): string
{
return $this->formatLine(sprintf('PHP %s Development Server started. <span class="text-yellow-500">Press Ctrl+C to stop.</span>', PHP_VERSION), $this->parseDate($line));
}

protected function formatRequestLine(string $line): string
{
$dateString = Str::betweenFirst($line, '[', ']');
$message = substr($line, strlen($dateString) + 3);

$statusCode = Str::between($message, ' [', ']:');
if ($statusCode >= 400) {
$message = str_replace($statusCode, sprintf('<span class="text-red-500">%s</span>', $statusCode), $message);
$iconColor = 'yellow-500';
}

return $this->formatLine($message, $this->parseDate($line), $iconColor ?? 'green-500');
}

protected function formatRequestStatusLine(string $line): string
{
$address = trim(Str::between($line, ']', ' '));
$status = str_contains($line, 'Accepted') ? 'Accepted' : 'Closing';

return $this->formatLine(sprintf('%s %s', $address, $status), $this->parseDate($line));
}

protected function formatLine(string $message, Carbon $date, string $iconColor = 'blue-500'): string
{
return sprintf(<<<'HTML'
<div class="flex w-full justify-between">
<span>
<span class="text-%s">i</span>
%s
</span>
<span class="text-gray">%s</span>
</div>
HTML,
$iconColor, $message, $date->format('Y-m-d H:i:s')
);
}

protected function parseDate(string $line): Carbon
{
return Carbon::parse(Str::betweenFirst($line, '[', ']'));
}

protected function getDefaultOutputHandler(): Closure
{
return function (string $type, string $line): void {
Expand All @@ -173,9 +80,7 @@ protected function getDefaultOutputHandler(): Closure

protected function getFancyOutputHandler(): Closure

Check warning on line 81 in packages/framework/src/Console/Commands/ServeCommand.php

View check run for this annotation

Codecov / codecov/patch

packages/framework/src/Console/Commands/ServeCommand.php#L81

Added line #L81 was not covered by tests
{
return function (string $type, string $line): void {
$this->handleOutput($line);
};
return ConsoleOutput::getFormatter($this->output->isVerbose());

Check warning on line 83 in packages/framework/src/Console/Commands/ServeCommand.php

View check run for this annotation

Codecov / codecov/patch

packages/framework/src/Console/Commands/ServeCommand.php#L83

Added line #L83 was not covered by tests
}

protected function useBasicOutput(): bool
Expand Down
127 changes: 126 additions & 1 deletion packages/realtime-compiler/src/ConsoleOutput.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,132 @@

namespace Hyde\RealtimeCompiler;

use Closure;
use Hyde\Hyde;
use Illuminate\Support\Str;
use Illuminate\Support\Carbon;

use function max;
use function str;
use function trim;
use function strlen;
use function substr;
use function sprintf;
use function str_repeat;
use function str_replace;
use function Termwind\render;

class ConsoleOutput
{
//
protected bool $verbose;

public static function printStartMessage(string $host, int $port): void
{
$title = 'HydePHP Realtime Compiler';
$version = ' v'.Hyde::version();

$url = sprintf('http://%s:%d', $host, $port);

$width = max(strlen("$title $version"), strlen("Listening on $url") + 1) + 1;
$spacing = str_repeat('&nbsp;', $width);
$lines = str_repeat('', $width);

$line1 = '&nbsp;'.sprintf('<span class="text-blue-500">%s</span>&nbsp;<span class="text-gray">%s</span>', $title, $version).str_repeat('&nbsp;', $width - strlen("$title $version"));
$line2 = '&nbsp;'.sprintf('<span class="text-white">Listening on </span>&nbsp;<a href="%s" class="text-yellow-500">%s</a>', $url, $url).str_repeat('&nbsp;', $width - strlen("Listening on $url") - 1);
render(<<<HTML
<div class="text-green-500">
<br>
&nbsp;╭{$lines}╮<br>
&nbsp;│{$spacing}│<br>
&nbsp;│{$line1}│<br>
&nbsp;│{$spacing}│<br>
&nbsp;│{$line2}│<br>
&nbsp;│{$spacing}│<br>
&nbsp;╰{$lines}
<br>
</div>
HTML);
}

public static function getFormatter(bool $verbose): Closure
{
$console = (new static($verbose));

return function (string $type, string $line) use ($console): void {
$console->handleOutput($line);
};
}

public function __construct(bool $verbose = false)
{
$this->verbose = $verbose;
}

protected function handleOutput(string $buffer): void
{
str($buffer)->trim()->explode("\n")->each(function (string $line): void {
if (str_contains($line, 'Development Server (http:')) {
$line = $this->formatServerStartedLine($line);
} elseif (str_contains($line, ']: ')) {
$line = $this->formatRequestLine($line);
} elseif (str_ends_with(trim($line), 'Accepted') || str_ends_with(trim($line), 'Closing')) {
if ($this->verbose) {
$line = $this->formatRequestStatusLine($line);
} else {
return;
}
} else {
$line = $this->formatLine($line, Carbon::now());
}

render($line);
});
}

protected function formatServerStartedLine(string $line): string
{
return $this->formatLine(sprintf('PHP %s Development Server started. <span class="text-yellow-500">Press Ctrl+C to stop.</span>', PHP_VERSION), $this->parseDate($line));
}

protected function formatRequestLine(string $line): string
{
$dateString = Str::betweenFirst($line, '[', ']');
$message = substr($line, strlen($dateString) + 3);

$statusCode = Str::between($message, ' [', ']:');
if ($statusCode >= 400) {
$message = str_replace($statusCode, sprintf('<span class="text-red-500">%s</span>', $statusCode), $message);
$iconColor = 'yellow-500';
}

return $this->formatLine($message, $this->parseDate($line), $iconColor ?? 'green-500');
}

protected function formatRequestStatusLine(string $line): string
{
$address = trim(Str::between($line, ']', ' '));
$status = str_contains($line, 'Accepted') ? 'Accepted' : 'Closing';

return $this->formatLine(sprintf('%s %s', $address, $status), $this->parseDate($line));
}

protected function formatLine(string $message, Carbon $date, string $iconColor = 'blue-500'): string
{
return sprintf(<<<'HTML'
<div class="flex w-full justify-between">
<span>
<span class="text-%s">i</span>
%s
</span>
<span class="text-gray">%s</span>
</div>
HTML,
$iconColor, $message, $date->format('Y-m-d H:i:s')
);
}

protected function parseDate(string $line): Carbon
{
return Carbon::parse(Str::betweenFirst($line, '[', ']'));
}
}

0 comments on commit 99ed9c1

Please sign in to comment.