Skip to content

Commit 62fccc4

Browse files
committed
Create bash to unify directory targets unique
1 parent 0cc9679 commit 62fccc4

File tree

1 file changed

+93
-55
lines changed

1 file changed

+93
-55
lines changed

src/dune_rules/odoc.ml

Lines changed: 93 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -784,21 +784,7 @@ let odoc_artefacts sctx target =
784784
| Lib lib ->
785785
let info = Lib.Local.info lib in
786786
let obj_dir = Lib_info.obj_dir info in
787-
let+ modules =
788-
let+ modules = Dir_contents.modules_of_local_lib sctx lib in
789-
Modules.fold modules ~init:[] ~f:(fun m acc ->
790-
(* Only include modules that:
791-
1. Have public visibility
792-
2. Are not wrapped library implementation modules (those with __ in the name) *)
793-
if Module.visibility m = Public
794-
&& (Module.obj_name m
795-
|> Module_name.Unique.to_name ~loc:Loc.none
796-
|> Module_name.to_string
797-
|> String.contains_double_underscore
798-
|> not)
799-
then m :: acc
800-
else acc)
801-
in
787+
let+ modules = entry_modules_by_lib sctx lib in
802788
List.map modules ~f:(fun m ->
803789
let odoc_file = Obj_dir.Module.odoc obj_dir m in
804790
create_odoc ctx ~target odoc_file)
@@ -905,10 +891,15 @@ let out_files ctx (output : Output_format.t) odocs =
905891
;;
906892

907893
let add_format_alias_deps ctx format target odocs =
908-
let paths = out_files ctx format odocs in
909-
Rules.Produce.Alias.add_deps
910-
(Dep.format_alias format ctx target)
911-
(Action_builder.paths paths)
894+
match (format : Output_format.t) with
895+
| Markdown ->
896+
(* skip intermediate aliases since package directories are directory targets *)
897+
Memo.return ()
898+
| Html | Json ->
899+
let paths = out_files ctx format odocs in
900+
Rules.Produce.Alias.add_deps
901+
(Dep.format_alias format ctx target)
902+
(Action_builder.paths paths)
912903
;;
913904

914905
let setup_lib_html_rules_def =
@@ -1010,7 +1001,15 @@ let setup_pkg_html_rules sctx ~pkg : unit Memo.t =
10101001
let setup_lib_markdown_rules sctx lib =
10111002
let target = Lib lib in
10121003
let* odocs = odoc_artefacts sctx target in
1013-
let* () = Memo.parallel_iter odocs ~f:(fun odoc -> setup_generate_markdown sctx odoc) in
1004+
(* For libraries WITH a package, generation happens in the package-level rule.
1005+
Only generate for libraries WITHOUT a package. *)
1006+
let* () =
1007+
match Lib_info.package (Lib.Local.info lib) with
1008+
| Some _ -> Memo.return () (* Package-level rule handles it *)
1009+
| None ->
1010+
(* No package, so we need individual rules *)
1011+
Memo.parallel_iter odocs ~f:(fun odoc -> setup_generate_markdown sctx odoc)
1012+
in
10141013
Memo.With_implicit_output.exec setup_lib_markdown_rules_def (sctx, lib)
10151014
;;
10161015

