Skip to content

Documentation

There is a separate devshell called docs which is provided for working with the docs locally.

It can be entered by running: nix develop .#docs

nix/devshells/docs.nix
{
  pkgs,
  ...
}:
pkgs.mkShellNoCC {
  packages =
    let
      inherit (pkgs) lib;

      # Capture root so we can identify our store paths below
      root = toString ./.;

      snakeCase = with lib; replaceStrings upperChars (map (s: "_" + s) lowerChars);

      # Eval Facter module
      eval = lib.evalModules {
        modules = [
          # Load the root module
          ./modules/nixos/facter.nix
          {
            # Disable checks so it doesn't complain about NixOS related options which aren't available
            config._module.check = false;
            # Use the basic vm's report
            config.facter.reportPath = ./hosts/basic/report.json;
          }
        ];
      };

      # Convert `/nix/store/...` store paths in the option declarations into a repository link.
      # NOTE: we point at the main branch, but for versioned docs this will be incorrect.
      # It's still a good starting point though.
      transformDeclaration =
        decl:
        let
          declStr = toString decl;
          subpath = lib.removePrefix "/" (lib.removePrefix root declStr);
        in
        assert lib.hasPrefix root declStr;
        {
          url = "https://github.com/numtide/nixos-facter-modules/blob/main/${subpath}";
          name = subpath;
        };

      # Convert options into options doc, transforming declaration paths to point to the github repository.
      nixosOptionsDoc =
        _name: options:
        pkgs.nixosOptionsDoc {
          inherit options;
          transformOptions =
            opt:
            opt
            // {
              declarations = map transformDeclaration opt.declarations;
            };
        };

      # Take an options attr set and produce a markdown file.
      mkMarkdown =
        name: options:
        let
          optionsDoc = nixosOptionsDoc name options;
        in
        pkgs.runCommand "${name}-markdown" { } ''
          mkdir $out
          cat ${optionsDoc.optionsCommonMark} > $out/${snakeCase name}.md
        '';

      # Allows us to gather all options that are immediate children of `facter` and which have no child options.
      # e.g. facter.reportPath, facter.report.
      # For all other options we group them by the first immediate child of `facter`.
      # e.g. facter.bluetooth, facter.boot and so on.
      # This allows us to have a page for root facter options "facter.md", and a page each for the major sub modules.
      facterOptionsFilter =
        _:
        {
          loc ? [ ],
          options ? [ ],
          ...
        }:
        (lib.length loc) == 2 && ((lib.elemAt loc 0) == "facter") && (lib.length options) == 0;

      otherOptionsFilter = n: v: !(facterOptionsFilter n v);

      facterMarkdown = mkMarkdown "facter" (lib.filterAttrs facterOptionsFilter eval.options.facter);
      otherMarkdown = lib.mapAttrsToList mkMarkdown (
        lib.filterAttrs otherOptionsFilter eval.options.facter
      );

      optionsMarkdown = pkgs.symlinkJoin {
        name = "facter-module-markdown";
        paths = [ facterMarkdown ] ++ otherMarkdown;
      };

    in
    with pkgs;
    [
      (pkgs.writeScriptBin "mkdocs" ''
        # rsync in NixOS modules doc to avoid issues with symlinks being owned by root
        rsync -aL --chmod=u+rw --delete-before ${optionsMarkdown}/ ./docs/content/reference/nixos_modules

        # execute the underlying command
        ${pkgs.mkdocs}/bin/mkdocs "$@"
      '')
    ]
    ++ (with pkgs.python3Packages; [
      mike
      mkdocs-material
    ]);
}

The docs are based on MkDocs and the MkDocs Material theme. You will find its configuration and content in the following locations:

  • mkdocs.yaml
  • ./docs

Serve locally

To serve the docs locally run mkdocs serve from the root of the repository:

1
2
3
4
5
6
7
8
❯ mkdocs serve
INFO    -  Building documentation...
INFO    -  Cleaning site directory
WARNING -  The following pages exist in the docs directory, but are not included in the "nav" configuration:
             - index.md
INFO    -  Documentation built in 0.26 seconds
INFO    -  [16:22:36] Watching paths for changes: 'docs/content', 'mkdocs.yml'
INFO    -  [16:22:36] Serving on http://127.0.0.1:8000/nixos-facter/

Versioning & Publication

Versioning of the docs is managed through mike.

It is responsible for managing the structure of the gh-pages branch in the repository, which Github Pages is configured to serve from.

Note

More information about versioning with MkDocs Material and mike can be found here.

There is a github workflow, .github/workflows/gh-pages.yml which is responsible for publishing the docs. It does the following:

  • On merge to main, the docs version main is updated.
  • When a new tag is created of the form v.<major>.<minor>.<patch> a docs version v<major>.<minor> is created and the latest alias is updated to point to this.

The idea is that users will land on the latest released version of the docs by default, with main being available if they wish to read about unreleased features and changes.

To preview the versions locally you can use mike serve instead of mkdocs serve.

Warning

Be sure to have fetched the latest changes for the gh-pages branch first. This is especially important if you are using mike locally to make manual changes to the published site.