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