lib.docs
Extraction half of the documentation generator that built this site.
#
lib.docs.mkDocsJSON
Extract a flake into a single JSON document.
Inputs
pkgs
: Package set the document is built with. Its system is the system the
documentation is generated on, which need not be a system the flake
targets -- a darwin option set evaluates and renders perfectly well from
Linux, since reading an option tree never builds anything.
self
: The flake being documented.
inputs
: That flake's inputs. Module trees are evaluated with these as specialArgs.
config
: A path to a flakedoc.toml, or the same structure as an attrset.
pkgsBySystem
: Package sets to evaluate option sets against, keyed by system. Defaults to
pkgs under its own system, which is enough for a single-platform flake.
stubs
: Extra modules per option-set id, for anything a tree needs before its
options can be read. Keep these minimal: whatever they set shows up in the
rendered default of every option that reads config.
Example
lib.docs.mkDocsJSON {
pkgs = pkgsFor.x86_64-linux;
inherit self inputs;
config = ./docs/flakedoc.toml;
pkgsBySystem = pkgsFor;
}
Type
mkDocsJSON :: AttrSet -> Derivation
#
lib.docs.mkSite
Build a flake's documentation site.
Takes everything mkDocsJSON does,
plus the prose to weave in, and runs the renderer over the result.
Inputs
content
: Directory of hand-written Markdown, or null for reference pages only.
flakedoc
: The renderer. Defaults to the one in the StewOS package scope.
templates
: Directory of minijinja templates overriding the built-in ones, or null.
Example
packages.x86_64-linux.docs = self.lib.docs.mkSite {
pkgs = pkgsFor.x86_64-linux;
inherit self inputs;
config = ./docs/flakedoc.toml;
content = ./docs/content;
};
Type
mkSite :: AttrSet -> Derivation
#
lib.docs.evalTree
Evaluate one module tree against a synthetic host and return its options.
The tree is addressed through the flake's own store path rather than a
relative one. That is load-bearing: an option's declarations record the
store path the module was read from, and isOurs below recognises a flake's
own options by that prefix. Importing ./modules/nixos from an expression
copies the directory to a different store path, and the filter then
silently matches nothing.
Inputs
kind
: Which evaluator to use -- one of nixos, home-manager or darwin.
pkgs
: The package set to evaluate against. Must match the option set's system,
which is not necessarily the system the documentation is built on.
inputs
: The documented flake's inputs, handed to the module system as specialArgs.
src
: The documented flake's source, normally self.outPath.
modules
: Source-relative paths of the module trees to evaluate, e.g.
[ "modules/nixos" ].
stub
: Extra modules defining whatever the tree needs before its options can be
read. Keep this as small as it will go.
Type
evalTree :: AttrSet -> AttrSet
#
lib.docs.mkOptionSet
Render an evaluated option tree into a documentation record.
Options are kept when at least one of their declarations lives inside src.
That is a better filter than matching an option-name prefix: it needs no
configuration, it cannot be fooled by a third-party module that happens to
share a namespace, and it catches options a flake declares outside its own
namespace -- StewOS's darwin tree, for example, declares programs.nh and
nothing under stewos.* at all.
It has one blind spot. A module imported as a value rather than as a path
-- imports = [ inputs.foo.homeManagerModules.default ] -- has no file of
its own to be attributed to, so the module system credits its options to the
file that imported it. Those options then look, correctly as far as anything
here can tell, like the importing flake's own.
The better remedy is at the import rather than here: giving the import a file restores the attribution, and improves that module's error messages while it is at it.
imports = [
{
_file = "inputs.foo/nix/hm-module.nix";
imports = [ inputs.foo.homeManagerModules.default ];
}
];
exclude is for when that is not available -- an import buried inside a
module you do not control.
Inputs
docPkgs
: Package set used to build the JSON. This is the system the docs are
built on, which need not be the system the options were evaluated for --
that split is what lets a Linux machine render the darwin option set.
options
: The options attrset from evalTree.
set
: The option set's { id, title, kind, system, ... } record from the
configuration file.
exclude
: Dotted option-name prefixes to drop even though they pass the declaration
filter. See above for the one case that needs this.
Type
mkOptionSet :: AttrSet -> AttrSet
#
lib.docs.mkHost
Collect everything one host sets, as a documentation record.
Only options the flake itself declares are considered, and only definitions
written inside the flake's own source are reported -- a module's internal
mkDefault is a fact about the module, documented on the module's page, not
a fact about the host.
Definitions are kept one per file rather than merged, so shared policy
(hosts/common/workstation.nix) stays distinguishable from what the host
itself asked for.
Inputs
name
: The attribute name of the configuration, e.g. framework-desktop.
kind
: nixos, home-manager or darwin.
configuration
: The evaluated configuration, i.e. an entry of self.nixosConfigurations
and friends.
optionPaths
: Location lists of the options the flake declares, as produced by
optionPathsOf. Bounding the
walk this way keeps it away from the many thousands of options nixpkgs and
home-manager contribute, most of which are expensive and some of which
throw when forced.
facts
: Dotted option paths to report by value rather than by definition, as
things that are true of the machine.
Some of what a configuration is built from never reaches the settings
list, because the settings list is built from where a value was written
and not everything has a usable "where". An identity passed straight into
a configuration builder is the usual case: it is defined by an inline
module, so the module system attributes it to whatever file it can find a
position in -- for StewOS's stewos.user that is nixpkgs' own flake.nix
on the NixOS side and <unknown-file> on the home-manager side. Neither
is somewhere a reader could go look.
Reading the merged value instead sidesteps provenance entirely, and has the property the settings list cannot offer here: a value handed to both halves of a machine reads identically on both their pages.
src
: The documented flake's source, normally self.outPath.
Type
mkHost :: AttrSet -> AttrSet
#
lib.docs.optionPathsOf
The location lists of every option in a set of option-set records, with the
<name> placeholders nixosOptionsDoc emits for attrsOf submodules dropped.
Those placeholders describe the shape of an option's value; they are not paths into an option tree and cannot be looked up in one.
Type
optionPathsOf :: [AttrSet] -> [[String]]
#
lib.docs.mkPackage
Describe one entry of a flake's packages output.
Inputs
attr
: The attribute name the package is exposed under.
drv
: The derivation itself.
src
: The documented flake's source, normally self.outPath.
packageDir
: Source-relative directory the flake keeps its package definitions in. A
package is linked there when meta.position points outside the flake,
which is what happens when a definition overrides an upstream derivation
and inherits its meta along with its provenance.
Type
mkPackage :: AttrSet -> AttrSet
#
lib.docs.mkOutputs
Describe a flake's outputs.
packages is deliberately absent: it is documented in full elsewhere, and
restating the attribute names here would only invite the two lists to
disagree.
Type
mkOutputs :: AttrSet -> AttrSet
#
lib.docs.mkInputs
Read a flake's direct inputs out of its lock file.
Only the root node's inputs are reported. Transitive nodes exist in the lock in their hundreds and describe other people's dependency graphs, not this flake's surface.
Inputs
lockFile
: Path to flake.lock.
Type
mkInputs :: AttrSet -> [AttrSet]
#
lib.docs.mkLibDocs
Run nixdoc over a flake's library files and collect the results.
Each namespace becomes one page. prefix and category together decide the
name a function is documented under: nixdoc renders <prefix>.<category>.<fn>,
so a lib.docs namespace wants prefix = "lib" and category = "docs".
A namespace may name several files. nixdoc reads one file at a time, but a
namespace assembled by re-exporting from its neighbours -- which is what a
lib/<name>/ directory usually is -- is one thing to its callers and should
be one page to its readers.
Inputs
namespaces
: List of { name, files, category, prefix, description } records, normally
straight out of the configuration file.
Type
mkLibDocs :: AttrSet -> Derivation