Skip to content
This repository was archived by the owner on May 14, 2020. It is now read-only.

Commit 8a44504

Browse files
committed
It possible now to expand the tilde-path written in the config and stop server in cli.
1 parent 24a9d5a commit 8a44504

File tree

10 files changed

+140
-20
lines changed

10 files changed

+140
-20
lines changed

bin/server

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use StaticServer\Console\DumpConfigCommand;
77
use StaticServer\Console\ReloadServerCommand;
88
use StaticServer\Console\RunServerCommand;
99
use StaticServer\Console\SignalHandler;
10+
use StaticServer\Console\StopServerCommand;
1011
use Symfony\Component\Console\Application;
1112

1213
$locations = [
@@ -35,6 +36,7 @@ pcntl_signal(SIGUSR1, [$sig, 'handle']);
3536
try {
3637
$app = new Application('Static server', Server::VERSION);
3738
$app->add(new RunServerCommand());
39+
$app->add(new StopServerCommand());
3840
$app->add(new DumpConfigCommand());
3941
$app->add(new ReloadServerCommand());
4042
$app->run();

composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
"ext-json": "*",
1212
"ext-dom": "*",
1313
"ext-pcntl": "*",
14+
"ext-posix": "*",
1415
"microparts/configuration-php": "2.*",
1516
"monolog/monolog": "^1.24",
1617
"masterminds/html5": "^2.5",

configuration/defaults/___server.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ defaults:
1414
handler:
1515
name: nginx
1616
options:
17-
pid: /tmp/spa_nginx.pid
18-
config: /tmp/generated_nginx.conf
17+
pid: ~/.server/spa_nginx.pid
18+
config: ~/.server/generated_nginx.conf
1919
prerender:
2020
enabled: false
2121
url: null

src/Application.php

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ public function setModifyConfigurator(ModifyConfiguratorInterface $configurator)
7575
* Dry run without start of server.
7676
*
7777
* @return void
78+
* @throws \Exception
7879
*/
7980
public function dryRun(): void
8081
{
@@ -100,7 +101,9 @@ public function run(): void
100101
$this->ready();
101102
$this->handler->start();
102103
} catch (Throwable $e) {
103-
$this->handler->stop();
104+
if (isset($this->handler)) {
105+
$this->handler->stop();
106+
}
104107
throw $e;
105108
}
106109
}
@@ -120,7 +123,9 @@ public function reload(): void
120123
$this->handler->reload();
121124
$this->logger->info('Configuration reloaded');
122125
} catch (Throwable $e) {
123-
$this->handler->stop();
126+
if (isset($this->handler)) {
127+
$this->handler->stop();
128+
}
124129
throw $e;
125130
}
126131
}
@@ -144,6 +149,7 @@ public function stop(): void
144149
* @codeCoverageIgnore
145150
* @param bool $checkConfig
146151
* @return void
152+
* @throws \Exception
147153
*/
148154
private function ready(bool $checkConfig = true): void
149155
{

src/Console/RunServerCommand.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ protected function configure(): void
1515
{
1616
$this
1717
->setName('run')
18+
->setAliases(['start'])
1819
->setDescription('Run server')
1920
->addOption('dry-run', null, InputOption::VALUE_NONE, 'Dry run command without server starting.')
2021
->setHelp('Example of usage: `server run`. If u want to change starting host or port, please change the __server_*.yaml configuration files.');

src/Console/StopServerCommand.php

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace StaticServer\Console;
4+
5+
use StaticServer\Server;
6+
use Symfony\Component\Console\Command\Command;
7+
use Symfony\Component\Console\Input\InputInterface;
8+
use Symfony\Component\Console\Output\OutputInterface;
9+
10+
class StopServerCommand extends Command
11+
{
12+
13+
protected function configure(): void
14+
{
15+
$this
16+
->setName('stop')
17+
->setDescription('Stop server')
18+
->setHelp('Example of usage: `server stop`.');
19+
}
20+
21+
/**
22+
* Execute command, captain.
23+
*
24+
* @param \Symfony\Component\Console\Input\InputInterface $input
25+
* @param \Symfony\Component\Console\Output\OutputInterface $output
26+
* @throws \Throwable
27+
*
28+
* @return int
29+
*/
30+
protected function execute(InputInterface $input, OutputInterface $output): int
31+
{
32+
Server::fromGlobals()->stop();
33+
34+
return 0;
35+
}
36+
}

src/Handler/AbstractHandler.php

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,36 @@
66
use Microparts\Configuration\ConfigurationAwareTrait;
77
use Psr\Log\LoggerAwareInterface;
88
use Psr\Log\LoggerAwareTrait;
9+
use Symfony\Component\Filesystem\Filesystem;
910
use Symfony\Component\Process\Process;
1011

1112
abstract class AbstractHandler implements HandlerInterface, ConfigurationAwareInterface, LoggerAwareInterface
1213
{
1314
use ConfigurationAwareTrait, LoggerAwareTrait;
1415

16+
/**
17+
* @var \Symfony\Component\Filesystem\Filesystem
18+
*/
19+
protected Filesystem $filesystem;
20+
21+
/**
22+
* AbstractHandler constructor.
23+
*/
24+
public function __construct()
25+
{
26+
$this->filesystem = new Filesystem();
27+
}
28+
1529
/**
1630
* @return string
1731
*/
1832
protected function getServerRoot(): string
1933
{
20-
return $this->configuration->get('server.modify.enabled')
34+
$path = $this->configuration->get('server.modify.enabled')
2135
? $this->configuration->get('server.modify.root')
2236
: $this->configuration->get('server.root');
37+
38+
return $this->expandPathLikeShell($path);
2339
}
2440

2541
/**
@@ -40,4 +56,49 @@ protected function runProcess(array $args, ?callable $callback = null): void
4056
$this->logger->info($buffer);
4157
});
4258
}
59+
60+
/**
61+
* @param string $filename
62+
*/
63+
protected function touchFile(string $filename): void
64+
{
65+
$filename = $this->expandPathLikeShell($filename);
66+
$this->logger->debug("Touch file: $filename");
67+
68+
$this->filesystem->touch($filename);
69+
}
70+
71+
/**
72+
* @param array $paths
73+
*/
74+
protected function makePathForFiles(array $paths): void
75+
{
76+
static $created = [];
77+
78+
foreach ($paths as $path) {
79+
$path = pathinfo($this->expandPathLikeShell($path), PATHINFO_DIRNAME);
80+
81+
if (!isset($created[$path])) {
82+
$this->logger->debug("Create nested dirs for: $path");
83+
$this->filesystem->mkdir($path, 0755);
84+
$created[$path]= true;
85+
}
86+
}
87+
}
88+
89+
/**
90+
* https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_01
91+
*
92+
* @param string $path
93+
* @return string
94+
*/
95+
protected function expandPathLikeShell(string $path): string
96+
{
97+
if (strpos($path, '~') !== false) {
98+
$info = posix_getpwuid(posix_getuid());
99+
$path = str_replace('~', $info['dir'], $path);
100+
}
101+
102+
return $path;
103+
}
43104
}

src/Handler/NginxHandler.php

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,14 @@ class NginxHandler extends AbstractHandler
1919
private Engine $templates;
2020

2121
/**
22-
* @var array<string, string>
22+
* @var string
2323
*/
24-
private array $options;
24+
private string $pidFile;
25+
26+
/**
27+
* @var string
28+
*/
29+
private string $configFile;
2530

2631
/**
2732
* @var bool
@@ -40,8 +45,11 @@ class NginxHandler extends AbstractHandler
4045
*/
4146
public function __construct(array $options = [])
4247
{
43-
$this->templates = new Engine(__DIR__ . DIRECTORY_SEPARATOR . 'templates');
44-
$this->options = $options;
48+
$this->templates = new Engine(__DIR__ . DIRECTORY_SEPARATOR . 'templates');
49+
$this->pidFile = $this->expandPathLikeShell($options['pid']);
50+
$this->configFile = $this->expandPathLikeShell($options['config']);
51+
52+
parent::__construct();
4553
}
4654

4755
/**
@@ -60,7 +68,9 @@ public function checkDependenciesBeforeStart(): void
6068
*/
6169
public function generateConfig(HeaderInterface $header): void
6270
{
63-
$this->logger->info("Nginx PID location: {$this->options['pid']}");
71+
$this->logger->info("Nginx PID location: {$this->pidFile}");
72+
$this->makePathForFiles([$this->pidFile, $this->configFile]);
73+
$this->touchFile($this->pidFile);
6474

6575
$data = $this->templates->render('nginx_default.conf', [
6676
'serverRoot' => realpath($this->getServerRoot()),
@@ -73,25 +83,25 @@ public function generateConfig(HeaderInterface $header): void
7383
'prerenderHost' => $this->getHostWithoutTrailingSlash('server.prerender.host'),
7484
'headers' => $header->convert($this->configuration),
7585
'connProcMethod' => $this->getConnectionProcessingMethod(),
76-
'pidLocation' => $this->options['pid'],
86+
'pidLocation' => $this->pidFile,
7787
'moduleBrotliInstalled' => $this->moduleBrotliInstalled,
7888
'platformSupportsAsyncIo' => $this->platformSupportsAsyncIo,
7989
]);
8090

81-
file_put_contents($this->options['config'], $data);
91+
file_put_contents($this->configFile, $data);
8292
}
8393

8494
public function checkConfig(): void
8595
{
86-
$this->runProcess(['nginx', '-c', $this->options['config'], '-t']);
96+
$this->runProcess(['nginx', '-c', $this->configFile, '-t']);
8797
}
8898

8999
/**
90100
* Start the web-server.
91101
*/
92102
public function start(): void
93103
{
94-
$this->runProcess(['nginx', '-c', $this->options['config']], function () {
104+
$this->runProcess(['nginx', '-c', $this->configFile], function () {
95105
$this->logger->info(sprintf(
96106
'Server started at: %s:%d',
97107
$this->configuration->get('server.host'),
@@ -102,20 +112,24 @@ public function start(): void
102112

103113
public function reload(): void
104114
{
105-
if (!file_exists($this->options['pid'])) {
115+
if (!file_exists($this->pidFile)) {
106116
throw new LogicException('Can\'t reload server. Pid file not found.');
107117
}
108118

109-
if (empty(file_get_contents($this->options['pid']))) {
119+
if (empty(file_get_contents($this->pidFile))) {
110120
throw new LogicException('Can\'t reload server. Pid file is empty.');
111121
}
112122

113-
$this->runProcess(['nginx', '-c', $this->options['config'], '-s', 'reload']);
123+
$this->runProcess(['nginx', '-c', $this->configFile, '-s', 'reload']);
114124
}
115125

116126
public function stop(): void
117127
{
118-
$this->runProcess(['nginx', '-c', $this->options['config'], '-s', 'stop']);
128+
$this->runProcess(['nginx', '-c', $this->configFile, '-s', 'stop']);
129+
130+
if ($this->filesystem->exists($this->configFile)) {
131+
$this->filesystem->remove($this->configFile);
132+
}
119133
}
120134

121135
/**

src/Server.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
namespace StaticServer;
44

55
use Microparts\Configuration\Configuration;
6-
use Microparts\Configuration\ConfigurationInterface;
76

87
final class Server
98
{

tests/Handler/HandlerFactoryTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ class HandlerFactoryTest extends TestCase
1111
{
1212
public function testHowFactoryCreatesObjects()
1313
{
14-
$object = HandlerFactory::createHandler('nginx', []);
14+
$object = HandlerFactory::createHandler('nginx', ['pid' => '', 'config' => '']);
1515

1616
$this->assertInstanceOf(NginxHandler::class, $object);
1717
}

0 commit comments

Comments
 (0)