docs: render zola pages in clan-core flake

This integrates the generated options docs part of our website into the clan-core project. This is better than having it in a separate repos because we want to lear about breakages as early as possible.

Changes which break the documentation should be blocked by this early on
This commit is contained in:
DavHau
2024-03-31 12:33:31 +07:00
parent 62f201696d
commit 492256ec54
3 changed files with 106 additions and 21 deletions

View File

@@ -0,0 +1,69 @@
{
self,
lib,
inputs,
...
}:
{
imports = [ ./zola-pages.nix ];
perSystem =
{ pkgs, ... }:
let
allNixosModules = (import "${inputs.nixpkgs}/nixos/modules/module-list.nix") ++ [
"${inputs.nixpkgs}/nixos/modules/misc/assertions.nix"
{ nixpkgs.hostPlatform = "x86_64-linux"; }
];
clanCoreNixosModules = [ self.nixosModules.clanCore ] ++ allNixosModules;
# TODO: optimally we would not have to evaluate all nixos modules for every page
# but some of our module options secretly depend on nixos modules.
# We would have to get rid of these implicit dependencies and make them explicit
clanCoreNixos = pkgs.nixos { imports = clanCoreNixosModules; };
# using extendModules here instead of re-evaluating nixos every time
# improves eval performance slightly (10%)
options = modules: (clanCoreNixos.extendModules { inherit modules; }).options;
docs =
options:
pkgs.nixosOptionsDoc {
options = options;
warningsAreErrors = false;
# transform each option so that the declaration link points to git.clan.lol
# and not to the /nix/store
transformOptions =
opt:
opt
// {
declarations = lib.forEach opt.declarations (
decl:
if lib.hasPrefix "${self}" decl then
let
subpath = lib.removePrefix "${self}" decl;
in
{
url = "https://git.clan.lol/clan/clan-core/src/branch/main/" + subpath;
name = subpath;
}
else
decl
);
};
};
outputsFor = name: docs: { packages."docs-md-${name}" = docs.optionsCommonMark; };
clanModulesPages = lib.flip lib.mapAttrsToList self.clanModules (
name: module: outputsFor "module-${name}" (docs ((options [ module ]).clan.${name} or { }))
);
in
{
imports = clanModulesPages ++ [
# renders all clanCore options in a single page
(outputsFor "core-options" (docs (options [ ]).clanCore))
];
};
}

View File

@@ -0,0 +1,88 @@
{
perSystem =
{
lib,
pkgs,
self',
...
}:
let
getMdPages =
prefix:
let
mdDocs' = lib.filterAttrs (name: _: lib.hasPrefix prefix name) self'.packages;
mdDocs = lib.mapAttrs' (name: pkg: lib.nameValuePair (lib.removePrefix prefix name) pkg) mdDocs';
in
if mdDocs != { } then
mdDocs
else
throw ''
Error: no markdown files found in clan-core.packages' with prefix "${prefix}"
'';
makeZolaIndexMd =
title: weight:
pkgs.writeText "_index.md" ''
+++
title = "${title}"
template = "docs/section.html"
weight = ${toString weight}
sort_by = "title"
draft = false
+++
'';
makeZolaPages =
{
sectionTitle,
files,
makeIntro ? _name: "",
weight ? 9999,
}:
pkgs.runCommand "zola-pages-clan-core" { } ''
mkdir $out
# create new section via _index.md
cp ${makeZolaIndexMd sectionTitle weight} $out/_index.md
# generate zola compatible md files for each nixos options md
${lib.concatStringsSep "\n" (
lib.flip lib.mapAttrsToList files (
name: md: ''
# generate header for zola with title, template, weight
title="${name}"
echo -e "+++\ntitle = \"$title\"\ntemplate = \"docs/page.html\"\nweight = 0\n+++" > "$out/${name}.md"
cat <<EOF >> "$out/${name}.md"
${makeIntro name}
EOF
# append everything from the nixpkgs generated md file
cat "${md}" >> "$out/${name}.md"
''
)
)}
'';
in
{
packages.docs-zola-pages-core = makeZolaPages {
sectionTitle = "cLAN Core Reference";
files = getMdPages "docs-md-core-";
weight = 20;
};
packages.docs-zola-pages-modules = makeZolaPages {
sectionTitle = "cLAN Modules Reference";
files = getMdPages "docs-md-module-";
weight = 25;
makeIntro = name: ''
To use this module, import it like this:
\`\`\`nix
{config, lib, inputs, ...}: {
imports = [inputs.clan-core.clanModules.${name}];
# ...
}
\`\`\`
'';
};
};
}