reynir.dk/src/reynir_www.ml
2023-11-14 09:20:41 +01:00

122 lines
3.6 KiB
OCaml

let caller = Filename.basename Sys.argv.(0)
let version = "%%VERSION%%"
let default_port = 8888
let default_target = Fpath.v "_site"
let program ~target =
let open Yocaml in
let* () = Task.move_css target in
let* () = Task.move_images target in
let* () = Task.move_js target in
let* () = Task.move_audio target in
let* () = Task.process_articles target in
let* () = Task.generate_about target in
let* () = Task.generate_contact target in
let* () = Task.generate_archive target in
Task.generate_index target
let local_build _quiet target =
Yocaml_unix.execute (program ~target:(Fpath.to_string target))
let watch quiet target potential_port =
let port = Option.value ~default:default_port potential_port in
let () = local_build quiet target in
let target = Fpath.to_string target in
let server = Yocaml_unix.serve ~filepath:target ~port (program ~target) in
Lwt_main.run server
let common_options = "COMMON OPTIONS"
let verbosity =
let open Cmdliner in
let env = Cmd.Env.info "REYNIR_LOGS" in
Logs_cli.level ~docs:common_options ~env ()
let renderer =
let open Cmdliner in
let env = Cmd.Env.info "REYNIR_FMT" in
Fmt_cli.style_renderer ~docs:common_options ~env ()
let utf_8 =
let open Cmdliner in
let doc = "Allow binaries to emit UTF-8 characters." in
let env = Cmd.Env.info "BLOGGER_UTF_8" in
Arg.(value & opt bool true & info [ "with-utf-8" ] ~doc ~env)
let reporter ppf =
let report src level ~over k msgf =
let k _ =
over ();
k ()
in
let with_metadata header _tags k ppf fmt =
Fmt.kpf
k
ppf
("%a[%a]: " ^^ fmt ^^ "\n%!")
Logs_fmt.pp_header
(level, header)
Fmt.(styled `Magenta string)
(Logs.Src.name src)
in
msgf @@ fun ?header ?tags fmt -> with_metadata header tags k ppf fmt
in
{ Logs.report }
let setup_logs utf_8 style_renderer level =
Fmt_tty.setup_std_outputs ~utf_8 ?style_renderer ();
Logs.set_level level;
Logs.set_reporter (reporter Fmt.stderr);
Option.is_none level
let setup_logs =
Cmdliner.Term.(const setup_logs $ utf_8 $ renderer $ verbosity)
let man =
let open Cmdliner in
[ `S Manpage.s_authors; `P "reynir.dk" ]
let watch_cmd =
let open Cmdliner in
let doc =
"Serve from the specified directory as an HTTP server and rebuild \
website on demand"
in
let exits = Cmd.Exit.defaults in
let path_arg =
let doc = "Specify where we build the website" in
let arg = Arg.info ~doc [ "destination" ] in
Arg.(value & opt (conv (Fpath.of_string, Fpath.pp)) default_target & arg)
in
let port_arg =
let doc = "The port" in
let arg = Arg.info ~doc [ "port"; "P"; "p" ] in
Arg.(value & opt (some int) None & arg)
in
let info = Cmd.info "watch" ~version ~doc ~exits ~man in
Cmd.v info Term.(const watch $ setup_logs $ path_arg $ port_arg)
let build_cmd =
let open Cmdliner in
let doc = "Build the website into the specified directory" in
let exits = Cmd.Exit.defaults in
let info = Cmd.info "build" ~version ~doc ~exits ~man in
let path_arg =
let doc = "Specify where to build the website" in
let arg = Arg.info ~doc ["destination"] in
Arg.(value & opt (conv (Fpath.of_string, Fpath.pp)) default_target & arg)
in
Cmd.v info Term.(const local_build $ setup_logs $ path_arg)
let cmd =
let open Cmdliner in
let sdocs = Manpage.s_common_options in
let doc = "Build, push or serve reynir.dk" in
let default_info = Cmd.info caller ~version ~doc ~sdocs ~man in
let default = Term.(ret (const (`Help (`Pager, None)))) in
Cmd.group ~default default_info [ build_cmd; watch_cmd ]
let () = exit @@ Cmdliner.Cmd.eval cmd