From 09065940154f2fb40e7b8b8ce1ea54797876556f Mon Sep 17 00:00:00 2001 From: Renan Medina Date: Fri, 3 Apr 2026 20:36:29 -0300 Subject: [PATCH 1/3] feat: Allow override of host for dev server up --- packages/dev-server/config/dev.php | 1 + .../dev-server/src/Command/DevUpCommand.php | 3 ++- .../tests/Command/DevUpCommandTest.php | 17 ++++++++++++++--- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/packages/dev-server/config/dev.php b/packages/dev-server/config/dev.php index b39eb52..3af2b69 100644 --- a/packages/dev-server/config/dev.php +++ b/packages/dev-server/config/dev.php @@ -4,6 +4,7 @@ return [ 'port' => 8000, + 'host' => 'localhost', 'detach' => true, 'docker' => true, 'frontend' => true, diff --git a/packages/dev-server/src/Command/DevUpCommand.php b/packages/dev-server/src/Command/DevUpCommand.php index 56945e1..8d3f81a 100644 --- a/packages/dev-server/src/Command/DevUpCommand.php +++ b/packages/dev-server/src/Command/DevUpCommand.php @@ -42,6 +42,7 @@ public function execute( ): int { $port = (int) ($input->getOption('port') ?? $input->getOption('p') ?? $this->config->getInt('dev.port')); $foreground = $input->hasOption('foreground') || $input->hasOption('f'); + $host = $input->getOption('host') ?? $input->getOption('h') ?? $this->config->getString('dev.host'); $detach = !$foreground && ($input->hasOption('detach') || $input->hasOption('d') || $this->config->getBool( 'dev.detach', )); @@ -156,7 +157,7 @@ public function execute( } // PHP server (always) — multiple workers needed for SSE - $phpCommand = "env PHP_CLI_SERVER_WORKERS=4 php -S localhost:$port -t public/"; + $phpCommand = "env PHP_CLI_SERVER_WORKERS=4 php -S $host:$port -t public/"; $output->writeLine(" Starting PHP server: php -S localhost:$port"); $pid = $startProcess('php', $phpCommand); diff --git a/packages/dev-server/tests/Command/DevUpCommandTest.php b/packages/dev-server/tests/Command/DevUpCommandTest.php index 10f52da..27dc2e9 100644 --- a/packages/dev-server/tests/Command/DevUpCommandTest.php +++ b/packages/dev-server/tests/Command/DevUpCommandTest.php @@ -87,6 +87,7 @@ function createDevUpCommand( $configDefaults = [ 'dev.port' => 8000, + 'dev.host' => 'localhost', 'dev.docker' => false, 'dev.frontend' => false, 'dev.pubsub' => false, @@ -150,6 +151,16 @@ function readStream(mixed $stream): string expect($pm->started['php'])->toContain('localhost:7500'); }); +it('reads host from config', function (): void { + ['command' => $command, 'processManager' => $pm] = createDevUpCommand(['host' => '0.0.0.0']); + ['output' => $output] = createMemoryOutput(); + + $input = new Input(['marko', 'dev:up']); + $command->execute($input, $output); + + expect($pm->started['php'])->toContain('0.0.0.0:8000'); +}); + it('reads docker setting from config', function (): void { ['command' => $command, 'processManager' => $pm] = createDevUpCommand([ 'dev.docker' => 'custom-docker-up', @@ -520,7 +531,7 @@ function readStream(mixed $stream): string $command->execute($input, $output); $entries = $pidFile->read(); - $names = array_map(fn ($e) => $e->name, $entries); + $names = array_map(fn($e) => $e->name, $entries); expect($names)->toContain('tailwind') ->and($names)->toContain('php'); @@ -544,7 +555,7 @@ function readStream(mixed $stream): string }); it('starts pubsub:listen as managed process in DevUpCommand when detected', function (): void { - $pubsubDetector = new class () extends PubSubDetector + $pubsubDetector = new class() extends PubSubDetector { protected function isPubSubInstalled(): bool { @@ -773,7 +784,7 @@ protected function isPubSubInstalled(): bool }); it('skips pubsub process when pubsub config is false', function (): void { - $pubsubDetector = new class () extends PubSubDetector + $pubsubDetector = new class() extends PubSubDetector { protected function isPubSubInstalled(): bool { From 010ba9d7bddb012364210857f477a50e07c47df8 Mon Sep 17 00:00:00 2001 From: Renan Medina Date: Fri, 3 Apr 2026 20:45:01 -0300 Subject: [PATCH 2/3] feat(dev-server): improve test coverage and php serve command --- packages/dev-server/src/Command/DevUpCommand.php | 4 ++-- .../dev-server/tests/Command/DevUpCommandTest.php | 15 +++++++++++++-- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/packages/dev-server/src/Command/DevUpCommand.php b/packages/dev-server/src/Command/DevUpCommand.php index 8d3f81a..9e919f6 100644 --- a/packages/dev-server/src/Command/DevUpCommand.php +++ b/packages/dev-server/src/Command/DevUpCommand.php @@ -157,8 +157,8 @@ public function execute( } // PHP server (always) — multiple workers needed for SSE - $phpCommand = "env PHP_CLI_SERVER_WORKERS=4 php -S $host:$port -t public/"; - $output->writeLine(" Starting PHP server: php -S localhost:$port"); + $phpCommand = "env PHP_CLI_SERVER_WORKERS=4 php -S {$host}:{$port} -t public/"; + $output->writeLine(" Starting PHP server: php -S {$host}:{$port}"); $pid = $startProcess('php', $phpCommand); // In foreground mode, verify PHP server is alive — if it died, port is likely in use. diff --git a/packages/dev-server/tests/Command/DevUpCommandTest.php b/packages/dev-server/tests/Command/DevUpCommandTest.php index 27dc2e9..ffc4709 100644 --- a/packages/dev-server/tests/Command/DevUpCommandTest.php +++ b/packages/dev-server/tests/Command/DevUpCommandTest.php @@ -152,13 +152,13 @@ function readStream(mixed $stream): string }); it('reads host from config', function (): void { - ['command' => $command, 'processManager' => $pm] = createDevUpCommand(['host' => '0.0.0.0']); + ['command' => $command, 'processManager' => $pm] = createDevUpCommand(['dev.host' => '127.0.0.1']); ['output' => $output] = createMemoryOutput(); $input = new Input(['marko', 'dev:up']); $command->execute($input, $output); - expect($pm->started['php'])->toContain('0.0.0.0:8000'); + expect($pm->started['php'])->toContain('127.0.0.1:8000'); }); it('reads docker setting from config', function (): void { @@ -428,6 +428,17 @@ function readStream(mixed $stream): string expect($pm->started['php'])->toContain('localhost:9000'); }); +it('overrides config port with -h short flag', function (): void { + ['command' => $command, 'processManager' => $pm] = createDevUpCommand(['dev.host' => 'localhost']); + ['output' => $output] = createMemoryOutput(); + + $input = new Input(['marko', 'dev:up', '-h=0.0.0.0']); + $command->execute($input, $output); + + expect($pm->started['php'])->toContain('0.0.0.0:8000'); +}); + + it('overrides config port with -p space syntax', function (): void { ['command' => $command, 'processManager' => $pm] = createDevUpCommand(['dev.port' => 8000]); ['output' => $output] = createMemoryOutput(); From 6020b64f0f0a122cd2abfc92cb1fa4c51578f623 Mon Sep 17 00:00:00 2001 From: Renan Medina Date: Fri, 3 Apr 2026 21:30:12 -0300 Subject: [PATCH 3/3] test(dev-server): Fixing DebvUpCommandTest to reuse default configs when possible --- .../tests/Command/DevUpCommandTest.php | 55 ++++++------------- 1 file changed, 16 insertions(+), 39 deletions(-) diff --git a/packages/dev-server/tests/Command/DevUpCommandTest.php b/packages/dev-server/tests/Command/DevUpCommandTest.php index ffc4709..ea41b32 100644 --- a/packages/dev-server/tests/Command/DevUpCommandTest.php +++ b/packages/dev-server/tests/Command/DevUpCommandTest.php @@ -59,6 +59,16 @@ public function runForeground(): void } } +const CONFIG_DEFAULTS = [ + 'dev.port' => 8000, + 'dev.host' => 'localhost', + 'dev.docker' => false, + 'dev.frontend' => false, + 'dev.pubsub' => false, + 'dev.detach' => true, + 'dev.processes' => [], +]; + /** * Helper to create a DevUpCommand with standard test dependencies. * @@ -85,16 +95,7 @@ function createDevUpCommand( file_put_contents($dir . '/public/index.php', ' 8000, - 'dev.host' => 'localhost', - 'dev.docker' => false, - 'dev.frontend' => false, - 'dev.pubsub' => false, - 'dev.detach' => true, - 'dev.processes' => [], - ]; - $fakeConfig = new FakeConfigRepository(array_merge($configDefaults, $config)); + $fakeConfig = new FakeConfigRepository(array_merge(CONFIG_DEFAULTS, $config)); $dockerDetector = new DockerDetector($dir); $frontendDetector = new FrontendDetector($dir); @@ -592,14 +593,7 @@ protected function isPubSubInstalled(): bool mkdir($dir, 0755, true); // Deliberately no public/index.php created - $fakeConfig = new FakeConfigRepository([ - 'dev.port' => 8000, - 'dev.docker' => false, - 'dev.frontend' => false, - 'dev.pubsub' => false, - 'dev.detach' => false, - 'dev.processes' => [], - ]); + $fakeConfig = new FakeConfigRepository(CONFIG_DEFAULTS); $command = new DevUpCommand( config: $fakeConfig, dockerDetector: new DockerDetector($dir), @@ -619,14 +613,7 @@ protected function isPubSubInstalled(): bool $dir = sys_get_temp_dir() . '/marko-no-index-msg-' . uniqid(); mkdir($dir, 0755, true); - $fakeConfig = new FakeConfigRepository([ - 'dev.port' => 8000, - 'dev.docker' => false, - 'dev.frontend' => false, - 'dev.pubsub' => false, - 'dev.detach' => false, - 'dev.processes' => [], - ]); + $fakeConfig = new FakeConfigRepository(CONFIG_DEFAULTS); $command = new DevUpCommand( config: $fakeConfig, dockerDetector: new DockerDetector($dir), @@ -654,14 +641,11 @@ protected function isPubSubInstalled(): bool $dir = sys_get_temp_dir() . '/marko-no-index-proc-' . uniqid(); mkdir($dir, 0755, true); - $fakeConfig = new FakeConfigRepository([ - 'dev.port' => 8000, + $fakeConfig = new FakeConfigRepository(array_merge(CONFIG_DEFAULTS, [ 'dev.docker' => 'docker compose up', 'dev.frontend' => 'yarn dev', - 'dev.pubsub' => false, 'dev.detach' => false, - 'dev.processes' => [], - ]); + ])); $pm = new FakeProcessManager(); $command = new DevUpCommand( config: $fakeConfig, @@ -690,14 +674,7 @@ protected function isPubSubInstalled(): bool mkdir($dir . '/public', 0755, true); file_put_contents($dir . '/public/index.php', ' 8000, - 'dev.docker' => false, - 'dev.frontend' => false, - 'dev.pubsub' => false, - 'dev.detach' => false, - 'dev.processes' => [], - ]); + $fakeConfig = new FakeConfigRepository(CONFIG_DEFAULTS); $pm = new FakeProcessManager(); $command = new DevUpCommand( config: $fakeConfig,