From 7ed8b76b0f15eb0b9751941b41e67ea41308186e Mon Sep 17 00:00:00 2001 From: Emile Trotignon Date: Thu, 18 Jul 2024 16:50:12 +0200 Subject: [PATCH 01/10] generation of asset files --- src/model/lang.ml | 5 ++ src/model/paths_types.ml | 1 + src/model/root.ml | 10 ++- src/model/root.mli | 3 + src/odoc/bin/main.ml | 42 +++++++++++ src/odoc/compile.ml | 18 +++++ src/odoc/compile.mli | 2 + src/odoc/depends.ml | 2 +- src/odoc/odoc_file.ml | 11 +++ src/odoc/odoc_file.mli | 3 + src/odoc/odoc_link.ml | 1 + src/odoc/rendering.ml | 1 + src/odoc/resolver.ml | 21 ++++-- test/odoc_print/odoc_print.ml | 1 + test/pages/new_assets.t/index.mld | 4 ++ test/pages/new_assets.t/run.t | 114 ++++++++++++++++++++++++++++++ test/pages/new_assets.t/test.mli | 7 ++ 17 files changed, 238 insertions(+), 8 deletions(-) create mode 100644 test/pages/new_assets.t/index.mld create mode 100644 test/pages/new_assets.t/run.t create mode 100644 test/pages/new_assets.t/test.mli diff --git a/src/model/lang.ml b/src/model/lang.ml index f39ebb1a92..d4a95573fb 100644 --- a/src/model/lang.ml +++ b/src/model/lang.ml @@ -569,6 +569,11 @@ module rec SourceTree : sig end = SourceTree +module rec Asset : sig + type t = { name : Identifier.AssetFile.t; root : Root.t } +end = + Asset + let umty_of_mty : ModuleType.expr -> ModuleType.U.expr option = function | Signature sg -> Some (Signature sg) | Path { p_path; _ } -> Some (Path p_path) diff --git a/src/model/paths_types.ml b/src/model/paths_types.ml index e5daaf17bb..63b40e84f9 100644 --- a/src/model/paths_types.ml +++ b/src/model/paths_types.ml @@ -52,6 +52,7 @@ module Identifier = struct type odoc_id_pv = [ page_pv | source_page_pv + | asset_file_pv | `Root of container_page option * ModuleName.t | `Implementation of ModuleName.t ] (** @canonical Odoc_model.Paths.Identifier.OdocId.t_pv *) diff --git a/src/model/root.ml b/src/model/root.ml index 3763534cd7..87f436c5f7 100644 --- a/src/model/root.ml +++ b/src/model/root.ml @@ -35,6 +35,7 @@ module Odoc_file = struct | Page of page | Compilation_unit of compilation_unit | Impl of string + | Asset let create_unit ~force_hidden name = let hidden = force_hidden || Names.contains_double_underscore name in @@ -46,10 +47,13 @@ module Odoc_file = struct let name = function | Page { name; _ } | Compilation_unit { name; _ } | Impl name -> name + | Asset -> failwith "todo" let hidden = function - | Page _ | Impl _ -> false + | Page _ | Impl _ | Asset -> false | Compilation_unit m -> m.hidden + + let asset = Asset end type t = { @@ -86,6 +90,10 @@ let to_string t = | `Root (None, name) -> Format.fprintf fmt "%a" Names.ModuleName.fmt name | `Implementation name -> Format.fprintf fmt "impl(%a)" Names.ModuleName.fmt name + | `AssetFile (parent, name) -> + Format.fprintf fmt "%a::%s" pp + (parent :> Paths.Identifier.OdocId.t) + name in Format.asprintf "%a" pp t.id diff --git a/src/model/root.mli b/src/model/root.mli index 75efa5b266..88b322d54e 100644 --- a/src/model/root.mli +++ b/src/model/root.mli @@ -34,6 +34,7 @@ module Odoc_file : sig | Page of page | Compilation_unit of compilation_unit | Impl of string + | Asset val create_unit : force_hidden:bool -> string -> t @@ -41,6 +42,8 @@ module Odoc_file : sig val create_impl : string -> t + val asset : t + val name : t -> string val hidden : t -> bool diff --git a/src/odoc/bin/main.ml b/src/odoc/bin/main.ml index 41dddc29f4..5e4eec9dc1 100644 --- a/src/odoc/bin/main.ml +++ b/src/odoc/bin/main.ml @@ -343,6 +343,47 @@ end = struct Term.info "compile" ~docs ~doc ~man end +module Compile_asset = struct + let compile_asset parent_id name output_dir = + Odoc_odoc.Compile.compile_asset ~parent_id ~name ~output_dir + + let output_dir = + let doc = "Output file directory. " in + Arg.( + required + & opt (some string) None + & info ~docs ~docv:"PATH" ~doc [ "output-dir" ]) + + let cmd = + let name_opt = + let doc = "Name of the asset." in + Arg.( + required + & opt (some string) None + & info ~docs ~docv:"NAME" ~doc [ "name" ]) + in + let parent_id_opt = + let doc = "Parent id." in + Arg.( + required + & opt (some string) None + & info ~docs ~docv:"PARENT" ~doc [ "parent-id" ]) + in + Term.(const compile_asset $ parent_id_opt $ name_opt $ output_dir) + + let info ~docs = + let man = + [ + `S "DEPENDENCIES"; + `P + "There are no dependency for compile assets, in particular you do \ + not need the asset itself at this stage."; + ] + in + let doc = "Declare the name of an asset." in + Term.info "compile-asset" ~docs ~doc ~man +end + module Source_tree = struct let prefix = "srctree-" @@ -1555,6 +1596,7 @@ let () = Occurrences.Count.(cmd, info ~docs:section_pipeline); Occurrences.Aggregate.(cmd, info ~docs:section_pipeline); Compile.(cmd, info ~docs:section_pipeline); + Compile_asset.(cmd, info ~docs:section_pipeline); Odoc_link.(cmd, info ~docs:section_pipeline); Odoc_html.generate ~docs:section_pipeline; Support_files_command.(cmd, info ~docs:section_pipeline); diff --git a/src/odoc/compile.ml b/src/odoc/compile.ml index 432a151fe2..bac042110f 100644 --- a/src/odoc/compile.ml +++ b/src/odoc/compile.ml @@ -337,3 +337,21 @@ let compile ~resolver ~hidden ~cli_spec ~warnings_options input = Error.handle_errors_and_warnings ~warnings_options result >>= fun unit -> Odoc_file.save_unit output ~warnings unit; Ok () + +let compile_asset ~parent_id ~name ~output_dir = + let open Odoc_model in + let parent_id = mk_id parent_id in + let id = + Paths.Identifier.Mk.asset_file ((parent_id :> Paths.Identifier.Page.t), name) + in + let directory = + path_of_id output_dir parent_id |> Fpath.to_string |> Fs.Directory.of_string + in + let name = "asset-" ^ name ^ ".odoc" in + let output = Fs.File.create ~directory ~name in + let digest = Digest.string name in + let root = + Root.{ id = (id :> Paths.Identifier.OdocId.t); digest; file = Asset } + in + let asset = Lang.Asset.{ name = id; root } in + Odoc_file.save_asset output ~warnings:[] asset diff --git a/src/odoc/compile.mli b/src/odoc/compile.mli index 04f82b3f2c..5153ed2c46 100644 --- a/src/odoc/compile.mli +++ b/src/odoc/compile.mli @@ -59,3 +59,5 @@ val compile : Fpath.t -> (unit, [> msg ]) result (** Produces .odoc files out of [.cm{i,t,ti}] or .mld files. *) + +val compile_asset : parent_id:string -> name:string -> output_dir:string -> unit diff --git a/src/odoc/depends.ml b/src/odoc/depends.ml index 33c0a3c4e3..d6d610d129 100644 --- a/src/odoc/depends.ml +++ b/src/odoc/depends.ml @@ -88,7 +88,7 @@ let deps_of_imports ~deps imports = let deps_of_odoc_file ~deps input = Odoc_file.load input >>= fun unit -> match unit.content with - | Page_content _ | Source_tree_content _ -> + | Page_content _ | Source_tree_content _ | Asset_content _ -> Ok () (* XXX something should certainly be done here *) | Impl_content impl -> deps_of_imports ~deps impl.Odoc_model.Lang.Implementation.imports diff --git a/src/odoc/odoc_file.ml b/src/odoc/odoc_file.ml index eb8a4c38ba..08cb9a1bbd 100644 --- a/src/odoc/odoc_file.ml +++ b/src/odoc/odoc_file.ml @@ -24,6 +24,7 @@ type content = | Source_tree_content of Lang.SourceTree.t | Impl_content of Lang.Implementation.t | Unit_content of unit_content + | Asset_content of Lang.Asset.t type t = { content : content; warnings : Odoc_model.Error.t list } @@ -116,3 +117,13 @@ let load_root file = let save_index dst idx = save_ dst (fun oc -> Marshal.to_channel oc idx []) let load_index file = load_ file (fun ic -> Ok (Marshal.from_channel ic)) + +let save_asset file ~warnings impl = + let dir = Fs.File.dirname file in + let base = Fs.File.(to_string @@ basename file) in + let file = + if Astring.String.is_prefix ~affix:"asset-" base then file + else Fs.File.create ~directory:dir ~name:("asset-" ^ base) + in + let t = { content = Asset_content impl; warnings } in + save_ file (fun oc -> Marshal.to_channel oc t []) diff --git a/src/odoc/odoc_file.mli b/src/odoc/odoc_file.mli index 8f3b58d9f0..1bd8ed56c0 100644 --- a/src/odoc/odoc_file.mli +++ b/src/odoc/odoc_file.mli @@ -27,6 +27,7 @@ type content = | Source_tree_content of Lang.SourceTree.t | Impl_content of Lang.Implementation.t | Unit_content of unit_content + | Asset_content of Lang.Asset.t type t = { content : content; warnings : Error.t list } @@ -62,3 +63,5 @@ val save_index : val load_index : Fs.File.t -> (Odoc_search.Entry.t Odoc_model.Lang.Index.t, [> msg ]) result (** Load a [.odoc-index] file. *) + +val save_asset : Fpath.t -> warnings:Error.t list -> Lang.Asset.t -> unit diff --git a/src/odoc/odoc_link.ml b/src/odoc/odoc_link.ml index 936cad9870..e66e37e1f7 100644 --- a/src/odoc/odoc_link.ml +++ b/src/odoc/odoc_link.ml @@ -100,3 +100,4 @@ let from_odoc ~resolver ~warnings_options input output = >>= fun (m, warnings) -> Odoc_file.save_unit output ~warnings m; Ok (`Module m) + | Asset_content _ -> failwith "todo" diff --git a/src/odoc/rendering.ml b/src/odoc/rendering.ml index 41ff6e705d..7372bbf4eb 100644 --- a/src/odoc/rendering.ml +++ b/src/odoc/rendering.ml @@ -98,6 +98,7 @@ let documents_of_odocl ~warnings_options ~renderer ~extra ~source ~syntax input | Unit_content odoctree -> documents_of_unit ~warnings_options ~source ~syntax ~renderer ~extra ~filename odoctree + | Asset_content _ -> failwith "todo" let documents_of_input ~renderer ~extra ~resolver ~warnings_options ~syntax input = diff --git a/src/odoc/resolver.ml b/src/odoc/resolver.ml index 113e5905bf..ba0d1de461 100644 --- a/src/odoc/resolver.ml +++ b/src/odoc/resolver.ml @@ -242,7 +242,8 @@ let unit_name ( Odoc_file.Unit_content { root; _ } | Page_content { root; _ } | Impl_content { root; _ } - | Source_tree_content { root; _ } ) = + | Source_tree_content { root; _ } + | Asset_content { root; _ } ) = root_name root let load_unit_from_file path = Odoc_file.load path >>= fun u -> Ok u.content @@ -300,7 +301,9 @@ let lookup_unit_by_name ap target_name = let first_unit u = match u with | Odoc_file.Unit_content m -> Some m - | Impl_content _ | Page_content _ | Source_tree_content _ -> None + | Impl_content _ | Page_content _ | Source_tree_content _ | Asset_content _ + -> + None in let rec find_ambiguous tl = match find_map first_unit tl with @@ -356,7 +359,9 @@ let lookup_page_by_name ap target_name = let is_page u = match u with | Odoc_file.Page_content p -> Some p - | Impl_content _ | Unit_content _ | Source_tree_content _ -> None + | Impl_content _ | Unit_content _ | Source_tree_content _ | Asset_content _ + -> + None in let units = load_units_from_name ap target_name in match find_map is_page units with @@ -369,7 +374,9 @@ let lookup_impl ap target_name = let is_impl u = match u with | Odoc_file.Impl_content p -> Some p - | Page_content _ | Unit_content _ | Source_tree_content _ -> None + | Page_content _ | Unit_content _ | Source_tree_content _ | Asset_content _ + -> + None in let units = load_units_from_name ap target_name in match find_map is_impl units with Some (p, _) -> Some p | None -> None @@ -382,7 +389,8 @@ let add_unit_to_cache u = | Odoc_file.Page_content _ -> "page-" | Impl_content _ -> "impl-" | Unit_content _ -> "" - | Source_tree_content _ -> "page-") + | Source_tree_content _ -> "page-" + | Asset_content _ -> "asset-") ^ unit_name u in Hashtbl.add unit_cache target_name [ u ] @@ -629,6 +637,7 @@ let resolve_import t target_name = | Ok root -> ( match root.Odoc_model.Root.file with | Compilation_unit _ -> Some root - | Impl _ | Page _ -> loop tl)) + | Impl _ | Page _ -> loop tl + | Asset -> failwith "todo")) in loop (Accessible_paths.find t.ap target_name) diff --git a/test/odoc_print/odoc_print.ml b/test/odoc_print/odoc_print.ml index e935f7f357..9ec0965747 100644 --- a/test/odoc_print/odoc_print.ml +++ b/test/odoc_print/odoc_print.ml @@ -252,6 +252,7 @@ let run inp short long_paths show_canonical show_expansions | false, None, _ -> print_json_desc Lang_desc.compilation_unit_t u; Ok ()) + | Asset_content _ -> failwith "todo" open Compatcmdliner diff --git a/test/pages/new_assets.t/index.mld b/test/pages/new_assets.t/index.mld new file mode 100644 index 0000000000..4e01eac22f --- /dev/null +++ b/test/pages/new_assets.t/index.mld @@ -0,0 +1,4 @@ +{0 Package page} + +Some image: +{%html: %} diff --git a/test/pages/new_assets.t/run.t b/test/pages/new_assets.t/run.t new file mode 100644 index 0000000000..a5a81436fd --- /dev/null +++ b/test/pages/new_assets.t/run.t @@ -0,0 +1,114 @@ +Blablabla + + $ cat index.mld + {0 Package page} + + Some image: + {%html: %} + +And we'll have a module that we'll put underneath this package page. + + $ cat test.mli + (** Humpf, let's try accessing the asset: + {%html: %} + *) + + (** Nevermind *) + type t + + + + + + +Compile the module first + + $ ocamlc -c -bin-annot test.mli + +Then we need to odoc-compile the package mld file, listing its children + + $ odoc compile index.mld --child module-test --child asset-img.jpg + Warning: Potential name clash - child page named 'index' + + $ odoc compile-asset --name img --parent-id page-test --output-dir odoc + + $ ls + index.mld + odoc + page-index.odoc + test.cmi + test.cmti + test.mli + + $ ls odoc + page-test + + $ ls odoc/page-test + asset-img.odoc + + +This will have produced a file called 'page-index.odoc'. +Now we can odoc-compile the module odoc file passing that file as parent. + + $ odoc compile test.cmti -I . --parent index + +Link and generate the HTML (forgetting the asset!): + + $ for i in *.odoc; do odoc link -I . $i; done + $ for i in *.odocl; do odoc html-generate $i -o html; done + File "img.jpg": + Warning: asset is missing. + +Note that the html was generated despite the missing asset (there might be dead refs!) + + $ find html -type f | sort + html/index/Test/index.html + html/index/index.html + +Which matches the output of the targets command (which emits no warning): + + $ odoc html-targets page-index.odocl -o html + html/index/index.html + +Trying to pass an asset which doesn't exist: +(also: some sed magic due to cmdliner output changing based on the version) + + $ odoc html-generate page-index.odocl --asset img.jpg -o html 2>&1 | \ + > sed 's/…/.../' | sed "s/\`/'/g" + odoc: option '--asset': no 'img.jpg' file or directory + Usage: odoc html-generate [OPTION]... FILE.odocl + Try 'odoc html-generate --help' or 'odoc --help' for more information. + +Creating then passing the asset alongside an incorrect one: + + $ touch img.jpg + $ odoc html-generate page-index.odocl --asset img.jpg --asset test.mli -o html + File "test.mli": + Warning: this asset was not declared as a child of index + +This time, the asset should have been copied at the right place: + + $ find html -type f | sort + html/index/Test/index.html + html/index/img.jpg + html/index/index.html + +Which once again matches the output of the targets command (still no warning!): + + $ odoc html-targets page-index.odocl --asset img.jpg --asset test.mli -o html + html/index/index.html + html/index/img.jpg + +Let's make sure the manpage and latex renderers "work" too + + $ for i in *.odocl; do odoc man-generate $i -o man; odoc latex-generate $i -o latex; done + + $ find man -type f | sort + man/index.3o + man/index/Test.3o + + $ find latex -type f | sort + latex/index.tex + latex/index/Test.tex + +Notice that the assets are *not* there. This should probably be fixed for the latex backend. diff --git a/test/pages/new_assets.t/test.mli b/test/pages/new_assets.t/test.mli new file mode 100644 index 0000000000..d329f104f8 --- /dev/null +++ b/test/pages/new_assets.t/test.mli @@ -0,0 +1,7 @@ +(** Humpf, let's try accessing the asset: + {%html: %} + *) + +(** Nevermind *) +type t + From 5b203c2c60b61c5e68a0b35b7224fc711a1482d5 Mon Sep 17 00:00:00 2001 From: Emile Trotignon Date: Tue, 23 Jul 2024 12:13:41 +0200 Subject: [PATCH 02/10] misc fixes --- src/model/root.ml | 10 +++++----- src/model/root.mli | 4 ++-- src/odoc/compile.ml | 7 ++++++- src/odoc/rendering.ml | 2 +- src/odoc/resolver.ml | 2 +- 5 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/model/root.ml b/src/model/root.ml index 87f436c5f7..aa37557192 100644 --- a/src/model/root.ml +++ b/src/model/root.ml @@ -31,11 +31,12 @@ module Odoc_file = struct type page = { name : string; title : Comment.link_content option } + type t = | Page of page | Compilation_unit of compilation_unit | Impl of string - | Asset + | Asset of string let create_unit ~force_hidden name = let hidden = force_hidden || Names.contains_double_underscore name in @@ -46,14 +47,13 @@ module Odoc_file = struct let create_impl name = Impl name let name = function - | Page { name; _ } | Compilation_unit { name; _ } | Impl name -> name - | Asset -> failwith "todo" + | Page { name; _ } | Compilation_unit { name; _ } | Impl name | Asset name -> name let hidden = function - | Page _ | Impl _ | Asset -> false + | Page _ | Impl _ | Asset _ -> false | Compilation_unit m -> m.hidden - let asset = Asset + let asset name = Asset name end type t = { diff --git a/src/model/root.mli b/src/model/root.mli index 88b322d54e..2fe2d4f2c1 100644 --- a/src/model/root.mli +++ b/src/model/root.mli @@ -34,7 +34,7 @@ module Odoc_file : sig | Page of page | Compilation_unit of compilation_unit | Impl of string - | Asset + | Asset of string val create_unit : force_hidden:bool -> string -> t @@ -42,7 +42,7 @@ module Odoc_file : sig val create_impl : string -> t - val asset : t + val asset : string -> t val name : t -> string diff --git a/src/odoc/compile.ml b/src/odoc/compile.ml index bac042110f..106d2848c6 100644 --- a/src/odoc/compile.ml +++ b/src/odoc/compile.ml @@ -351,7 +351,12 @@ let compile_asset ~parent_id ~name ~output_dir = let output = Fs.File.create ~directory ~name in let digest = Digest.string name in let root = - Root.{ id = (id :> Paths.Identifier.OdocId.t); digest; file = Asset } + Root. + { + id = (id :> Paths.Identifier.OdocId.t); + digest; + file = Odoc_file.asset name; + } in let asset = Lang.Asset.{ name = id; root } in Odoc_file.save_asset output ~warnings:[] asset diff --git a/src/odoc/rendering.ml b/src/odoc/rendering.ml index 7372bbf4eb..8cd7e028b7 100644 --- a/src/odoc/rendering.ml +++ b/src/odoc/rendering.ml @@ -98,7 +98,7 @@ let documents_of_odocl ~warnings_options ~renderer ~extra ~source ~syntax input | Unit_content odoctree -> documents_of_unit ~warnings_options ~source ~syntax ~renderer ~extra ~filename odoctree - | Asset_content _ -> failwith "todo" + | Asset_content _ -> Ok [] let documents_of_input ~renderer ~extra ~resolver ~warnings_options ~syntax input = diff --git a/src/odoc/resolver.ml b/src/odoc/resolver.ml index ba0d1de461..2d2006a728 100644 --- a/src/odoc/resolver.ml +++ b/src/odoc/resolver.ml @@ -638,6 +638,6 @@ let resolve_import t target_name = match root.Odoc_model.Root.file with | Compilation_unit _ -> Some root | Impl _ | Page _ -> loop tl - | Asset -> failwith "todo")) + | Asset _ -> failwith "todo")) in loop (Accessible_paths.find t.ap target_name) From eb628c30f1e44adbe0dbe18d096d891ec01e7990 Mon Sep 17 00:00:00 2001 From: Emile Trotignon Date: Tue, 23 Jul 2024 16:35:11 +0200 Subject: [PATCH 03/10] test promotion --- test/pages/new_assets.t/run.t | 114 ++++------------------------------ 1 file changed, 12 insertions(+), 102 deletions(-) diff --git a/test/pages/new_assets.t/run.t b/test/pages/new_assets.t/run.t index a5a81436fd..5980b1c0c8 100644 --- a/test/pages/new_assets.t/run.t +++ b/test/pages/new_assets.t/run.t @@ -1,25 +1,3 @@ -Blablabla - - $ cat index.mld - {0 Package page} - - Some image: - {%html: %} - -And we'll have a module that we'll put underneath this package page. - - $ cat test.mli - (** Humpf, let's try accessing the asset: - {%html: %} - *) - - (** Nevermind *) - type t - - - - - Compile the module first @@ -32,83 +10,15 @@ Then we need to odoc-compile the package mld file, listing its children $ odoc compile-asset --name img --parent-id page-test --output-dir odoc - $ ls - index.mld - odoc - page-index.odoc - test.cmi - test.cmti - test.mli - - $ ls odoc - page-test - - $ ls odoc/page-test - asset-img.odoc - - -This will have produced a file called 'page-index.odoc'. -Now we can odoc-compile the module odoc file passing that file as parent. - - $ odoc compile test.cmti -I . --parent index - -Link and generate the HTML (forgetting the asset!): - - $ for i in *.odoc; do odoc link -I . $i; done - $ for i in *.odocl; do odoc html-generate $i -o html; done - File "img.jpg": - Warning: asset is missing. - -Note that the html was generated despite the missing asset (there might be dead refs!) - - $ find html -type f | sort - html/index/Test/index.html - html/index/index.html - -Which matches the output of the targets command (which emits no warning): - - $ odoc html-targets page-index.odocl -o html - html/index/index.html - -Trying to pass an asset which doesn't exist: -(also: some sed magic due to cmdliner output changing based on the version) - - $ odoc html-generate page-index.odocl --asset img.jpg -o html 2>&1 | \ - > sed 's/…/.../' | sed "s/\`/'/g" - odoc: option '--asset': no 'img.jpg' file or directory - Usage: odoc html-generate [OPTION]... FILE.odocl - Try 'odoc html-generate --help' or 'odoc --help' for more information. - -Creating then passing the asset alongside an incorrect one: - - $ touch img.jpg - $ odoc html-generate page-index.odocl --asset img.jpg --asset test.mli -o html - File "test.mli": - Warning: this asset was not declared as a child of index - -This time, the asset should have been copied at the right place: - - $ find html -type f | sort - html/index/Test/index.html - html/index/img.jpg - html/index/index.html - -Which once again matches the output of the targets command (still no warning!): - - $ odoc html-targets page-index.odocl --asset img.jpg --asset test.mli -o html - html/index/index.html - html/index/img.jpg - -Let's make sure the manpage and latex renderers "work" too - - $ for i in *.odocl; do odoc man-generate $i -o man; odoc latex-generate $i -o latex; done - - $ find man -type f | sort - man/index.3o - man/index/Test.3o - - $ find latex -type f | sort - latex/index.tex - latex/index/Test.tex - -Notice that the assets are *not* there. This should probably be fixed for the latex backend. + $ tree + . + |-- index.mld -> ../../../../../../default/test/pages/new_assets.t/index.mld + |-- odoc + | `-- page-test + | `-- asset-img.odoc + |-- page-index.odoc + |-- test.cmi + |-- test.cmti + `-- test.mli -> ../../../../../../default/test/pages/new_assets.t/test.mli + + 3 directories, 6 files From def5f848a1bcf8fcb292f41e8fd44cc34edb0fec Mon Sep 17 00:00:00 2001 From: Paul-Elliot Date: Wed, 24 Jul 2024 08:09:55 +0200 Subject: [PATCH 04/10] Compile-aseet: Fix test Signed-off-by: Paul-Elliot --- test/pages/new_assets.t/index.mld | 4 ---- test/pages/new_assets.t/run.t | 26 +++----------------------- test/pages/new_assets.t/test.mli | 7 ------- 3 files changed, 3 insertions(+), 34 deletions(-) delete mode 100644 test/pages/new_assets.t/index.mld delete mode 100644 test/pages/new_assets.t/test.mli diff --git a/test/pages/new_assets.t/index.mld b/test/pages/new_assets.t/index.mld deleted file mode 100644 index 4e01eac22f..0000000000 --- a/test/pages/new_assets.t/index.mld +++ /dev/null @@ -1,4 +0,0 @@ -{0 Package page} - -Some image: -{%html: %} diff --git a/test/pages/new_assets.t/run.t b/test/pages/new_assets.t/run.t index 5980b1c0c8..011af4b79e 100644 --- a/test/pages/new_assets.t/run.t +++ b/test/pages/new_assets.t/run.t @@ -1,24 +1,4 @@ + $ odoc compile-asset --name img.png --parent-id root/test --output-dir odoc -Compile the module first - - $ ocamlc -c -bin-annot test.mli - -Then we need to odoc-compile the package mld file, listing its children - - $ odoc compile index.mld --child module-test --child asset-img.jpg - Warning: Potential name clash - child page named 'index' - - $ odoc compile-asset --name img --parent-id page-test --output-dir odoc - - $ tree - . - |-- index.mld -> ../../../../../../default/test/pages/new_assets.t/index.mld - |-- odoc - | `-- page-test - | `-- asset-img.odoc - |-- page-index.odoc - |-- test.cmi - |-- test.cmti - `-- test.mli -> ../../../../../../default/test/pages/new_assets.t/test.mli - - 3 directories, 6 files + $ ls odoc/root/test + asset-img.png.odoc diff --git a/test/pages/new_assets.t/test.mli b/test/pages/new_assets.t/test.mli deleted file mode 100644 index d329f104f8..0000000000 --- a/test/pages/new_assets.t/test.mli +++ /dev/null @@ -1,7 +0,0 @@ -(** Humpf, let's try accessing the asset: - {%html: %} - *) - -(** Nevermind *) -type t - From 35e64852cd6d99b5845e97e2fe774ba4d46158e4 Mon Sep 17 00:00:00 2001 From: Paul-Elliot Date: Wed, 24 Jul 2024 08:35:47 +0200 Subject: [PATCH 05/10] Compile asset: extract compile_asset in its own module Signed-off-by: Paul-Elliot --- src/odoc/asset.ml | 23 +++++++++++++++++++++++ src/odoc/asset.mli | 1 + src/odoc/bin/main.ml | 6 +++--- src/odoc/compile.ml | 23 ----------------------- src/odoc/compile.mli | 3 +-- 5 files changed, 28 insertions(+), 28 deletions(-) create mode 100644 src/odoc/asset.ml create mode 100644 src/odoc/asset.mli diff --git a/src/odoc/asset.ml b/src/odoc/asset.ml new file mode 100644 index 0000000000..9ae597c022 --- /dev/null +++ b/src/odoc/asset.ml @@ -0,0 +1,23 @@ +let compile ~parent_id ~name ~output_dir = + let open Odoc_model in + let parent_id = Compile.mk_id parent_id in + let id = + Paths.Identifier.Mk.asset_file ((parent_id :> Paths.Identifier.Page.t), name) + in + let directory = + Compile.path_of_id output_dir parent_id + |> Fpath.to_string |> Fs.Directory.of_string + in + let name = "asset-" ^ name ^ ".odoc" in + let output = Fs.File.create ~directory ~name in + let digest = Digest.string name in + let root = + Root. + { + id = (id :> Paths.Identifier.OdocId.t); + digest; + file = Odoc_file.asset name; + } + in + let asset = Lang.Asset.{ name = id; root } in + Odoc_file.save_asset output ~warnings:[] asset diff --git a/src/odoc/asset.mli b/src/odoc/asset.mli new file mode 100644 index 0000000000..157cbbcea8 --- /dev/null +++ b/src/odoc/asset.mli @@ -0,0 +1 @@ +val compile : parent_id:string -> name:string -> output_dir:string -> unit diff --git a/src/odoc/bin/main.ml b/src/odoc/bin/main.ml index 5e4eec9dc1..16c5d72d68 100644 --- a/src/odoc/bin/main.ml +++ b/src/odoc/bin/main.ml @@ -345,7 +345,7 @@ end module Compile_asset = struct let compile_asset parent_id name output_dir = - Odoc_odoc.Compile.compile_asset ~parent_id ~name ~output_dir + Odoc_odoc.Asset.compile ~parent_id ~name ~output_dir let output_dir = let doc = "Output file directory. " in @@ -362,14 +362,14 @@ module Compile_asset = struct & opt (some string) None & info ~docs ~docv:"NAME" ~doc [ "name" ]) in - let parent_id_opt = + let parent_id = let doc = "Parent id." in Arg.( required & opt (some string) None & info ~docs ~docv:"PARENT" ~doc [ "parent-id" ]) in - Term.(const compile_asset $ parent_id_opt $ name_opt $ output_dir) + Term.(const compile_asset $ parent_id $ name_opt $ output_dir) let info ~docs = let man = diff --git a/src/odoc/compile.ml b/src/odoc/compile.ml index 106d2848c6..432a151fe2 100644 --- a/src/odoc/compile.ml +++ b/src/odoc/compile.ml @@ -337,26 +337,3 @@ let compile ~resolver ~hidden ~cli_spec ~warnings_options input = Error.handle_errors_and_warnings ~warnings_options result >>= fun unit -> Odoc_file.save_unit output ~warnings unit; Ok () - -let compile_asset ~parent_id ~name ~output_dir = - let open Odoc_model in - let parent_id = mk_id parent_id in - let id = - Paths.Identifier.Mk.asset_file ((parent_id :> Paths.Identifier.Page.t), name) - in - let directory = - path_of_id output_dir parent_id |> Fpath.to_string |> Fs.Directory.of_string - in - let name = "asset-" ^ name ^ ".odoc" in - let output = Fs.File.create ~directory ~name in - let digest = Digest.string name in - let root = - Root. - { - id = (id :> Paths.Identifier.OdocId.t); - digest; - file = Odoc_file.asset name; - } - in - let asset = Lang.Asset.{ name = id; root } in - Odoc_file.save_asset output ~warnings:[] asset diff --git a/src/odoc/compile.mli b/src/odoc/compile.mli index 5153ed2c46..dfa17159b0 100644 --- a/src/odoc/compile.mli +++ b/src/odoc/compile.mli @@ -50,6 +50,7 @@ val resolve_parent_page : and its children as a list of reference. *) val mk_id : string -> Identifier.ContainerPage.t +val path_of_id : string -> Comment.Identifier.Id.container_page -> Fpath.t val compile : resolver:Resolver.t -> @@ -59,5 +60,3 @@ val compile : Fpath.t -> (unit, [> msg ]) result (** Produces .odoc files out of [.cm{i,t,ti}] or .mld files. *) - -val compile_asset : parent_id:string -> name:string -> output_dir:string -> unit From bc50b836b254a214d3d622cef84196b045d93f97 Mon Sep 17 00:00:00 2001 From: Paul-Elliot Date: Wed, 24 Jul 2024 08:42:00 +0200 Subject: [PATCH 06/10] Asset: allow linking of assets Signed-off-by: Paul-Elliot --- src/odoc/odoc_link.ml | 4 +++- src/odoc/rendering.ml | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/odoc/odoc_link.ml b/src/odoc/odoc_link.ml index e66e37e1f7..f9be0ec4b9 100644 --- a/src/odoc/odoc_link.ml +++ b/src/odoc/odoc_link.ml @@ -100,4 +100,6 @@ let from_odoc ~resolver ~warnings_options input output = >>= fun (m, warnings) -> Odoc_file.save_unit output ~warnings m; Ok (`Module m) - | Asset_content _ -> failwith "todo" + | Asset_content a -> + Odoc_file.save_asset output ~warnings:[] a; + Ok (`Asset a) diff --git a/src/odoc/rendering.ml b/src/odoc/rendering.ml index 8cd7e028b7..d4497a5657 100644 --- a/src/odoc/rendering.ml +++ b/src/odoc/rendering.ml @@ -98,7 +98,7 @@ let documents_of_odocl ~warnings_options ~renderer ~extra ~source ~syntax input | Unit_content odoctree -> documents_of_unit ~warnings_options ~source ~syntax ~renderer ~extra ~filename odoctree - | Asset_content _ -> Ok [] + | Asset_content _ -> Ok [] (* TODO *) let documents_of_input ~renderer ~extra ~resolver ~warnings_options ~syntax input = @@ -110,6 +110,7 @@ let documents_of_input ~renderer ~extra ~resolver ~warnings_options ~syntax | `Module m -> documents_of_unit ~warnings_options ~source:None ~filename:"" ~syntax ~renderer ~extra m + | `Asset _ -> Ok [] (* TODO *) let render_document renderer ~sidebar ~output:root_dir ~extra_suffix ~extra doc = From 9fe192f459a3fb46206723d134026624f27bea8f Mon Sep 17 00:00:00 2001 From: Paul-Elliot Date: Wed, 24 Jul 2024 08:46:24 +0200 Subject: [PATCH 07/10] Asset: Ignore asset units during import resolving Signed-off-by: Paul-Elliot --- src/odoc/bin/main.ml | 4 ++-- src/odoc/resolver.ml | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/odoc/bin/main.ml b/src/odoc/bin/main.ml index 16c5d72d68..66fa30775b 100644 --- a/src/odoc/bin/main.ml +++ b/src/odoc/bin/main.ml @@ -355,7 +355,7 @@ module Compile_asset = struct & info ~docs ~docv:"PATH" ~doc [ "output-dir" ]) let cmd = - let name_opt = + let asset_name = let doc = "Name of the asset." in Arg.( required @@ -369,7 +369,7 @@ module Compile_asset = struct & opt (some string) None & info ~docs ~docv:"PARENT" ~doc [ "parent-id" ]) in - Term.(const compile_asset $ parent_id $ name_opt $ output_dir) + Term.(const compile_asset $ parent_id $ asset_name $ output_dir) let info ~docs = let man = diff --git a/src/odoc/resolver.ml b/src/odoc/resolver.ml index 2d2006a728..8610476293 100644 --- a/src/odoc/resolver.ml +++ b/src/odoc/resolver.ml @@ -637,7 +637,6 @@ let resolve_import t target_name = | Ok root -> ( match root.Odoc_model.Root.file with | Compilation_unit _ -> Some root - | Impl _ | Page _ -> loop tl - | Asset _ -> failwith "todo")) + | Impl _ | Page _ | Asset _ -> loop tl)) in loop (Accessible_paths.find t.ap target_name) From ae0b5d9e6bda3fbce731c7ef1c82574dfa34c8ee Mon Sep 17 00:00:00 2001 From: Paul-Elliot Date: Wed, 24 Jul 2024 09:34:49 +0200 Subject: [PATCH 08/10] Asset: fix marshalling to a file The previous saving to file did not include the root first, making the loading fail. This commits also includes proper testing and completes lang_desc Signed-off-by: Paul-Elliot --- src/model_desc/lang_desc.ml | 8 ++++++++ src/odoc/odoc_file.ml | 20 ++++++++++---------- test/odoc_print/odoc_print.ml | 4 +++- test/pages/new_assets.t/run.t | 12 ++++++++++-- 4 files changed, 31 insertions(+), 13 deletions(-) diff --git a/src/model_desc/lang_desc.ml b/src/model_desc/lang_desc.ml index ff0facc5ec..810a23f8a7 100644 --- a/src/model_desc/lang_desc.ml +++ b/src/model_desc/lang_desc.ml @@ -719,3 +719,11 @@ and source_tree_page_t = F ("digest", (fun t -> t.digest), Digest.t); F ("source_children", (fun t -> t.source_children), List identifier); ] + +and asset_t = + let open Lang.Asset in + Record + [ + F ("name", (fun t -> t.name), identifier); + F ("root", (fun t -> t.root), root); + ] diff --git a/src/odoc/odoc_file.ml b/src/odoc/odoc_file.ml index 08cb9a1bbd..8b9a9cb01d 100644 --- a/src/odoc/odoc_file.ml +++ b/src/odoc/odoc_file.ml @@ -73,6 +73,16 @@ let save_impl file ~warnings impl = save_unit file impl.Lang.Implementation.root { content = Impl_content impl; warnings } +let save_asset file ~warnings asset = + let dir = Fs.File.dirname file in + let base = Fs.File.(to_string @@ basename file) in + let file = + if Astring.String.is_prefix ~affix:"asset-" base then file + else Fs.File.create ~directory:dir ~name:("asset-" ^ base) + in + let t = { content = Asset_content asset; warnings } in + save_unit file asset.root t + let save_unit file ~warnings m = save_unit file m.Lang.Compilation_unit.root { content = Unit_content m; warnings } @@ -117,13 +127,3 @@ let load_root file = let save_index dst idx = save_ dst (fun oc -> Marshal.to_channel oc idx []) let load_index file = load_ file (fun ic -> Ok (Marshal.from_channel ic)) - -let save_asset file ~warnings impl = - let dir = Fs.File.dirname file in - let base = Fs.File.(to_string @@ basename file) in - let file = - if Astring.String.is_prefix ~affix:"asset-" base then file - else Fs.File.create ~directory:dir ~name:("asset-" ^ base) - in - let t = { content = Asset_content impl; warnings } in - save_ file (fun oc -> Marshal.to_channel oc t []) diff --git a/test/odoc_print/odoc_print.ml b/test/odoc_print/odoc_print.ml index 9ec0965747..45c2f4339e 100644 --- a/test/odoc_print/odoc_print.ml +++ b/test/odoc_print/odoc_print.ml @@ -252,7 +252,9 @@ let run inp short long_paths show_canonical show_expansions | false, None, _ -> print_json_desc Lang_desc.compilation_unit_t u; Ok ()) - | Asset_content _ -> failwith "todo" + | Asset_content a -> + print_json_desc Lang_desc.asset_t a; + Ok () open Compatcmdliner diff --git a/test/pages/new_assets.t/run.t b/test/pages/new_assets.t/run.t index 011af4b79e..6341bb6e03 100644 --- a/test/pages/new_assets.t/run.t +++ b/test/pages/new_assets.t/run.t @@ -1,4 +1,12 @@ $ odoc compile-asset --name img.png --parent-id root/test --output-dir odoc - $ ls odoc/root/test - asset-img.png.odoc + $ odoc_print odoc/root/test/asset-img.png.odoc + { + "name": { + "`AssetFile": [ + { "`Page": [ { "Some": { "`Page": [ "None", "root" ] } }, "test" ] }, + "img.png" + ] + }, + "root": "" + } From fa7ffd2f05af12ad94931bc682c9df790cc9a57a Mon Sep 17 00:00:00 2001 From: Paul-Elliot Date: Wed, 24 Jul 2024 09:40:04 +0200 Subject: [PATCH 09/10] Compile-asset: added changelog entry Signed-off-by: Paul-Elliot --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index 588fedb8d8..799c974040 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -24,6 +24,7 @@ - Added a `--occurrences` argument to the `compile-index` command to output the number of occurrences of each entry of the index in the json output (@panglesd, #1076). +- Added a `compile-asset` command (@EmileTrotignon, @panglesd, #1170) ### Changed From 716562757f20e5ca60f97d5c0db08ccab040dc16 Mon Sep 17 00:00:00 2001 From: Paul-Elliot Date: Wed, 24 Jul 2024 09:41:09 +0200 Subject: [PATCH 10/10] Format Signed-off-by: Paul-Elliot --- src/model/root.ml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/model/root.ml b/src/model/root.ml index aa37557192..4b0461a108 100644 --- a/src/model/root.ml +++ b/src/model/root.ml @@ -31,7 +31,6 @@ module Odoc_file = struct type page = { name : string; title : Comment.link_content option } - type t = | Page of page | Compilation_unit of compilation_unit @@ -47,7 +46,9 @@ module Odoc_file = struct let create_impl name = Impl name let name = function - | Page { name; _ } | Compilation_unit { name; _ } | Impl name | Asset name -> name + | Page { name; _ } | Compilation_unit { name; _ } | Impl name | Asset name + -> + name let hidden = function | Page _ | Impl _ | Asset _ -> false