@@ -1023,8 +1022,45 @@ let setup_pkg_markdown_rules_def =
10231022
Memo.List.concat_map libs ~f:(fun lib -> odoc_artefacts sctx (Lib lib))
10241023
in
10251024
let all_odocs = pkg_odocs @ lib_odocs in
1025+
(* Generate ALL markdown for this package in ONE rule with directory target.
1026+
Since odoc generates unpredictable files (Belt.md, Belt-Array.md, Belt-List.md, etc.)
1027+
from nested submodules, we must use a directory target and batch all odoc commands. *)
1028+
let* () =
1029+
if List.is_empty all_odocs
1030+
then Memo.return ()
1031+
else
1032+
let pkg_markdown_dir = Paths.markdown ctx (Pkg pkg) in
1033+
let markdown_root = Paths.markdown_root ctx in
1034+
let rule =
1035+
let bash_cmd_args =
1036+
let open Action_builder.O in
1037+
let* odoc_prog = odoc_program sctx (Context.build_dir ctx) in
1038+
let odoc_path = Action.Prog.ok_exn odoc_prog |> Path.to_string in
1039+
let bash_cmd =
1040+
List.map all_odocs ~f:(fun odoc ->
1041+
let odocl_rel = Path.reach (Path.build odoc.odocl_file) ~from:(Path.build markdown_root) in
1042+
Printf.sprintf "%s markdown-generate -o . %s" odoc_path odocl_rel)
1043+
|> String.concat ~sep:" && "
1044+
in
1045+
let* () =
1046+
List.map all_odocs ~f:(fun odoc -> Action_builder.path (Path.build odoc.odocl_file))
1047+
|> Action_builder.all
1048+
>>| ignore
1049+
in
1050+
Action_builder.return (Command.Args.S [ A "-c"; A bash_cmd ])
1051+
in
1052+
let deps = Action_builder.env_var "ODOC_SYNTAX" in
1053+
let open Action_builder.With_targets.O in
1054+
Action_builder.with_no_targets deps
1055+
>>> Command.run
1056+
~dir:(Path.build markdown_root)
1057+
(Ok (Path.of_string "/bin/bash"))
1058+
[ Dyn bash_cmd_args ]
1059+
|> Action_builder.With_targets.add_directories ~directory_targets:[ pkg_markdown_dir ]
1060+
in
1061+
add_rule sctx rule
1062+
in
10261063
let* () = Memo.parallel_iter libs ~f:(setup_lib_markdown_rules sctx) in
1027-
let* () = Memo.parallel_iter pkg_odocs ~f:(setup_generate_markdown sctx) in
10281064
add_format_alias_deps ctx Markdown (Pkg pkg) all_odocs
10291065
in
10301066
setup_pkg_rules_def "setup-package-markdown-rules" f
@@ -1045,11 +1081,20 @@ let setup_package_aliases_format sctx (pkg : Package.t) (output : Output_format.
10451081
let* libs =
10461082
Context.name ctx |> libs_of_pkg ~pkg:name >>| List.map ~f:(fun lib -> Lib lib)
10471083
in
1048-
Pkg name :: libs
1049-
|> List.map ~f:(Dep.format_alias output ctx)
1050-
|> Dune_engine.Dep.Set.of_list_map ~f:(fun f -> Dune_engine.Dep.alias f)
1051-
|> Action_builder.deps
1052-
|> Rules.Produce.Alias.add_deps alias
1084+
let deps =
1085+
match (output : Output_format.t) with
1086+
| Markdown ->
1087+
let directory_target = Paths.markdown ctx (Pkg name) in
1088+
let toplevel_index = Paths.markdown_index ctx in
1089+
let* () = Action_builder.path (Path.build directory_target) in
1090+
Action_builder.path (Path.build toplevel_index)
1091+
| Html | Json ->
1092+
Pkg name :: libs
1093+
|> List.map ~f:(Dep.format_alias output ctx)
1094+
|> Dune_engine.Dep.Set.of_list_map ~f:(fun f -> Dune_engine.Dep.alias f)
1095+
|> Action_builder.deps
1096+
in
1097+
Rules.Produce.Alias.add_deps alias deps
10531098
;;
10541099

10551100
let setup_package_aliases sctx (pkg : Package.t) =
@@ -1185,36 +1230,29 @@ let gen_rules sctx ~dir rest =
11851230
>>> setup_css_rule sctx
11861231
>>> setup_toplevel_index_rule sctx Html
11871232
>>> setup_toplevel_index_rule sctx Json)
1188-
| [ "_markdown" ] -> has_rules (setup_toplevel_index_rule sctx Markdown)
1189-
| [ "_markdown"; lib_unique_name_or_pkg ] ->
1233+
| [ "_markdown" ] ->
1234+
let* packages = Dune_load.packages () in
1235+
let ctx = Super_context.context sctx in
1236+
let all_package_dirs =
1237+
Package.Name.Map.to_list packages
1238+
|> List.map ~f:(fun (_, (pkg : Package.t)) ->
1239+
let pkg_name = Package.name pkg in
1240+
Paths.markdown ctx (Pkg pkg_name))
1241+
in
1242+
let directory_targets =
1243+
List.fold_left all_package_dirs ~init:Path.Build.Map.empty ~f:(fun acc dir ->
1244+
Path.Build.Map.set acc dir Loc.none)
1245+
in
11901246
has_rules
1191-
(
1192-
let ctx = Super_context.context sctx in
1193-
let* lib, lib_db = Scope_key.of_string (Context.name ctx) lib_unique_name_or_pkg in
1194-
let* lib =
1195-
let+ lib = Lib.DB.find lib_db lib in
1196-
Option.bind ~f:Lib.Local.of_lib lib
1197-
in
1198-
let+ () =
1199-
match lib with
1200-
| None -> Memo.return ()
1201-
| Some lib ->
1202-
(match Lib_info.package (Lib.Local.info lib) with
1203-
| None ->
1204-
(* lib with no package above it *)
1205-
setup_lib_markdown_rules sctx lib
1206-
| Some pkg -> setup_pkg_markdown_rules sctx ~pkg)
1207-
and+ () =
1208-
let* packages = Dune_load.packages () in
1209-
match
1210-
Package.Name.Map.find packages (Package.Name.of_string lib_unique_name_or_pkg)
1211-
with
1212-
| None -> Memo.return ()
1213-
| Some pkg ->
1214-
let name = Package.name pkg in
1215-
setup_pkg_markdown_rules sctx ~pkg:name
1216-
in
1217-
())
1247+
~directory_targets
1248+
(let* () = setup_toplevel_index_rule sctx Markdown in
1249+
Package.Name.Map.to_seq packages
1250+
|> Memo.parallel_iter_seq ~f:(fun (_, (pkg : Package.t)) ->
1251+
let pkg_name = Package.name pkg in
1252+
setup_pkg_markdown_rules sctx ~pkg:pkg_name))
1253+
| [ "_markdown"; _lib_unique_name_or_pkg ] ->
1254+
(* package directories are directory targets *)
1255+
Memo.return Gen_rules.no_rules
12181256
| [ "_mlds"; pkg ] ->
12191257
with_package pkg ~f:(fun pkg ->
12201258
let pkg = Package.name pkg in

0 commit comments

Comments
 (0)