Skip to content

Commit

Permalink
Merge pull request #1450 from hydephp/pass-through-settings-to-realti…
Browse files Browse the repository at this point in the history
…me-compiler

Pass through settings to realtime compiler
  • Loading branch information
caendesilva authored Nov 12, 2023
2 parents dfdc1dd + 1b4b1a8 commit 0594ddc
Show file tree
Hide file tree
Showing 9 changed files with 453 additions and 57 deletions.
58 changes: 48 additions & 10 deletions packages/framework/src/Console/Commands/ServeCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,12 @@
use Closure;
use Hyde\Hyde;
use Hyde\Facades\Config;
use Illuminate\Support\Arr;
use InvalidArgumentException;
use Hyde\RealtimeCompiler\ConsoleOutput;
use Illuminate\Support\Facades\Process;
use LaravelZero\Framework\Commands\Command;
use Hyde\Publications\Commands\ValidatingCommand;

use function sprintf;
use function class_exists;
Expand All @@ -19,20 +22,24 @@
*
* @see https://github.com/hydephp/realtime-compiler
*/
class ServeCommand extends Command
class ServeCommand extends ValidatingCommand
{
/** @var string */
protected $signature = 'serve
{--host= : <comment>[default: "localhost"]</comment>}}
{--port= : <comment>[default: 8080]</comment>}
{--save-preview= : Should the served page be saved to disk? (Overrides config setting)}
{--dashboard= : Enable the realtime compiler dashboard. (Overrides config setting)}
{--pretty-urls= : Enable pretty URLs. (Overrides config setting)}
{--play-cdn= : Enable the Tailwind Play CDN. (Overrides config setting)}
';

/** @var string */
protected $description = 'Start the realtime compiler server.';

protected ConsoleOutput $console;

public function handle(): int
public function safeHandle(): int
{
$this->configureOutput();
$this->printStartMessage();
Expand All @@ -46,14 +53,14 @@ public function handle(): int
return Command::SUCCESS;
}

protected function getPortSelection(): int
protected function getHostSelection(): string
{
return (int) ($this->option('port') ?: Config::getInt('hyde.server.port', 8080));
return (string) $this->option('host') ?: Config::getString('hyde.server.host', 'localhost');
}

protected function getHostSelection(): string
protected function getPortSelection(): int
{
return (string) $this->option('host') ?: Config::getString('hyde.server.host', 'localhost');
return (int) ($this->option('port') ?: Config::getInt('hyde.server.port', 8080));
}

protected function getExecutablePath(): string
Expand All @@ -68,9 +75,13 @@ protected function runServerProcess(string $command): void

protected function getEnvironmentVariables(): array
{
return [
'HYDE_RC_REQUEST_OUTPUT' => ! $this->option('no-ansi'),
];
return Arr::whereNotNull([
'HYDE_SERVER_REQUEST_OUTPUT' => ! $this->option('no-ansi'),
'HYDE_SERVER_SAVE_PREVIEW' => $this->parseEnvironmentOption('save-preview'),
'HYDE_SERVER_DASHBOARD' => $this->parseEnvironmentOption('dashboard'),
'HYDE_PRETTY_URLS' => $this->parseEnvironmentOption('pretty-urls'),
'HYDE_PLAY_CDN' => $this->parseEnvironmentOption('play-cdn'),
]);
}

protected function configureOutput(): void
Expand All @@ -84,7 +95,7 @@ protected function printStartMessage(): void
{
$this->useBasicOutput()
? $this->output->writeln('<info>Starting the HydeRC server...</info> Press Ctrl+C to stop')
: $this->console->printStartMessage($this->getHostSelection(), $this->getPortSelection());
: $this->console->printStartMessage($this->getHostSelection(), $this->getPortSelection(), $this->getEnvironmentVariables());
}

protected function getOutputHandler(): Closure
Expand All @@ -98,4 +109,31 @@ protected function useBasicOutput(): bool
{
return $this->option('no-ansi') || ! class_exists(ConsoleOutput::class);
}

protected function parseEnvironmentOption(string $name): ?string
{
$value = $this->option($name) ?? $this->checkArgvForOption($name);

if ($value !== null) {
return match ($value) {
'true', '' => 'enabled',
'false' => 'disabled',
default => throw new InvalidArgumentException(sprintf('Invalid boolean value for --%s option.', $name))
};
}

return null;
}

/** Fallback check so that an environment option without a value is acknowledged as true. */
protected function checkArgvForOption(string $name): ?string
{
if (isset($_SERVER['argv'])) {
if (in_array("--$name", $_SERVER['argv'], true)) {
return 'true';
}
}

return null;
}
}
51 changes: 38 additions & 13 deletions packages/framework/src/Foundation/Internal/LoadConfiguration.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@

use Phar;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Contracts\Config\Repository as RepositoryContract;
use Illuminate\Contracts\Config\Repository;
use Illuminate\Foundation\Bootstrap\LoadConfiguration as BaseLoadConfiguration;

use function getenv;
use function array_merge;
use function dirname;
use function in_array;
Expand All @@ -30,7 +31,7 @@ protected function getConfigurationFiles(Application $app): array
}

/** Load the configuration items from all the files. */
protected function loadConfigurationFiles(Application $app, RepositoryContract $repository): void
protected function loadConfigurationFiles(Application $app, Repository $repository): void
{
parent::loadConfigurationFiles($app, $repository);

Expand All @@ -39,7 +40,7 @@ protected function loadConfigurationFiles(Application $app, RepositoryContract $
$this->loadRuntimeConfiguration($app, $repository);
}

private function mergeConfigurationFiles(RepositoryContract $repository): void
private function mergeConfigurationFiles(Repository $repository): void
{
// These files do commonly not need to be customized by the user, so to get them out of the way,
// we don't include them in the default project install.
Expand All @@ -49,7 +50,7 @@ private function mergeConfigurationFiles(RepositoryContract $repository): void
}
}

