139 lines
2.5 KiB
V
139 lines
2.5 KiB
V
module commands
|
|
|
|
import log
|
|
import net.http
|
|
import os
|
|
import internal.config
|
|
|
|
const cport = 8080
|
|
|
|
struct ServeCommand {
|
|
mut:
|
|
logger log.Log
|
|
port int
|
|
buildcmd BuildCommand
|
|
}
|
|
|
|
// new_serve_cmd creates a new ServeCommand instance.
|
|
pub fn new_serve_cmd(conf config.Config, logger log.Log) ServeCommand {
|
|
return ServeCommand{
|
|
logger: logger
|
|
port: commands.cport
|
|
buildcmd: new_build_cmd(conf, logger)
|
|
}
|
|
}
|
|
|
|
struct MyHttpHandler {
|
|
mut:
|
|
root string
|
|
}
|
|
|
|
fn normalise_path(path string) string {
|
|
cwd := os.getwd() + os.path_separator
|
|
mut res := os.abs_path(path).replace(cwd, '').replace(os.path_separator, '/')
|
|
return res
|
|
}
|
|
|
|
fn (mut handler MyHttpHandler) handle(req http.Request) http.Response {
|
|
mut r := http.Response{
|
|
header: req.header
|
|
}
|
|
|
|
// コンテンツを返すための処理
|
|
wd := os.getwd()
|
|
os_spec_path := req.url.replace('/', os.path_separator)
|
|
mut file := wd + os.path_separator + handler.root + os_spec_path
|
|
|
|
if os.is_dir(file) {
|
|
file = file + os.path_separator + 'index.html'
|
|
} else {
|
|
if !os.is_file(file) {
|
|
file = file + '.html'
|
|
}
|
|
}
|
|
|
|
html := os.read_file(file) or {
|
|
eprintln(err)
|
|
r.set_status(.not_found)
|
|
r.body = 'Not Found'
|
|
r.set_version(req.version)
|
|
return r
|
|
}
|
|
|
|
r.body = html
|
|
r.set_status(.ok)
|
|
r.set_version(req.version)
|
|
return r
|
|
}
|
|
|
|
struct Watcher {
|
|
path string
|
|
mut:
|
|
time_stamp i64
|
|
}
|
|
|
|
fn (mut s ServeCommand) watch(path string) {
|
|
mut res := []string{}
|
|
os.walk_with_context(path, &res, fn (mut res []string, fpath string) {
|
|
res << fpath
|
|
})
|
|
|
|
mut watchers := []Watcher{}
|
|
for p in res {
|
|
mut w := Watcher{
|
|
path: p
|
|
time_stamp: os.file_last_mod_unix(p)
|
|
}
|
|
watchers << w
|
|
}
|
|
|
|
ignore := '.' + os.path_separator + 'dist'
|
|
for {
|
|
for mut w in watchers {
|
|
if w.path.starts_with(ignore) {
|
|
continue
|
|
}
|
|
now := os.file_last_mod_unix(w.path)
|
|
if now > w.time_stamp {
|
|
println('modified file: ${w.path}')
|
|
w.time_stamp = now
|
|
|
|
s.build() or {
|
|
s.logger.error(err.msg())
|
|
println('Build failed')
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
fn (mut s ServeCommand) build() ! {
|
|
s.buildcmd.run()!
|
|
}
|
|
|
|
// run serve command main process.
|
|
pub fn (mut s ServeCommand) run() ! {
|
|
mut handler := MyHttpHandler{
|
|
root: 'dist'
|
|
}
|
|
mut server := &http.Server{
|
|
handler: handler
|
|
port: commands.cport
|
|
}
|
|
|
|
// base_url を localhost にする
|
|
local_base_url := 'http://localhost:${commands.cport}/'
|
|
s.buildcmd.set_base_url(local_base_url)
|
|
|
|
// build
|
|
s.build() or {
|
|
s.logger.error(err.msg())
|
|
println('build failed')
|
|
}
|
|
|
|
println(local_base_url)
|
|
w := spawn s.watch('.')
|
|
server.listen_and_serve()
|
|
|
|
w.wait()
|
|
}
|