Merge branch 'feat/nixlet-docs' into 'main'

feat: add function to generate docs for nixlet values

Closes #2

See merge request TECHNOFAB/nixlets!3
This commit is contained in:
TECHNOFAB 2025-07-19 16:38:50 +02:00
commit 60c71a53d4
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,8 +4,7 @@
... ...
} @ 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;
}; };
@ -20,8 +19,8 @@ with lib; rec {
}; };
}) })
]; ];
}) });
.config; mkValues = file: args: (evalValues file args).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,8 +43,19 @@ with lib; rec {
description ? "", description ? "",
defaultProject ? null, defaultProject ? null,
... ...
}: rec { }: 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; inherit name version description path;
values = evalValues "${path}/values.nix" {
rawValues = {};
nixlet = baseNixletArg;
};
mkDocs = opts: mkDocs (opts // {inherit nixlet;});
eval = { eval = {
system, system,
project ? defaultProject, project ? defaultProject,
@ -53,10 +63,7 @@ with lib; rec {
values ? {}, values ? {},
}: }:
assert lib.assertMsg (project != null) "No default project set, please pass a project to the render method"; let 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 = baseNixletArg // {inherit project;};
nixletArg = {
inherit name project version description;
};
in (kubenix.evalModules.${system} { in (kubenix.evalModules.${system} {
module = {kubenix, ...}: { module = {kubenix, ...}: {
imports = with kubenix.modules; [ imports = with kubenix.modules; [
@ -89,15 +96,17 @@ with lib; rec {
overrides ? ({...}: {}), overrides ? ({...}: {}),
values ? {}, values ? {},
}: }:
(eval { (nixlet.eval {
inherit system project overrides values; inherit system project overrides values;
}) })
.config .config
.kubernetes .kubernetes
.resultYAML; .resultYAML;
# combines all secrets files in a single directory # combines all secrets files in a single directory
secrets = args: (eval args).config.kubernetes.secretsCombined; 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