private function mergeConfigurationFile(RepositoryContract $repository, string $file): void
private function mergeConfigurationFile(Repository $repository, string $file): void
{
// We of course want the user to be able to customize the config files,
// if they're present, so we'll merge their changes here.
Expand Down Expand Up @@ -78,18 +79,42 @@ private static function providePharSupportIfNeeded(array &$files): void
}
}

private function loadRuntimeConfiguration(Application $app, RepositoryContract $repository): void
private function loadRuntimeConfiguration(Application $app, Repository $repository): void
{
if ($app->runningInConsole() && isset($_SERVER['argv'])) {
// Check if the `--pretty-urls` CLI argument is set, and if so, set the config value accordingly.
if (in_array('--pretty-urls', $_SERVER['argv'], true)) {
$repository->set('hyde.pretty_urls', true);
if ($app->runningInConsole()) {
if ($this->getArgv() !== null) {
$this->mergeCommandLineArguments($repository, '--pretty-urls', 'hyde.pretty_urls', true);
$this->mergeCommandLineArguments($repository, '--no-api', 'hyde.api_calls', false);
}

// Check if the `--no-api` CLI argument is set, and if so, set the config value accordingly.
if (in_array('--no-api', $_SERVER['argv'], true)) {
$repository->set('hyde.api_calls', false);
}
$this->mergeRealtimeCompilerEnvironment($repository, 'HYDE_SERVER_SAVE_PREVIEW', 'hyde.server.save_preview');
$this->mergeRealtimeCompilerEnvironment($repository, 'HYDE_SERVER_DASHBOARD', 'hyde.server.dashboard.enabled');
$this->mergeRealtimeCompilerEnvironment($repository, 'HYDE_PRETTY_URLS', 'hyde.pretty_urls');
$this->mergeRealtimeCompilerEnvironment($repository, 'HYDE_PLAY_CDN', 'hyde.use_play_cdn');
}
}

private function mergeCommandLineArguments(Repository $repository, string $argumentName, string $configKey, bool $value): void
{
if (in_array($argumentName, $this->getArgv(), true)) {
$repository->set($configKey, $value);
}
}

private function mergeRealtimeCompilerEnvironment(Repository $repository, string $environmentKey, string $configKey): void
{
if ($this->getEnv($environmentKey) !== false) {
$repository->set($configKey, $this->getEnv($environmentKey) === 'enabled');
}
}

protected function getArgv(): ?array
{
return $_SERVER['argv'] ?? null;
}

protected function getEnv(string $name): string|false|null
{
return getenv($name);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@

/**
* @covers \Hyde\Console\Commands\ServeCommand
*
* @see \Hyde\Framework\Testing\Unit\ServeCommandOptionsUnitTest
*/
class ServeCommandTest extends TestCase
{
Expand Down Expand Up @@ -144,7 +146,7 @@ public function test_hyde_serve_command_passes_through_process_output()

Process::shouldReceive('env')
->once()
->with(['HYDE_RC_REQUEST_OUTPUT' => false])
->with(['HYDE_SERVER_REQUEST_OUTPUT' => false])
->andReturnSelf();

Process::shouldReceive('run')
Expand Down
51 changes: 43 additions & 8 deletions packages/framework/tests/Unit/LoadConfigurationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,57 @@ class LoadConfigurationTest extends UnitTestCase
{
public function testItLoadsRuntimeConfiguration()
{
$serverBackup = $_SERVER;
$app = new Application(getcwd());

$_SERVER['argv'] = ['--pretty-urls', '--no-api'];
$loader = new LoadConfigurationTestClass([]);
$loader->bootstrap($app);

$app = new Application(getcwd());
$this->assertFalse(config('hyde.pretty_urls'));
$this->assertNull(config('hyde.api_calls'));

$loader = new LoadConfiguration();
$loader = new LoadConfigurationTestClass(['--pretty-urls', '--no-api']);
$loader->bootstrap($app);

$this->assertTrue(config('hyde.pretty_urls'));
$this->assertFalse(config('hyde.api_calls'));
}

public function testItLoadsRealtimeCompilerEnvironmentConfiguration()
{
(new LoadConfigurationEnvironmentTestClass(['HYDE_SERVER_DASHBOARD' => 'enabled']))->bootstrap(new Application(getcwd()));
$this->assertTrue(config('hyde.server.dashboard.enabled'));

$_SERVER = $serverBackup;
(new LoadConfigurationEnvironmentTestClass(['HYDE_SERVER_DASHBOARD' => 'disabled']))->bootstrap(new Application(getcwd()));
$this->assertFalse(config('hyde.server.dashboard.enabled'));
}
}

$loader->bootstrap($app);
$this->assertFalse(config('hyde.pretty_urls'));
$this->assertNull(config('hyde.api_calls'));
class LoadConfigurationTestClass extends LoadConfiguration
{
protected array $argv;

public function __construct(array $argv)
{
$this->argv = $argv;
}

protected function getArgv(): ?array
{
return $this->argv;
}
}

class LoadConfigurationEnvironmentTestClass extends LoadConfiguration
{
protected array $env;

public function __construct(array $env)
{
$this->env = $env;
}

protected function getEnv(string $name): string|false|null
{
return $this->env[$name];
}
}
Loading

0 comments on commit 0594ddc

Please sign in to comment.