lol

Merge pull request #33898 from oxij/nixos/related-packages-v5

nixos: doc: implement related packages in the manual (again)

authored by

Graham Christensen and committed by
GitHub
5aabf0fc 94e62d50

+165 -29
+4 -3
lib/default.nix
··· 56 56 replaceStrings seq stringLength sub substring tail; 57 57 inherit (trivial) id const concat or and boolToString mergeAttrs 58 58 flip mapNullable inNixShell min max importJSON warn info 59 - nixpkgsVersion mod functionArgs setFunctionArgs isFunction; 59 + nixpkgsVersion mod compare splitByAndCompare 60 + functionArgs setFunctionArgs isFunction; 60 61 61 62 inherit (fixedPoints) fix fix' extends composeExtensions 62 63 makeExtensible makeExtensibleWithCustomName; ··· 71 72 inherit (lists) singleton foldr fold foldl foldl' imap0 imap1 72 73 concatMap flatten remove findSingle findFirst any all count 73 74 optional optionals toList range partition zipListsWith zipLists 74 - reverseList listDfs toposort sort take drop sublist last init 75 - crossLists unique intersectLists subtractLists 75 + reverseList listDfs toposort sort compareLists take drop sublist 76 + last init crossLists unique intersectLists subtractLists 76 77 mutuallyExclusive; 77 78 inherit (strings) concatStrings concatMapStrings concatImapStrings 78 79 intersperse concatStringsSep concatMapStringsSep
+24
lib/lists.nix
··· 385 385 if len < 2 then list 386 386 else (sort strictLess pivot.left) ++ [ first ] ++ (sort strictLess pivot.right)); 387 387 388 + /* 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 + 388 412 /* Return the first (at most) N elements of a list. 389 413 390 414 Example:
+5 -4
lib/options.nix
··· 14 14 , defaultText ? null # Textual representation of the default, for in the manual. 15 15 , example ? null # Example value used in the manual. 16 16 , description ? null # String describing the option. 17 + , relatedPackages ? null # Related packages used in the manual (see `genRelatedPackages` in ../nixos/doc/manual/default.nix). 17 18 , type ? null # Option type, providing type-checking and value merging. 18 19 , apply ? null # Function that converts the option value to something else. 19 20 , internal ? null # Whether the option is for NixOS developers only. ··· 76 77 getValues = map (x: x.value); 77 78 getFiles = map (x: x.file); 78 79 79 - 80 80 # Generate documentation template from the list of option declaration like 81 81 # the set generated with filterOptionSets. 82 82 optionAttrSetToDocList = optionAttrSetToDocList' []; ··· 93 93 readOnly = opt.readOnly or false; 94 94 type = opt.type.description or null; 95 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 {}); 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; }; 99 100 100 101 subOptions = 101 102 let ss = opt.type.getSubOptions opt.loc;
+36
lib/trivial.nix
··· 81 81 */ 82 82 mod = base: int: base - (int * (builtins.div base int)); 83 83 84 + /* 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 + 84 120 /* Reads a JSON file. */ 85 121 importJSON = path: 86 122 builtins.fromJSON (builtins.readFile path);
+50 -6
nixos/doc/manual/default.nix
··· 6 6 lib = pkgs.lib; 7 7 8 8 # Remove invisible and internal options. 9 - optionsList = lib.filter (opt: opt.visible && !opt.internal) (lib.optionAttrSetToDocList options); 9 + optionsListVisible = lib.filter (opt: opt.visible && !opt.internal) (lib.optionAttrSetToDocList options); 10 10 11 11 # Replace functions by the string <function> 12 12 substFunction = x: ··· 15 15 else if lib.isFunction x then "<function>" 16 16 else x; 17 17 18 - # Clean up declaration sites to not refer to the NixOS source tree. 19 - optionsList' = lib.flip map optionsList (opt: opt // { 18 + # 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. 20 49 declarations = map stripAnyPrefixes opt.declarations; 21 50 } 22 51 // lib.optionalAttrs (opt ? example) { example = substFunction opt.example; } 23 52 // lib.optionalAttrs (opt ? default) { default = substFunction opt.default; } 24 - // lib.optionalAttrs (opt ? type) { type = substFunction opt.type; }); 53 + // lib.optionalAttrs (opt ? type) { type = substFunction opt.type; } 54 + // lib.optionalAttrs (opt ? relatedPackages) { relatedPackages = genRelatedPackages opt.relatedPackages; }); 25 55 26 56 # We need to strip references to /nix/store/* from options, 27 57 # including any `extraSources` if some modules came from elsewhere, ··· 32 62 prefixesToStrip = map (p: "${toString p}/") ([ ../../.. ] ++ extraSources); 33 63 stripAnyPrefixes = lib.flip (lib.fold lib.removePrefix) prefixesToStrip; 34 64 65 + # 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 + 35 79 # Convert the list of options into an XML file. 36 - optionsXML = builtins.toFile "options.xml" (builtins.toXML optionsList'); 80 + optionsXML = builtins.toFile "options.xml" (builtins.toXML optionsList); 37 81 38 82 optionsDocBook = runCommand "options-db.xml" {} '' 39 83 optionsXML=${optionsXML} ··· 191 235 mkdir -p $dst 192 236 193 237 cp ${builtins.toFile "options.json" (builtins.unsafeDiscardStringContext (builtins.toJSON 194 - (builtins.listToAttrs (map (o: { name = o.name; value = removeAttrs o ["name" "visible" "internal"]; }) optionsList')))) 238 + (builtins.listToAttrs (map (o: { name = o.name; value = removeAttrs o ["name" "visible" "internal"]; }) optionsList)))) 195 239 } $dst/options.json 196 240 197 241 mkdir -p $out/nix-support
+9
nixos/doc/manual/options-to-docbook.xsl
··· 70 70 </para> 71 71 </xsl:if> 72 72 73 + <xsl:if test="attr[@name = 'relatedPackages']"> 74 + <para> 75 + <emphasis>Related packages:</emphasis> 76 + <xsl:text> </xsl:text> 77 + <xsl:value-of disable-output-escaping="yes" 78 + select="attr[@name = 'relatedPackages']/string/@value" /> 79 + </para> 80 + </xsl:if> 81 + 73 82 <xsl:if test="count(attr[@name = 'declarations']/list/*) != 0"> 74 83 <para> 75 84 <emphasis>Declared by:</emphasis>
+1
nixos/modules/programs/adb.nix
··· 16 16 To grant access to a user, it must be part of adbusers group: 17 17 <code>users.extraUsers.alice.extraGroups = ["adbusers"];</code> 18 18 ''; 19 + relatedPackages = [ ["androidenv" "platformTools"] ]; 19 20 }; 20 21 }; 21 22 };
+6 -1
nixos/modules/programs/tmux.nix
··· 61 61 options = { 62 62 programs.tmux = { 63 63 64 - enable = mkEnableOption "<command>tmux</command> - a <command>screen</command> replacement."; 64 + enable = mkOption { 65 + type = types.bool; 66 + default = false; 67 + description = "Whenever to configure <command>tmux</command> system-wide."; 68 + relatedPackages = [ "tmux" ]; 69 + }; 65 70 66 71 aggressiveResize = mkOption { 67 72 default = false;
+4
nixos/modules/rename.nix
··· 210 210 "Set the option `services.xserver.displayManager.sddm.package' instead.") 211 211 (mkRemovedOptionModule [ "fonts" "fontconfig" "forceAutohint" ] "") 212 212 (mkRemovedOptionModule [ "fonts" "fontconfig" "renderMonoTTFAsBitmap" ] "") 213 + (mkRemovedOptionModule [ "virtualisation" "xen" "qemu" ] "You don't need this option anymore, it will work without it.") 213 214 214 215 # ZSH 215 216 (mkRenamedOptionModule [ "programs" "zsh" "enableSyntaxHighlighting" ] [ "programs" "zsh" "syntaxHighlighting" "enable" ]) ··· 220 221 (mkRenamedOptionModule [ "programs" "zsh" "oh-my-zsh" "theme" ] [ "programs" "zsh" "ohMyZsh" "theme" ]) 221 222 (mkRenamedOptionModule [ "programs" "zsh" "oh-my-zsh" "custom" ] [ "programs" "zsh" "ohMyZsh" "custom" ]) 222 223 (mkRenamedOptionModule [ "programs" "zsh" "oh-my-zsh" "plugins" ] [ "programs" "zsh" "ohMyZsh" "plugins" ]) 224 + 225 + # Xen 226 + (mkRenamedOptionModule [ "virtualisation" "xen" "qemu-package" ] [ "virtualisation" "xen" "package-qemu" ]) 223 227 ]; 224 228 }
+10 -15
nixos/modules/virtualisation/xen-dom0.nix
··· 35 35 description = '' 36 36 The package used for Xen binary. 37 37 ''; 38 + relatedPackages = [ "xen" "xen-light" ]; 38 39 }; 39 40 40 - virtualisation.xen.qemu = mkOption { 41 - type = types.path; 42 - defaultText = "\${pkgs.xen}/lib/xen/bin/qemu-system-i386"; 43 - example = literalExample "''${pkgs.qemu_xen-light}/bin/qemu-system-i386"; 44 - description = '' 45 - The qemu binary to use for Dom-0 backend. 46 - ''; 47 - }; 48 - 49 - virtualisation.xen.qemu-package = mkOption { 41 + virtualisation.xen.package-qemu = mkOption { 50 42 type = types.package; 51 43 defaultText = "pkgs.xen"; 52 44 example = literalExample "pkgs.qemu_xen-light"; 53 45 description = '' 54 - The package with qemu binaries for xendomains. 46 + The package with qemu binaries for dom0 qemu and xendomains. 55 47 ''; 48 + relatedPackages = [ "xen" 49 + { name = "qemu_xen-light"; comment = "For use with pkgs.xen-light."; } 50 + ]; 56 51 }; 57 52 58 53 virtualisation.xen.bootParams = ··· 158 153 } ]; 159 154 160 155 virtualisation.xen.package = mkDefault pkgs.xen; 161 - virtualisation.xen.qemu = mkDefault "${pkgs.xen}/lib/xen/bin/qemu-system-i386"; 162 - virtualisation.xen.qemu-package = mkDefault pkgs.xen; 156 + virtualisation.xen.package-qemu = mkDefault pkgs.xen; 163 157 virtualisation.xen.stored = mkDefault "${cfg.package}/bin/oxenstored"; 164 158 165 159 environment.systemPackages = [ cfg.package ]; ··· 339 333 after = [ "xen-console.service" ]; 340 334 requires = [ "xen-store.service" ]; 341 335 serviceConfig.ExecStart = '' 342 - ${cfg.qemu} -xen-attach -xen-domid 0 -name dom0 -M xenpv \ 336 + ${cfg.package-qemu}/${cfg.package-qemu.qemu-system-i386} \ 337 + -xen-attach -xen-domid 0 -name dom0 -M xenpv \ 343 338 -nographic -monitor /dev/null -serial /dev/null -parallel /dev/null 344 339 ''; 345 340 }; ··· 448 443 before = [ "dhcpd.service" ]; 449 444 restartIfChanged = false; 450 445 serviceConfig.RemainAfterExit = "yes"; 451 - path = [ cfg.package cfg.qemu-package ]; 446 + path = [ cfg.package cfg.package-qemu ]; 452 447 environment.XENDOM_CONFIG = "${cfg.package}/etc/sysconfig/xendomains"; 453 448 preStart = "mkdir -p /var/lock/subsys -m 755"; 454 449 serviceConfig.ExecStart = "${cfg.package}/etc/init.d/xendomains start";
+4
pkgs/applications/virtualization/qemu/default.nix
··· 101 101 else if stdenv.isAarch64 then ''makeWrapper $out/bin/qemu-system-aarch64 $out/bin/qemu-kvm --add-flags "\$([ -e /dev/kvm ] && echo -enable-kvm)"'' 102 102 else ""; 103 103 104 + passthru = { 105 + qemu-system-i386 = "bin/qemu-system-i386"; 106 + }; 107 + 104 108 meta = with stdenv.lib; { 105 109 homepage = http://www.qemu.org/; 106 110 description = "A generic and open source machine emulator and virtualizer";
+6
pkgs/applications/virtualization/xen/4.5.nix
··· 248 248 -i tools/libxl/libxl_device.c 249 249 ''; 250 250 251 + passthru = { 252 + qemu-system-i386 = if withInternalQemu 253 + then "lib/xen/bin/qemu-system-i386" 254 + else throw "this xen has no qemu builtin"; 255 + }; 256 + 251 257 })) ({ ocamlPackages = ocamlPackages_4_02; } // args)
+6
pkgs/applications/virtualization/xen/4.8.nix
··· 176 176 -i tools/libxl/libxl_device.c 177 177 ''; 178 178 179 + passthru = { 180 + qemu-system-i386 = if withInternalQemu 181 + then "lib/xen/bin/qemu-system-i386" 182 + else throw "this xen has no qemu builtin"; 183 + }; 184 + 179 185 })) args