odd#
Keep an opam switch's HTML documentation continuously up to date.
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
odd-driver. 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 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/<package>/, with a landing
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.)
See doc/DESIGN.md for the full design, and
doc/DESIGN_DOC.md / doc/DESIGN_COMPLETE.md
for the doc and complete commands.
Setup#
$ odd setup # show the opam configuration to be added
$ odd setup --apply # add it to ~/.opam/config via `opam option`
$ odd rebuild --all # Initial (slow!) build of all the docs
The odoc driver (odd-driver) is bundled with odd (vendored under
driver/, built and installed alongside the odd binary), so there's nothing
else to install. It drives the odoc, odoc-md and sherlodoc binaries,
which must be present in the switch.
Commands#
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/odd/log.odd rebuild [--all | PKG...]— mark packages stale and sync. Exits non-zero on failure (user-facing, unlike the hook commands).odd order [PKG...]— print the dependency order that sync would use (debugging aid).odd search [--package PKG]... [-n N] QUERY— search the generated documentation. Queries every package'ssherlodoc_db.marshaltogether (a single query covers the whole switch), printing each match with its owning library and package.--packagerestricts to named packages.odd doc 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.Stdlibis 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 bareindex, a page in every package), it lists the package-qualified alternatives instead of picking one.odd complete PARTIAL— list the referencesPARTIALcould 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 the units under a/pkg/path. The engine for shell completion.
Shell completion (zsh)#
A zsh completion is shipped in completions/zsh/_odd. It completes the
subcommands and, for doc and complete, the reference argument — by calling
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.
opam install puts it under the package's share dir. That directory isn't on
zsh's $fpath by default, so add it (before compinit) in ~/.zshrc:
fpath=("$(opam var odd:share)/zsh" $fpath)
autoload -U compinit && compinit
(Or point $fpath at completions/zsh in a source checkout.)
Development#
$ opam install . --deps-only --with-test
$ dune build
$ dune runtest