StewOS
Source

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

Defined in lib/docs/default.nix

# 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

Defined in lib/docs/default.nix

# 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

Defined in lib/docs/options.nix

# 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

Defined in lib/docs/options.nix

# 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

Defined in lib/docs/hosts.nix

# 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]]

Defined in lib/docs/hosts.nix

# 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

Defined in lib/docs/packages.nix

# 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

Defined in lib/docs/outputs.nix

# 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]

Defined in lib/docs/outputs.nix

# 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

Defined in lib/docs/nixdoc.nix