From 0b661ae865c482a5f89abdff746a51c01b10a488 Mon Sep 17 00:00:00 2001 From: Pyrox Date: Wed, 24 Jul 2024 13:37:27 -0400 Subject: [PATCH] add nixos options markdown generation --- mkdocs.yml | 1 + packages/md-manual/default.nix | 1 + packages/nixos-options/default.nix | 17 +++- packages/nixos-options/gen-options-md.py | 109 +++++++++++++++++++++++ 4 files changed, 126 insertions(+), 2 deletions(-) create mode 100755 packages/nixos-options/gen-options-md.py diff --git a/mkdocs.yml b/mkdocs.yml index 095d1bd..5ed4420 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -53,6 +53,7 @@ markdown_extensions: emoji_index: !!python/name:material.extensions.emoji.twemoji emoji_generator: !!python/name:material.extensions.emoji.to_svg - pymdownx.highlight + - pymdownx.inlinehilite - pymdownx.snippets - pymdownx.superfences - pymdownx.tasklist: diff --git a/packages/md-manual/default.nix b/packages/md-manual/default.nix index 97fd0b1..200975d 100644 --- a/packages/md-manual/default.nix +++ b/packages/md-manual/default.nix @@ -19,6 +19,7 @@ stdenvNoCC.mkDerivation { cp -r ${pkgs.amg.nixpkgs-manual} $out/Nixpkgs/ cp -r ${pkgs.amg.aux-wiki} $out/Aux cp -r ${pkgs.amg.lix-docs} $out/Lix + cp -r ${pkgs.amg.nixos-options} $out/NixOS chmod -R u+w $out/Lix pushd $out/Lix find . -type f -exec perl -pi -e 's/\
\n\n/\?\?\? bug\n\n\ \ /g' {} \; diff --git a/packages/nixos-options/default.nix b/packages/nixos-options/default.nix index 244f24c..979b706 100644 --- a/packages/nixos-options/default.nix +++ b/packages/nixos-options/default.nix @@ -41,15 +41,28 @@ let options = (buildFromConfig ({ ... }: { }) (config: config.system.build.manual.optionsJSON)).x86_64-linux; + + customPython = pkgs.python312.withPackages (ps: [ + ps.jq + ps.rich + ]); in stdenv.mkDerivation { pname = "nixos-options"; inherit version; - src = inputs.nixpkgs; + src = ./.; + + nativeBuildInputs = [ customPython ]; + + buildPhase = '' + ${customPython.interpreter} ./gen-options-md.py ${options}/share/doc/nixos/options.json + ''; installPhase = '' mkdir $out - cp -r ${options} $out/options + cp -r ./nixos-docs/* $out/ + + rm -rf $out/_module.md ''; } diff --git a/packages/nixos-options/gen-options-md.py b/packages/nixos-options/gen-options-md.py new file mode 100755 index 0000000..f82bf4d --- /dev/null +++ b/packages/nixos-options/gen-options-md.py @@ -0,0 +1,109 @@ +#!/usr/bin/env python3 +import sys +import json +import os +import shutil +import logging + +from rich.progress import track +import jq + +# Set up logging +logger = logging.getLogger(__name__) +logging.basicConfig(level=logging.INFO) + +TWO_LEVEL_PREFIXES = [ + "boot", + "networking", + "programs", + "security", + "services", + "systemd", + "users", + "virtualisation", +] + +REMOVE_PREFIXES = [ + "_module" +] + +OUT = "./nixos-docs" + +# Load file specified on command line +j = json.load(open(sys.argv[1], 'r')) +logger.info("JSON Loaded") + +# Make output directory +logger.info("Creating output directory") +if not os.path.exists(OUT): + os.makedirs(OUT) +else: + shutil.rmtree(OUT) + os.makedirs(OUT) + + +ALL_PREFIXES = jq.compile("map(.loc[0]) | unique | .[]").input_value(j) + +for p in track(ALL_PREFIXES.all(), description="Creating filetree..."): + if p in TWO_LEVEL_PREFIXES: + os.makedirs(f"{OUT}/{p}") + elif p in REMOVE_PREFIXES: + pass + else: + f = open(f"{OUT}/{p}.md", "w") + f.write(f"{p.title()}\n\n") + f.close() + +for k, v in track(j.items(), description="Writing..."): + opts = v['loc'] + + if (opts[0] in REMOVE_PREFIXES): + pass + + desc: str = v["description"] + + default: str | None = None + + example: str | None = None + + optType: str = v["type"] + + if 'default' not in v: + pass + elif v['default']['_type'] == "literalExpression": + default = f"`#!nix {v['default']['text']}`" + elif v['default']['_type'] == "literalMD": + default = v['default']['text'] + + if "example" not in v: + pass + elif v['example']['_type'] == "literalExpression": + example = f"`#!nix {v['example']['text']}`" + elif v['example']['_type'] == "literalMD": + example = v['example']['text'] + + decl: str = f"https://github.com/nixos/nixpkgs/blob/master/{v["declarations"][0]}" + + if (opts[0] not in TWO_LEVEL_PREFIXES): + f = open(f"{OUT}/{opts[0]}.md", "a") + elif(opts[0] in TWO_LEVEL_PREFIXES): + if len(opts) == 2: + f = open(f"{OUT}/{opts[0]}/index.md", "a") + elif len(opts) > 2: + f = open(f"{OUT}/{opts[0]}/{opts[1]}.md", "a") + + heading: str = "-".join(opts) + + f.write(f"## `{k}` {{{heading}}}\n\n") + f.write(f"{desc}\n") + f.write(f"**Type:** `{optType}`\n\n") + if default: + f.write(f"### Default {{{heading}-default}}\n") + f.write(default) + f.write("\n\n") + if example: + f.write(f"### Example {{{heading}-example}}\n") + f.write(example) + f.write("\n\n") + f.write(f"**Declared by:** <{decl}>\n\n") + f.close()