diff --git a/commands/serve.v b/commands/serve.v new file mode 100644 index 0000000..31ae6f5 --- /dev/null +++ b/commands/serve.v @@ -0,0 +1,119 @@ +module commands + +import cli +import log +import net.http +import os + +const cport = 8080 + +fn new_serve_cmd() cli.Command { + return cli.Command{ + name: 'serve' + description: 'serve dist' + usage: 'vss serve' + execute: fn (cmd cli.Command) ? { + mut logger := log.Log{} + logger.set_level(log.Level.info) + serve(mut logger) or { + logger.error(err.msg()) + println('serve failed') + } + } + } +} + +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 watch(path string, mut logger log.Log) { + 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 + } + + for { + for mut w in watchers { + now := os.file_last_mod_unix(w.path) + if now > w.time_stamp { + println('modified file: $w.path') + w.time_stamp = now + + build(mut logger) or { + logger.error(err.msg()) + println('Build failed') + } + } + } + } +} + +fn serve(mut logger log.Log) ? { + mut handler := MyHttpHandler{ + root: 'dist' + } + mut server := &http.Server{ + handler: handler + port: commands.cport + } + println('http://localhost:$commands.cport') + w := go watch('dist', mut logger) + server.listen_and_serve() or { panic(err) } + + w.wait() +} diff --git a/commands/vss.v b/commands/vss.v index 93910b4..90c47aa 100644 --- a/commands/vss.v +++ b/commands/vss.v @@ -6,7 +6,7 @@ import cli pub fn execute() { mut app := cli.Command{ name: 'vss' - version: '0.0.9' + version: '0.0.10' description: 'static site generator' execute: fn (cmd cli.Command) ? { println(cmd.help_message()) @@ -14,6 +14,7 @@ pub fn execute() { } app.add_command(new_build_cmd()) + app.add_command(new_serve_cmd()) app.setup() app.parse(os.args)