From b56afb2ca7ac49aa84550f3b9ce70c51f0e01408 Mon Sep 17 00:00:00 2001 From: catvayor Date: Wed, 11 Dec 2024 17:03:41 +0100 Subject: [PATCH] feat(son): experimental auto-extranix --- machines/kat-son/configuration.nix | 41 ++++++ .../doc/0001-fix-pretty-no-defaults.patch | 25 ++++ machines/kat-son/doc/default.nix | 125 ++++++++++++++++++ .../hugo-theme-extranix-options-search.nix | 31 +++++ machines/kat-son/doc/webroot.nix | 22 +++ machines/kat-son/static-data/images/dgnum.png | Bin 0 -> 22319 bytes .../kat-son/static-data/images/forgejo.png | Bin 0 -> 4919 bytes 7 files changed, 244 insertions(+) create mode 100644 machines/kat-son/doc/0001-fix-pretty-no-defaults.patch create mode 100644 machines/kat-son/doc/default.nix create mode 100644 machines/kat-son/doc/hugo-theme-extranix-options-search.nix create mode 100644 machines/kat-son/doc/webroot.nix create mode 100644 machines/kat-son/static-data/images/dgnum.png create mode 100644 machines/kat-son/static-data/images/forgejo.png diff --git a/machines/kat-son/configuration.nix b/machines/kat-son/configuration.nix index ddaba31..d472767 100644 --- a/machines/kat-son/configuration.nix +++ b/machines/kat-son/configuration.nix @@ -1,5 +1,6 @@ { lib, + pkgs, ... }: { @@ -11,6 +12,7 @@ imports = [ ./hardware-configuration.nix ./disks.nix + ./doc ]; boot = { @@ -74,6 +76,45 @@ }; }; }; + extranix = { + enable = true; + modules."netconf" = let + netconf = pkgs.fetchgit { + url = "https://git.dgnum.eu/DGNum/Netconf-Module.git"; + rev = "8f58ee21fe9c0ad22e3f16e58c3837c1c97eb5e8"; + outputHash = "sha256-OXKSFEOjeeRFVbVodJSkhuT+r7+p6QPUzjbw2vs6Xao="; + name = "netconf"; + }; + in { + paths = [ "${netconf.outPath}/junos" "${netconf.outPath}/dgn-module.nix" ]; + base = netconf.outPath; + url = "https://git.dgnum.eu/DGNum/Netconf-Module/src/branch/master/"; + }; + static-data = ./static-data; + host = "son.katvayor.net"; + settings = { + baseUrl = "https://dgnum.eu/"; + title = "DGNum netconf module documentation"; + languageCode = "en-us"; + params = { + release_current_stable = "netconf"; + logo = "images/dgnum.png"; + footer_credits_line = '' + Powered by catvayor | + Based on Home Manager Option Search + ''; + footer_copyright_line = '' + Made by catvayor for the DGNum. + ''; + main_menu = [ + { + name = '' Source''; + url = "https://git.dgnum.eu/DGNum/Netconf-Module/"; + } + ]; + }; + }; + }; }; system.stateVersion = "23.11"; diff --git a/machines/kat-son/doc/0001-fix-pretty-no-defaults.patch b/machines/kat-son/doc/0001-fix-pretty-no-defaults.patch new file mode 100644 index 0000000..605fadb --- /dev/null +++ b/machines/kat-son/doc/0001-fix-pretty-no-defaults.patch @@ -0,0 +1,25 @@ +From f050ca4374c8c4d9d4fa85e46a1dedaaaedec791 Mon Sep 17 00:00:00 2001 +From: catvayor +Date: Wed, 11 Dec 2024 15:34:42 +0100 +Subject: [PATCH] fix: pretty no defaults + +--- + static/js/script.js | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/static/js/script.js b/static/js/script.js +index 56b633b..04234d7 100644 +--- a/static/js/script.js ++++ b/static/js/script.js +@@ -293,7 +293,7 @@ var expandOption = function(el){ + var elDesc = "
Description
" + parseDescription(currentSet[el].description) + "
"; + var elType = "
Type
" + currentSet[el].type + "
"; + //var elNote = ( currentSet[el].note == "" ? "": "
Note
" + currentSet[el].note + "
"); +- var elDefault = "
Default
" + currentSet[el].default + "
"; ++ var elDefault = ( currentSet[el].default == "" ? "" : "
Default
" + currentSet[el].default + "
"); + var elExample = ( currentSet[el].example == "" ? "" : "
Example
" + currentSet[el].example + "
"); + + //var declared_by_str = currentSet[el].declarations[0].name; +-- +2.47.0 + diff --git a/machines/kat-son/doc/default.nix b/machines/kat-son/doc/default.nix new file mode 100644 index 0000000..c510d80 --- /dev/null +++ b/machines/kat-son/doc/default.nix @@ -0,0 +1,125 @@ +{ + lib, + config, + pkgs, + ... +}: +let + inherit (lib) + mkOption + mkEnableOption + mkIf + types + importJSON + filterAttrs + mapAttrs' + mapAttrsToList + removePrefix + pathIsDirectory + hasSuffix + ; + inherit (lib.strings) + sanitizeDerivationName + ; + yaml = pkgs.formats.yaml { }; + json = pkgs.formats.json { }; + cfg = config.services.extranix; + + module-eval = + module: + let + eval = lib.evalModules { modules = module.paths; }; + opts-doc = pkgs.nixosOptionsDoc { inherit (eval) options; }; + val = importJSON "${opts-doc.optionsJSON}/share/doc/nixos/options.json"; + filtered-opts = filterAttrs (name: _: name != "_module.args") val; + 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 ( + decl: + let + baseString1 = toString module.base; + baseString = baseString1 + (if hasSuffix "/" baseString1 then "" else "/"); + innerPath1 = if pathIsDirectory decl then decl + "/default.nix" else decl; + innerPath = removePrefix baseString innerPath1; + in + { + name = "<${innerPath}>"; + url = "${module.url}${if hasSuffix "/" module.url then "" else "/"}${innerPath}"; + } + ) val.declarations; + }) filtered-opts; + }; + in + result; + + options-files = mapAttrs' (name: value: { + name = sanitizeDerivationName name; + value = module-eval 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 = { + paths = mkOption { + type = types.listOf types.path; + }; + base = mkOption { + type = types.path; + }; + url = mkOption { + type = types.str; + }; + }; + 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}/"; + }; + }; + }; +} diff --git a/machines/kat-son/doc/hugo-theme-extranix-options-search.nix b/machines/kat-son/doc/hugo-theme-extranix-options-search.nix new file mode 100644 index 0000000..cfcbba6 --- /dev/null +++ b/machines/kat-son/doc/hugo-theme-extranix-options-search.nix @@ -0,0 +1,31 @@ +{ + fetchFromGitHub, + stdenv, + lib, +}: +stdenv.mkDerivation { + name = "hugo-theme-extranix-options-search"; + + src = fetchFromGitHub { + owner = "mipmip"; + repo = "hugo-theme-extranix-options-search"; + rev = "1b5cdc63b3127ab81aed2736b0dea7ed09b7ec72"; + hash = "sha256-oowopWC9JdZIex548S0W91MIPSDCaJ3isuNLfesjT9U="; + }; + + patches = [ + ./0001-fix-pretty-no-defaults.patch + ]; + + installPhase = '' + mkdir $out + cp -r * $out + ''; + + meta = { + description = "Theme which implements a nix modules options search machine."; + homepage = "https://github.com/mipmip/hugo-theme-extranix-options-search"; + license = lib.licenses.asl20; + maintainers = [ ]; + }; +} diff --git a/machines/kat-son/doc/webroot.nix b/machines/kat-son/doc/webroot.nix new file mode 100644 index 0000000..a930983 --- /dev/null +++ b/machines/kat-son/doc/webroot.nix @@ -0,0 +1,22 @@ +{ + hugo, + hugo-theme-extranix-options-search, + options-files, + settings, + static-data, + lib, + runCommand, +}: +runCommand "nix-doc-webroot" { } +'' + mkdir themes + ln -s ${hugo-theme-extranix-options-search} themes/extranix-options-search + cp -rs ${static-data} static + chmod -R u+w static + mkdir static/data + ${lib.concatStringsSep "\n" ( + lib.mapAttrsToList (name: file: "ln -s ${file} static/data/options-${name}.json") options-files + )} + ln -s ${settings} config.yaml + ${lib.getExe hugo} --noBuildLock -d $out +'' diff --git a/machines/kat-son/static-data/images/dgnum.png b/machines/kat-son/static-data/images/dgnum.png new file mode 100644 index 0000000000000000000000000000000000000000..e2a56a6511c4dc6af75210c425126baca49d7e38 GIT binary patch literal 22319 zcmXtA2RPO3`~TWAd(VGoe^2dtPmPxXPrv+8(AUa zf1lrV{kyLBRmOKbEp8CTF3SX_8 zeh5PI4*wrPpHI0He3BibZhrrqHbFL3Uc>1C<3%M26TptK%>9xfQ`}QW#BAg(V@NA{Rb;qvGwsNxDt_g{yC*tt@Wr9ULdrOaIOFbGf%T zW%b1YP0Tpzc(C>BQ$%EB(eK$e0q*Y}oiTi2RxOIy*O*ihDxbshAtVUp2aMm1i{CR4 z>GoK}v5ErmL4H&IAkB}8ic)`d|KHwJ9J@5BW&)Q=t!?|$%*-ctVFx5{0yZ?v%vka) z37?+9DPeVy6~qX!Ci7+NvSFmpv{yaG*=b_pq%;vCWQS~sNLd!C-XEy7dBc*Mn_FI4 z`Sx3*2R%J~c!AnuzKa*>e)h(z-MYoMw>}lgef8d1NlE=UF#$w^DBAd`mEe|iH!%@5 z`ec|e{~Y!X5=Q(K$)~jTxL$O@wk@53k+HwKJN$~*H}po^wqEu2l`B^kHa7IXfB$Y` zVuFTyFtM>|H8nLw?7VpDiCiT(;>9-gb_57Y^HaeeEZpA@Y<+O56!q}o)7n}|sb0*v_J2qR+0e-3-*5baL38hyX_glhWVhv6x_odh zivH&q2$gMZZFe@mt8plW23G$hARuV)nO7P*x1_lAUp#Cx=uad+XhE?IDInMuqVMCWsx;q%K;2cd?v8 zP@yldG$ui6oV4pMB5jXEBu{lUc}?RM79LVC3gT9b!@PwhBpzjDal-YT$jx!f%j6Fp zJouO`�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 Y!IqE3#8h8~vRgW1eN(-%b53{v2O`h?{{R30 literal 0 HcmV?d00001 diff --git a/machines/kat-son/static-data/images/forgejo.png b/machines/kat-son/static-data/images/forgejo.png new file mode 100644 index 0000000000000000000000000000000000000000..2cb009ca6f8c2ebe3b28a72ea4b74e3cde9b0b28 GIT binary patch literal 4919 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 mbaC2B=F*BLlPO^KSXngb