From 67ccabec49b5f4d24147839291fcae7c19d3e8c9 Mon Sep 17 00:00:00 2001 From: Guillaume Petiot Date: Tue, 15 Aug 2023 12:16:28 +0100 Subject: [PATCH] Document each part of voodoo (#110) --- .ocamlformat | 1 + Makefile | 43 ---------- README.md | 135 +++++++++++++++++--------------- src/voodoo-do/do.ml | 17 ++-- src/voodoo-do/do.mli | 5 +- src/voodoo-do/main.ml | 2 +- src/voodoo-gen/markdown.mli | 6 ++ src/voodoo-gen/package_info.mli | 3 + src/voodoo-gen/rendering.mli | 6 ++ src/voodoo-gen/search_index.ml | 8 -- src/voodoo-gen/search_index.mli | 3 + src/voodoo-prep/main.ml | 5 +- src/voodoo-prep/opam.ml | 9 +-- src/voodoo-prep/opam.mli | 14 +++- src/voodoo-prep/package.mli | 3 + src/voodoo-prep/paths.ml | 2 +- src/voodoo-prep/paths.mli | 3 + src/voodoo-prep/prep.ml | 25 ++---- src/voodoo-prep/prep.mli | 7 ++ src/voodoo-prep/util.ml | 1 - src/voodoo-prep/util.mli | 9 +++ src/voodoo/compat.mli | 5 +- src/voodoo/dune.ml | 1 - src/voodoo/dune.mli | 4 + src/voodoo/error_log.ml | 2 - src/voodoo/error_log.mli | 2 + src/voodoo/index.ml | 8 +- src/voodoo/index.mli | 6 ++ src/voodoo/mld.ml | 10 +-- src/voodoo/mld.mli | 17 +++- src/voodoo/ocamlobjinfo.mli | 4 + src/voodoo/odoc.ml | 12 +-- src/voodoo/odoc.mli | 13 ++- src/voodoo/opam.ml | 8 +- src/voodoo/opam.mli | 4 + src/voodoo/otherdocs.ml | 3 - src/voodoo/otherdocs.mli | 3 + src/voodoo/package.mli | 3 + src/voodoo/package_info.ml | 4 +- src/voodoo/package_info.mli | 9 +-- src/voodoo/package_mlds.ml | 8 +- src/voodoo/package_mlds.mli | 9 ++- src/voodoo/paths.ml | 2 +- src/voodoo/paths.mli | 8 ++ src/voodoo/sourceinfo.ml | 15 ++-- src/voodoo/sourceinfo.mli | 9 +++ src/voodoo/util.ml | 1 - src/voodoo/util.mli | 12 +++ src/voodoo/version.ml | 4 - src/voodoo/version.mli | 1 + 50 files changed, 263 insertions(+), 231 deletions(-) diff --git a/.ocamlformat b/.ocamlformat index bd1f239e..b9d934f9 100644 --- a/.ocamlformat +++ b/.ocamlformat @@ -1,2 +1,3 @@ version=0.25.1 profile=conventional +parse-docstrings=true diff --git a/Makefile b/Makefile index 47c7b9ce..f6615f5b 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,3 @@ -.DEFAULT_GOAL := all - ARGS := $(wordlist 2,$(words $(MAKECMDGOALS)),$(MAKECMDGOALS)) $(eval $(ARGS):;@:) @@ -19,10 +17,6 @@ create_switch: .PHONY: switch switch: create_switch deps ## Create an opam switch and install development dependencies -.PHONY: lock -lock: ## Generate a lock file - opam lock -y . - .PHONY: build build: ## Build the project, including non installable libraries and executables opam exec -- dune build --root . @@ -47,43 +41,6 @@ doc: ## Generate odoc documentation fmt: ## Format the codebase with ocamlformat opam exec -- dune build --root . --auto-promote @fmt -.PHONY: watch -watch: ## Watch for the filesystem and rebuild on every change - opam exec -- script/watch.sh - .PHONY: utop utop: ## Run a REPL and link with the project's libraries opam exec -- dune utop --root . lib -- -implicit-bindings - -.PHONY: promote -promote: ## Promote files to the source directory - dune build client/voodoo_client.bc.js --profile release - cp _build/default/client/voodoo_client.bc.js src/voodoo-gen/static/voodoo_client.bc.js - -_generated: - rm -rf _generated; mkdir _generated - -.PHONY: support -support: - odoc support-files -o _generated/html - -.PHONY: prep -prep: _generated - cd _generated; opam exec -- dune exec -- voodoo-prep - -.PHONY: example -example: all prep ## Build an sample output - cd _generated; opam exec -- dune exec -- voodoo-do -p ocaml-base-compiler -b - cd _generated; opam exec -- dune exec -- voodoo-gen -o output - -.PHONY: gen -gen: - cd _generated; rm -rf output - cd _generated; opam exec -- dune exec -- voodoo-gen -o output - -.PHONY: serve -serve: - opam exec -- dream-serve _generated/html - -.DEFAULT: - cd _generated; opam exec -- dune exec -- voodoo-do -p $@ -b diff --git a/README.md b/README.md index 409b1b80..5c32e957 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,26 @@ -# Voodoo +

+ voodoo +

-Voodoo is the OCaml documentation generator. +

+ Voodoo is the OCaml documentation generator. +

-## Getting started +

+ + OCaml-CI Build Status + +

-This package is intended to be used as part of an -[ocurrent](https://github.com/ocurrent/ocurrent) pipeline, for example -via [ocaml-docs-ci](https://github.com/ocurrent/ocaml-docs-ci). As such, -it's tricky to use in isolation. - -Having said that, there is some rudimentary support for using it this way. The steps below will guide you to build to build a small documentation website locally. +## :rocket: Getting started -### Setup your development environment +**voodoo** is intended to be used as part of an +[ocurrent](https://github.com/ocurrent/ocurrent) pipeline, for example +via [ocaml-docs-ci](https://github.com/ocurrent/ocaml-docs-ci). -You need Opam, you can install it by following [Opam's documentation](https://opam.ocaml.org/doc/Install.html). +You need `opam`, you can install it by following [Opam's documentation](https://opam.ocaml.org/doc/Install.html). -With Opam installed, you can install the dependencies in a new local switch with: +With `opam` installed, you can install the dependencies in a new local switch with: ```bash make switch @@ -27,42 +32,39 @@ Then, build the project with: make build ``` -### Generating an example +**voodoo** is run in three successive steps detailed below. -To create an example, run: +## :seedling: 1. Prepare the packages: voodoo-prep -```bash -make example +To prepare the packages just run: + +```sh +voodoo-prep [-u ] ``` -This will create a sample website with the documentation of `ocaml-base-compiler` in `_generated/output/p`. +Where `` is a comma-separated list of packages and universes `pkg1:unv1,pkg2:unv2,...`. -Here are some commands that will be executed when running the above: +When you don't provide a universe explicitly, each package installed in the current switch will be prepared (prepped) for the compiling step. -```bash -$ mkdir _generated -$ cd _generated; opam exec -- dune exec -- voodoo-prep -$ cd _generated; opam exec -- dune exec -- voodoo-do -p ocaml-base-compiler -b -$ cd _generated; opam exec -- dune exec -- voodoo-gen -o output -``` +This creates an ad-hoc directory structure and populates it with `.cmt`, `.cmi`, `.cmti`, `.mld` from the current switch. +The `ocamlobjinfo` of the `.cma` files are also copied, as well as the documentation files such as `.md`, `.html` and others (such as the `opam` files). -Read further for the detailed version of the above commands. -```bash -$ cd _generated -$ opam exec -- dune exec -- voodoo-prep -Warning: No universes have been specified: will generate dummy universes -$ opam exec -- dune exec -- voodoo-do -p ocaml-base-compiler -b -$ opam exec -- dune exec -- voodoo-do -p result -b -$ opam exec -- dune exec -- voodoo-do ... +## :sweat_drops: 2. Compiling and linking the packages: voodoo-do + +Once `voodoo-prep` has run, `voodoo-do` is able to process packages. Simply run: + +```sh +voodoo-do -p [-b] [--failed] ``` -When new packages are installed in the current switch `voodoo-prep` needs to be executed in -for `voodoo-do` to be able to process them. If the packages are done out of dependency order, - `voodoo-prep` will alert that there are missing dependencies: +This command runs `odoc compile` and `odoc link` on the package specified after `-p`. +If the `--failed` flag is set, a file named `failed` containing `"failed"` is also generated. -```bash -$ opam exec -- dune exec -- voodoo-do -p odoc -b +If the packages are processed out of dependency order, `voodoo-do` will alert that there are missing dependencies. + +```sh +voodoo-do -p odoc -b ... Missing dependency: Stdlib c21c5d26416461b543321872a551ea0d ... @@ -70,60 +72,63 @@ Missing dependency: Stdlib c21c5d26416461b543321872a551ea0d In this case, we need to run `voodoo-do -p ocaml-base-compiler -b` first. -Note that when being used in this mode, the `-b` (blessed) switch should -always be passed to `voodoo-do`. +Note that when being used in this mode, the `-b` flag should always be passed to `voodoo-do`. At this point, to view the output, use `odoc` to generate the support files (mostly: copying `highlight.js` from https://highlightjs.org and `odoc.css`): ```bash -$ cd .. -$ odoc support-files -o _generated/html +cd .. +odoc support-files -o html ``` -and load the package index in your browser (adjust `x.y.z` according to the current switch): +You can load the package index in your browser: -```bash -$ open _generated/html/p/ocaml-base-compiler/4.14.0/doc/index.html +```sh +open ./html/p///doc/index.html ``` -~~An alternative to executing `voodoo-do -p ...` in order is simply to run -`voodoo-do` with no arguments. This naively executes `voodoo-do` in order -based on the current switch's dependencies, and is slow and inefficient.~~ +## :deciduous_tree: 3. Rendering the packages: voodoo-gen -To generate the website with the documentation, run: +Once `voodoo-do` has run, you can generate the website with the documentation, run: ```bash -$ opam exec -- dune exec -- voodoo-gen -o output +voodoo-gen -o [-n ] [--pkg-version ] ``` -And serve it with: - -```bash -$ opam install dream-serve -$ dream-serve _generated/html -``` +This command runs `odoc html-generate` to render the files of the specified package as html. -Load the package index in your browser (adjust `x.y.z` according to the current switch): +You can serve it with: ```bash -$ open http://localhost:8080/p/ocaml-base-compiler/4.14.0/doc/index.html +opam install dream-serve +dream-serve ./html ``` -You may use the `.DEFAULT` target from the `Makefile` to generate additional -documentation: +Load the package index in your browser: -``` -make odoc +```bash +$ open http://localhost:8080/p///doc/index.html ``` -### Summary +## :horse_racing: TLDR 1. Install packages to be documented in the current switch using `opam` 1. Create `_generated` directory 1. Run `voodoo-prep`. This creates the _ad-hoc_ directory structure inside `_generated` and populates it with `.cmt`, `.cmi`, `.cmti`, `.mld` from the current switch. Documentation files such as `.md`, `.html` and others are also copied. -1. Run `voodoo-do` on each package or all at once. This triggers Odoc to generate the actual HTML documentation files. -1. Run `voodoo-gen` to create the `_generated/output` directory -1. Run `doc support-files -o _generated/html` to add css and styling to the `html` subdirectory +1. Run `voodoo-do` on each package to compile and link the odoc files. +1. Run `voodoo-gen` to create the `_generated/output` directory and generate the HTML files. +1. Run `odoc support-files -o _generated/html` to add css and styling to the `html` subdirectory 1. Serve `_generated/html` `voodoo-*` commands must be called from the `_generated` directory. + +```sh +mkdir _generated +cd _generated +opam exec -- dune exec -- voodoo-prep +opam exec -- dune exec -- voodoo-do -p -b +opam exec -- dune exec -- voodoo-gen -o output +cd .. +odoc support-files -o _generated/html +dream-serve _generated/html +``` diff --git a/src/voodoo-do/do.ml b/src/voodoo-do/do.ml index d1e630f1..9e5f23c1 100644 --- a/src/voodoo-do/do.ml +++ b/src/voodoo-do/do.ml @@ -1,5 +1,3 @@ -(* do! - perform the odoc compile and link stages *) - open Voodoo_lib module Result = Bos_setup.R open Result.Infix @@ -110,7 +108,7 @@ let find_universe_and_version pkg_name = | _ :: _ :: u :: _, [ version ] -> Ok (u, Fpath.to_string version) | _ -> Error (`Msg (Format.sprintf "Failed to find package %s" pkg_name)) -let run pkg_name is_blessed failed = +let run pkg_name ~blessed ~failed = let is_interesting p = List.mem (Fpath.get_ext p) [ ".cmti"; ".cmt"; ".cmi" ] in @@ -153,7 +151,7 @@ let run pkg_name is_blessed failed = in let package = { Package.universe; name = pkg_name; version } in let output_path = - if is_blessed then Fpath.(Paths.link / "p" / pkg_name / version) + if blessed then Fpath.(Paths.link / "p" / pkg_name / version) else Fpath.(Paths.link / "u" / universe / pkg_name / version) in Util.mkdir_p output_path; @@ -191,11 +189,11 @@ let run pkg_name is_blessed failed = let error_log = Error_log.find package in let parent = - Version.gen_parent package ~blessed:is_blessed ~modules ~dune ~libraries - ~package_mlds ~error_log ~failed + Version.gen_parent package ~blessed ~modules ~dune ~libraries ~package_mlds + ~error_log ~failed in - let () = Package_info.gen ~output:output_path ~dune ~libraries () in + let () = Package_info.gen ~output:output_path ~dune ~libraries in let sis = Compat.List.concat_map (get_source_info parent) prep in let this_index = InputSelect.select sis in @@ -219,7 +217,7 @@ let run pkg_name is_blessed failed = si.path :: compiled in let _ = ignore (Index.M.fold compile this_index.intern []) in - let mldvs = Package_mlds.compile parent package_mlds in + let mldvs = Package_mlds.compile ~parent package_mlds in let unit_includes = IncludePaths.link index in let docs_includes = Package_mlds.include_paths mldvs in let all_includes = Fpath.Set.union unit_includes docs_includes in @@ -253,8 +251,7 @@ let run pkg_name is_blessed failed = Format.eprintf "%d other files to copy\n%!" (List.length otherdocs); let otherdocs, _opam_file = Otherdocs.copy parent otherdocs opam_file in List.iter (fun p -> Format.eprintf "dest: %a\n%!" Fpath.pp p) otherdocs; - List.iter (Odoc.html output) odocls; - (* Odoc.voodoo_gen Fpath.(output / "tailwind") pkg_name version; *) + List.iter (Odoc.html ~output) odocls; let () = Bos.OS.File.delete (Fpath.v "compile/page-p.odoc") |> Result.get_ok in diff --git a/src/voodoo-do/do.mli b/src/voodoo-do/do.mli index eac16690..edc5a0c9 100644 --- a/src/voodoo-do/do.mli +++ b/src/voodoo-do/do.mli @@ -1 +1,4 @@ -val run : string -> bool -> bool -> unit +val run : string -> blessed:bool -> failed:bool -> unit +(** [run pkg ~blessed ~failed] runs [odoc compile] and [odoc link] on package + [pkg]. If [failed] is set, a file named [failed] containing "failed" is also + generated. *) diff --git a/src/voodoo-do/main.ml b/src/voodoo-do/main.ml index e19cfa19..566819d4 100644 --- a/src/voodoo-do/main.ml +++ b/src/voodoo-do/main.ml @@ -6,7 +6,7 @@ open Cmdliner let run package blessed switch failed = Opam.switch := switch; - Do.run package blessed failed + Do.run package ~blessed ~failed let package = let doc = "Select the package to process" in diff --git a/src/voodoo-gen/markdown.mli b/src/voodoo-gen/markdown.mli index 6157b517..0d156809 100644 --- a/src/voodoo-gen/markdown.mli +++ b/src/voodoo-gen/markdown.mli @@ -2,13 +2,19 @@ val read_org : Fpath.t -> Odoc_document.Url.Path.t -> (Odoc_document.Types.Page.t, [ `Msg of string ]) result +(** [read_org f url] returns the odoc page generated from the org file [f] + having the url [url]. *) val read_md : Fpath.t -> Odoc_document.Url.Path.t -> (Odoc_document.Types.Page.t, [ `Msg of string ]) result +(** [read_md f url] returns the odoc page generated from the markdown file [f] + having the url [url]. *) val read_plain : Fpath.t -> Odoc_document.Url.Path.t -> (Odoc_document.Types.Page.t, [ `Msg of string ]) result +(** [read_plain f url] returns the odoc page generated from the plain file [f] + having the url [url]. *) diff --git a/src/voodoo-gen/package_info.mli b/src/voodoo-gen/package_info.mli index 4e8a967b..150ca8f5 100644 --- a/src/voodoo-gen/package_info.mli +++ b/src/voodoo-gen/package_info.mli @@ -1,2 +1,5 @@ val gen : input:Fpath.t -> output:Fpath.t -> Odoc_document.Types.Page.t list -> unit +(** [gen ~input ~output paths] reads a [packags.json] located at [input] and + generates a new [package.json] located at [output] describing the same + package and using [paths] to add children information. *) diff --git a/src/voodoo-gen/rendering.mli b/src/voodoo-gen/rendering.mli index 67f60074..60220727 100644 --- a/src/voodoo-gen/rendering.mli +++ b/src/voodoo-gen/rendering.mli @@ -2,9 +2,15 @@ val render : output:(Fpath.t -> Odoc_odoc.Fs.File.t) -> Fpath.t -> (Odoc_document.Types.Page.t list, [ `Msg of string ]) result +(** [render ~output f] renders the [.odocl] file [f] as html by running + [odoc html-generate]. [output] determines the output path from the input + path. *) val render_other : output:(Fpath.t -> Odoc_odoc.Fs.File.t) -> parent:Odoc_odoc.Fs.File.t -> otherdocs:Fpath.t list -> (unit, [ `Msg of string ]) result +(** [render_other ~output ~parent ~otherdocs] renders the documents [otherdocs] + as html. [parent] is used to get the path to the document. [output] + determines the output path from the input path. *) diff --git a/src/voodoo-gen/search_index.ml b/src/voodoo-gen/search_index.ml index 6321f0f1..76ef57c8 100644 --- a/src/voodoo-gen/search_index.ml +++ b/src/voodoo-gen/search_index.ml @@ -359,12 +359,6 @@ let generate_index dirs output = in Format.fprintf ppf "let documents = ["; let () = List.iter (Load_doc.unit ppf) units in - (* List.iter *) - (* (fun entry -> *) - (* match string_of_entry entry with *) - (* | Ok entry -> Format.fprintf ppf "%s,\n" entry *) - (* | Error _ -> ()) *) - (* index; *) let () = Format.fprintf ppf {|]; @@ -372,5 +366,3 @@ const options = { keys: ['name', 'comment'] }; var idx_fuse = new Fuse(documents, options);|} in Ok () -(* Ok *) -(* (Generate.render_index index output) *) diff --git a/src/voodoo-gen/search_index.mli b/src/voodoo-gen/search_index.mli index b17ad16d..fbdea1e9 100644 --- a/src/voodoo-gen/search_index.mli +++ b/src/voodoo-gen/search_index.mli @@ -1,2 +1,5 @@ val generate_index : Odoc_odoc.Fs.directory list -> Fpath.t -> (unit, [ `Msg of string ]) result +(** [generate_index dirs output] reads the [*.odocl] files located in [dirs] and + generates a JavaScript file [output] describing the contents of the + [*.odocl] files. *) diff --git a/src/voodoo-prep/main.ml b/src/voodoo-prep/main.ml index 830e2b7e..5ee5a85e 100644 --- a/src/voodoo-prep/main.ml +++ b/src/voodoo-prep/main.ml @@ -1,6 +1,3 @@ -(* Odoc documentation generator - -*) open Cmdliner [@@@ocaml.warning "-3"] @@ -20,7 +17,7 @@ module Prep = struct Prep.run universes let universes = - let doc = "Provide universe spec as 'package=universe id' couples" in + let doc = "Provide universe spec as 'package:universe_id' couples" in Arg.( value & opt (list (pair ~sep:':' string string)) [] diff --git a/src/voodoo-prep/opam.ml b/src/voodoo-prep/opam.ml index 9949e2e6..b3c2e61a 100644 --- a/src/voodoo-prep/opam.ml +++ b/src/voodoo-prep/opam.ml @@ -1,4 +1,3 @@ -(* opam *) open Bos let opam = Cmd.v "opam" @@ -34,10 +33,10 @@ let all_opam_packages () = |> List.map deps_of_opam_result |> List.flatten -let pkg_contents pkg = +let pkg_contents { Package.name; _ } = let prefix = Fpath.v (prefix ()) in let changes_file = - Format.asprintf "%a/.opam-switch/install/%s.changes" Fpath.pp prefix pkg + Format.asprintf "%a/.opam-switch/install/%s.changes" Fpath.pp prefix name in let file = OpamFilename.raw changes_file in let filename = @@ -72,9 +71,9 @@ let pkg_contents pkg = | _ -> acc) changed [] in - List.map (fun path -> Fpath.(v path)) added + List.map Fpath.v added -let opam_file name version = +let opam_file { Package.name; version; _ } = let prefix = Fpath.v (prefix ()) in let opam_file = Format.asprintf "%a/.opam-switch/packages/%s.%s/opam" Fpath.pp prefix name diff --git a/src/voodoo-prep/opam.mli b/src/voodoo-prep/opam.mli index 32b49230..5ce7fa28 100644 --- a/src/voodoo-prep/opam.mli +++ b/src/voodoo-prep/opam.mli @@ -1,7 +1,17 @@ type package = { name : string; version : string } +(** Equivalent of type [Package.t] when the universe is not yet known. *) val switch : string option ref +(** [switch] returns the local opam switch name. *) + val prefix : unit -> string +(** [prefix ()] returns the root directory of the local opam switch. *) + val all_opam_packages : unit -> package list -val pkg_contents : string -> Fpath.t list -val opam_file : string -> string -> string list option +(** [all_opam_packages ()] returns the list of installed packages. *) + +val pkg_contents : Package.t -> Fpath.t list +(** [pkg_contents p] returns the list of files installed by package [p]. *) + +val opam_file : Package.t -> string list option +(** [opam_file p] returns the contents of the opam file of package [p]. *) diff --git a/src/voodoo-prep/package.mli b/src/voodoo-prep/package.mli index f9124874..72a6200b 100644 --- a/src/voodoo-prep/package.mli +++ b/src/voodoo-prep/package.mli @@ -1,3 +1,6 @@ type t = { universe_id : string; name : string; version : string } val prep_path : t -> Fpath.t +(** [prep_path p] is the directory where the prepped package [p] is stored. + + Warning: it needs to stay in sync with [src/voodoo/package.ml]*) diff --git a/src/voodoo-prep/paths.ml b/src/voodoo-prep/paths.ml index 3e4f95c9..2a08e746 100644 --- a/src/voodoo-prep/paths.ml +++ b/src/voodoo-prep/paths.ml @@ -1,3 +1,3 @@ type t = Fpath.t -let prep = Fpath.v "prep" (* warning: to keep in sync with lib/paths.ml *) +let prep = Fpath.v "prep" diff --git a/src/voodoo-prep/paths.mli b/src/voodoo-prep/paths.mli index 5ef0e105..f4063bdb 100644 --- a/src/voodoo-prep/paths.mli +++ b/src/voodoo-prep/paths.mli @@ -1,3 +1,6 @@ type t = Fpath.t val prep : t +(** [prep] is the root directory where the prepped packages are stored. + + Warning: it needs to stay in sync with [src/voodoo/paths.ml] *) diff --git a/src/voodoo-prep/prep.ml b/src/voodoo-prep/prep.ml index 0d1be66e..9f96d87d 100644 --- a/src/voodoo-prep/prep.ml +++ b/src/voodoo-prep/prep.ml @@ -1,13 +1,7 @@ -(* Prep - * - *) - -type actions = { - copy : (Fpath.t * Fpath.t) list; - info : Fpath.t list; - objinfo : Fpath.t list; -} +type actions = { copy : (Fpath.t * Fpath.t) list; objinfo : Fpath.t list } +(** [process_package root p files] copies some files among [files] to the + [Package.prep_path p]. Store the [ocamlobjinfo] of the [.cma] files. *) let process_package : Fpath.t -> Package.t -> Fpath.t list -> unit = fun root package files -> let dest = Package.prep_path package in @@ -47,13 +41,10 @@ let process_package : Fpath.t -> Package.t -> Fpath.t list -> unit = if do_copy then Fpath.(root // fpath, dest // fpath) :: acc.copy else acc.copy in - let info = if is_module then fpath :: acc.info else acc.info in let objinfo = if is_cma then fpath :: acc.objinfo else acc.objinfo in - { copy; info; objinfo } - in - let actions = - List.fold_right foldfn files { copy = []; info = []; objinfo = [] } + { copy; objinfo } in + let actions = List.fold_right foldfn files { copy = []; objinfo = [] } in List.iter (fun (src, dst) -> let dir, _ = Fpath.split_base dst in @@ -103,16 +94,14 @@ let run (universes : (string * string) list) = in let root = Opam.prefix () |> Fpath.v in let pkg_contents = - List.map - (fun package -> (package, Opam.pkg_contents package.Package.name)) - packages + List.map (fun package -> (package, Opam.pkg_contents package)) packages in List.iter (fun (package, files) -> process_package root package files) pkg_contents; List.iter (fun package -> - match Opam.opam_file package.Package.name package.version with + match Opam.opam_file package with | Some lines -> let dest = Package.prep_path package in Util.write_file Fpath.(dest / "opam") lines diff --git a/src/voodoo-prep/prep.mli b/src/voodoo-prep/prep.mli index ac3bc085..59bfff4f 100644 --- a/src/voodoo-prep/prep.mli +++ b/src/voodoo-prep/prep.mli @@ -1 +1,8 @@ val run : (string * string) list -> unit +(** [run universes] prepares all packages installed in the current switch. + + For each package [p]: + + - copy some of the files installed by [p] to the [prep/] directory. + - store the [ocamlobjinfo] of the [.cma] files in the same directory. + - copy the [opam] file. *) diff --git a/src/voodoo-prep/util.ml b/src/voodoo-prep/util.ml index 8e5d363a..eadf3f29 100644 --- a/src/voodoo-prep/util.ml +++ b/src/voodoo-prep/util.ml @@ -1,4 +1,3 @@ -(* util.ml *) open Bos let lines_of_channel ic = diff --git a/src/voodoo-prep/util.mli b/src/voodoo-prep/util.mli index c29779d9..b5664de7 100644 --- a/src/voodoo-prep/util.mli +++ b/src/voodoo-prep/util.mli @@ -1,5 +1,14 @@ val lines_of_channel : in_channel -> string list +(** [lines_of_channel c] returns lines read on channel [c]. *) + val lines_of_process : Bos.Cmd.t -> string list +(** [lines_of_process p] returns lines read from the output of process [p]. *) + val mkdir_p : Fpath.t -> unit +(** [mkdir_p x] recursively creates directory [x] and its parents. *) + val write_file : Fpath.t -> string list -> unit +(** [write_file f lines] writes [lines] into file [f]. *) + val cp : string -> string -> unit +(** [cp src dst] copies [src] to [dst]. *) diff --git a/src/voodoo/compat.mli b/src/voodoo/compat.mli index bca8dad8..8aa83a05 100644 --- a/src/voodoo/compat.mli +++ b/src/voodoo/compat.mli @@ -3,6 +3,7 @@ module List : sig (** [concat_map f l] gives the same result as [List.concat (List.map f l)]. *) val find_opt : ('a -> bool) -> 'a list -> 'a option - (** [find_opt f l] returns the first element of the list [l] that satisfies the predicate [f]. - Returns [None] if there is no value that satisfies [f] in the list [l]. *) + (** [find_opt f l] returns the first element of the list [l] that satisfies + the predicate [f]. Returns [None] if there is no value that satisfies [f] + in the list [l]. *) end diff --git a/src/voodoo/dune.ml b/src/voodoo/dune.ml index 14ef0bba..84d5b49b 100644 --- a/src/voodoo/dune.ml +++ b/src/voodoo/dune.ml @@ -1,4 +1,3 @@ -(* Process dune-package *) module Result = Bos_setup.R open Result.Infix diff --git a/src/voodoo/dune.mli b/src/voodoo/dune.mli index 55227ab8..cf90dbfc 100644 --- a/src/voodoo/dune.mli +++ b/src/voodoo/dune.mli @@ -23,4 +23,8 @@ end type t = { name : string; version : string option; libraries : Library.t list } val process_file : Fpath.t -> (t, [> `Msg of string ]) Bos_setup.result +(** [process_file f] processes the [dune-package] file located at [f]. *) + val find : Package.t -> (Fpath.t, [> Bos_setup.R.msg ]) Bos_setup.result +(** [find p] returns the path to the [dune-package], if it exists, in the + prepped directory of package [p]. *) diff --git a/src/voodoo/error_log.ml b/src/voodoo/error_log.ml index 52b3981e..209fad11 100644 --- a/src/voodoo/error_log.ml +++ b/src/voodoo/error_log.ml @@ -1,5 +1,3 @@ -(* Pull out error log *) - type t = string list option let find package = diff --git a/src/voodoo/error_log.mli b/src/voodoo/error_log.mli index cd4cf015..1f4385b1 100644 --- a/src/voodoo/error_log.mli +++ b/src/voodoo/error_log.mli @@ -1,3 +1,5 @@ type t = string list option val find : Package.t -> t +(** [find p] returns the contents of the [opam.err.log] file, if it exists, + located in the prepped directory of package [p]. *) diff --git a/src/voodoo/index.ml b/src/voodoo/index.ml index 6d04418f..39ebb874 100644 --- a/src/voodoo/index.ml +++ b/src/voodoo/index.ml @@ -1,4 +1,3 @@ -(* Map of module digest to source info *) module M = Map.Make (String) type t = { intern : Sourceinfo.t M.t; extern : Fpath.t M.t } @@ -10,12 +9,8 @@ type serialisable = (string * Fpath.t) list let find_opt name t = try Some (M.find name t.intern) with _ -> None let find_extern_opt name t = try Some (M.find name t.extern) with _ -> None -(* Write the index file into 'packages///index.m or - universes////index.m *) let write t parent_mld = - (* Format.eprintf "Index.write: parent_mld=%a\n%!" Mld.pp parent_mld; *) let output_dir = Mld.compile_dir parent_mld in - (* Format.eprintf "Output dir: %a\n%!" Fpath.pp output_dir; *) Util.mkdir_p Fpath.(output_dir / parent_mld.name); let oc = open_out Fpath.(to_string (output_dir / parent_mld.name / "index.m")) @@ -39,8 +34,7 @@ let read f = in { intern = M.empty; extern } -let combine : t -> t -> t = - fun t1 t2 -> +let combine t1 t2 = { intern = M.fold M.add t1.intern t2.intern; extern = M.fold M.add t1.extern t2.extern; diff --git a/src/voodoo/index.mli b/src/voodoo/index.mli index 7c794e2e..611f8ee7 100644 --- a/src/voodoo/index.mli +++ b/src/voodoo/index.mli @@ -1,3 +1,4 @@ +(** Map of module digest to source info *) module M : sig include module type of Map.Make (String) end @@ -7,7 +8,12 @@ type t = { intern : Sourceinfo.t M.t; extern : Fpath.t M.t } val empty : t val find_opt : M.key -> t -> Sourceinfo.t option val find_extern_opt : M.key -> t -> Fpath.t option + val write : t -> Mld.t -> unit +(** [write x parent_mld] writes the index file [x] into + 'packages///index.m' or + 'universes////index.m' *) + val read : Fpath.t -> t val combine : t -> t -> t val of_source_infos : Sourceinfo.t list -> t diff --git a/src/voodoo/mld.ml b/src/voodoo/mld.ml index ba475280..da303818 100644 --- a/src/voodoo/mld.ml +++ b/src/voodoo/mld.ml @@ -27,12 +27,8 @@ let rec output_dir : base:Fpath.t -> t -> Paths.t = let compile_dir = output_dir ~base:Paths.compile let link_dir = output_dir ~base:Paths.link - -let output_file mld = - Fpath.(output_dir ~base:Paths.compile mld / ("page-" ^ mld.name ^ ".odoc")) - -let output_odocl mld = - Fpath.(output_dir ~base:Paths.link mld / ("page-" ^ mld.name ^ ".odocl")) +let output_file mld = Fpath.(compile_dir mld / ("page-" ^ mld.name ^ ".odoc")) +let output_odocl mld = Fpath.(link_dir mld / ("page-" ^ mld.name ^ ".odocl")) let rec compile mld = let () = Bos.OS.File.delete (output_file mld) |> Result.get_ok in @@ -60,7 +56,7 @@ let v dir name parent children contents = write mld contents; mld -let of_fpath parent path = +let of_fpath ~parent path = let _, name_ext = Fpath.split_base path in let name = Fpath.rem_ext name_ext |> Fpath.to_string in { path; name; parent = Some parent; children = [] } diff --git a/src/voodoo/mld.mli b/src/voodoo/mld.mli index 48e5b182..b08b20fe 100644 --- a/src/voodoo/mld.mli +++ b/src/voodoo/mld.mli @@ -7,10 +7,25 @@ type t = { val pp : t Fmt.t val output_dir : base:Fpath.t -> t -> Fpath.t + val compile_dir : t -> Fpath.t +(** [compile_dir x] returns the directory containing the files produced by + running [odoc compile] on [x]. *) + val link_dir : t -> Fpath.t +(** [link_dir x] returns the directory containing the files produced by running + [odoc link] on [x]. *) + val output_file : t -> Fpath.t +(** [output_file x] returns the path of the [.odoc] file resulting of running + [odoc compile] on [x]. *) + val output_odocl : t -> Fpath.t +(** [output_odocl x] returns the path of the [.odocl] file resulting of running + [odoc link] on [x]. *) + val compile : t -> unit +(** [compile x] calls [odoc compile] on [x] and its parents. *) + val v : Fpath.t -> string -> t option -> Odoc.child list -> string -> t -val of_fpath : t -> Fpath.t -> t +val of_fpath : parent:t -> Fpath.t -> t diff --git a/src/voodoo/ocamlobjinfo.mli b/src/voodoo/ocamlobjinfo.mli index b30890ad..bb7c6aa1 100644 --- a/src/voodoo/ocamlobjinfo.mli +++ b/src/voodoo/ocamlobjinfo.mli @@ -1,4 +1,8 @@ type t = { library_name : string; units : string list } val process : Fpath.t list -> t list +(** [process lx] processes the [*.ocamlobjinfo] files [lx]. *) + val find : Package.t -> (Fpath.t list, [> Bos_setup.R.msg ]) Bos_setup.result +(** [find p] looks for the [*.ocamlobjinfo] files in the prepped directory of + package [p]. *) diff --git a/src/voodoo/odoc.ml b/src/voodoo/odoc.ml index 6fcba198..379c36f1 100644 --- a/src/voodoo/odoc.ml +++ b/src/voodoo/odoc.ml @@ -1,10 +1,5 @@ -(* Odoc *) - type compile_dep = { c_unit_name : string; c_digest : string } -(** The name and optional digest of a dependency. Modules compiled with --no-alias-deps don't have - digests for purely aliased modules *) - type link_dep = { l_package : string; l_name : string; @@ -55,10 +50,7 @@ let compile_deps file = Format.eprintf "Failed to find digest for self (%s)\n%!" name; None -type child = - | CModule of string (* module name, e.g. 'String' *) - | CPage of string -(* page name, e.g. 'packages' *) +type child = CModule of string | CPage of string let compile ?parent ?output path ~includes ~children = let cmd = Bos.Cmd.(v "odoc" % "compile" % Fpath.to_string path) in @@ -103,7 +95,7 @@ let link path ~includes ~output = in Util.run_silent cmd -let html output path = +let html path ~output = let cmd = Bos.Cmd.( v "odoc" % "html-generate" % "--indent" % Fpath.to_string path % "-o" diff --git a/src/voodoo/odoc.mli b/src/voodoo/odoc.mli index 4a8046d7..bfb64a22 100644 --- a/src/voodoo/odoc.mli +++ b/src/voodoo/odoc.mli @@ -1,4 +1,6 @@ type compile_dep = { c_unit_name : string; c_digest : string } +(** The name and optional digest of a dependency. Modules compiled with + [--no-alias-deps] don't have digests for purely aliased modules. *) type link_dep = { l_package : string; @@ -11,7 +13,9 @@ type link_dep = { val pp_link_dep : Format.formatter -> link_dep -> unit val compile_deps : Fpath.t -> (string * string * compile_dep list) option -type child = CModule of string | CPage of string +type child = + | CModule of string (** module name, e.g. 'String' *) + | CPage of string (** page name, e.g. 'packages' *) val compile : ?parent:string -> @@ -20,6 +24,11 @@ val compile : includes:Fpath.set -> children:child list -> unit +(** [compile p ?parent ?output ~includes ~children] runs [odoc compile] on path + [p]. *) val link : Fpath.t -> includes:Fpath.set -> output:Fpath.t -> unit -val html : Fpath.t -> Fpath.t -> unit +(** [link p ~includes ~output] runs [odoc link] on path [p]. *) + +val html : Fpath.t -> output:Fpath.t -> unit +(** [html p ~output] runs [odoc html-generate] on path [p]. *) diff --git a/src/voodoo/opam.ml b/src/voodoo/opam.ml index 164570f4..8367c543 100644 --- a/src/voodoo/opam.ml +++ b/src/voodoo/opam.ml @@ -1,11 +1,7 @@ -(* opam *) +module Result = Bos_setup.R let switch = ref None -open Result - -let join = function Ok r -> r | Error _ as e -> e - let find package = let path = Package.prep_path package in Bos.OS.Dir.fold_contents ~dotfiles:true @@ -14,4 +10,4 @@ let find package = if name = Fpath.v "opam" then Ok p else acc) (Error (`Msg "No opam file found")) path - |> join + |> Result.join diff --git a/src/voodoo/opam.mli b/src/voodoo/opam.mli index 51a6a11b..e4a56d4a 100644 --- a/src/voodoo/opam.mli +++ b/src/voodoo/opam.mli @@ -1,2 +1,6 @@ val switch : string option ref +(** [switch] returns the local opam switch name. *) + val find : Package.t -> (Fpath.t, [> Bos_setup.R.msg ]) Bos_setup.result +(** [find p] returns the path to the [opam] file of package [p], in the prepped + directory of [p]. *) diff --git a/src/voodoo/otherdocs.ml b/src/voodoo/otherdocs.ml index 37434d41..a40a98d7 100644 --- a/src/voodoo/otherdocs.ml +++ b/src/voodoo/otherdocs.ml @@ -1,6 +1,3 @@ -(* otherdocs *) - -(* Copy the other docs into the version directory *) let copy version docs opam_file = let dir = Fpath.(Mld.link_dir version / version.name) in let copy src = diff --git a/src/voodoo/otherdocs.mli b/src/voodoo/otherdocs.mli index c8a1195f..5dcc1dcd 100644 --- a/src/voodoo/otherdocs.mli +++ b/src/voodoo/otherdocs.mli @@ -1,2 +1,5 @@ val copy : Mld.t -> Fpath.t list -> Fpath.t option -> Fpath.t list * Fpath.t option +(** [copy version docs opam_file] copies the other docs [docs] and [opam_file] + into the [version] directory, returns paths to the successfully copied + files. *) diff --git a/src/voodoo/package.mli b/src/voodoo/package.mli index ba32bae4..70193ed7 100644 --- a/src/voodoo/package.mli +++ b/src/voodoo/package.mli @@ -1,3 +1,6 @@ type t = { universe : string; name : string; version : string } val prep_path : t -> Fpath.t +(** [prep_path p] is the directory where the prepped package [p] is stored. + + Warning: it needs to stay in sync with [src/voodoo-prep/package.ml] *) diff --git a/src/voodoo/package_info.ml b/src/voodoo/package_info.ml index 98200a5e..69f7c644 100644 --- a/src/voodoo/package_info.ml +++ b/src/voodoo/package_info.ml @@ -1,6 +1,4 @@ -(* Generate a package.json describing the content of that package *) - -let gen ~output ~(dune : Dune.t option) ~libraries () = +let gen ~output ~(dune : Dune.t option) ~libraries = let dune_modules = function | Dune.Library.Singleton m -> [ m ] | Unwrapped { modules; _ } -> modules diff --git a/src/voodoo/package_info.mli b/src/voodoo/package_info.mli index edac1bf5..458ecf0d 100644 --- a/src/voodoo/package_info.mli +++ b/src/voodoo/package_info.mli @@ -1,6 +1,5 @@ val gen : - output:Fpath.t -> - dune:Dune.t option -> - libraries:Ocamlobjinfo.t list -> - unit -> - unit + output:Fpath.t -> dune:Dune.t option -> libraries:Ocamlobjinfo.t list -> unit +(** [gen ~output ~dune ~libraries] generates a [package.json] describing the + content of the package described by the dune file [dune], or the libraries + [libraries]. *) diff --git a/src/voodoo/package_mlds.ml b/src/voodoo/package_mlds.ml index 06b24472..5600117f 100644 --- a/src/voodoo/package_mlds.ml +++ b/src/voodoo/package_mlds.ml @@ -1,5 +1,3 @@ -(* package mlds *) - let find package = let path = Fpath.(Package.prep_path package / "doc" / package.name) in let res = @@ -20,7 +18,7 @@ let find package = Format.eprintf "Found no other pages\n%!"; ([], []) -let compile version package_mlds = +let compile ~parent package_mlds = if List.length package_mlds = 0 then ( Format.eprintf "No children\n%!"; []) @@ -30,9 +28,7 @@ let compile version package_mlds = let package_mlds = List.filter (fun p -> Fpath.basename p <> "index.mld") package_mlds in - let package_mldvs = - List.map (fun p -> Mld.of_fpath version p) package_mlds - in + let package_mldvs = List.map (Mld.of_fpath ~parent) package_mlds in List.iter Mld.compile package_mldvs; package_mldvs) diff --git a/src/voodoo/package_mlds.mli b/src/voodoo/package_mlds.mli index c080a731..ca251162 100644 --- a/src/voodoo/package_mlds.mli +++ b/src/voodoo/package_mlds.mli @@ -1,3 +1,10 @@ val find : Package.t -> Fpath.t list * Fpath.t list -val compile : Mld.t -> Fpath.t list -> Mld.t list +(** [find p] returns the list of [.mld] pages and other pages from the [doc/] + directory in the prepped directory of package [p]. *) + +val compile : parent:Mld.t -> Fpath.t list -> Mld.t list +(** [compile ~parent mlds] calls [odoc compile] on each mld file of [mlds]. *) + val include_paths : Mld.t list -> Fpath.set +(** [include_paths mlds] returns the paths of the parents of each mld file of + [mlds]. *) diff --git a/src/voodoo/paths.ml b/src/voodoo/paths.ml index e7529328..702e8bb2 100644 --- a/src/voodoo/paths.ml +++ b/src/voodoo/paths.ml @@ -1,5 +1,5 @@ type t = Fpath.t let compile = Fpath.v "compile" -let prep = Fpath.v "prep" (* warning: to keep in sync with bin/prep/paths.ml *) +let prep = Fpath.v "prep" let link = Fpath.v "linked" diff --git a/src/voodoo/paths.mli b/src/voodoo/paths.mli index f9fd2fe2..3e8abed4 100644 --- a/src/voodoo/paths.mli +++ b/src/voodoo/paths.mli @@ -1,5 +1,13 @@ type t = Fpath.t val compile : Fpath.t +(** [compile] is the root directory where the results of [odoc compile] are + stored. *) + val prep : Fpath.t +(** [prep] is the root directory where the prepped packages are stored. + + Warning: it needs to stay in sync with [src/voodoo-prep/paths.ml] *) + val link : Fpath.t +(** [link] is the root directory where the results of [odoc link] are stored. *) diff --git a/src/voodoo/sourceinfo.ml b/src/voodoo/sourceinfo.ml index 6c630378..49438a2c 100644 --- a/src/voodoo/sourceinfo.ml +++ b/src/voodoo/sourceinfo.ml @@ -7,8 +7,7 @@ type t = { deps : Odoc.compile_dep list; } -let output_dir : base:Fpath.t -> t -> Fpath.t = - fun ~base si -> +let output_dir ~base si = let segs = Fpath.segs si.path in match segs with | _prep :: _universe :: _package :: _version :: rest -> @@ -18,12 +17,8 @@ let output_dir : base:Fpath.t -> t -> Fpath.t = (Fpath.split_base fpath' |> fst) | _ -> failwith "Invalid path" -let compile_dir : t -> Fpath.t = output_dir ~base:Paths.compile - -let output_file : t -> Fpath.t = function - | si -> Fpath.(output_dir ~base:Paths.compile si / (si.name ^ ".odoc")) - -let output_odocl : t -> Fpath.t = function - | si -> Fpath.(output_dir ~base:Paths.link si / (si.name ^ ".odocl")) - +let compile_dir = output_dir ~base:Paths.compile +let link_dir = output_dir ~base:Paths.link +let output_file si = Fpath.(compile_dir si / (si.name ^ ".odoc")) +let output_odocl si = Fpath.(link_dir si / (si.name ^ ".odocl")) let is_hidden t = Util.is_hidden t.name diff --git a/src/voodoo/sourceinfo.mli b/src/voodoo/sourceinfo.mli index a932b05c..18852446 100644 --- a/src/voodoo/sourceinfo.mli +++ b/src/voodoo/sourceinfo.mli @@ -8,6 +8,15 @@ type t = { } val compile_dir : t -> Fpath.t +(** [compile_dir x] returns the directory containing the files produced by + running [odoc compile] on [x]. *) + val output_file : t -> Fpath.t +(** [output_file x] returns the path of the [.odoc] file resulting of running + [odoc compile] on [x]. *) + val output_odocl : t -> Fpath.t +(** [output_odocl x] returns the path of the [.odocl] file resulting of running + [odoc link] on [x]. *) + val is_hidden : t -> bool diff --git a/src/voodoo/util.ml b/src/voodoo/util.ml index de520302..b652c4f2 100644 --- a/src/voodoo/util.ml +++ b/src/voodoo/util.ml @@ -1,4 +1,3 @@ -(* util.ml *) open Bos module Result = Bos_setup.R open Result.Infix diff --git a/src/voodoo/util.mli b/src/voodoo/util.mli index 1984d2f3..efb28c5e 100644 --- a/src/voodoo/util.mli +++ b/src/voodoo/util.mli @@ -1,6 +1,18 @@ val is_hidden : string -> bool +(** [is_hidden s] returns whether [s] is the name of a hidden module, ie. if it + is generated by [odoc] and contains "__". *) + val lines_of_channel : in_channel -> string list +(** [lines_of_channel c] returns lines read on channel [c]. *) + val lines_of_process : Bos.Cmd.t -> string list +(** [lines_of_process p] returns lines read from the output of process [p]. *) + val run_silent : Bos.Cmd.t -> unit +(** [run_silent c] runs command [c] without displaying the output. *) + val mkdir_p : Fpath.t -> unit +(** [mkdir_p x] recursively creates directory [x] and its parents. *) + val copy : Fpath.t -> Fpath.t -> (unit, [> Bos_setup.R.msg ]) Bos_setup.result +(** [copy src dst] copies [src] to [dst]. *) diff --git a/src/voodoo/version.ml b/src/voodoo/version.ml index 5e6c4164..c0134223 100644 --- a/src/voodoo/version.ml +++ b/src/voodoo/version.ml @@ -1,7 +1,3 @@ -(* Version page *) - -(* Used to calculate the contents of the version page *) - let gen_with_dune (dune : Dune.t) = let libraries = if List.length dune.Dune.libraries = 0 then [] diff --git a/src/voodoo/version.mli b/src/voodoo/version.mli index 0b09b6fa..1e4c0c50 100644 --- a/src/voodoo/version.mli +++ b/src/voodoo/version.mli @@ -8,3 +8,4 @@ val gen_parent : error_log:Error_log.t -> failed:bool -> Mld.t +(** [gen_parent] generates the content of the version page. *)