giscus comments
[mdref/mdref] / bin / serve-stub
1 #!/usr/bin/env php
2 <?php
3
4 namespace mdref;
5
6 require_once $_composer_autoload_path ?? __DIR__."/../vendor/autoload.php";
7
8 if ($argc < 2) {
9 fprintf(STDERR, "Usage: %s <stub.php> [<ns>]\n", $argv[0]);
10 exit(1);
11 }
12
13 if (!($stub = realpath($argv[1]))) {
14 $stat = stat($stub);
15 assert(!$stat);
16 exit(2);
17 }
18 if ($argc > 2) {
19 $namespace = $argv[2];
20 } else {
21 $namespace = basename($stub, ".stub.php");
22 }
23
24 $tmplck = tempnam(sys_get_temp_dir(), "mdref.");
25 $tmpdir = $tmplck . ".d";
26 mkdir($tmpdir) && chdir($tmpdir) || exit(-1);
27
28 $running = true;
29 $shutdown = function() use($tmpdir, $tmplck, &$running) {
30 $running = false;
31 chdir(__DIR__) && rm_r($tmpdir, $tmplck);
32 };
33 register_shutdown_function($shutdown);
34 pcntl_signal(SIGINT, $shutdown, false);
35 pcntl_signal(SIGTERM, $shutdown, false);
36
37 $passthru = fn($cmd) => fn() => printf("%s\n", $cmd) && !passthru("$cmd 2>&1 >/dev/null", $rc) && !$rc;
38 $stub2ref = $passthru(
39 sprintf("%s/stub2ref %s %s %s",
40 __DIR__,
41 escapeshellarg($namespace),
42 escapeshellarg($stub),
43 escapeshellarg($tmpdir)
44 )
45 );
46 $ref2html = $passthru(
47 sprintf("%s/ref2html . .",
48 __DIR__,
49 )
50 );
51 $update = fn() => $stub2ref() && $ref2html();
52
53 if ($update()) {
54 $ifd = inotify_init();
55 inotify_add_watch($ifd, $stub, IN_MODIFY);
56 stream_set_blocking($ifd, false);
57
58 file_put_contents("router.php", file_get_contents(__FILE__, false, null, __COMPILER_HALT_OFFSET__));
59 $php = popen(sprintf("%s -S localhost:0 -t . router.php 2>&1 | grep --line-buffered -Ev 'Accepted|Closing|GET'", PHP_BINARY), "r");
60 echo fgets($php);
61 stream_set_blocking($php, false);
62
63 while ($running) {
64 $R = [$ifd, $php]; $W = []; $E = [];
65 if (stream_select($R, $W, $E, null)) {
66 foreach ($R as $r) {
67 switch ($r) {
68 case $php:
69 while (($string = fgets($php))) echo $string;
70 break;
71 case $ifd:
72 // cooldown
73 usleep(50 * 1000);
74 while (inotify_read($ifd));
75 $update();
76 break;
77 }
78 }
79 }
80 pcntl_signal_dispatch();
81 }
82 }
83
84 function rm_r(string ...$args) {
85 foreach ($args as $del) {
86 if (is_dir($del)) {
87 rm_r(...array_map(fn($sub) => "$del/$sub", array_slice(scandir($del), 2)));
88 rmdir($del);
89 } else if (file_exists($del)) {
90 unlink($del);
91 }
92 }
93 }
94
95 __HALT_COMPILER();
96 <?php
97
98 $file = __DIR__ . urldecode($_SERVER["REQUEST_URI"]);
99
100 if (is_file($file)) {
101 return false;
102 }
103
104 if (is_dir($file) && file_exists($file."/index.html")) {
105 readfile($file."/index.html");
106 } else {
107 $file = rtrim($file, "/").".html";
108 if (file_exists($file)) {
109 readfile($file);
110 } else {
111 return false;
112 }
113 }