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 = { doc = {
path = ./docs; 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 = { config = {
site_name = "Nixlets"; site_name = "Nixlets";
repo_name = "TECHNOFAB/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 = [ nav = [
{"Introduction" = "index.md";} {"Introduction" = "index.md";}
{"Creating Nixlets" = "creation.md";} {"Creating Nixlets" = "creation.md";}
{"Packaging" = "packaging.md";} {"Packaging" = "packaging.md";}
{"Usage" = "usage.md";} {"Usage" = "usage.md";}
{"Secrets" = "secrets.md";} {"Secrets" = "secrets.md";}
{
"Nixlets Values" =
lib.mapAttrsToList (n: v: {
${v.name} = "options/${n}.md";
})
self.nixlets;
}
]; ];
markdown_extensions = [ markdown_extensions = [
{ {

View file

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