feat(modules/extranix): Simplify
Some checks failed
Build all the nodes / netcore00 (pull_request) Successful in 20s
Build all the nodes / netaccess01 (pull_request) Successful in 21s
Build all the nodes / netcore01 (pull_request) Successful in 21s
Check meta / check_meta (pull_request) Successful in 32s
Check workflows / check_workflows (pull_request) Successful in 32s
Check meta / check_dns (pull_request) Successful in 32s
Build all the nodes / netcore02 (pull_request) Successful in 21s
Build all the nodes / geo01 (pull_request) Successful in 1m7s
Build all the nodes / bridge01 (pull_request) Successful in 1m9s
Build all the nodes / hypervisor02 (pull_request) Successful in 1m7s
Build all the nodes / build01 (pull_request) Successful in 1m11s
Build all the nodes / hypervisor03 (pull_request) Successful in 1m9s
Build all the nodes / hypervisor01 (pull_request) Successful in 1m10s
Build all the nodes / ap01 (pull_request) Successful in 1m20s
Build all the nodes / rescue01 (pull_request) Successful in 58s
Build all the nodes / storage01 (pull_request) Failing after 1m2s
Check workflows / check_workflows (push) Successful in 17s
Build the shell / build-shell (pull_request) Successful in 24s
Run pre-commit on all files / pre-commit (pull_request) Successful in 29s
Build all the nodes / compute01 (pull_request) Successful in 1m46s
Build all the nodes / web02 (pull_request) Successful in 1m3s
Build all the nodes / geo02 (pull_request) Successful in 1m55s
Build all the nodes / cof02 (pull_request) Successful in 2m6s
Build all the nodes / web03 (pull_request) Successful in 1m1s
Build all the nodes / tower01 (pull_request) Successful in 1m48s
Build all the nodes / vault01 (pull_request) Successful in 2m2s
Build all the nodes / web01 (pull_request) Successful in 2m29s
Build all the nodes / netaccess01 (push) Successful in 20s
Build all the nodes / netcore01 (push) Successful in 21s
Build all the nodes / netcore00 (push) Successful in 39s
Build all the nodes / netcore02 (push) Successful in 39s
Build all the nodes / bridge01 (push) Successful in 1m14s
Build all the nodes / hypervisor01 (push) Successful in 1m12s
Build all the nodes / hypervisor03 (push) Successful in 1m13s
Build all the nodes / geo01 (push) Successful in 1m14s
Build all the nodes / ap01 (push) Successful in 1m21s
Build all the nodes / tower01 (push) Successful in 1m26s
Build all the nodes / hypervisor02 (push) Successful in 1m30s
Build all the nodes / build01 (push) Successful in 1m32s
Build all the nodes / storage01 (push) Successful in 1m31s
Build all the nodes / cof02 (push) Successful in 1m33s
Build all the nodes / vault01 (push) Successful in 1m14s
Build the shell / build-shell (push) Successful in 25s
Run pre-commit on all files / pre-commit (push) Successful in 29s
Build all the nodes / geo02 (push) Successful in 1m58s
Build all the nodes / rescue01 (push) Successful in 1m59s
Build all the nodes / web01 (push) Successful in 1m38s
Build all the nodes / web02 (push) Successful in 1m58s
Build all the nodes / web03 (push) Successful in 2m4s
Build all the nodes / compute01 (push) Successful in 3m21s

This commit is contained in:
Tom Hubrecht 2025-04-15 00:08:56 +02:00 committed by thubrecht
parent 447e4df244
commit bb7c377cb3
15 changed files with 260 additions and 753 deletions

View file

