From 2cc44e3c6c56e994414dcb7b837fcf8edbd4c35d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Reynir=20Bj=C3=B6rnsson?= Date: Mon, 22 May 2023 13:20:53 +0200 Subject: [PATCH] Initial commit Nothing works --- dune-project | 3 ++ src/dune | 20 ++++++++ src/file.ml | 16 +++++++ src/file.mli | 6 +++ src/reynir_www.ml | 114 ++++++++++++++++++++++++++++++++++++++++++++++ src/task.ml | 24 ++++++++++ 6 files changed, 183 insertions(+) create mode 100644 dune-project create mode 100644 src/dune create mode 100644 src/file.ml create mode 100644 src/file.mli create mode 100644 src/reynir_www.ml create mode 100644 src/task.ml diff --git a/dune-project b/dune-project new file mode 100644 index 0000000..5c3d447 --- /dev/null +++ b/dune-project @@ -0,0 +1,3 @@ +(lang dune 3.7) + +(name reynir-www) diff --git a/src/dune b/src/dune new file mode 100644 index 0000000..950c76f --- /dev/null +++ b/src/dune @@ -0,0 +1,20 @@ +(executable + (name reynir_www) + (libraries + logs + logs.fmt + logs.cli + fmt + fmt.tty + fmt.cli + cmdliner + preface + mirage-clock-unix + http-lwt-client + git-unix + yocaml + yocaml_yaml + yocaml_markdown + yocaml_unix + yocaml_git + yocaml_jingoo)) diff --git a/src/file.ml b/src/file.ml new file mode 100644 index 0000000..1c664ed --- /dev/null +++ b/src/file.ml @@ -0,0 +1,16 @@ +open Yocaml + +let is_css = with_extension "css" +let is_javascript = with_extension "js" + +let is_image = + let open Preface.Predicate in + with_extension "png" || + with_extension "svg" || + with_extension "jpg" || + with_extension "jpeg" || + with_extension "gif" + +let is_markdown = + let open Preface.Predicate in + with_extension "md" || with_extension "markdown" diff --git a/src/file.mli b/src/file.mli new file mode 100644 index 0000000..c44bc0d --- /dev/null +++ b/src/file.mli @@ -0,0 +1,6 @@ +open Yocaml + +val is_css : Filepath.t -> bool +val is_javascript : Filepath.t -> bool +val is_image : Filepath.t -> bool +val is_markdown : Filepath.t -> bool diff --git a/src/reynir_www.ml b/src/reynir_www.ml new file mode 100644 index 0000000..acc4d72 --- /dev/null +++ b/src/reynir_www.ml @@ -0,0 +1,114 @@ +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 + Task.move_images 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 diff --git a/src/task.ml b/src/task.ml new file mode 100644 index 0000000..524eadd --- /dev/null +++ b/src/task.ml @@ -0,0 +1,24 @@ +open Yocaml +module Metaformat = Yocaml_yaml +module Markup = Yocaml_markdown +module Template = Yocaml_jingoo + +let css_target target = "css" |> into target +let images_target target = "images" |> into target +let index_html target = "index.html" |> into target +let about_us_html target = "about_us.html" |> into target +let our_work_html target = "our_work.html" |> into target +let donate_html target = "donate.html" |> into target + +let move_css target = + process_files + [ "css" ] + File.is_css + (Build.copy_file ~into:(css_target target)) + +let move_images target = + process_files + [ "images" ] + File.is_image + (Build.copy_file ~into:(images_target target)) +