15
15
16
16
use League \Tactician \CommandBus ;
17
17
use Monolog \Handler \ErrorLogHandler ;
18
+ use Monolog \Logger ;
18
19
use phpDocumentor \FileSystem \FlySystemAdapter ;
19
20
use phpDocumentor \Guides \Cli \Internal \RunCommand ;
20
21
use phpDocumentor \Guides \Cli \Internal \ServerFactory ;
21
22
use phpDocumentor \Guides \Cli \Internal \Watcher \FileModifiedEvent ;
22
- use phpDocumentor \Guides \Cli \Internal \Watcher \INotifyWatcher ;
23
23
use phpDocumentor \Guides \Compiler \CompilerContext ;
24
24
use phpDocumentor \Guides \Event \PostParseDocument ;
25
25
use phpDocumentor \Guides \Handlers \CompileDocumentsCommand ;
26
26
use phpDocumentor \Guides \Handlers \ParseFileCommand ;
27
27
use phpDocumentor \Guides \Handlers \RenderDocumentCommand ;
28
+ use phpDocumentor \Guides \Nodes \DocumentNode ;
28
29
use phpDocumentor \Guides \RenderContext ;
29
30
use phpDocumentor \Guides \Renderer \DocumentListIterator ;
30
31
use phpDocumentor \Guides \Renderer \DocumentTreeIterator ;
31
- use Psr \EventDispatcher \EventDispatcherInterface ;
32
- use Psr \Log \LoggerInterface ;
33
- use React \EventLoop \Loop ;
34
32
use Symfony \Component \Console \Command \Command ;
35
33
use Symfony \Component \Console \Input \InputInterface ;
36
34
use Symfony \Component \Console \Input \InputOption ;
37
35
use Symfony \Component \Console \Output \OutputInterface ;
38
36
37
+ use function assert ;
38
+ use function is_int ;
39
+ use function is_string ;
39
40
use function sprintf ;
41
+ use function substr ;
40
42
41
43
final class Serve extends Command
42
44
{
43
45
public function __construct (
44
- private LoggerInterface $ logger ,
45
- private EventDispatcherInterface $ dispatcher ,
46
+ private readonly Logger $ logger ,
46
47
private SettingsBuilder $ settingsBuilder ,
47
48
private CommandBus $ commandBus ,
48
49
private ServerFactory $ serverFactory ,
@@ -55,46 +56,53 @@ protected function configure(): void
55
56
$ this ->settingsBuilder ->configureCommand ($ this );
56
57
$ this ->addOption ('host ' , null , InputOption::VALUE_REQUIRED , 'Hostname to serve on ' , 'localhost ' );
57
58
$ this ->addOption ('port ' , 'p ' , InputOption::VALUE_REQUIRED , 'Port to run the server on ' , 1337 );
58
- $ this ->addOption ('listen ' , 'l ' , InputOption::VALUE_REQUIRED , 'Address to listen on ' , '0.0.0.0 ' );
59
59
}
60
60
61
61
protected function execute (InputInterface $ input , OutputInterface $ output ): int
62
62
{
63
63
$ this ->logger ->pushHandler (new ErrorLogHandler (ErrorLogHandler::OPERATING_SYSTEM ));
64
- // Enable tick processing for signal handling
65
- declare (ticks=1 );
66
-
67
- $ loop = Loop::get ();
68
- $ loop ->addSignal (SIGINT , static function () use ($ loop , $ output ): void {
69
- $ output ->writeln ('Shutting down server... ' );
70
- $ loop ->stop ();
71
- $ output ->writeln ('Server stopped ' );
72
- exit (0 );
73
- });
74
-
75
64
76
65
$ dir = $ input ->getOption ('output ' );
77
- if ($ dir === null ) {
66
+ if (! is_string ( $ dir) ) {
78
67
$ output ->writeln ('<error>Please specify an output directory using --output option</error> ' );
79
68
80
69
return Command::FAILURE ;
81
70
}
82
71
72
+ $ inputDir = $ input ->getArgument ('input ' );
73
+ if (!is_string ($ inputDir )) {
74
+ $ output ->writeln ('<error>Please specify an input directory using the input argument</error> ' );
75
+
76
+ return Command::FAILURE ;
77
+ }
78
+
79
+ $ host = $ input ->getOption ('host ' );
80
+ if (!is_string ($ host )) {
81
+ $ output ->writeln ('<error>Please specify a valid host using --host option</error> ' );
82
+
83
+ return Command::FAILURE ;
84
+ }
85
+
86
+ $ port = $ input ->getOption ('port ' );
87
+ if (!is_int ($ port )) {
88
+ $ output ->writeln ('<error>Please specify a valid port using --port option</error> ' );
89
+
90
+ return Command::FAILURE ;
91
+ }
92
+
83
93
$ files = FlySystemAdapter::createForPath ($ dir );
84
- $ app = $ this ->serverFactory ->createWebserver (
94
+ $ app = $ this ->serverFactory ->createDevServer (
95
+ $ inputDir ,
85
96
$ files ,
86
- $ loop ,
87
- $ input ->getOption ('host ' ),
88
- $ input ->getOption ('listen ' ),
89
- (int ) $ input ->getOption ('port ' ),
97
+ $ host ,
98
+ '0.0,0.0 ' ,
99
+ $ port ,
90
100
);
91
101
92
- $ watcher = new InotifyWatcher ($ loop , $ this ->dispatcher , $ input ->getArgument ('input ' ));
93
-
94
- $ this ->dispatcher ->addListener (
102
+ $ app ->addListener (
95
103
PostParseDocument::class,
96
- static function (PostParseDocument $ event ) use ($ watcher ): void {
97
- $ watcher -> addPath ($ event ->getOriginalFileName ());
104
+ static function (PostParseDocument $ event ) use ($ app ): void {
105
+ $ app -> watch ($ event ->getOriginalFileName ());
98
106
},
99
107
);
100
108
@@ -104,6 +112,7 @@ static function (PostParseDocument $event) use ($watcher): void {
104
112
$ projectNode = $ this ->settingsBuilder ->createProjectNode ();
105
113
$ sourceFileSystem = FlySystemAdapter::createForPath ($ settings ->getInput ());
106
114
115
+ /** @var array<string, DocumentNode> $documents */
107
116
$ documents = $ this ->commandBus ->handle (
108
117
new RunCommand (
109
118
$ settings ,
@@ -112,9 +121,9 @@ static function (PostParseDocument $event) use ($watcher): void {
112
121
),
113
122
);
114
123
115
- $ this -> dispatcher ->addListener (
124
+ $ app ->addListener (
116
125
FileModifiedEvent::class,
117
- function (FileModifiedEvent $ event ) use ($ sourceFileSystem , $ projectNode , $ settings , $ app , $ output ): void {
126
+ function (FileModifiedEvent $ event ) use ($ documents , $ sourceFileSystem , $ projectNode , $ settings , $ app , $ output ): void {
118
127
$ output ->writeln (
119
128
sprintf (
120
129
'File modified: %s, rerendering... ' ,
@@ -123,7 +132,7 @@ function (FileModifiedEvent $event) use ($sourceFileSystem, $projectNode, $setti
123
132
);
124
133
$ file = substr ($ event ->path , 0 , -4 );
125
134
126
- $ documents [ $ file ] = $ this ->commandBus ->handle (
135
+ $ document = $ this ->commandBus ->handle (
127
136
new ParseFileCommand (
128
137
$ sourceFileSystem ,
129
138
'' ,
@@ -134,12 +143,14 @@ function (FileModifiedEvent $event) use ($sourceFileSystem, $projectNode, $setti
134
143
true ,
135
144
),
136
145
);
146
+ assert ($ document instanceof DocumentNode);
147
+
148
+ $ documents [$ file ] = $ document ;
137
149
150
+ /** @var array<string, DocumentNode> $documents */
138
151
$ documents = $ this ->commandBus ->handle (new CompileDocumentsCommand ($ documents , new CompilerContext ($ projectNode )));
139
152
$ destinationFileSystem = FlySystemAdapter::createForPath ($ settings ->getOutput ());
140
153
141
- $ outputFormats = $ settings ->getOutputFormats ();
142
-
143
154
$ documentIterator = new DocumentListIterator (
144
155
new DocumentTreeIterator (
145
156
[$ projectNode ->getRootDocumentEntry ()],
@@ -148,33 +159,34 @@ function (FileModifiedEvent $event) use ($sourceFileSystem, $projectNode, $setti
148
159
$ documents ,
149
160
);
150
161
151
- //foreach ($outputFormats as $format) {
152
-
153
- $ renderContext = RenderContext::forProject (
154
- $ projectNode ,
155
- $ documents ,
156
- $ sourceFileSystem ,
157
- $ destinationFileSystem ,
158
- '/ ' ,
159
- 'html ' ,
160
- )->withIterator ($ documentIterator );
161
-
162
- $ this ->commandBus ->handle (
163
- new RenderDocumentCommand (
164
- $ documents [$ file ],
165
- $ renderContext ->withDocument ($ documents [$ file ]),
166
- ),
167
- );
168
- //}
162
+ $ renderContext = RenderContext::forProject (
163
+ $ projectNode ,
164
+ $ documents ,
165
+ $ sourceFileSystem ,
166
+ $ destinationFileSystem ,
167
+ '/ ' ,
168
+ 'html ' ,
169
+ )->withIterator ($ documentIterator );
170
+
171
+ $ this ->commandBus ->handle (
172
+ new RenderDocumentCommand (
173
+ $ documents [$ file ],
174
+ $ renderContext ->withDocument ($ documents [$ file ]),
175
+ ),
176
+ );
169
177
170
178
$ output ->writeln ('Rerendering completed. ' );
171
179
$ app ->notifyClients ();
172
180
},
173
181
);
174
182
175
-
176
- $ output ->writeln (sprintf ('Server running at http://localhost:1337 ' ));
177
- $ output ->writeln ('WebSocket server running at ws://localhost:1337/ws ' );
183
+ $ output ->writeln (
184
+ sprintf (
185
+ 'Server running at http://%s:%d ' ,
186
+ $ host ,
187
+ $ port ,
188
+ ),
189
+ );
178
190
$ output ->writeln ('Press Ctrl+C to stop the server ' );
179
191
180
192
$ app ->run ();
0 commit comments