diff --git a/DESIGN.md b/DESIGN.md index ad87aca..dd5537b 100644 --- a/DESIGN.md +++ b/DESIGN.md @@ -1,4 +1,4 @@ -# odoc-switchdocs — design +# odd — design Keep per-switch HTML documentation continuously up to date by hooking into opam's session lifecycle and rebuilding only the packages each session @@ -39,8 +39,8 @@ invocation it documents **one package installed in the current switch**: - `--odoc-dir`, `--odocl-dir` and `--html-dir` all default to `/odoc`. Intermediate `.odoc`/`.odocl` files and HTML share that tree, with each package's output directly under - `odoc//` (flat layout, same as plain `odoc_driver`). This is a - switchdocs-owned tree, kept separate from opam's own `/doc`, where + `odoc//` (flat layout, same as plain `odoc_driver`). This is an + odd-owned tree, kept separate from opam's own `/doc`, where packages install their own documentation. - Previously built dependencies are discovered by scanning `--odoc-dir` for the `.odoc_pkg_marker` / `.odoc_lib_marker` files written on earlier @@ -58,26 +58,26 @@ cleaning up removals are done directly by the coreutils hooks, see below). ### 1. opam hooks (configured in `~/.opam/config`, shipped via opamrc) Three wrapper fields drive everything. The two per-package hooks are plain -coreutils — crucially they invoke **no switchdocs binary** — so they keep -working even in a switch where switchdocs isn't installed (or is mid-upgrade, +coreutils — crucially they invoke **no odd binary** — so they keep +working even in a switch where odd isn't installed (or is mid-upgrade, or where a *global* hook fires for a switch that never had it). All real work happens once per session, in the one hook that does need the binary. ``` post-install-commands: [ - [ "sh" "-c" "mkdir -p \"$1/odoc/$2\" && touch \"$1/odoc/$2/.switchdocs-stale\"" + [ "sh" "-c" "mkdir -p \"$1/odoc/$2\" && touch \"$1/odoc/$2/.odd-stale\"" "--" "%{prefix}%" "%{name}%" ] { error-code = 0 } ] post-remove-commands: [ [ "rm" "-rf" "%{prefix}%/odoc/%{name}%" ] { error-code = 0 } ] post-session-commands: [ - [ "%{hooks}%/switchdocs" "sync" "--prefix" "%{prefix}%" ] { success } + [ "%{hooks}%/odd" "sync" "--prefix" "%{prefix}%" ] { success } ] ``` - **post-install** marks the package stale by `touch`-ing - `odoc//.switchdocs-stale` (after `mkdir -p`-ing the dir). It fires for + `odoc//.odd-stale` (after `mkdir -p`-ing the dir). It fires for every install action including same-version rebuilds — which matters, because a dependency-triggered rebuild changes the `.cmti`s but is invisible to session-level `%{new}%`/`%{removed}%`. A marker is a single empty file per @@ -88,22 +88,22 @@ post-session-commands: [ - **post-remove** deletes the package's doc subtree outright. Removal needs no marker and no deferral: the deletion *is* the action, done immediately and binary-free. (This also clears any stale marker that lived in that subtree.) -- **post-session** runs `switchdocs sync`, the one hook that needs the binary. +- **post-session** runs `odd sync`, the one hook that needs the binary. It always exits 0: doc failures are logged, never propagated, because opam aborts the invocation with a configuration error if a session hook fails - (`opamSolution.ml`, post-session handling). If switchdocs is absent, this + (`opamSolution.ml`, post-session handling). If odd is absent, this hook simply doesn't run; the markers persist and are drained by the next session that does have it — deferred, never lost. ### 2. State and layout (all under `$OPAM_SWITCH_PREFIX`) ``` -var/cache/switchdocs/ +var/cache/odd/ log # sync output, since hooks must stay quiet lock # guards a manual sync against a hook-invoked one odoc/ / - .switchdocs-stale # marker: post-install touched it, sync rebuilds + .odd-stale # marker: post-install touched it, sync rebuilds ... # per-package odoc, odocl and HTML (driver defaults) index.html # switch-wide landing page (ours) odoc-search/... # driver support files, search assets @@ -111,9 +111,9 @@ odoc/ The driver's defaults are taken as-is: one `odoc/` tree per switch holding both intermediates and HTML, separate from opam's own `/doc`. The -work list lives in that tree too — a `.switchdocs-stale` marker file inside +work list lives in that tree too — a `.odd-stale` marker file inside each stale package's dir — so the post-install hook can write it without -switchdocs. Our only other state is the log and lock. +odd. Our only other state is the log and lock. ### 3. The `sync` step @@ -126,7 +126,7 @@ the right switch; being read-only, the nested opam calls don't contend with the lock the surrounding session holds. 1. **Collect the stale set**: the package names whose `odoc//` holds a - `.switchdocs-stale` marker, intersected with the installed set. (A marker + `.odd-stale` marker, intersected with the installed set. (A marker for a no-longer-installed package can only survive an install+remove in the same session — the remove hook's `rm -rf` normally clears it — so tidy it away.) Removals need no handling here: the post-remove hook already deleted @@ -202,19 +202,19 @@ itself) behaves — possibly just a no-op build to skip. ## Tool shape -One OCaml executable, `switchdocs`, with subcommands: +One OCaml executable, `odd`, with subcommands: -- `switchdocs sync` — the session worker described above (the post-session hook). -- `switchdocs rebuild [--all | ...]` — manual escape hatch: mark +- `odd sync` — the session worker described above (the post-session hook). +- `odd rebuild [--all | ...]` — manual escape hatch: mark packages (or everything installed) stale and run sync. `--all` works on pre-existing switches because the installed-package metadata is always present, whether or not hooks were configured at install time. -- `switchdocs setup` — write the three wrapper fields into `~/.opam/config` +- `odd setup` — write the three wrapper fields into `~/.opam/config` with `opam option --global` (idempotent). There is deliberately **no** `record` subcommand: recording a change (a `touch`) and cleaning up a removal (an `rm -rf`) are plain coreutils in the -hooks, so they never depend on switchdocs being installed. +hooks, so they never depend on odd being installed. Dependencies: `opam-format` (opam file parsing), `bos`, `fpath`, `cmdliner`; `odoc_driver_opam` is invoked as an external binary so its @@ -223,14 +223,14 @@ should be installed per-switch (it links against the switch's odoc), found via the switch `PATH`. Distribution: an opamrc adding the three `*-commands` fields for -`opam init --config`; `switchdocs setup` for retrofitting existing roots. +`opam init --config`; `odd setup` for retrofitting existing roots. ## Failure handling summary | Failure | Behaviour | |---|---| | package build fails | hooks filtered on `error-code = 0` / `{ success }`; the package isn't marked stale, no sync | -| switchdocs not installed in the switch | post-install/post-remove still work (coreutils); markers accumulate, drained by the next session that has switchdocs — deferred, never lost | +| odd not installed in the switch | post-install/post-remove still work (coreutils); markers accumulate, drained by the next session that has odd — deferred, never lost | | doc build fails for one package | logged; its marker is re-created; later packages still attempted (their deps' docs may be stale — accepted, fixed on retry) | | sync interrupted | markers intact (a marker is only cleared by a successful build); next session resumes | | `odoc_driver_opam` missing from switch | sync logs and exits 0; markers survive until the driver is installed | diff --git a/DESIGN_COMPLETE.md b/DESIGN_COMPLETE.md index 36bd848..095889a 100644 --- a/DESIGN_COMPLETE.md +++ b/DESIGN_COMPLETE.md @@ -1,6 +1,6 @@ -# odoc-switchdocs — `complete`: reference completion +# odd — `complete`: reference completion -> **Status: implemented** (`lib/complete.ml`, `switchdocs complete`). The shared +> **Status: implemented** (`lib/complete.ml`, `odd complete`). The shared > resolve/load substrate was extracted into `Refs` (`lib/refs.ml`) rather than > left in `show.ml`; `Show` and `Complete` are thin layers over it. Deviations > from the design below: names containing `__` (wrapped internal modules) are @@ -14,18 +14,18 @@ completions — one per line, each a full reference string the user could type next. ``` -$ switchdocs complete /o +$ odd complete /o /ocaml-compiler /odoc /odoc.model ... -$ switchdocs complete List.m +$ odd complete List.m List.map List.mapi List.map2 List.mem ... -$ switchdocs complete module-List.type- +$ odd complete module-List.type- module-List.type-t ``` @@ -170,7 +170,7 @@ disambiguate). ## CLI shape ``` -switchdocs complete [--prefix DIR] PARTIAL +odd complete [--prefix DIR] PARTIAL ``` - Prints candidates one per line, sorted, on stdout. Each is a complete @@ -180,7 +180,7 @@ switchdocs complete [--prefix DIR] PARTIAL - A `--kind`-style filter is unnecessary: the kind tag is part of `PARTIAL` (`module-List.type-`), which is also what the user is mid-typing. -Shell glue (bash/zsh `complete -C`, a zsh `_switchdocs` function) is a thin +Shell glue (bash/zsh `complete -C`, a zsh `_odd` function) is a thin wrapper over this and is left to a follow-up; the command is the engine. ## Performance diff --git a/DESIGN_SHOW.md b/DESIGN_SHOW.md index 730b75c..3431599 100644 --- a/DESIGN_SHOW.md +++ b/DESIGN_SHOW.md @@ -1,10 +1,10 @@ -# odoc-switchdocs — `show`: print the docs for a reference +# odd — `show`: print the docs for a reference A CLI subcommand that takes an odoc reference and prints the docstring of the item it names, as Markdown: ``` -$ switchdocs show Odoc_model.Paths.Identifier +$ odd show Odoc_model.Paths.Identifier ``` The job is essentially the reference-resolution half of `odoc link`, run @@ -70,10 +70,10 @@ derived, not configured. scanning the directories it is given for `*.odoc` files. In a switch the driver writes these under `$OPAM_SWITCH_PREFIX/odoc///.odoc` (verified on the dev switch: e.g. `odoc/astring/astring/astring.odoc`). (This is the -switchdocs-owned tree, separate from opam's own `/doc`.) So: +odd-owned tree, separate from opam's own `/doc`.) So: - discover the switch prefix exactly as the existing commands do - (`Switchdocs.Switch.detect`, `--prefix`); + (`Odd.Switch.detect`, `--prefix`); - recursively collect every directory under `/odoc` that contains a `.odoc` file, and pass them all as `directories` (`Show.scan`). @@ -209,7 +209,7 @@ A user-facing subcommand alongside `search`, `rebuild`, etc. in `bin/main.ml`, backed by `lib/show.ml` (mirroring how `lib/search.ml` backs `search`): ``` -switchdocs show [--prefix DIR] REFERENCE +odd show [--prefix DIR] REFERENCE ``` - `REFERENCE` is an odoc reference string (`Odoc_model.Paths.Identifier`, @@ -232,7 +232,7 @@ switchdocs show [--prefix DIR] REFERENCE `odoc.odoc` (for `Resolver`/`Semantics`), `odoc.document`, `odoc.markdown`. These must be the *same* odoc that produced the switch's `.odoc`/`.odocl` (the formats are version-coupled). In this repo's dev switch odoc is pinned to the -driver's source, so they match; in general `switchdocs` should be built against +driver's source, so they match; in general `odd` should be built against the switch's odoc. ## Open questions / future work @@ -251,4 +251,4 @@ the switch's odoc. the single item) — a reasonable follow-up. - **Cross-reference link targets.** With `Base ""` the in-comment links are not meaningfully clickable from a terminal; a future mode could rewrite them to - `switchdocs show` invocations or to the switch's HTML. + `odd show` invocations or to the switch's HTML. diff --git a/README.md b/README.md index f91f3f8..f43c18c 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,17 @@ -# odoc-switchdocs +# odd Keep an opam switch's HTML documentation continuously up to date. -`switchdocs` wires opam's `post-install-commands`, `post-remove-commands` +`odd` wires opam's `post-install-commands`, `post-remove-commands` and `post-session-commands` hooks so that after every successful `opam install` / `opam upgrade` / `opam remove`, the docs for exactly the packages that changed are regenerated, in dependency order, by `odoc_driver_opam`. The per-package hooks are plain coreutils (a `touch` to mark a package stale, an `rm -rf` to drop a removed one's docs), so they keep -working even when switchdocs itself isn't installed in the switch; only the +working even when odd itself isn't installed in the switch; only the once-per-session worker needs the binary. Docs are written to `$OPAM_SWITCH_PREFIX/odoc//`, with a landing -page at `$OPAM_SWITCH_PREFIX/odoc/index.html`. (This is switchdocs' own tree, +page at `$OPAM_SWITCH_PREFIX/odoc/index.html`. (This is odd's own tree, kept separate from opam's `$OPAM_SWITCH_PREFIX/doc`, where packages install their own documentation.) @@ -20,8 +20,8 @@ See [DESIGN.md](DESIGN.md) for the full design. ## Setup ``` -$ switchdocs setup # show the opam configuration to be added -$ switchdocs setup --apply # add it to ~/.opam/config via `opam option` +$ odd setup # show the opam configuration to be added +$ odd setup --apply # add it to ~/.opam/config via `opam option` ``` `odoc_driver_opam` must be installed in each switch you want documented @@ -29,26 +29,26 @@ $ switchdocs setup --apply # add it to ~/.opam/config via `opam option` ## Commands -- `switchdocs sync` — session worker (the post-session hook); rebuilds every +- `odd sync` — session worker (the post-session hook); rebuilds every package marked stale, in dependency order, and regenerates the landing page. Always exits 0; details go to - `$OPAM_SWITCH_PREFIX/var/cache/switchdocs/log`. -- `switchdocs rebuild [--all | PKG...]` — mark packages stale and sync. + `$OPAM_SWITCH_PREFIX/var/cache/odd/log`. +- `odd rebuild [--all | PKG...]` — mark packages stale and sync. Exits non-zero on failure (user-facing, unlike the hook commands). -- `switchdocs order [PKG...]` — print the dependency order that sync would +- `odd order [PKG...]` — print the dependency order that sync would use (debugging aid). -- `switchdocs search [--package PKG]... [-n N] QUERY` — search the generated +- `odd search [--package PKG]... [-n N] QUERY` — search the generated documentation. Queries every package's `sherlodoc_db.marshal` together (a single query covers the whole switch), printing each match with its owning library and package. `--package` restricts to named packages. -- `switchdocs show REFERENCE` — print an item's documentation as Markdown, +- `odd show REFERENCE` — print an item's documentation as Markdown, under a header naming the item and the library/package it comes from, resolving an odoc reference against the whole switch. `Stdlib` is open, so bare names work (`List`, `print_endline`); references may also be qualified (`Astring.String`) or package-qualified (`/stdlib/Stdlib.List.map`). When a reference is ambiguous (e.g. a bare `index`, a page in every package), it lists the package-qualified alternatives instead of picking one. -- `switchdocs complete PARTIAL` — list the references `PARTIAL` could be +- `odd complete PARTIAL` — list the references `PARTIAL` could be completed to, one per line: members of what it names so far (`List.m` → `List.map`, …; kind tags filter, e.g. `module-List.type-` → `module-List.type-t`), package/library names for a leading `/` (`/o` → `/odoc`, `/odoc.model`, …), or @@ -56,9 +56,9 @@ $ switchdocs setup --apply # add it to ~/.opam/config via `opam option` ## Shell completion (zsh) -A zsh completion is shipped in `completions/zsh/_switchdocs`. It completes the +A zsh completion is shipped in `completions/zsh/_odd`. It completes the subcommands and, for `show` and `complete`, the reference argument — by calling -`switchdocs complete`, so completion always matches the command's own resolver +`odd complete`, so completion always matches the command's own resolver (`Stdlib` open, package-qualified `/pkg/...` paths, kind tags like `type-`, section labels, …). Type `.` or `/` and press TAB again to drill in. @@ -66,7 +66,7 @@ section labels, …). Type `.` or `/` and press TAB again to drill in. zsh's `$fpath` by default, so add it (before `compinit`) in `~/.zshrc`: ```zsh -fpath=("$(opam var odoc-switchdocs:share)/zsh" $fpath) +fpath=("$(opam var odd:share)/zsh" $fpath) autoload -U compinit && compinit ``` diff --git a/bin/dune b/bin/dune index 63e3de9..71c0dfb 100644 --- a/bin/dune +++ b/bin/dune @@ -1,5 +1,5 @@ (executable (name main) - (public_name switchdocs) - (package odoc-switchdocs) - (libraries switchdocs cmdliner fpath bos)) + (public_name odd) + (package odd) + (libraries odd cmdliner fpath bos)) diff --git a/bin/main.ml b/bin/main.ml index ea5b830..2dc2a5b 100644 --- a/bin/main.ml +++ b/bin/main.ml @@ -12,8 +12,8 @@ let switch_t = Arg.(value & opt (some string) None & info [ "prefix" ] ~docv:"DIR" ~doc) in let resolve = function - | Some p -> Ok (Switchdocs.Switch.v (Fpath.v p)) - | None -> Switchdocs.Switch.detect () + | Some p -> Ok (Odd.Switch.v (Fpath.v p)) + | None -> Odd.Switch.detect () in Term.(const resolve $ prefix) @@ -29,7 +29,7 @@ let driver_t = value & opt string "odoc_driver_opam" & info [ "driver" ] ~docv:"BIN" ~doc - ~env:(Cmd.Env.info "SWITCHDOCS_DRIVER")) + ~env:(Cmd.Env.info "ODD_DRIVER")) in let resolve d = if String.contains d '/' then @@ -47,23 +47,23 @@ let driver_t = Term.(const resolve $ arg) let print_outcome sw outcome = - Printf.printf "switchdocs: %s\n" (Switchdocs.Sync.summary outcome); - if outcome.Switchdocs.Sync.failed <> [] then - Printf.printf "switchdocs: see %s\n" - (Fpath.to_string (Switchdocs.Switch.log_file sw)) + Printf.printf "odd: %s\n" (Odd.Sync.summary outcome); + if outcome.Odd.Sync.failed <> [] then + Printf.printf "odd: see %s\n" + (Fpath.to_string (Odd.Switch.log_file sw)) (* sync — hook-facing: always exits 0. *) let sync_cmd = let run switch driver = (match switch with - | Error (`Msg m) -> Printf.eprintf "switchdocs sync: %s\n" m + | Error (`Msg m) -> Printf.eprintf "odd sync: %s\n" m | Ok sw -> ( - match Switchdocs.Sync.sync ~driver sw with + match Odd.Sync.sync ~driver sw with | Ok { built = []; failed = [] } -> () | Ok outcome -> print_outcome sw outcome | Error (`Msg m) -> - Switchdocs.Sync.log sw m; - Printf.eprintf "switchdocs sync: %s\n" m)); + Odd.Sync.log sw m; + Printf.eprintf "odd sync: %s\n" m)); 0 in let doc = "Bring the switch documentation up to date (opam hook worker)" in @@ -97,7 +97,7 @@ let rebuild_cmd = match switch with | Error (`Msg m) -> `Error (false, m) | Ok sw -> ( - let installed = Switchdocs.Switch.installed sw in + let installed = Odd.Switch.installed sw in let targets = if all then Ok installed else if pkgs = [] then @@ -118,16 +118,16 @@ let rebuild_cmd = let mark_all = List.fold_left (fun acc (name, _version) -> - Result.bind acc @@ fun () -> Switchdocs.Pending.mark sw name) + Result.bind acc @@ fun () -> Odd.Pending.mark sw name) (Ok ()) targets in match - Result.bind mark_all @@ fun () -> Switchdocs.Sync.sync ~driver sw + Result.bind mark_all @@ fun () -> Odd.Sync.sync ~driver sw with | Error (`Msg m) -> `Error (false, m) | Ok outcome -> print_outcome sw outcome; - if outcome.Switchdocs.Sync.failed <> [] then + if outcome.Odd.Sync.failed <> [] then `Ok exit_doc_failure else `Ok 0)) in @@ -138,7 +138,7 @@ let rebuild_cmd = `P "The manual escape hatch: marks the given packages (or, with \ $(b,--all), every installed package) as stale and runs the same \ - worker as $(b,switchdocs sync). Unlike the hook-facing commands this \ + worker as $(b,odd sync). Unlike the hook-facing commands this \ exits non-zero when a documentation build fails."; ] in @@ -161,11 +161,11 @@ let order_cmd = | Error (`Msg m) -> `Error (false, m) | Ok sw -> let pkgs = - if pkgs = [] then List.map fst (Switchdocs.Switch.installed sw) + if pkgs = [] then List.map fst (Odd.Switch.installed sw) else pkgs in let warn m = Printf.eprintf "warning: %s\n" m in - List.iter print_endline (Switchdocs.Deps.order ~warn sw pkgs); + List.iter print_endline (Odd.Deps.order ~warn sw pkgs); `Ok 0 in let doc = "Print the dependency order sync would use" in @@ -175,7 +175,7 @@ let order_cmd = `P "Prints the given packages in dependency order, one per line: every \ package appears after its (transitive) dependencies among the listed \ - packages. This is the order $(b,switchdocs sync) processes stale \ + packages. This is the order $(b,odd sync) processes stale \ packages in."; ] in @@ -211,13 +211,13 @@ let search_cmd = | Error (`Msg m) -> `Error (false, m) | Ok sw -> let warn m = Printf.eprintf "warning: %s\n" m in - (match Switchdocs.Search.search ~warn ~limit ~packages sw query with + (match Odd.Search.search ~warn ~limit ~packages sw query with | [] -> Printf.printf "No results.\n"; `Ok 0 | results -> List.iter - (fun r -> Format.printf "%a@." Switchdocs.Search.pp r) + (fun r -> Format.printf "%a@." Odd.Search.pp r) results; `Ok 0) in @@ -256,7 +256,7 @@ let show_cmd = match switch with | Error (`Msg m) -> `Error (false, m) | Ok sw -> ( - match Switchdocs.Show.show sw reference with + match Odd.Show.show sw reference with | Ok markdown -> print_string markdown; `Ok 0 @@ -264,7 +264,7 @@ let show_cmd = (* A failure to resolve or find docs is a runtime outcome, not a command-line misuse, so report it on stderr and exit non-zero rather than with cmdliner's CLI-error code. *) - Printf.eprintf "switchdocs show: %s\n" m; + Printf.eprintf "odd show: %s\n" m; `Ok exit_doc_failure) in let doc = "Print the documentation for a reference, as Markdown" in @@ -301,7 +301,7 @@ let complete_cmd = match switch with | Error (`Msg m) -> `Error (false, m) | Ok sw -> - List.iter print_endline (Switchdocs.Complete.complete sw partial); + List.iter print_endline (Odd.Complete.complete sw partial); `Ok 0 in let doc = "List the possible completions of a partial reference" in @@ -341,24 +341,24 @@ let setup_cmd = else exe in if not apply then ( - Switchdocs.Setup.print ~exe; + Odd.Setup.print ~exe; `Ok 0) else - match Switchdocs.Setup.apply ~exe with + match Odd.Setup.apply ~exe with | Ok () -> `Ok 0 | Error (`Msg m) -> `Error (false, m) in - let doc = "Configure the opam hooks that drive switchdocs" in + let doc = "Configure the opam hooks that drive odd" in let man = [ `S Manpage.s_description; `P "Adds to the global opam configuration: a $(b,post-install-commands) \ hook that marks a package's docs stale (a plain $(b,mkdir)+$(b,touch), \ - so it works even when switchdocs isn't installed), a \ + so it works even when odd isn't installed), a \ $(b,post-remove-commands) hook that deletes a package's docs \ ($(b,rm -rf)), and a $(b,post-session-commands) hook that runs \ - $(b,switchdocs sync). Without $(b,--apply), prints the $(b,opam \ + $(b,odd sync). Without $(b,--apply), prints the $(b,opam \ option) invocations instead of running them. Fields already carrying \ our command are skipped, so the command is idempotent."; ] @@ -373,17 +373,17 @@ let main_cmd = `P "$(mname) keeps the HTML documentation of an opam switch in sync with \ its installed packages. An opam post-install hook marks each changed \ - package stale (a marker file it touches, needing no switchdocs binary) \ + package stale (a marker file it touches, needing no odd binary) \ and a post-remove hook deletes a package's docs; at the end of the \ session the worker rebuilds exactly the stale packages, in dependency \ order, using an odoc driver. Output goes to \ $(b,\\$OPAM_SWITCH_PREFIX/odoc), with a landing page at \ $(b,odoc/index.html)."; - `P "Run $(b,switchdocs setup) to configure the hooks."; + `P "Run $(b,odd setup) to configure the hooks."; ] in Cmd.group - (Cmd.info "switchdocs" ~version:"%%VERSION%%" ~doc ~man) + (Cmd.info "odd" ~version:"%%VERSION%%" ~doc ~man) [ sync_cmd; rebuild_cmd; diff --git a/completions/dune b/completions/dune index 8ce2875..57ab21e 100644 --- a/completions/dune +++ b/completions/dune @@ -1,10 +1,10 @@ ; Install the zsh completion under the package's own share dir, -; /share/odoc-switchdocs/zsh/_switchdocs. (The switch's +; /share/odd/zsh/_odd. (The switch's ; share/zsh/site-functions is not on zsh's $fpath by default, so there is no ; benefit to that layout — the user adds this dir to $fpath either way; see the ; README.) (install (section share) - (package odoc-switchdocs) + (package odd) (files - (zsh/_switchdocs as zsh/_switchdocs))) + (zsh/_odd as zsh/_odd))) diff --git a/completions/zsh/_switchdocs b/completions/zsh/_odd similarity index 75% rename from completions/zsh/_switchdocs rename to completions/zsh/_odd index 131a37f..ff395cc 100644 --- a/completions/zsh/_switchdocs +++ b/completions/zsh/_odd @@ -1,17 +1,17 @@ -#compdef switchdocs +#compdef odd # -# zsh completion for switchdocs. +# zsh completion for odd. # # Install: put this file's directory on $fpath before compinit. After # `opam install` it lives under the package's share dir; add to ~/.zshrc: # -# fpath=("$(opam var odoc-switchdocs:share)/zsh" $fpath) +# fpath=("$(opam var odd:share)/zsh" $fpath) # autoload -U compinit && compinit # # (or point $fpath at completions/zsh in a source checkout.) # # Reference arguments (to `show` and `complete`) are completed by calling -# `switchdocs complete`, which resolves the partial reference against the whole +# `odd complete`, which resolves the partial reference against the whole # switch and returns the candidates — so completion is always in sync with the # command's own resolver (Stdlib open, package-qualified `/pkg/...` paths, kind # tags like `type-`, section labels, …). @@ -27,9 +27,9 @@ cmds=( 'setup:configure the opam hooks' ) -# Word 1 is "switchdocs"; word 2 is the subcommand. +# Word 1 is "odd"; word 2 is the subcommand. if (( CURRENT == 2 )); then - _describe -t commands 'switchdocs command' cmds + _describe -t commands 'odd command' cmds return fi @@ -41,11 +41,11 @@ case ${words[2]} in elif [[ $prev == (--prefix|-p) ]]; then _files -/ else - # Hand the current word to `switchdocs complete`; it returns full + # Hand the current word to `odd complete`; it returns full # reference strings. Empty suffix so dotted/slashed references can be # drilled into (type `.` and complete again). local -a refs - refs=(${(f)"$(switchdocs complete -- "$cur" 2>/dev/null)"}) + refs=(${(f)"$(odd complete -- "$cur" 2>/dev/null)"}) compadd -S '' -- $refs fi ;; diff --git a/dune-project b/dune-project index e80ec2d..731d127 100644 --- a/dune-project +++ b/dune-project @@ -1,20 +1,20 @@ (lang dune 3.16) -(name odoc-switchdocs) +(name odd) (cram enable) (generate_opam_files true) -(source (github jonludlam/odoc-switchdocs)) +(source (github jonludlam/odd)) (license ISC) (authors "Jon Ludlam ") (maintainers "Jon Ludlam ") (package - (name odoc-switchdocs) + (name odd) (synopsis "Keep an opam switch's documentation up to date via opam hooks") (description - "switchdocs wires opam's post-install, post-remove and post-session hooks \ + "odd wires opam's post-install, post-remove and post-session hooks \ to an odoc driver so that the HTML documentation of every package \ installed in a switch is regenerated incrementally, in dependency order, \ after each opam invocation.") diff --git a/lib/dune b/lib/dune index fd306ce..86907e7 100644 --- a/lib/dune +++ b/lib/dune @@ -1,5 +1,5 @@ (library - (name switchdocs) + (name odd) (libraries bos fpath diff --git a/lib/pending.ml b/lib/pending.ml index 3b4beb6..43167be 100644 --- a/lib/pending.ml +++ b/lib/pending.ml @@ -1,4 +1,4 @@ -let marker_name = ".switchdocs-stale" +let marker_name = ".odd-stale" let marker sw name = Fpath.(Switch.odoc_dir sw / name / marker_name) let read sw = diff --git a/lib/pending.mli b/lib/pending.mli index f8e7ddd..2393fb5 100644 --- a/lib/pending.mli +++ b/lib/pending.mli @@ -1,14 +1,14 @@ (** Stale markers: the set of packages whose documentation is out of date. - A package is marked by the empty file [/odoc//.switchdocs-stale]. + A package is marked by the empty file [/odoc//.odd-stale]. The opam post-install hook creates it with a plain [mkdir -p] + [touch], so - recording a change needs no switchdocs binary in the switch — only [sync] + recording a change needs no odd binary in the switch — only [sync] (and [rebuild]) do. Removals are handled directly by the post-remove hook ([rm -rf] of the package's doc directory), which also clears any marker, so there is no remove marker. *) val marker : Switch.t -> string -> Fpath.t -(** [/odoc//.switchdocs-stale]. *) +(** [/odoc//.odd-stale]. *) val read : Switch.t -> string list (** Names of packages with a stale marker — the subdirectories of diff --git a/lib/setup.ml b/lib/setup.ml index ee11e20..538b5a6 100644 --- a/lib/setup.ml +++ b/lib/setup.ml @@ -2,8 +2,8 @@ let quote s = Printf.sprintf "%S" s (* Each entry is an opam field, the command to append to it, and a substring that identifies our command if it is already present (for idempotency). The - per-package hooks deliberately don't mention the switchdocs binary — they are - plain coreutils so recording works even when switchdocs isn't installed — so + per-package hooks deliberately don't mention the odd binary — they are + plain coreutils so recording works even when odd isn't installed — so the marker can't just be [exe]. *) let fields ~exe = [ @@ -11,14 +11,14 @@ let fields ~exe = [mkdir -p] then [touch], passing prefix/name as $1/$2 to avoid quoting opam variables into the script. *) ( "post-install-commands", - {|["sh" "-c" "mkdir -p \"$1/odoc/$2\" && touch \"$1/odoc/$2/.switchdocs-stale\"" "--" "%{prefix}%" "%{name}%"] {error-code = 0}|}, - ".switchdocs-stale" ); + {|["sh" "-c" "mkdir -p \"$1/odoc/$2\" && touch \"$1/odoc/$2/.odd-stale\"" "--" "%{prefix}%" "%{name}%"] {error-code = 0}|}, + ".odd-stale" ); (* post-remove: delete the package's docs outright. Run as an argv list (no shell), so a prefix with spaces needs no quoting. *) ( "post-remove-commands", {|["rm" "-rf" "%{prefix}%/odoc/%{name}%"] {error-code = 0}|}, "/odoc/%{name}%" ); - (* post-session: the one hook that needs switchdocs — rebuild stale packages + (* post-session: the one hook that needs odd — rebuild stale packages and refresh the landing page. *) ( "post-session-commands", Printf.sprintf {|[%s "sync" "--prefix" "%%{prefix}%%"] {success}|} diff --git a/lib/setup.mli b/lib/setup.mli index 372d299..65bde44 100644 --- a/lib/setup.mli +++ b/lib/setup.mli @@ -6,7 +6,7 @@ val fields : exe:string -> (string * string * string) list (** The wrapper fields, the command to append to each, and a substring identifying our command if already present. The per-package hooks are plain - coreutils ([mkdir]/[touch]/[rm]) so they work without switchdocs installed; + coreutils ([mkdir]/[touch]/[rm]) so they work without odd installed; only the post-session worker invokes the binary at [exe]. *) val print : exe:string -> unit diff --git a/lib/switch.ml b/lib/switch.ml index c07a1a3..4267009 100644 --- a/lib/switch.ml +++ b/lib/switch.ml @@ -28,7 +28,7 @@ let detect () = $OPAM_SWITCH_PREFIX or pass --prefix" m))) -let state_dir t = Fpath.(t.prefix / "var" / "cache" / "switchdocs") +let state_dir t = Fpath.(t.prefix / "var" / "cache" / "odd") let log_file t = Fpath.(state_dir t / "log") let lock_file t = Fpath.(state_dir t / "lock") let work_dir t = Fpath.(state_dir t / "work") diff --git a/lib/switch.mli b/lib/switch.mli index 215504c..94f367d 100644 --- a/lib/switch.mli +++ b/lib/switch.mli @@ -1,4 +1,4 @@ -(** An opam switch and the paths switchdocs uses within it. *) +(** An opam switch and the paths odd uses within it. *) type t @@ -12,7 +12,7 @@ val detect : unit -> (t, [ `Msg of string ]) result val prefix : t -> Fpath.t val state_dir : t -> Fpath.t -(** [/var/cache/switchdocs], holding the log and lock. *) +(** [/var/cache/odd], holding the log and lock. *) val log_file : t -> Fpath.t val lock_file : t -> Fpath.t diff --git a/lib/sync.mli b/lib/sync.mli index 0031998..57c58c4 100644 --- a/lib/sync.mli +++ b/lib/sync.mli @@ -3,7 +3,7 @@ type outcome = { built : string list; failed : string list } val log : Switch.t -> string -> unit -(** Append a timestamped line to the switch's switchdocs log. Best-effort; never +(** Append a timestamped line to the switch's odd log. Best-effort; never raises. *) val sync : ?driver:Bos.Cmd.t -> Switch.t -> (outcome, [ `Msg of string ]) result diff --git a/odoc-switchdocs.opam b/odd.opam similarity index 59% rename from odoc-switchdocs.opam rename to odd.opam index 111a1fb..145a3b7 100644 --- a/odoc-switchdocs.opam +++ b/odd.opam @@ -2,12 +2,12 @@ opam-version: "2.0" synopsis: "Keep an opam switch's documentation up to date via opam hooks" description: - "switchdocs wires opam's post-install, post-remove and post-session hooks to an odoc driver so that the HTML documentation of every package installed in a switch is regenerated incrementally, in dependency order, after each opam invocation." + "odd wires opam's post-install, post-remove and post-session hooks to an odoc driver so that the HTML documentation of every package installed in a switch is regenerated incrementally, in dependency order, after each opam invocation." maintainer: ["Jon Ludlam "] authors: ["Jon Ludlam "] license: "ISC" -homepage: "https://github.com/jonludlam/odoc-switchdocs" -bug-reports: "https://github.com/jonludlam/odoc-switchdocs/issues" +homepage: "https://github.com/jonludlam/odd" +bug-reports: "https://github.com/jonludlam/odd/issues" depends: [ "dune" {>= "3.16"} "ocaml" {>= "5.2.0"} @@ -32,4 +32,4 @@ build: [ "@doc" {with-doc} ] ] -dev-repo: "git+https://github.com/jonludlam/odoc-switchdocs.git" +dev-repo: "git+https://github.com/jonludlam/odd.git" diff --git a/test/dune b/test/dune index 7980d37..136a2a6 100644 --- a/test/dune +++ b/test/dune @@ -1,2 +1,2 @@ (cram - (deps %{bin:switchdocs})) + (deps %{bin:odd})) diff --git a/test/order.t b/test/order.t index 0bccaa7..1daff0c 100644 --- a/test/order.t +++ b/test/order.t @@ -16,17 +16,17 @@ under /.opam-switch/packages/./opam. Dependencies come before dependents, whatever order the names are given in: - $ switchdocs order --prefix prefix c b a + $ odd order --prefix prefix c b a a b c - $ switchdocs order --prefix prefix a c + $ odd order --prefix prefix a c a c With no arguments, every installed package is ordered: - $ switchdocs order --prefix prefix + $ odd order --prefix prefix a b c @@ -34,7 +34,7 @@ With no arguments, every installed package is ordered: Names that are not installed are ignored, as sync ignores them (they are removals, not builds): - $ switchdocs order --prefix prefix c nosuchpkg a + $ odd order --prefix prefix c nosuchpkg a a c @@ -50,7 +50,7 @@ on x; without the exclusion this would be a cycle. > opam-version: "2.0" > depends: [ "x" {post} ] > EOF - $ switchdocs order --prefix prefix x y + $ odd order --prefix prefix x y y x @@ -61,7 +61,7 @@ influenced the build, hence the docs. z has no hard deps but depopts on c: > opam-version: "2.0" > depopts: [ "c" ] > EOF - $ switchdocs order --prefix prefix z c b + $ odd order --prefix prefix z c b b c z @@ -76,7 +76,7 @@ A genuine dependency cycle is reported and broken rather than fatal: > opam-version: "2.0" > depends: [ "p" ] > EOF - $ switchdocs order --prefix prefix p q + $ odd order --prefix prefix p q q p warning: dependency cycle through p; breaking it diff --git a/test/sync.t b/test/sync.t index b541075..805fa33 100644 --- a/test/sync.t +++ b/test/sync.t @@ -23,20 +23,20 @@ package's doc directory. The post-install hook marks a package stale by touching a marker file; the post-remove hook just deletes the package's doc directory. Stand in for them: - $ stale() { mkdir -p "prefix/odoc/$1"; touch "prefix/odoc/$1/.switchdocs-stale"; } + $ stale() { mkdir -p "prefix/odoc/$1"; touch "prefix/odoc/$1/.odd-stale"; } $ removed() { rm -rf "prefix/odoc/$1"; } No stale markers is a no-op with no output: - $ switchdocs sync --prefix prefix --driver ./driver.sh + $ odd sync --prefix prefix --driver ./driver.sh Marked packages are rebuilt in dependency order, regardless of the order they were marked in (b was marked first but depends on a): $ stale b $ stale a - $ switchdocs sync --prefix prefix --driver ./driver.sh - switchdocs: 2 built, 0 failed + $ odd sync --prefix prefix --driver ./driver.sh + odd: 2 built, 0 failed $ cat prefix/build-order a b @@ -44,7 +44,7 @@ were marked in (b was marked first but depends on a): A successful build clears the marker, and a landing page lists the documented packages: - $ test -e prefix/odoc/a/.switchdocs-stale || echo consumed + $ test -e prefix/odoc/a/.odd-stale || echo consumed consumed $ grep -o '
  • .*
  • ' prefix/odoc/index.html | sed 's/<[^>]*>//g' a 1 @@ -57,10 +57,10 @@ A failing package stays marked for the next session; others still build: > EOF $ stale bad $ stale a - $ switchdocs sync --prefix prefix --driver ./driver.sh - switchdocs: 1 built, 1 failed - switchdocs: see $TESTCASE_ROOT/prefix/var/cache/switchdocs/log - $ test -e prefix/odoc/bad/.switchdocs-stale && echo still-marked + $ odd sync --prefix prefix --driver ./driver.sh + odd: 1 built, 1 failed + odd: see $TESTCASE_ROOT/prefix/var/cache/odd/log + $ test -e prefix/odoc/bad/.odd-stale && echo still-marked still-marked A removal deletes the package's docs (post-remove hook); the landing page @@ -71,9 +71,9 @@ run, is retried (and fails again) — the designed retry behaviour: present $ rm -r prefix/.opam-switch/packages/b.1 $ removed b - $ switchdocs sync --prefix prefix --driver ./driver.sh - switchdocs: 0 built, 1 failed - switchdocs: see $TESTCASE_ROOT/prefix/var/cache/switchdocs/log + $ odd sync --prefix prefix --driver ./driver.sh + odd: 0 built, 1 failed + odd: see $TESTCASE_ROOT/prefix/var/cache/odd/log $ test -d prefix/odoc/b || echo gone gone $ grep -o '
  • .*
  • ' prefix/odoc/index.html | sed 's/<[^>]*>//g' @@ -83,20 +83,20 @@ A missing driver leaves marked packages stale and is reported via the summary (sync still exits 0 — it is hook-facing): $ stale a - $ switchdocs sync --prefix prefix --driver ./no-such-driver - switchdocs: 0 built, 2 failed - switchdocs: see $TESTCASE_ROOT/prefix/var/cache/switchdocs/log - $ ls prefix/odoc/a/.switchdocs-stale prefix/odoc/bad/.switchdocs-stale - prefix/odoc/a/.switchdocs-stale - prefix/odoc/bad/.switchdocs-stale + $ odd sync --prefix prefix --driver ./no-such-driver + odd: 0 built, 2 failed + odd: see $TESTCASE_ROOT/prefix/var/cache/odd/log + $ ls prefix/odoc/a/.odd-stale prefix/odoc/bad/.odd-stale + prefix/odoc/a/.odd-stale + prefix/odoc/bad/.odd-stale rebuild is the user-facing equivalent: it marks packages stale itself and fails loudly: - $ switchdocs rebuild --prefix prefix --driver ./driver.sh a bad - switchdocs: 1 built, 1 failed - switchdocs: see $TESTCASE_ROOT/prefix/var/cache/switchdocs/log + $ odd rebuild --prefix prefix --driver ./driver.sh a bad + odd: 1 built, 1 failed + odd: see $TESTCASE_ROOT/prefix/var/cache/odd/log [1] - $ switchdocs rebuild --prefix prefix --driver ./driver.sh nosuchpkg - switchdocs: not installed in this switch: nosuchpkg + $ odd rebuild --prefix prefix --driver ./driver.sh nosuchpkg + odd: not installed in this switch: nosuchpkg [124]