config-perso/machines/kat-son/doc/default.nix

168 lines
4.5 KiB
Nix

{
lib,
config,
pkgs,
...
}:
let
inherit (lib)
mkOption
mkEnableOption
mkIf
types
importJSON
mapAttrs'
mapAttrsToList
removePrefix
pathIsDirectory
hasSuffix
hasPrefix
attrNames
filter
head
;
inherit (lib.strings)
sanitizeDerivationName
;
yaml = pkgs.formats.yaml { };
json = pkgs.formats.json { };
cfg = config.services.extranix;
module-eval =
module-name: module:
let
ignored-eval = lib.evalModules {
modules = module.ignored-modules;
inherit (module) specialArgs;
};
ignored-opts-doc = pkgs.nixosOptionsDoc { inherit (ignored-eval) options; };
ignored-opts = importJSON "${ignored-opts-doc.optionsJSON}/share/doc/nixos/options.json";
eval = lib.evalModules {
modules = module.paths ++ module.ignored-modules;
inherit (module) specialArgs;
};
opts-doc = pkgs.nixosOptionsDoc { inherit (eval) options; };
opts = importJSON "${opts-doc.optionsJSON}/share/doc/nixos/options.json";
filtered-opts = removeAttrs opts (attrNames ignored-opts);
path-translation =
let
translations = map (
{ base, url }:
{
url = "${url}${if hasSuffix "/" url then "" else "/"}";
base =
let
base1 = toString base;
in
base1 + (if hasSuffix "/" base1 then "" else "/");
}
) module.path-translations;
in
path:
let
fullPath = path + (if pathIsDirectory path then "/default.nix" else "");
fitting = filter ({ base, ... }: hasPrefix base fullPath) translations;
translate-info = head (
fitting ++ [ (throw "${fullPath} is not in any base path of ${module-name}") ]
);
innerPath = removePrefix translate-info.base fullPath;
in
{
name = "<${innerPath}>";
url = "${translate-info.url}${innerPath}";
};
result = json.generate "options-extranix.json" {
last_update = "-/-";
options = mapAttrsToList (title: val: {
inherit title;
inherit (val)
type
readOnly
description
loc
;
example = val.example.text or "";
default = val.default.text or "";
declarations = map path-translation val.declarations;
}) filtered-opts;
};
in
result;
options-files = mapAttrs' (name: value: {
name = sanitizeDerivationName name;
value = module-eval name value;
}) cfg.modules;
webroot = pkgs.callPackage ./webroot.nix {
inherit options-files;
inherit (cfg) static-data;
settings = yaml.generate "config.yaml" cfg.settings;
hugo-theme-extranix-options-search = pkgs.callPackage ./hugo-theme-extranix-options-search.nix { };
};
in
{
options.services.extranix = {
enable = mkEnableOption "extranix documentation";
modules = mkOption {
type =
let
module-mod.options = {
specialArgs = mkOption {
type = types.attrs;
default = { };
};
paths = mkOption {
type = types.listOf types.path;
};
ignored-modules = mkOption {
type = types.listOf types.deferredModule;
default = [ ];
};
path-translations = mkOption {
type =
let
path-mod.options = {
base = mkOption {
type = types.path;
};
url = mkOption {
type = types.str;
};
};
in
types.listOf (types.submodule path-mod);
};
};
in
types.attrsOf (types.submodule module-mod);
};
settings = mkOption {
type = yaml.type;
};
static-data = mkOption {
type = types.path;
};
host = mkOption {
type = types.str;
};
};
config = mkIf cfg.enable {
services = {
extranix = {
settings = {
markup.goldmark.renderer.unsafe = true;
theme = "extranix-options-search";
params.releases = mapAttrsToList (name: _: {
inherit name;
value = sanitizeDerivationName name;
}) cfg.modules;
};
};
nginx = {
enable = true;
virtualHosts.${cfg.host}.locations."/".alias = "${webroot}/";
};
};
};
}