Skip to content

Commit

Permalink
Fix #142, fix #157: Add config for serve command
Browse files Browse the repository at this point in the history
  • Loading branch information
dood- committed Jul 19, 2022
1 parent 9ef7e59 commit b0583e4
Show file tree
Hide file tree
Showing 7 changed files with 111 additions and 11 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Expand Up @@ -2,7 +2,7 @@

## 1.1.2 under development

- no changes in this release.
- Enh #157: Add config for `serve` command (@dood-)

## 1.1.1 July 04, 2022

Expand Down
26 changes: 26 additions & 0 deletions README.md
Expand Up @@ -115,6 +115,32 @@ The command can be marked as hidden by prefixing its name with `|`.
],
```

### Runs PHP built-in web server

You can start local built-in web development server using the command:
```
./yii serve
```
Your application will be accessible in your web browser at http://localhost:8080 by default.
To configure default settings, set the options in `\Yiisoft\Yii\Console\CommandLoader` configuration.

```php
'yiisoft/yii-console' => [
'serve' => [
'appRootPath' => null,
'options' => [
'address' => '127.0.0.1',
'port' => '8080',
'docroot' => 'public',
'router' => 'public/index.php',
],
],
],
```

Alternatively, you can pass the settings through the console options. To see the available options, run
`./yii serve --help`

## Testing

### Unit testing
Expand Down
9 changes: 9 additions & 0 deletions config/console.php
Expand Up @@ -6,6 +6,7 @@
use Symfony\Component\Console\Input\InputOption;
use Yiisoft\Definitions\Reference;
use Yiisoft\Yii\Console\Application;
use Yiisoft\Yii\Console\Command\Serve;
use Yiisoft\Yii\Console\CommandLoader;
use Yiisoft\Yii\Console\SymfonyEventDispatcher;

Expand All @@ -19,6 +20,14 @@
],
],

Serve::class => [
'class' => Serve::class,
'__construct()' => [
'appRootPath' => $params['yiisoft/yii-console']['serve']['appRootPath'],
'options' => $params['yiisoft/yii-console']['serve']['options'],
],
],

Application::class => [
'__construct()' => [
$params['yiisoft/yii-console']['name'],
Expand Down
9 changes: 9 additions & 0 deletions config/params.php
Expand Up @@ -13,5 +13,14 @@
'commands' => [
'serve' => Serve::class,
],
'serve' => [
'appRootPath' => null,
'options' => [
'address' => '127.0.0.1',
'port' => '8080',
'docroot' => 'public',
'router' => 'public/index.php',
],
],
],
];
3 changes: 3 additions & 0 deletions psalm.xml
Expand Up @@ -7,5 +7,8 @@
>
<projectFiles>
<directory name="src" />
<ignoreFiles>
<directory name="vendor"/>
</ignoreFiles>
</projectFiles>
</psalm>
36 changes: 26 additions & 10 deletions src/Command/Serve.php
Expand Up @@ -27,26 +27,42 @@ final class Serve extends Command
public const EXIT_CODE_NO_ROUTING_FILE = 3;
public const EXIT_CODE_ADDRESS_TAKEN_BY_ANOTHER_PROCESS = 5;

private const DEFAULT_PORT = '8080';
private const DEFAULT_DOCROOT = 'public';
private const DEFAULT_ROUTER = 'public/index.php';
private string $defaultAddress;
private string $defaultPort;
private string $defaultDocroot;
private string $defaultRouter;

protected static $defaultName = 'serve';
protected static $defaultDescription = 'Runs PHP built-in web server';

public function __construct(private ?string $appRootPath = null)
/**
* @param string|null $appRootPath
* @param array|null $options
* @psalm-param array{
* address?:non-empty-string,
* port?:non-empty-string,
* docroot?:string,
* router?:string
* } $options
*/
public function __construct(private ?string $appRootPath = null, ?array $options = [])
{
$this->defaultAddress = $options['address'] ?? '127.0.0.1';
$this->defaultPort = $options['port'] ?? '8080';
$this->defaultDocroot = $options['docroot'] ?? 'public';
$this->defaultRouter = $options['router'] ?? 'public/index.php';

parent::__construct();
}

public function configure(): void
{
$this
->setHelp('In order to access server from remote machines use 0.0.0.0:8000. That is especially useful when running server in a virtual machine.')
->addArgument('address', InputArgument::OPTIONAL, 'Host to serve at', '127.0.0.1')
->addOption('port', 'p', InputOption::VALUE_OPTIONAL, 'Port to serve at', self::DEFAULT_PORT)
->addOption('docroot', 't', InputOption::VALUE_OPTIONAL, 'Document root to serve from', self::DEFAULT_DOCROOT)
->addOption('router', 'r', InputOption::VALUE_OPTIONAL, 'Path to router script', self::DEFAULT_ROUTER)
->addArgument('address', InputArgument::OPTIONAL, 'Host to serve at', $this->defaultAddress)
->addOption('port', 'p', InputOption::VALUE_OPTIONAL, 'Port to serve at', $this->defaultPort)
->addOption('docroot', 't', InputOption::VALUE_OPTIONAL, 'Document root to serve from', $this->defaultDocroot)
->addOption('router', 'r', InputOption::VALUE_OPTIONAL, 'Path to router script', $this->defaultRouter)
->addOption('env', 'e', InputOption::VALUE_OPTIONAL, 'It is only used for testing.');
}

Expand Down Expand Up @@ -74,8 +90,8 @@ protected function execute(InputInterface $input, OutputInterface $output): int
/** @var string $docroot */
$docroot = $input->getOption('docroot');

if ($router === self::DEFAULT_ROUTER && !file_exists(self::DEFAULT_ROUTER)) {
$io->warning('Default router "' . self::DEFAULT_ROUTER . '" does not exist. Serving without router. URLs with dots may fail.');
if ($router === $this->defaultRouter && !file_exists($this->defaultRouter)) {
$io->warning('Default router "' . $this->defaultRouter . '" does not exist. Serving without router. URLs with dots may fail.');
$router = null;
}

Expand Down
37 changes: 37 additions & 0 deletions tests/ServeCommandTest.php
Expand Up @@ -71,6 +71,43 @@ public function testServeCommandExecuteWithDocRoot(): void
);
}

public function testServeCommandExecuteWithConfig(): void
{
$command = new Serve(null, [
'address' => '127.0.0.2',
'port' => '8081',
'docroot' => 'tests',
'router' => 'public/index.php',
]);

$commandCreate = new CommandTester($command);

$commandCreate->setInputs(['yes']);

$commandCreate->execute([
'--env' => 'test',
]);

$output = $commandCreate->getDisplay(true);

$this->assertSame(ExitCode::OK, $commandCreate->getStatusCode());

$this->assertStringContainsString(
'Server started on http://127.0.0.2:8081/',
$output
);

$this->assertStringContainsString(
'Document root is',
$output
);

$this->assertStringContainsString(
'Quit the server with CTRL-C or COMMAND-C.',
$output
);
}

public function testErrorWhenAddressIsTaken(): void
{
$command = $this
Expand Down

0 comments on commit b0583e4

Please sign in to comment.