···56 replaceStrings seq stringLength sub substring tail;
57 inherit (trivial) id const concat or and boolToString mergeAttrs
58 flip mapNullable inNixShell min max importJSON warn info
59- nixpkgsVersion mod functionArgs setFunctionArgs isFunction;
06061 inherit (fixedPoints) fix fix' extends composeExtensions
62 makeExtensible makeExtensibleWithCustomName;
···71 inherit (lists) singleton foldr fold foldl foldl' imap0 imap1
72 concatMap flatten remove findSingle findFirst any all count
73 optional optionals toList range partition zipListsWith zipLists
74- reverseList listDfs toposort sort take drop sublist last init
75- crossLists unique intersectLists subtractLists
76 mutuallyExclusive;
77 inherit (strings) concatStrings concatMapStrings concatImapStrings
78 intersperse concatStringsSep concatMapStringsSep
···56 replaceStrings seq stringLength sub substring tail;
57 inherit (trivial) id const concat or and boolToString mergeAttrs
58 flip mapNullable inNixShell min max importJSON warn info
59+ nixpkgsVersion mod compare splitByAndCompare
60+ functionArgs setFunctionArgs isFunction;
6162 inherit (fixedPoints) fix fix' extends composeExtensions
63 makeExtensible makeExtensibleWithCustomName;
···72 inherit (lists) singleton foldr fold foldl foldl' imap0 imap1
73 concatMap flatten remove findSingle findFirst any all count
74 optional optionals toList range partition zipListsWith zipLists
75+ reverseList listDfs toposort sort compareLists take drop sublist
76+ last init crossLists unique intersectLists subtractLists
77 mutuallyExclusive;
78 inherit (strings) concatStrings concatMapStrings concatImapStrings
79 intersperse concatStringsSep concatMapStringsSep
+24
lib/lists.nix
···385 if len < 2 then list
386 else (sort strictLess pivot.left) ++ [ first ] ++ (sort strictLess pivot.right));
387000000000000000000000000388 /* Return the first (at most) N elements of a list.
389390 Example:
···385 if len < 2 then list
386 else (sort strictLess pivot.left) ++ [ first ] ++ (sort strictLess pivot.right));
387388+ /* Compare two lists element-by-element.
389+390+ Example:
391+ compareLists compare [] []
392+ => 0
393+ compareLists compare [] [ "a" ]
394+ => -1
395+ compareLists compare [ "a" ] []
396+ => 1
397+ compareLists compare [ "a" "b" ] [ "a" "c" ]
398+ => 1
399+ */
400+ compareLists = cmp: a: b:
401+ if a == []
402+ then if b == []
403+ then 0
404+ else -1
405+ else if b == []
406+ then 1
407+ else let rel = cmp (head a) (head b); in
408+ if rel == 0
409+ then compareLists cmp (tail a) (tail b)
410+ else rel;
411+412 /* Return the first (at most) N elements of a list.
413414 Example:
+5-4
lib/options.nix
···14 , defaultText ? null # Textual representation of the default, for in the manual.
15 , example ? null # Example value used in the manual.
16 , description ? null # String describing the option.
017 , type ? null # Option type, providing type-checking and value merging.
18 , apply ? null # Function that converts the option value to something else.
19 , internal ? null # Whether the option is for NixOS developers only.
···76 getValues = map (x: x.value);
77 getFiles = map (x: x.file);
7879-80 # Generate documentation template from the list of option declaration like
81 # the set generated with filterOptionSets.
82 optionAttrSetToDocList = optionAttrSetToDocList' [];
···93 readOnly = opt.readOnly or false;
94 type = opt.type.description or null;
95 }
96- // (if opt ? example then { example = scrubOptionValue opt.example; } else {})
97- // (if opt ? default then { default = scrubOptionValue opt.default; } else {})
98- // (if opt ? defaultText then { default = opt.defaultText; } else {});
099100 subOptions =
101 let ss = opt.type.getSubOptions opt.loc;
···14 , defaultText ? null # Textual representation of the default, for in the manual.
15 , example ? null # Example value used in the manual.
16 , description ? null # String describing the option.
17+ , relatedPackages ? null # Related packages used in the manual (see `genRelatedPackages` in ../nixos/doc/manual/default.nix).
18 , type ? null # Option type, providing type-checking and value merging.
19 , apply ? null # Function that converts the option value to something else.
20 , internal ? null # Whether the option is for NixOS developers only.
···77 getValues = map (x: x.value);
78 getFiles = map (x: x.file);
79080 # Generate documentation template from the list of option declaration like
81 # the set generated with filterOptionSets.
82 optionAttrSetToDocList = optionAttrSetToDocList' [];
···93 readOnly = opt.readOnly or false;
94 type = opt.type.description or null;
95 }
96+ // optionalAttrs (opt ? example) { example = scrubOptionValue opt.example; }
97+ // optionalAttrs (opt ? default) { default = scrubOptionValue opt.default; }
98+ // optionalAttrs (opt ? defaultText) { default = opt.defaultText; }
99+ // optionalAttrs (opt ? relatedPackages && opt.relatedPackages != null) { inherit (opt) relatedPackages; };
100101 subOptions =
102 let ss = opt.type.getSubOptions opt.loc;
+36
lib/trivial.nix
···81 */
82 mod = base: int: base - (int * (builtins.div base int));
8300000000000000000000000000000000000084 /* Reads a JSON file. */
85 importJSON = path:
86 builtins.fromJSON (builtins.readFile path);
···81 */
82 mod = base: int: base - (int * (builtins.div base int));
8384+ /* C-style comparisons
85+86+ a < b, compare a b => -1
87+ a == b, compare a b => 0
88+ a > b, compare a b => 1
89+ */
90+ compare = a: b:
91+ if a < b
92+ then -1
93+ else if a > b
94+ then 1
95+ else 0;
96+97+ /* Split type into two subtypes by predicate `p`, take all elements
98+ of the first subtype to be less than all the elements of the
99+ second subtype, compare elements of a single subtype with `yes`
100+ and `no` respectively.
101+102+ Example:
103+104+ let cmp = splitByAndCompare (hasPrefix "foo") compare compare; in
105+106+ cmp "a" "z" => -1
107+ cmp "fooa" "fooz" => -1
108+109+ cmp "f" "a" => 1
110+ cmp "fooa" "a" => -1
111+ # while
112+ compare "fooa" "a" => 1
113+114+ */
115+ splitByAndCompare = p: yes: no: a: b:
116+ if p a
117+ then if p b then yes a b else -1
118+ else if p b then 1 else no a b;
119+120 /* Reads a JSON file. */
121 importJSON = path:
122 builtins.fromJSON (builtins.readFile path);
+50-6
nixos/doc/manual/default.nix
···6 lib = pkgs.lib;
78 # Remove invisible and internal options.
9- optionsList = lib.filter (opt: opt.visible && !opt.internal) (lib.optionAttrSetToDocList options);
1011 # Replace functions by the string <function>
12 substFunction = x:
···15 else if lib.isFunction x then "<function>"
16 else x;
1718- # Clean up declaration sites to not refer to the NixOS source tree.
19- optionsList' = lib.flip map optionsList (opt: opt // {
0000000000000000000000000000020 declarations = map stripAnyPrefixes opt.declarations;
21 }
22 // lib.optionalAttrs (opt ? example) { example = substFunction opt.example; }
23 // lib.optionalAttrs (opt ? default) { default = substFunction opt.default; }
24- // lib.optionalAttrs (opt ? type) { type = substFunction opt.type; });
02526 # We need to strip references to /nix/store/* from options,
27 # including any `extraSources` if some modules came from elsewhere,
···32 prefixesToStrip = map (p: "${toString p}/") ([ ../../.. ] ++ extraSources);
33 stripAnyPrefixes = lib.flip (lib.fold lib.removePrefix) prefixesToStrip;
340000000000000035 # Convert the list of options into an XML file.
36- optionsXML = builtins.toFile "options.xml" (builtins.toXML optionsList');
3738 optionsDocBook = runCommand "options-db.xml" {} ''
39 optionsXML=${optionsXML}
···191 mkdir -p $dst
192193 cp ${builtins.toFile "options.json" (builtins.unsafeDiscardStringContext (builtins.toJSON
194- (builtins.listToAttrs (map (o: { name = o.name; value = removeAttrs o ["name" "visible" "internal"]; }) optionsList'))))
195 } $dst/options.json
196197 mkdir -p $out/nix-support
···6 lib = pkgs.lib;
78 # Remove invisible and internal options.
9+ optionsListVisible = lib.filter (opt: opt.visible && !opt.internal) (lib.optionAttrSetToDocList options);
1011 # Replace functions by the string <function>
12 substFunction = x:
···15 else if lib.isFunction x then "<function>"
16 else x;
1718+ # Generate DocBook documentation for a list of packages. This is
19+ # what `relatedPackages` option of `mkOption` from
20+ # ../../../lib/options.nix influences.
21+ #
22+ # Each element of `relatedPackages` can be either
23+ # - a string: that will be interpreted as an attribute name from `pkgs`,
24+ # - a list: that will be interpreted as an attribute path from `pkgs`,
25+ # - an attrset: that can specify `name`, `path`, `package`, `comment`
26+ # (either of `name`, `path` is required, the rest are optional).
27+ genRelatedPackages = packages:
28+ let
29+ unpack = p: if lib.isString p then { name = p; }
30+ else if lib.isList p then { path = p; }
31+ else p;
32+ describe = args:
33+ let
34+ name = args.name or (lib.concatStringsSep "." args.path);
35+ path = args.path or [ args.name ];
36+ package = args.package or (lib.attrByPath path (throw "Invalid package attribute path `${toString path}'") pkgs);
37+ in "<listitem>"
38+ + "<para><literal>pkgs.${name} (${package.meta.name})</literal>"
39+ + lib.optionalString (!package.meta.evaluates) " <emphasis>[UNAVAILABLE]</emphasis>"
40+ + ": ${package.meta.description or "???"}.</para>"
41+ + lib.optionalString (args ? comment) "\n<para>${args.comment}</para>"
42+ # Lots of `longDescription's break DocBook, so we just wrap them into <programlisting>
43+ + lib.optionalString (package.meta ? longDescription) "\n<programlisting>${package.meta.longDescription}</programlisting>"
44+ + "</listitem>";
45+ in "<itemizedlist>${lib.concatStringsSep "\n" (map (p: describe (unpack p)) packages)}</itemizedlist>";
46+47+ optionsListDesc = lib.flip map optionsListVisible (opt: opt // {
48+ # Clean up declaration sites to not refer to the NixOS source tree.
49 declarations = map stripAnyPrefixes opt.declarations;
50 }
51 // lib.optionalAttrs (opt ? example) { example = substFunction opt.example; }
52 // lib.optionalAttrs (opt ? default) { default = substFunction opt.default; }
53+ // lib.optionalAttrs (opt ? type) { type = substFunction opt.type; }
54+ // lib.optionalAttrs (opt ? relatedPackages) { relatedPackages = genRelatedPackages opt.relatedPackages; });
5556 # We need to strip references to /nix/store/* from options,
57 # including any `extraSources` if some modules came from elsewhere,
···62 prefixesToStrip = map (p: "${toString p}/") ([ ../../.. ] ++ extraSources);
63 stripAnyPrefixes = lib.flip (lib.fold lib.removePrefix) prefixesToStrip;
6465+ # Custom "less" that pushes up all the things ending in ".enable*"
66+ # and ".package"
67+ optionListLess = a: b:
68+ let
69+ splt = lib.splitString ".";
70+ ise = lib.hasPrefix "enable";
71+ isp = lib.hasPrefix "package";
72+ cmp = lib.splitByAndCompare ise lib.compare
73+ (lib.splitByAndCompare isp lib.compare lib.compare);
74+ in lib.compareLists cmp (splt a) (splt b) < 0;
75+76+ # Customly sort option list for the man page.
77+ optionsList = lib.sort (a: b: optionListLess a.name b.name) optionsListDesc;
78+79 # Convert the list of options into an XML file.
80+ optionsXML = builtins.toFile "options.xml" (builtins.toXML optionsList);
8182 optionsDocBook = runCommand "options-db.xml" {} ''
83 optionsXML=${optionsXML}
···235 mkdir -p $dst
236237 cp ${builtins.toFile "options.json" (builtins.unsafeDiscardStringContext (builtins.toJSON
238+ (builtins.listToAttrs (map (o: { name = o.name; value = removeAttrs o ["name" "visible" "internal"]; }) optionsList))))
239 } $dst/options.json
240241 mkdir -p $out/nix-support
···16 To grant access to a user, it must be part of adbusers group:
17 <code>users.extraUsers.alice.extraGroups = ["adbusers"];</code>
18 '';
019 };
20 };
21 };
···16 To grant access to a user, it must be part of adbusers group:
17 <code>users.extraUsers.alice.extraGroups = ["adbusers"];</code>
18 '';
19+ relatedPackages = [ ["androidenv" "platformTools"] ];
20 };
21 };
22 };