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..9e919f6 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,8 +157,8 @@ public function execute( } // PHP server (always) — multiple workers needed for SSE - $phpCommand = "env PHP_CLI_SERVER_WORKERS=4 php -S localhost:$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 10f52da..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,15 +95,7 @@ function createDevUpCommand( file_put_contents($dir . '/public/index.php', ' 8000, - '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); @@ -150,6 +152,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(['dev.host' => '127.0.0.1']); + ['output' => $output] = createMemoryOutput(); + + $input = new Input(['marko', 'dev:up']); + $command->execute($input, $output); + + expect($pm->started['php'])->toContain('127.0.0.1:8000'); +}); + it('reads docker setting from config', function (): void { ['command' => $command, 'processManager' => $pm] = createDevUpCommand([ 'dev.docker' => 'custom-docker-up', @@ -417,6 +429,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(); @@ -520,7 +543,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 +567,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 { @@ -570,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), @@ -597,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), @@ -632,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, @@ -668,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, @@ -773,7 +772,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 {