feat: add function to generate docs for nixlet values

add docs for nixlets in this repo to the mkdocs site
This commit is contained in:
technofab 2025-07-19 16:25:46 +02:00
parent 2cb8c69aaa
commit 48e8cf48b0
No known key found for this signature in database
3 changed files with 214 additions and 74 deletions

View file

@ -60,7 +60,23 @@
doc = {
path = ./docs;
deps = pp: [pp.mkdocs-material (pp.callPackage inputs.mkdocs-material-umami {})];
deps = pp: [
pp.mkdocs-material
(pp.callPackage inputs.mkdocs-material-umami {})
(pp.buildPythonPackage rec {
pname = "mkdocs-gen-files";
version = "0.5.0";
pyproject = true;
build-system = [pp.hatchling];
src = pkgs.fetchFromGitHub {
owner = "oprypin";
repo = "mkdocs-gen-files";
rev = "v${version}";
hash = "sha256-nRRdY7/en42s4PmHH+9vccRIl4pIp1F/Ka1bYvSHpBw=";
};
dependencies = [pp.mkdocs];
})
];
config = {
site_name = "Nixlets";
repo_name = "TECHNOFAB/nixlets";
@ -95,13 +111,41 @@
}
];
};
plugins = ["search" "material-umami"];
plugins = [
"search"
"material-umami"
{
# bit hacky, but works :D
"gen-files".scripts = let
docsEntries = builtins.toJSON (builtins.mapAttrs (n: v: v.mkDocs {}) self.nixlets);
in [
(builtins.toFile "gen.py"
# py
''
import mkdocs_gen_files, json
data = json.loads('${docsEntries}')
for name, file in data.items():
with open(file, 'r') as infile:
content = infile.read()
with mkdocs_gen_files.open(f"options/{name}.md", "w") as outfile:
outfile.write(content)
'')
];
}
];
nav = [
{"Introduction" = "index.md";}
{"Creating Nixlets" = "creation.md";}
{"Packaging" = "packaging.md";}
{"Usage" = "usage.md";}
{"Secrets" = "secrets.md";}
{
"Nixlets Values" =
lib.mapAttrsToList (n: v: {
${v.name} = "options/${n}.md";
})
self.nixlets;
}
];
markdown_extensions = [
{

View file

@ -4,24 +4,23 @@
...
} @ attrs:
with lib; rec {
mkValues = file: {rawValues, ...} @ args:
(lib.evalModules {
specialArgs = {
utils = import ./utils.nix attrs;
};
modules = [
file
({...}: {
# pass through all args to the values.nix module
config =
rawValues
// {
_module.args = args;
};
})
];
})
.config;
evalValues = file: {rawValues, ...} @ args: (lib.evalModules {
specialArgs = {
utils = import ./utils.nix attrs;
};
modules = [
file
({...}: {
# pass through all args to the values.nix module
config =
rawValues
// {
_module.args = args;
};
})
];
});
mkValues = file: args: (evalValues file args).config;
# wraps mkNixletInner to allow passing either a path or an attrset
mkNixlet = arg:
@ -44,60 +43,70 @@ with lib; rec {
description ? "",
defaultProject ? null,
...
}: rec {
inherit name version description path;
eval = {
system,
project ? defaultProject,
overrides ? ({...}: {}),
values ? {},
}:
assert lib.assertMsg (project != null) "No default project set, please pass a project to the render method"; let
# every nixlet gets "nixlet" as arg with some useful data about itself
nixletArg = {
inherit name project version description;
};
in (kubenix.evalModules.${system} {
module = {kubenix, ...}: {
imports = with kubenix.modules; [
k8s
helm
docker
files
./secretsModule.nix
({...}: let
finalValues = mkValues "${path}/values.nix" {
rawValues = values;
nixlet = nixletArg;
};
in {
imports = [path];
_module.args.nixlet =
{
values = finalValues;
}
// nixletArg;
})
overrides
];
kubenix.project = project;
};
});
render = {
system,
project ? defaultProject,
overrides ? ({...}: {}),
values ? {},
}:
(eval {
inherit system project overrides values;
})
.config
.kubernetes
.resultYAML;
# combines all secrets files in a single directory
secrets = args: (eval args).config.kubernetes.secretsCombined;
};
}: let
# every nixlet gets "nixlet" as arg with some useful data about itself
baseNixletArg = {
inherit name version description;
project = defaultProject;
};
nixlet = {
inherit name version description path;
values = evalValues "${path}/values.nix" {
rawValues = {};
nixlet = baseNixletArg;
};
mkDocs = opts: mkDocs (opts // {inherit nixlet;});
eval = {
system,
project ? defaultProject,
overrides ? ({...}: {}),
values ? {},
}:
assert lib.assertMsg (project != null) "No default project set, please pass a project to the render method"; let
nixletArg = baseNixletArg // {inherit project;};
in (kubenix.evalModules.${system} {
module = {kubenix, ...}: {
imports = with kubenix.modules; [
k8s
helm
docker
files
./secretsModule.nix
({...}: let
finalValues = mkValues "${path}/values.nix" {
rawValues = values;
nixlet = nixletArg;
};
in {
imports = [path];
_module.args.nixlet =
{
values = finalValues;
}
// nixletArg;
})
overrides
];
kubenix.project = project;
};
});
render = {
system,
project ? defaultProject,
overrides ? ({...}: {}),
values ? {},
}:
(nixlet.eval {
inherit system project overrides values;
})
.config
.kubernetes
.resultYAML;
# combines all secrets files in a single directory
secrets = args: (nixlet.eval args).config.kubernetes.secretsCombined;
};
in
nixlet;
fetchNixlet = url: sha256: mkNixlet (builtins.fetchTarball {inherit url sha256;});
fetchNixletFromGitlab = {
@ -140,4 +149,7 @@ with lib; rec {
nixlets
)
);
mkDocs = {nixlet, ...} @ opts:
import ./valuesDocs.nix (opts // {inherit lib;});
}

84
lib/valuesDocs.nix Normal file
View file

@ -0,0 +1,84 @@
{
lib,
nixlet,
transformOptions ? opt: opt,
filter ? _: true,
headingDepth ? 3,
...
}: let
inherit
(lib)
removeSuffix
concatStringsSep
mapAttrsToList
concatStrings
replicate
;
_transformOptions = opt:
transformOptions (opt
// {
visible = let
filtered = !builtins.elem (builtins.head opt.loc) ["_module"];
in
filtered && opt.visible && (filter opt);
name = lib.removePrefix "config." opt.name;
});
rawOpts = lib.optionAttrSetToDocList nixlet.values.options;
transformedOpts = map _transformOptions rawOpts;
filteredOpts = lib.filter (opt: opt.visible && !opt.internal) transformedOpts;
optionsNix = builtins.listToAttrs (
map (o: {
name = o.name;
value = removeAttrs o [
"visible"
"internal"
];
})
filteredOpts
);
optToMd = opt: let
headingDecl = concatStrings (replicate headingDepth "#");
in
''
${headingDecl} `${opt.name}`
${
if opt.description != null
then opt.description
else "(no description)"
}
**Type**:
```console
${opt.type}
```
''
+ (lib.optionalString (opt ? default && opt.default != null) ''
**Default value**:
```nix
${removeSuffix "\n" opt.default.text}
```
'')
+ (lib.optionalString (opt ? example) ''
**Example value**:
```nix
${removeSuffix "\n" opt.example.text}
```
'')
+ "\n";
opts = mapAttrsToList (name: opt:
optToMd opt)
optionsNix;
markdown = concatStringsSep "\n" opts;
in
builtins.toFile "values-doc.md" markdown