-
Notifications
You must be signed in to change notification settings - Fork 25
/
default.nix
115 lines (105 loc) · 3.6 KB
/
default.nix
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# adapted from: https://discourse.nixos.org/t/franken-script-to-generate-nixos-options-docs-with-custom-modules/1674/4
{ pkgs, options }:
let
extraSources = [ ];
lib = pkgs.lib;
optionsListVisible = lib.filter (opt: opt.visible && !opt.internal) (lib.optionAttrSetToDocList options);
# Replace functions by the string <function>
substFunction = x:
if builtins.isAttrs x
then lib.mapAttrs (name: substFunction) x
else if builtins.isList x
then map substFunction x
else if lib.isFunction x
then "<function>"
else if isPath x
then toString x
else x;
isPath = x: (builtins.typeOf x) == "path";
optionsListDesc = lib.flip map optionsListVisible (opt:
opt // {
description =
let
attempt = builtins.tryEval opt.description;
in
if attempt.success
then attempt.value
else "N/A";
declarations = map stripAnyPrefixes opt.declarations;
} // lib.optionalAttrs (opt ? example) {
example = substFunction opt.example;
} // lib.optionalAttrs (opt ? default) {
default = substFunction opt.default;
} // lib.optionalAttrs (opt ? type) {
type = substFunction opt.type;
} // lib.optionalAttrs (opt ? relatedPackages && opt.relatedPackages != [ ]) {
relatedPackages = genRelatedPackages opt.relatedPackages;
}
);
genRelatedPackages = packages:
let
unpack = p:
if lib.isString p
then { name = p; }
else if lib.isList p
then { path = p; }
else p;
describe = args:
let
title = args.title or null;
name = args.name or (lib.concatStringsSep "." args.path);
path = args.path or [ args.name ];
package =
args.package
or (lib.attrByPath path
(throw
"Invalid package attribute path '${toString path}'")
pkgs);
in
"<listitem>"
+ "<para><literal>${lib.optionalString (title != null)
"${title} aka "}pkgs.${name} (${package.meta.name})</literal>"
+ lib.optionalString (!package.meta.available)
" <emphasis>[UNAVAILABLE]</emphasis>"
+ ": ${package.meta.description or "???"}.</para>"
+ lib.optionalString (args ? comment)
"\n<para>${args.comment}</para>"
+ lib.optionalString (package.meta ? longDescription)
"\n<programlisting>${package.meta.longDescription}"
+ "</programlisting>"
+ "</listitem>";
in
"<itemizedlist>${lib.concatStringsSep "\n" (map (p:
describe (unpack p))
packages)}</itemizedlist>";
optionLess = a: b:
let
ise = lib.hasPrefix "enable";
isp = lib.hasPrefix "package";
cmp =
lib.splitByAndCompare ise lib.compare
(lib.splitByAndCompare isp lib.compare lib.compare);
in
lib.compareLists cmp a.loc b.loc < 0;
prefixesToStrip = map (p: "${toString p}/") ([ ../../.. ] ++ extraSources);
stripAnyPrefixes = lib.flip (lib.fold lib.removePrefix) prefixesToStrip;
###############################################################################
# This is the REAL meat of what we were after.
# Output this however you want.
optionsList = lib.sort optionLess optionsListDesc;
optionsJSON = builtins.unsafeDiscardStringContext (builtins.toJSON
(builtins.listToAttrs (map
(o: {
name = o.name;
value = removeAttrs o [
# Select the fields you want to drop here:
"name"
"visible"
"internal"
"loc"
"readOnly"
];
})
optionsList)));
in
pkgs.writeText "options.json" optionsJSON