diff --git a/src/driver/common_args.ml b/src/driver/common_args.ml index ec9d06518e..3d50dfcd36 100644 --- a/src/driver/common_args.ml +++ b/src/driver/common_args.ml @@ -40,6 +40,10 @@ let odoc_bin = let doc = "Odoc binary to use" in Arg.(value & opt (some string) None & info [ "odoc" ] ~doc) +let odoc_md_bin = + let doc = "Odoc-md binary to use" in + Arg.(value & opt (some string) None & info [ "odoc-md" ] ~doc) + let compile_grep = let doc = "Show compile commands containing the string" in Arg.(value & opt (some string) None & info [ "compile-grep" ] ~doc) @@ -74,6 +78,7 @@ type t = { stats : bool; nb_workers : int; odoc_bin : string option; + odoc_md_bin : string option; compile_grep : string option; link_grep : string option; generate_grep : string option; @@ -95,6 +100,7 @@ let term = and+ stats = stats and+ nb_workers = nb_workers and+ odoc_bin = odoc_bin + and+ odoc_md_bin = odoc_md_bin and+ compile_grep = compile_grep and+ generate_json = generate_json and+ link_grep = link_grep @@ -111,6 +117,7 @@ let term = stats; nb_workers; odoc_bin; + odoc_md_bin; compile_grep; link_grep; generate_grep; diff --git a/src/driver/compile.ml b/src/driver/compile.ml index 51f6d46a5d..fe799c8eca 100644 --- a/src/driver/compile.ml +++ b/src/driver/compile.ml @@ -278,8 +278,11 @@ let html_generate ~occurrence_file ~remaps ~generate_json output_dir linked = let sidebar = match sidebar with | None -> None - | Some { output_file; json } -> + | Some { output_file; json; pkg_dir } -> Odoc.sidebar_generate ~output_file ~json index.output_file (); + Odoc.sidebar_generate + ~output_file:Fpath.(output_dir // pkg_dir / "sidebar.json") + ~json:true index.output_file (); Some output_file in (sherlodoc_index_one ~output_dir index, sidebar) diff --git a/src/driver/dune_style.ml b/src/driver/dune_style.ml index d1416cc3ef..d20b0f2026 100644 --- a/src/driver/dune_style.ml +++ b/src/driver/dune_style.ml @@ -125,6 +125,7 @@ let of_dune_build dir = selected = false; remaps = []; pkg_dir; + doc_dir = pkg_dir; other_docs = []; config = Global_config.empty; } ) diff --git a/src/driver/odoc.mli b/src/driver/odoc.mli index 127d83db9c..ec8473d3c9 100644 --- a/src/driver/odoc.mli +++ b/src/driver/odoc.mli @@ -9,6 +9,7 @@ val index_filename : string val sidebar_filename : string val odoc : Bos.Cmd.t ref +val odoc_md : Bos.Cmd.t ref type compile_deps = { digest : Digest.t; deps : (string * Digest.t) list } val compile_deps : Fpath.t -> (compile_deps, [> `Msg of string ]) result diff --git a/src/driver/odoc_driver.ml b/src/driver/odoc_driver.ml index b7c536d791..3236c6cb23 100644 --- a/src/driver/odoc_driver.ml +++ b/src/driver/odoc_driver.ml @@ -135,6 +135,7 @@ let run mode stats; nb_workers; odoc_bin; + odoc_md_bin; compile_grep; link_grep; generate_grep; @@ -143,6 +144,10 @@ let run mode generate_json; } = Option.iter (fun odoc_bin -> Odoc.odoc := Bos.Cmd.v odoc_bin) odoc_bin; + Option.iter + (fun odoc_md_bin -> Odoc.odoc_md := Bos.Cmd.v odoc_md_bin) + odoc_md_bin; + let _ = Voodoo.find_universe_and_version "foo" in Eio_main.run @@ fun env -> Eio.Switch.run @@ fun sw -> @@ -151,22 +156,24 @@ let run mode Stats.init_nprocs nb_workers; let () = Worker_pool.start_workers env sw nb_workers in - let all, extra_paths, actions = + let all, extra_paths, actions, gen_indices = match mode with | Voodoo { package_name = p; blessed; actions } -> let all = Voodoo.of_voodoo p ~blessed in let extra_paths = Voodoo.extra_paths odoc_dir in - (all, extra_paths, actions) + (all, extra_paths, actions, false) | Dune { path } -> - (Dune_style.of_dune_build path, Voodoo.empty_extra_paths, All) + (Dune_style.of_dune_build path, Voodoo.empty_extra_paths, All, true) | OpamLibs { libs } -> ( Packages.of_libs ~packages_dir:None (Util.StringSet.of_list libs), Voodoo.empty_extra_paths, - All ) + All, + true ) | OpamPackages { packages } -> ( Packages.of_packages ~packages_dir:None packages, Voodoo.empty_extra_paths, - All ) + All, + true ) in let virtual_check = @@ -221,7 +228,7 @@ let run mode let odocl_dir = Option.value odocl_dir ~default:odoc_dir in { Odoc_unit.odoc_dir; odocl_dir; index_dir; mld_dir } in - Odoc_units_of.packages ~dirs ~extra_paths ~remap all + Odoc_units_of.packages ~dirs ~gen_indices ~extra_paths ~remap all in Compile.init_stats units; let compiled = diff --git a/src/driver/odoc_unit.ml b/src/driver/odoc_unit.ml index cc60aded15..b46f528325 100644 --- a/src/driver/odoc_unit.ml +++ b/src/driver/odoc_unit.ml @@ -44,7 +44,7 @@ module Pkg_args = struct (Util.StringMap.bindings x.libs) end -type sidebar = { output_file : Fpath.t; json : bool } +type sidebar = { output_file : Fpath.t; json : bool; pkg_dir : Fpath.t } type index = { roots : Fpath.t list; @@ -126,9 +126,10 @@ and pp : all_kinds unit Fmt.t = (Fmt.option pp_index) x.index pp_kind (x.kind :> all_kinds) -let doc_dir pkg = pkg.Packages.pkg_dir -let lib_dir pkg lib = Fpath.(pkg.Packages.pkg_dir / lib.Packages.lib_name) -let src_dir pkg = Fpath.(pkg.Packages.pkg_dir / "src") +let pkg_dir pkg = pkg.Packages.pkg_dir +let doc_dir pkg = pkg.Packages.doc_dir +let lib_dir pkg lib = Fpath.(doc_dir pkg / lib.Packages.lib_name) +let src_dir pkg = Fpath.(doc_dir pkg / "src") let src_lib_dir pkg lib = Fpath.(src_dir pkg / lib.Packages.lib_name) type dirs = { diff --git a/src/driver/odoc_unit.mli b/src/driver/odoc_unit.mli index 7cbc39c867..8141455b6e 100644 --- a/src/driver/odoc_unit.mli +++ b/src/driver/odoc_unit.mli @@ -18,7 +18,7 @@ module Pkg_args : sig val pp : t Fmt.t end -type sidebar = { output_file : Fpath.t; json : bool } +type sidebar = { output_file : Fpath.t; json : bool; pkg_dir : Fpath.t } type index = { roots : Fpath.t list; output_file : Fpath.t; @@ -55,10 +55,11 @@ type t = [ impl | intf | mld | asset | md ] unit val pp : t Fmt.t +val pkg_dir : Packages.t -> Fpath.t val lib_dir : Packages.t -> Packages.libty -> Fpath.t val doc_dir : Packages.t -> Fpath.t -val src_lib_dir : Packages.t -> Packages.libty -> Fpath.t val src_dir : Packages.t -> Fpath.t +val src_lib_dir : Packages.t -> Packages.libty -> Fpath.t type dirs = { odoc_dir : Fpath.t; diff --git a/src/driver/odoc_units_of.ml b/src/driver/odoc_units_of.ml index 2f55ec6c60..b45d9d9117 100644 --- a/src/driver/odoc_units_of.ml +++ b/src/driver/odoc_units_of.ml @@ -1,6 +1,7 @@ open Odoc_unit -let packages ~dirs ~extra_paths ~remap (pkgs : Packages.t list) : t list = +let packages ~dirs ~extra_paths ~remap ~gen_indices (pkgs : Packages.t list) : + t list = let { odoc_dir; odocl_dir; index_dir; mld_dir = _ } = dirs in (* [module_of_hash] Maps a hash to the corresponding [Package.t], library name and [Packages.modulety]. [lib_dirs] maps a library name to the odoc dir containing its @@ -80,15 +81,16 @@ let packages ~dirs ~extra_paths ~remap (pkgs : Packages.t list) : t list = let index_of pkg = let roots = [ Fpath.( // ) odocl_dir (doc_dir pkg) ] in let output_file = Fpath.(index_dir / pkg.name / Odoc.index_filename) in + let pkg_dir = doc_dir pkg in let sidebar = let output_file = Fpath.(index_dir / pkg.name / Odoc.sidebar_filename) in - { output_file; json = false } + { output_file; json = false; pkg_dir } in { roots; output_file; json = false; - search_dir = pkg.pkg_dir; + search_dir = doc_dir pkg; sidebar = Some sidebar; } in @@ -226,7 +228,7 @@ let packages ~dirs ~extra_paths ~remap (pkgs : Packages.t list) : t list = let ext = Fpath.get_ext md in match ext with | ".md" -> - let rel_dir = doc_dir pkg in + let rel_dir = pkg_dir pkg in let kind = `Md in let name = md |> Fpath.rem_ext |> Fpath.basename |> ( ^ ) "page-" in let lib_deps = Util.StringSet.empty in @@ -295,6 +297,7 @@ let packages ~dirs ~extra_paths ~remap (pkgs : Packages.t list) : t list = ((pkg_index :: src_index :: lib_units) @ mld_units @ asset_units @ md_units) in - - let pkg_list :> t = Landing_pages.package_list ~dirs ~remap pkgs in - pkg_list :: List.concat_map of_package pkgs + if gen_indices then + let gen_indices :> t = Landing_pages.package_list ~dirs ~remap pkgs in + gen_indices :: List.concat_map of_package pkgs + else List.concat_map of_package pkgs diff --git a/src/driver/odoc_units_of.mli b/src/driver/odoc_units_of.mli index 67a7b74b05..cc862c3ac8 100644 --- a/src/driver/odoc_units_of.mli +++ b/src/driver/odoc_units_of.mli @@ -4,5 +4,6 @@ val packages : dirs:dirs -> extra_paths:Voodoo.extra_paths -> remap:bool -> + gen_indices:bool -> Packages.t list -> t list diff --git a/src/driver/opam.ml b/src/driver/opam.ml index 9216cd2948..fcf4bd0493 100644 --- a/src/driver/opam.ml +++ b/src/driver/opam.ml @@ -146,7 +146,47 @@ let pp_fpaths_of_package fmt l = docs) l -let classify_contents prefix only_package contents = +let classify_docs prefix only_package contents = + let pkg_match pkg = + match only_package with None -> true | Some p -> p = pkg + in + + let is_dir f = + try Sys.is_directory (Fpath.to_string f) with Sys_error _ -> false + in + + List.fold_left + (fun acc fpath -> + match Fpath.segs fpath with + | "doc" :: pkg :: "odoc-pages" :: _ :: _ + when pkg_match pkg && not (is_dir Fpath.(prefix // fpath)) -> + Logs.debug (fun m -> m "Found odoc page: %a" Fpath.pp fpath); + let kind = + match Fpath.get_ext fpath with ".mld" -> `Mld | _ -> `Asset + in + let rel_path = + Fpath.rem_prefix Fpath.(v "doc" / pkg / "odoc-pages") fpath + |> Option.get + in + { kind; file = Fpath.(prefix // fpath); rel_path } :: acc + | "doc" :: pkg :: "odoc-assets" :: _ :: _ + when pkg_match pkg && not (is_dir Fpath.(prefix // fpath)) -> + Logs.debug (fun m -> m "Found odoc page: %a" Fpath.pp fpath); + let rel_path = + Fpath.rem_prefix Fpath.(v "doc" / pkg / "odoc-assets") fpath + |> Option.get + in + let rel_path = Fpath.(v "_assets" // rel_path) in + { kind = `Asset; file = Fpath.(prefix // fpath); rel_path } :: acc + | [ "doc"; pkg; _ ] + when pkg_match pkg && not (is_dir Fpath.(prefix // fpath)) -> + Logs.debug (fun m -> m "Found other doc: %a" Fpath.pp fpath); + let rel_path = Fpath.base fpath in + { kind = `Other; file = Fpath.(prefix // fpath); rel_path } :: acc + | _ -> acc) + [] contents + +let classify_libs prefix only_package contents = let pkg_match pkg = match only_package with None -> true | Some p -> p = pkg in @@ -162,44 +202,7 @@ let classify_contents prefix only_package contents = | _ -> set) Fpath.Set.empty contents in - - let is_dir f = - try Sys.is_directory (Fpath.to_string f) with Sys_error _ -> false - in - - let docs = - List.fold_left - (fun acc fpath -> - match Fpath.segs fpath with - | "doc" :: pkg :: "odoc-pages" :: _ :: _ - when pkg_match pkg && not (is_dir Fpath.(prefix // fpath)) -> - Logs.debug (fun m -> m "Found odoc page: %a" Fpath.pp fpath); - let kind = - match Fpath.get_ext fpath with ".mld" -> `Mld | _ -> `Asset - in - let rel_path = - Fpath.rem_prefix Fpath.(v "doc" / pkg / "odoc-pages") fpath - |> Option.get - in - { kind; file = Fpath.(prefix // fpath); rel_path } :: acc - | "doc" :: pkg :: "odoc-assets" :: _ :: _ - when pkg_match pkg && not (is_dir Fpath.(prefix // fpath)) -> - Logs.debug (fun m -> m "Found odoc page: %a" Fpath.pp fpath); - let rel_path = - Fpath.rem_prefix Fpath.(v "doc" / pkg / "odoc-assets") fpath - |> Option.get - in - let rel_path = Fpath.(v "_assets" // rel_path) in - { kind = `Asset; file = Fpath.(prefix // fpath); rel_path } :: acc - | [ "doc"; pkg; _ ] - when pkg_match pkg && not (is_dir Fpath.(prefix // fpath)) -> - Logs.debug (fun m -> m "Found other doc: %a" Fpath.pp fpath); - let rel_path = Fpath.base fpath in - { kind = `Other; file = Fpath.(prefix // fpath); rel_path } :: acc - | _ -> acc) - [] contents - in - (libs, docs) + libs let dune_overrides () = let ocamlpath = Sys.getenv_opt "OCAMLPATH" in @@ -243,7 +246,8 @@ let dune_overrides () = (Util.StringSet.elements packages)); Util.StringSet.fold (fun pkg acc -> - let libs, docs = classify_contents base (Some pkg) contents in + let libs = classify_libs base (Some pkg) contents in + let docs = classify_docs base (Some pkg) contents in Logs.debug (fun m -> m "pkg %s Found %d docs" pkg (List.length docs)); ({ name = pkg; version = "dev" }, { libs; docs }) :: acc) @@ -262,7 +266,8 @@ let pkg_to_dir_map () = List.map (fun p -> let contents = pkg_contents p in - let libs, docs = classify_contents (Fpath.v prefix) None contents in + let libs = classify_libs (Fpath.v prefix) None contents in + let docs = classify_docs (Fpath.v prefix) None contents in (p, { libs; docs })) pkgs in diff --git a/src/driver/opam.mli b/src/driver/opam.mli index 86cf177e9f..4a56e0bf13 100644 --- a/src/driver/opam.mli +++ b/src/driver/opam.mli @@ -14,6 +14,8 @@ type package_of_fpath = package Fpath.map type fpaths_of_package = (package * installed_files) list val all_opam_packages : unit -> package list +val classify_docs : Fpath.t -> string option -> Fpath.t list -> doc_file list + val deps : string list -> package list val pkg_to_dir_map : unit -> fpaths_of_package * package_of_fpath val pp : Format.formatter -> package -> unit diff --git a/src/driver/packages.ml b/src/driver/packages.ml index af91eebad8..57a17bf08e 100644 --- a/src/driver/packages.ml +++ b/src/driver/packages.ml @@ -91,6 +91,7 @@ type t = { remaps : (string * string) list; other_docs : Fpath.t list; pkg_dir : Fpath.t; + doc_dir : Fpath.t; config : Global_config.t; } @@ -271,22 +272,21 @@ end (* Construct the list of mlds and assets from a package name and its list of pages *) let mk_mlds docs = - let mlds, assets = - List.fold_left - (fun (mlds, assets) doc -> - match doc.Opam.kind with - | `Mld -> - ( { mld_path = doc.Opam.file; mld_rel_path = doc.Opam.rel_path } - :: mlds, - assets ) - | `Asset -> - ( mlds, - { asset_path = doc.Opam.file; asset_rel_path = doc.Opam.rel_path } - :: assets ) - | `Other -> (mlds, assets)) - ([], []) docs - in - (mlds, assets) + List.fold_left + (fun (mlds, assets, others) doc -> + match doc.Opam.kind with + | `Mld -> + ( { mld_path = doc.Opam.file; mld_rel_path = doc.Opam.rel_path } + :: mlds, + assets, + others ) + | `Asset -> + ( mlds, + { asset_path = doc.Opam.file; asset_rel_path = doc.Opam.rel_path } + :: assets, + others ) + | `Other -> (mlds, assets, doc.Opam.file :: others)) + ([], [], []) docs let fix_missing_deps pkgs = let lib_name_by_hash = @@ -396,7 +396,7 @@ let of_libs ~packages_dir libs = pkg = pkg') opam_map in - let mlds, assets = mk_mlds docs in + let mlds, assets, _ = mk_mlds docs in Some { name = pkg.name; @@ -408,6 +408,7 @@ let of_libs ~packages_dir libs = remaps = []; other_docs = []; pkg_dir; + doc_dir = pkg_dir; config; }) acc) @@ -457,7 +458,7 @@ let of_packages ~packages_dir packages = in let pkg_dir = pkg_dir packages_dir pkg.name in let config = Global_config.load pkg.name in - let mlds, assets = mk_mlds files.docs in + let mlds, assets, _ = mk_mlds files.docs in let selected = List.mem pkg.name packages in let remaps = if selected then [] @@ -491,6 +492,7 @@ let of_packages ~packages_dir packages = remaps; other_docs = []; pkg_dir; + doc_dir = pkg_dir; config; } acc) diff --git a/src/driver/packages.mli b/src/driver/packages.mli index 61ed731de9..f6a2d5e0e8 100644 --- a/src/driver/packages.mli +++ b/src/driver/packages.mli @@ -77,6 +77,7 @@ type t = { remaps : (string * string) list; other_docs : Fpath.t list; pkg_dir : Fpath.t; + doc_dir : Fpath.t; config : Global_config.t; } @@ -84,6 +85,8 @@ val pp : Format.formatter -> t -> unit type set = t Util.StringMap.t +val mk_mlds : Opam.doc_file list -> mld list * asset list * Fpath.t list + val of_libs : packages_dir:Fpath.t option -> Util.StringSet.t -> set (** Turns a set of libraries into a map from package name to package *) diff --git a/src/driver/stats.ml b/src/driver/stats.ml index 0c402ebf39..397af57357 100644 --- a/src/driver/stats.ml +++ b/src/driver/stats.ml @@ -174,7 +174,7 @@ let compute_produced_tree cmd dir = | Error _ -> acc in Bos.OS.Dir.fold_contents ~dotfiles:true ~elements:`Files acc_file_sizes [] dir - |> Result.get_ok + |> Result.value ~default:[] |> compute_metric_int "produced" cmd ("files produced by 'odoc " ^ cmd ^ "'") (** Analyze the running time of the slowest commands. *) diff --git a/src/driver/voodoo.ml b/src/driver/voodoo.ml index 52eb6b2dd0..a1c686c92b 100644 --- a/src/driver/voodoo.ml +++ b/src/driver/voodoo.ml @@ -67,50 +67,6 @@ let metas_of_pkg pkg = filename = "META") pkg.files -(* Given a [pkg] and an output [pkg_path], returns a pair of lists of assets an mlds *) -let assets_and_mlds_of_pkg pkg_path pkg = - pkg.files - |> List.filter_map (fun p -> - let prefix = Fpath.(v "doc" / pkg.name / "odoc-pages") in - let asset_prefix = Fpath.(v "doc" / pkg.name / "odoc-assets") in - let check_name pkg_name = - if pkg_name <> pkg.name then ( - Logs.err (fun k -> - k - "Error: name in 'doc' dir does not match package name: %s \ - <> %s" - pkg_name pkg.name); - None) - else Some () - in - let ( >>= ) = Option.bind in - match Fpath.segs p with - | "doc" :: pkg_name :: "odoc-pages" :: _ :: _ -> ( - check_name pkg_name >>= fun () -> - match Fpath.rem_prefix prefix p with - | None -> None - | Some rel_path -> - let path = Fpath.(pkg_path // p) in - if Fpath.has_ext "mld" p then - Some - (`M { Packages.mld_path = path; mld_rel_path = rel_path }) - else - Some - (`A - { Packages.asset_path = path; asset_rel_path = rel_path }) - ) - | "doc" :: pkg_name :: "odoc-assets" :: _ :: _ -> ( - check_name pkg_name >>= fun () -> - match Fpath.rem_prefix asset_prefix p with - | None -> None - | Some asset_rel_path -> - let asset_path = Fpath.(pkg_path // p) in - Some (`A { Packages.asset_path; asset_rel_path })) - | _ -> None) - |> List.partition_map (function - | `A asset -> Either.Left asset - | `M mld -> Either.Right mld) - let process_package pkg = let metas = metas_of_pkg pkg in @@ -139,7 +95,8 @@ let process_package pkg = Fmt.(list ~sep:comma (pair ~sep:comma string ss_pp)) (Util.StringMap.bindings all_lib_deps)); - let assets, mlds = assets_and_mlds_of_pkg pkg_path pkg in + let docs = Opam.classify_docs pkg_path (Some pkg.name) pkg.files in + let mlds, assets, other_docs = Packages.mk_mlds docs in let config = let config_file = @@ -222,6 +179,8 @@ let process_package pkg = |> List.flatten in let libraries = meta_libraries @ non_meta_libraries in + let pkg_dir = top_dir pkg in + let doc_dir = Fpath.(pkg_dir / "doc") in let result = { Packages.name = pkg.name; @@ -231,8 +190,9 @@ let process_package pkg = assets; selected = true; remaps = []; - other_docs = []; - pkg_dir = top_dir pkg; + other_docs; + pkg_dir; + doc_dir; config; } in @@ -284,7 +244,6 @@ let of_voodoo pkg_name ~blessed = match packages with | [ package ] -> let package = process_package package in - Logs.debug (fun m -> m "Package: %a\n%!" Packages.pp package); Util.StringMap.singleton pkg_name package | [] -> Logs.err (fun m -> m "No package found for %s" pkg_name); @@ -315,17 +274,17 @@ let extra_paths compile_dir = (fun (pkgs, libs) abs_path -> let path = Fpath.rem_prefix compile_dir abs_path |> Option.get in match Fpath.segs path with - | [ "p"; _pkg; _version; libname; l ] when l = lib_marker -> + | [ "p"; _pkg; _version; "doc"; libname; l ] when l = lib_marker -> Logs.debug (fun m -> m "Found lib marker: %a" Fpath.pp path); (pkgs, Util.StringMap.add libname (Fpath.parent path) libs) - | [ "p"; pkg; _version; l ] when l = pkg_marker -> + | [ "p"; pkg; _version; "doc"; l ] when l = pkg_marker -> Logs.debug (fun m -> m "Found pkg marker: %a" Fpath.pp path); (Util.StringMap.add pkg (Fpath.parent path) pkgs, libs) - | [ "u"; _universe; _pkg; _version; libname; l ] when l = lib_marker - -> + | [ "u"; _universe; _pkg; _version; "doc"; libname; l ] + when l = lib_marker -> Logs.debug (fun m -> m "Found lib marker: %a" Fpath.pp path); (pkgs, Util.StringMap.add libname (Fpath.parent path) libs) - | [ "u"; _universe; pkg; _version; l ] when l = pkg_marker -> + | [ "u"; _universe; pkg; _version; "doc"; l ] when l = pkg_marker -> Logs.debug (fun m -> m "Found pkg marker: %a" Fpath.pp path); (Util.StringMap.add pkg (Fpath.parent path) pkgs, libs) | _ -> (pkgs, libs))