I was hoping to be able to write some index.mld in submodule2 with a dune file specifying (documentation) but that makes dune crash.
Alternatively I could write submodule2.ml and write documentation in there but I’d have to copy module A = A module B = B ...and keep adding lines every time I add a module.. It’s not very expensive but it’s the kind of tiny paper cuts that are annoying when projects grow.
I managed to get away with the following make_entry_point.ml
let () =
if Array.length Sys.argv != 2 then
Printf.eprintf "Usage: %s <folder>" Sys.argv.(0)
let normalise_path path =
let sep =
if String.length Filename.dir_sep != 1 then
failwith "dir_sep is not a character"
else Filename.dir_sep.[0]
in
let with_indirections =
if Filename.is_relative path then Filename.concat (Sys.getcwd ()) path
else path
in
let parts = String.split_on_char sep with_indirections in
let rec aux acc = function
| [] -> String.concat Filename.dir_sep (List.rev acc)
| x :: tl when String.equal Filename.current_dir_name x -> aux acc tl
| x :: tl when String.equal Filename.parent_dir_name x -> (
match acc with [] -> aux (x :: acc) tl | _ :: acc_tl -> aux acc_tl tl)
| x :: tl -> aux (x :: acc) tl
in
aux [] parts
let folder = Sys.argv.(1) |> normalise_path
let doc_file =
Filename.concat folder (Filename.basename folder ^ ".mld") |> normalise_path
let doc_content = In_channel.with_open_text doc_file In_channel.input_all
let module_list =
Sys.readdir folder
|> Array.to_seq
|> Seq.filter (fun f ->
Filename.check_suffix f ".ml" && not (Filename.check_suffix f ".pp.ml"))
|> Seq.map (fun f ->
let f = Filename.chop_suffix f ".ml" in
if String.length f = 0 then failwith "Empty filename";
let f = String.capitalize_ascii f in
Printf.sprintf "module %s = %s" f f)
|> List.of_seq
|> String.concat "\n"
let whole_file = Printf.sprintf "(**\n%s\n*)\n\n\n%s" doc_content module_list
let () = Printf.printf "%s\n" whole_file
(though admittedly frutrating that most of the code is about normalising a path, and stdlib has no means of splitting a string on a string, only on a char)