@ -1,147 +0,0 @@
From 5e5f68209b3b023fce260c9da1625844ca4d3c22 Mon Sep 17 00:00:00 2001
From: catvayor <catvayor@katvayor.net>
Date: Mon, 16 Dec 2024 00:11:47 +0100
Subject: [PATCH 1/2] revert: don't parse md in js
---
static/js/script.js | 106 +-------------------------------------------
1 file changed, 2 insertions(+), 104 deletions(-)
diff --git a/static/js/script.js b/static/js/script.js
index 04234d7..d3ec223 100644
--- a/static/js/script.js
+++ b/static/js/script.js
@@ -27,97 +27,6 @@ function encodeAttr(str) {
return (str+'').replace(/"/g, '&quot;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
}
-/** Parse Markdown into an HTML String. */
-function parseMD(md, prevLinks) {
- let tokenizer = /((?:^|\n+)(?:\n---+|\* \*(?: \*)+)\n)|(?:^``` *(\w*)\n([\s\S]*?)\n```$)|((?:(?:^|\n+)(?:\t| {2,}).+)+\n*)|((?:(?:^|\n)([>*+-]|\d+\.)\s+.*)+)|(?:!\[([^\]]*?)\]\(([^)]+?)\))|(\[)|(\](?:\(([^)]+?)\))?)|(?:(?:^|\n+)([^\s].*)\n(-{3,}|={3,})(?:\n+|$))|(?:(?:^|\n+)(#{1,6})\s*(.+)(?:\n+|$))|(?:`([^`].*?)`)|( \n\n*|\n{2,}|__|\*\*|[_*]|~~)/gm,
- context = [],
- out = '',
- links = prevLinks || {},
- last = 0,
- chunk, prev, token, inner, t;
-
- function tag(token) {
- let desc = TAGS[token[1] || ''];
- let end = context[context.length-1] == token;
- if (!desc) return token;
- if (!desc[1]) return desc[0];
- if (end) context.pop();
- else context.push(token);
- return desc[end|0];
- }
-
- function flush() {
- let str = '';
- while (context.length) str += tag(context[context.length-1]);
- return str;
- }
-
- md = md.replace(/^\[(.+?)\]:\s*(.+)$/gm, (s, name, url) => {
- links[name.toLowerCase()] = url;
- return '';
- }).replace(/^\n+|\n+$/g, '');
-
- while ( (token=tokenizer.exec(md)) ) {
- prev = md.substring(last, token.index);
- last = tokenizer.lastIndex;
- chunk = token[0];
- if (prev.match(/[^\\](\\\\)*\\$/)) {
- // escaped
- }
- // Code/Indent blocks:
- else if (t = (token[3] || token[4])) {
- chunk = '<pre class="code '+(token[4]?'poetry':token[2].toLowerCase())+'"><code'+(token[2] ? ` class="language-${token[2].toLowerCase()}"` : '')+'>'+outdent(encodeAttr(t).replace(/^\n+|\n+$/g, ''))+'</code></pre>';
- }
- // > Quotes, -* lists:
- else if (t = token[6]) {
- if (t.match(/\./)) {
- token[5] = token[5].replace(/^\d+/gm, '');
- }
- inner = parse(outdent(token[5].replace(/^\s*[>*+.-]/gm, '')));
- if (t=='>') t = 'blockquote';
- else {
- t = t.match(/\./) ? 'ol' : 'ul';
- inner = inner.replace(/^(.*)(\n|$)/gm, '<li>$1</li>');
- }
- chunk = '<'+t+'>' + inner + '</'+t+'>';
- }
- // Images:
- else if (token[8]) {
- chunk = `<img src="${encodeAttr(token[8])}" alt="${encodeAttr(token[7])}">`;
- }
- // Links:
- else if (token[10]) {
- out = out.replace('<a>', `<a href="${encodeAttr(token[11] || links[prev.toLowerCase()])}">`);
- chunk = flush() + '</a>';
- }
- else if (token[9]) {
- chunk = '<a>';
- }
- // Headings:
- else if (token[12] || token[14]) {
- t = 'h' + (token[14] ? token[14].length : (token[13]>'=' ? 1 : 2));
- chunk = '<'+t+'>' + parse(token[12] || token[15], links) + '</'+t+'>';
- }
- // `code`:
- else if (token[16]) {
- chunk = '<code>'+encodeAttr(token[16])+'</code>';
- }
- // Inline formatting: *em*, **strong** & friends
- else if (token[17] || token[1]) {
- chunk = tag(token[17] || '--');
- }
- out += prev;
- out += chunk;
- }
-
- return (out + md.substring(last) + flush()).replace(/^\n+|\n+$/g, '');
-}
-
-
-/*************************
- * END MARKDOWN PARSER
- */
-
var search, results, allOptions, currentSet = [];
var lastUpdate = "?";
@@ -254,22 +163,11 @@ var updateOptionsTable = function(options) {
-function parseDescription(text){
-
- text = text.replace(/<https(\s*([^>]*))/gi ,'<a href="https$1">&lt;https$1</a>');
- text = text.replace(/\[\]\(#opt-(\s*([^)]*))/gi ,'<strong>$1</strong>').replace(/\)/gi,'');
- //[](#opt-wayland.windowManager.hyprland.plugins)
- text = text.replace(/\{var\}(\s*([^\n]*))/gi ,'<strong>$1</strong>').replace(/`/gi,'')
- text = text.replace(/:::\ \{\.note\}(\s*([^:::]*))/gi ,'<div class="alert alert-info" role="alert">$1</div>').replace(/:::/,'').replace(/\n/g, '<br />')
- return text;
-}
-
var expandOptionMD = function(el){
modalTitle.innerHTML = currentSet[el].title;
- let dhtml = parseMD(currentSet[el].doc);
- var elDesc = "<h5 style='margin:1em 0 0 0'>Description</h5><div>" + dhtml + "</div>";
+ var elDesc = "<h5 style='margin:1em 0 0 0'>Description</h5><div>" + currentSet[el].doc + "</div>";
var elArgs = "<h5 style='margin:1em 0 0 0'>Args</h5><div>" + currentSet[el].args.join(', ') + "</div>";
// var elNote = ( currentSet[el].note == "" ? "": "<h5 style='margin:1em 0 0 0'>Note</h5><div>" + currentSet[el].note + "</div>");
// var elDefault = "<h5 style='margin:1em 0 0 0'>Default</h5><div><pre style='margin-top:0.5em'>" + currentSet[el].default + "</pre></div>";
@@ -290,7 +188,7 @@ var expandOption = function(el){
//console.log(currentSet[el].description.replace(/:::\ \{\.note\}(\s*([^:::]*))/gi ,'<div class="alert alert-info" role="alert">$1</div>').replace(/:::/,''));
- var elDesc = "<h5 style='margin:1em 0 0 0'>Description</h5><div>" + parseDescription(currentSet[el].description) + "</div>";
+ var elDesc = "<h5 style='margin:1em 0 0 0'>Description</h5><div>" + currentSet[el].description + "</div>";
var elType = "<h5 style='margin:1em 0 0 0'>Type</h5><div>" + currentSet[el].type + "</div>";
//var elNote = ( currentSet[el].note == "" ? "": "<h5 style='margin:1em 0 0 0'>Note</h5><div>" + currentSet[el].note + "</div>");
var elDefault = ( currentSet[el].default == "" ? "" : "<h5 style='margin:1em 0 0 0'>Default</h5><div><pre style='margin-top:0.5em'>" + currentSet[el].default + "</pre></div>");
--
2.47.0

View file

@ -1,24 +0,0 @@
From 957189be0a61f954a1bcfb204f982f59ae6435ea Mon Sep 17 00:00:00 2001
From: catvayor <catvayor@katvayor.net>
Date: Thu, 12 Dec 2024 17:04:45 +0100
Subject: [PATCH 2/2] chore: remove useless dependencies
---
layouts/index.html | 1 -
1 file changed, 1 deletion(-)
diff --git a/layouts/index.html b/layouts/index.html
index 63a6158..780ea78 100644
--- a/layouts/index.html
+++ b/layouts/index.html
@@ -17,7 +17,6 @@
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
- <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css">
<link href="css/nucleus.css" rel="stylesheet">
<link href="css/style-nix.css" rel="stylesheet">
<link rel="stylesheet" href="css/style-q2.css">
--
2.47.0

View file

@ -1,25 +0,0 @@
From b0f6c845280bee20bcc28a136436e000bde8a457 Mon Sep 17 00:00:00 2001
From: catvayor <catvayor@katvayor.net>
Date: Mon, 16 Dec 2024 11:25:38 +0100
Subject: [PATCH] feat: separate HTML description of MD description
---
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 d3ec223..5d9fc6e 100644
--- a/static/js/script.js
+++ b/static/js/script.js
@@ -188,7 +188,7 @@ var expandOption = function(el){
//console.log(currentSet[el].description.replace(/:::\ \{\.note\}(\s*([^:::]*))/gi ,'<div class="alert alert-info" role="alert">$1</div>').replace(/:::/,''));
- var elDesc = "<h5 style='margin:1em 0 0 0'>Description</h5><div>" + currentSet[el].description + "</div>";
+ var elDesc = "<h5 style='margin:1em 0 0 0'>Description</h5><div>" + currentSet[el].descriptionHTML + "</div>";
var elType = "<h5 style='margin:1em 0 0 0'>Type</h5><div>" + currentSet[el].type + "</div>";
//var elNote = ( currentSet[el].note == "" ? "": "<h5 style='margin:1em 0 0 0'>Note</h5><div>" + currentSet[el].note + "</div>");
var elDefault = ( currentSet[el].default == "" ? "" : "<h5 style='margin:1em 0 0 0'>Default</h5><div><pre style='margin-top:0.5em'>" + currentSet[el].default + "</pre></div>");
--
2.47.0

View file

@ -1,26 +0,0 @@
From e31e0330b9b012b6e09f8eb6bc670e4336d1aedc Mon Sep 17 00:00:00 2001
From: catvayor <catvayor@katvayor.net>
Date: Mon, 16 Dec 2024 12:53:27 +0100
Subject: [PATCH] fix: indentation of <ul>
---
static/css/nucleus.css | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/static/css/nucleus.css b/static/css/nucleus.css
index a4674a8..9ada521 100644
--- a/static/css/nucleus.css
+++ b/static/css/nucleus.css
@@ -533,7 +533,8 @@ p {
ul, ol {
margin-top: 1.7rem;
- margin-bottom: 1.7rem; }
+ margin-bottom: 1.7rem;
+ margin-left: 1rem; }
ul ul, ul ol, ol ul, ol ol {
margin-top: 0;
margin-bottom: 0; }
--
2.47.0

View file

@ -1,28 +0,0 @@
From 206ce2744cdaa166ee482fba90a879f2688b234a Mon Sep 17 00:00:00 2001
From: catvayor <catvayor@katvayor.net>
Date: Sat, 21 Dec 2024 10:14:46 +0100
Subject: [PATCH] feat: match all substring by default
---
layouts/index.html | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/layouts/index.html b/layouts/index.html
index 780ea78..c50ada4 100644
--- a/layouts/index.html
+++ b/layouts/index.html
@@ -109,9 +109,9 @@
<li>Strategy</li>
<li>
<select id="indexStrategySelect" style="margin-bottom:0">
- <option value="JsSearch.AllSubstringsIndexStrategy">All substrings</option>
+ <option value="JsSearch.AllSubstringsIndexStrategy" selected>All substrings</option>
<option value="JsSearch.ExactWordIndexStrategy">Exact match</option>
- <option value="JsSearch.PrefixIndexStrategy" selected>Prefix matching</option>
+ <option value="JsSearch.PrefixIndexStrategy">Prefix matching</option>
</select>
</li>
</div>
--
2.47.0

View file

@ -1,4 +1,5 @@
# SPDX-FileCopyrightText: 2024 Lubin Bailly <lubin.bailly@dgnum.eu>
# SPDX-FileCopyrightText: 2025 Tom Hubrecht <tom.hubrecht@dgnum.eu>
#
# SPDX-License-Identifier: EUPL-1.2
@ -8,201 +9,305 @@
pkgs,
...
}:
let
inherit (lib)
attrNames
concatMapStringsSep
concatStringsSep
escapeXML
evalModules
filter
getExe
flip
getAttr
hasPrefix
hasSuffix
head
importJSON
mapAttrs'
listToAttrs
mapAttrsToList
mkDefault
literalExpression
mkEnableOption
mkIf
mkOption
nameValuePair
optionAttrSetToDocList
optionalString
pathIsDirectory
pipe
removeAttrs
removePrefix
removeSuffix
;
inherit (lib.strings)
sanitizeDerivationName
;
inherit (lib.types)
attrs
attrsOf
deferredModule
listOf
nullOr
path
submodule
str
;
yaml = pkgs.formats.yaml { };
json = pkgs.formats.json { };
cfg = config.services.extranix;
module-eval =
module-name: module:
inherit (pkgs)
fetchFromGitea
hugo
runCommand
symlinkJoin
;
mkDocJSON =
module:
{
ignored-modules,
path-translations,
paths,
specialArgs,
...
}:
let
ignored-eval = lib.evalModules {
modules = module.ignored-modules;
inherit (module) specialArgs;
};
ignored-opts-doc = pkgs.nixosOptionsDoc { inherit (ignored-eval) options; };
ignored-opts = importJSON "${ignored-opts-doc.optionsJSON}/share/doc/nixos/options.json";
eval = lib.evalModules {
modules = module.paths ++ module.ignored-modules;
inherit (module) specialArgs;
};
opts-doc = pkgs.nixosOptionsDoc { inherit (eval) options; };
opts = importJSON "${opts-doc.optionsJSON}/share/doc/nixos/options.json";
filtered-opts = removeAttrs opts (attrNames ignored-opts);
path-translation =
let
translations = map (
{ base, url }:
{
url = "${url}${optionalString (!hasSuffix "/" url) "/"}";
base =
let
base1 = toString base;
in
base1 + (optionalString (!hasSuffix "/" base1) "/");
}
) module.path-translations;
in
# NOTE: A big simplification of nixpkgs' make-options-doc
# It turns out that we only need the json output, and have
# no `baseOptionsJSON`, so the transformation done is `id`
mkOpts = (flip pipe) [
# Evaluate the modules
(modules: evalModules { inherit modules specialArgs; })
# Extract the options
(getAttr "options")
# Transform into a list of options
optionAttrSetToDocList
# Remove invisible and internal options
(filter (o: o.visible && !o.internal))
# Remove extraneous attributes
(builtins.map (
o:
nameValuePair o.name (
removeAttrs o [
"name"
"visible"
"internal"
]
)
))
# Transform back to an attribute set
listToAttrs
];
# INFO: Subtract options of the ignored modules from
# the complete set of options
ignored = attrNames (mkOpts ignored-modules);
options = removeAttrs (mkOpts (paths ++ ignored-modules)) ignored;
directories = builtins.map (getAttr "base") path-translations;
mkTranslation =
path:
let
fullPath = path + (optionalString (pathIsDirectory path) "/default.nix");
fitting = filter ({ base, ... }: hasPrefix base fullPath) translations;
translate-info = head (
fitting
++ [
(throw (
"${fullPath} is not in any base path of ${module-name}. Base paths are "
+ concatMapStringsSep "\n" ({ base, ... }: base) translations
))
]
);
innerPath = removePrefix translate-info.base fullPath;
# Get the file associated to the module
file = if pathIsDirectory path then path + "/default.nix" else path;
# Get the parent module set
matching = filter (m: hasPrefix m.base path) path-translations;
parent = head matching;
filePath = removePrefix parent.base file;
in
{
name = "<${innerPath}>";
url = "${translate-info.url}${innerPath}";
};
result' = json.generate "options-extranix-fileDesc.json" {
last_update = "-/-";
options = mapAttrsToList (title: val: {
inherit title;
inherit (val)
type
readOnly
loc
;
descriptionHTML = pkgs.runCommand "option-${title}.html" { } ''
${getExe pkgs.pandoc} -f markdown-raw_html ${pkgs.writeText "option-${title}.md" val.description} > $out
'';
description = escapeXML val.description;
example = escapeXML (val.example.text or "");
default = escapeXML (val.default.text or "");
declarations = map path-translation val.declarations;
}) filtered-opts;
};
result =
pkgs.runCommand "options-extranix.json"
if matching == [ ] then
(throw "${file} is not a descendant of ${module}. Declared parents are: \n ${concatStringsSep "\n " directories}")
else
{
nativeBuildInputs = [ pkgs.jq ];
}
''
jq -r '.options[].descriptionHTML | "--rawfile\n" + . + "\n" + .' ${result'} | xargs \
jq -c '.options |= map(.descriptionHTML as $desc | .descriptionHTML |= $ARGS.named.[$desc])' ${result'} \
> $out
'';
name = "<${filePath}>";
url = "${parent.url}/${filePath}";
};
in
result;
pkgs.runCommand "options-extranix"
{
fileName = sanitizeDerivationName "options-${module}.json";
nativeBuildInputs = [ pkgs.jq ];
options-files = mapAttrs' (name: value: {
name = sanitizeDerivationName name;
value = module-eval name value;
}) cfg.modules;
passAsFile = [ "result" ];
result = builtins.toJSON {
last_update = "-/-";
options = mapAttrsToList (
title:
{
default ? {
text = "";
},
description,
example ? {
text = "";
},
loc,
readOnly,
type,
declarations,
...
}:
{
inherit
loc
readOnly
title
type
;
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 { };
};
descriptionHTML = pkgs.runCommandLocal "option-${title}.html" {
inherit description;
passAsFile = [ "description" ];
nativeBuildInputs = [ pkgs.pandoc ];
} "pandoc -f markdown-raw_html $descriptionPath > $out";
description = escapeXML description;
example = escapeXML example.text;
default = escapeXML default.text;
declarations = builtins.map mkTranslation declarations;
}
) options;
};
}
''
mkdir -p $out
jq -r '.options[].descriptionHTML | "--rawfile\n" + . + "\n" + .' $resultPath | xargs \
jq -c '.options |= map(.descriptionHTML as $desc | .descriptionHTML |= $ARGS.named.[$desc])' $resultPath \
> $out/$fileName
'';
website =
runCommand "search-infra"
{
theme = fetchFromGitea {
domain = "git.dgnum.eu";
owner = "DGNum";
repo = "options-search-theme";
rev = "bcdc3e724ad5478ed39ce62a6e3342130a1bcabd";
hash = "sha256-pg0NifmHdfK4OltSOQfYgTVa7juZlGF642Q4Du3uheY=";
};
nativeBuildInputs = [ hugo ];
config = builtins.toJSON cfg.settings;
passAsFile = [ "config" ];
data = symlinkJoin {
name = "options-data";
paths = mapAttrsToList mkDocJSON cfg.modules;
};
}
''
# Setup the directory structure
mkdir themes && ln -s $theme themes/options-search
ln -s $configPath hugo.json
mkdir static
${optionalString (cfg.static != null) "cp -R ${cfg.static} static"}
ln -s $data static/data
# Build the website
hugo -d $out
'';
cfg = config.services.extranix;
in
{
options.services.extranix = {
enable = mkEnableOption "extranix documentation";
modules = mkOption {
type =
attrsOf (submodule {
options = {
specialArgs = mkOption {
type = attrs;
default = { };
description = ''
Special arguments to give to evalModules.
'';
};
paths = mkOption {
type = listOf deferredModule;
description = ''
Modules to from which to document options.
'';
};
ignored-modules = mkOption {
type = listOf deferredModule;
default = [ ];
description = ''
Modules required to make modules of `paths` valid.
'';
example = ''
import "''${infra-modulesPath}/module-list.nix"
'';
};
path-translations = mkOption {
type = listOf (submodule {
options = {
base = mkOption {
type = path;
description = ''
Base path of some module files to be documented.
'';
};
url = mkOption {
type = str;
description = ''
Url root to use for files on this path.
'';
};
};
});
description = ''
Rules to convert file paths to urls in the documentation to indicate where
the option is declared.
'';
};
modules = mkOption {
type = attrsOf (submodule {
options = {
specialArgs = mkOption {
type = attrs;
default = { };
description = ''
Special arguments to give to evalModules.
'';
};
});
paths = mkOption {
type = listOf deferredModule;
description = ''
Modules to from which to document options.
'';
};
ignored-modules = mkOption {
type = listOf deferredModule;
default = [ ];
description = ''
Modules required to make modules of `paths` valid.
'';
example = ''
import "''${infra-modulesPath}/module-list.nix"
'';
};
path-translations = mkOption {
type = listOf (submodule {
options = {
base = mkOption {
type = path;
description = ''
Base path of some module files to be documented.
'';
apply = v: "${removeSuffix "/" (builtins.toString v)}/";
};
url = mkOption {
type = str;
description = ''
Url root to use for files on this path.
'';
apply = removeSuffix "/";
};
};
});
description = ''
Rules to convert file paths to urls in the documentation to indicate where
the option is declared.
'';
};
};
});
description = ''
Sets of modules to be documented separately. The identifier to give for
`settings.params.release_current_stable` (which is the default module shown) is the key after
passing through `sanitizeDerivationName`.
'';
};
settings = mkOption {
inherit (yaml) type;
host = mkOption {
type = str;
description = ''
Settings for the `config.yaml` for the hugo instantiation.
Hostname of the service.
'';
};
index = mkOption {
type = str;
default = head (attrNames cfg.modules);
defaultText = literalExpression "head (attrNames config.services.extranix.modules)";
description = ''
The main module to show when loading the website.
'';
apply = sanitizeDerivationName;
};
static = mkOption {
type = nullOr path;
default = null;
description = ''
Path to extra static files.
'';
};
settings = mkOption {
inherit (pkgs.formats.json { }) type;
description = ''
Settings of the hugo website.
'';
example = {
baseUrl = "https://example.org/";
@ -226,36 +331,28 @@ in
};
};
};
static-data = mkOption {
type = path;
description = ''
Static files for the website. Should have `images/favicon.png` for favicon.
'';
};
host = mkOption {
type = str;
description = ''
Hostname of the service.
'';
};
};
config = mkIf cfg.enable {
services = {
extranix.settings = {
theme = "extranix-options-search";
theme = "options-search";
params = {
releases = mapAttrsToList (name: _: {
inherit name;
value = sanitizeDerivationName name;
}) cfg.modules;
release_current_stable = mkDefault (head (attrNames options-files));
release_current_stable = cfg.index;
};
};
nginx = {
enable = true;
virtualHosts.${cfg.host}.locations."/".alias = "${webroot}/";
virtualHosts.${cfg.host}.locations."/".root = website;
};
};
assertions = [
{
assertion = cfg.modules != { };
@ -263,14 +360,6 @@ in
`services.extranix` can't be enabled without any modules to document.
'';
}
{
assertion = options-files ? ${cfg.settings.params.release_current_stable};
message = ''
`services.extranix.settings.params.release_current_stable` should be the
`sanitizeDerivationName` of a key of `services.extranix.modules`, here one of:
+ ${concatStringsSep "\n + " (attrNames options-files)}
'';
}
];
};
}

View file

@ -1,75 +0,0 @@
# SPDX-FileCopyrightText: 2024 Lubin Bailly <lubin.bailly@dgnum.eu>
#
# SPDX-License-Identifier: EUPL-1.2
{
fetchFromGitHub,
stdenv,
lib,
fetchurl,
}:
stdenv.mkDerivation {
name = "hugo-theme-extranix-options-search";
src = fetchFromGitHub {
owner = "mipmip";
repo = "hugo-theme-extranix-options-search";
rev = "3252b5bd98adcbbe629327d72c8416c25014a0d6";
hash = "sha256-XV7Js1KaBiWv9qao8iyzQ546nT1KkwCtvyAs++oeXFo=";
};
patches = [
./0001-revert-don-t-parse-md-in-js.patch
./0002-chore-remove-useless-dependencies.patch
./0003-feat-separate-HTML-description-of-MD-description.patch
./0004-fix-indentation-of-ul.patch
./0005-feat-match-all-substring-by-default.patch
];
installPhase =
let
js-search = fetchurl {
url = "https://unpkg.com/js-search@2.0.1/dist/umd/js-search.min.js";
hash = "sha256-LD9UsSATk+xTzAbk8nD2gA2bjHKvetXtCMDAFkM2K5Q=";
};
jquery = fetchurl {
url = "https://code.jquery.com/jquery-3.7.1.slim.min.js";
hash = "sha256-kmHvs0B+OpCW5GVHUNjv9rOmY0IvSIRcf7zGUDTDQM8=";
};
bootstrap.css.main = fetchurl {
url = "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css";
hash = "sha256-916EbMg70RQy9LHiGkXzG8hSg9EdNy97GazNG/aiY1w=";
};
bootstrap.css.theme = fetchurl {
url = "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css";
hash = "sha256-ZT4HPpdCOt2lvDkXokHuhJfdOKSPFLzeAJik5U/Q+l4=";
};
bootstrap.js = fetchurl {
url = "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js";
hash = "sha256-U5ZEeKfGNOja007MMD3YBI0A3OSZOQbeG6z2f2Y0hu8=";
};
in
''
mkdir $out
rm static/images/favicon.*
cp -r * $out
cp ${js-search} $out/static/js/js-search.min.js
cp ${jquery} $out/static/js/jquery.slim.min.js
cp ${bootstrap.css.main} $out/static/css/bootstrap.min.css
cp ${bootstrap.css.theme} $out/static/css/bootstrap-theme.min.css
cp ${bootstrap.js} $out/static/js/bootstrap.min.js
substituteInPlace $out/layouts/index.html \
--replace-fail 'https://unpkg.com/js-search@2.0.1/dist/umd/js-search.min.js' js/js-search.min.js \
--replace-fail 'https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js' js/jquery.slim.min.js \
--replace-fail 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css' css/bootstrap.min.css \
--replace-fail 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css' css/bootstrap-theme.min.css \
--replace-fail 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js' js/bootstrap.min.js \
'';
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 = [ ];
};
}

View file

@ -1,25 +0,0 @@
# SPDX-FileCopyrightText: 2024 Lubin Bailly <lubin.bailly@dgnum.eu>
#
# SPDX-License-Identifier: EUPL-1.2
{
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
''