about summary refs log tree commit diff
diff options
context:
space:
mode:
authorArseniy Seroka <jagajaga@users.noreply.github.com>2017-12-23 03:34:58 +0300
committerGitHub <noreply@github.com>2017-12-23 03:34:58 +0300
commit36e02645eba174dd6a76aaebc62b5095bb7005a9 (patch)
tree4d37dda40510984edef81b7d15567e8e6ece39a1
parentd0bb0a2c538dbe84189da00848dd1f8d5e0deda3 (diff)
parent3be0e1bd728f2500f1e8543ebc121d3ba9dabb4d (diff)
downloadnixlib-36e02645eba174dd6a76aaebc62b5095bb7005a9.tar
nixlib-36e02645eba174dd6a76aaebc62b5095bb7005a9.tar.gz
nixlib-36e02645eba174dd6a76aaebc62b5095bb7005a9.tar.bz2
nixlib-36e02645eba174dd6a76aaebc62b5095bb7005a9.tar.lz
nixlib-36e02645eba174dd6a76aaebc62b5095bb7005a9.tar.xz
nixlib-36e02645eba174dd6a76aaebc62b5095bb7005a9.tar.zst
nixlib-36e02645eba174dd6a76aaebc62b5095bb7005a9.zip
Merge pull request #32424 from oxij/nixos/related-packages
nixos: doc: implement related packages in the manual
-rw-r--r--lib/default.nix6
-rw-r--r--lib/lists.nix24
-rw-r--r--lib/options.nix9
-rw-r--r--lib/trivial.nix25
-rw-r--r--nixos/doc/manual/default.nix34
-rw-r--r--nixos/doc/manual/options-to-docbook.xsl9
-rw-r--r--nixos/modules/programs/tmux.nix7
-rw-r--r--nixos/modules/rename.nix4
-rw-r--r--nixos/modules/virtualisation/xen-dom0.nix25
-rw-r--r--pkgs/applications/virtualization/qemu/default.nix4
-rw-r--r--pkgs/applications/virtualization/xen/4.5.nix6
-rw-r--r--pkgs/applications/virtualization/xen/4.8.nix6
12 files changed, 133 insertions, 26 deletions
diff --git a/lib/default.nix b/lib/default.nix
index 9dc4fea99fc2..eb19dc06ce80 100644
--- a/lib/default.nix
+++ b/lib/default.nix
@@ -56,7 +56,7 @@ let
       replaceStrings seq stringLength sub substring tail;
     inherit (trivial) id const concat or and boolToString mergeAttrs
       flip mapNullable inNixShell min max importJSON warn info
-      nixpkgsVersion mod;
+      nixpkgsVersion mod compare splitByAndCompare;
 
     inherit (fixedPoints) fix fix' extends composeExtensions
       makeExtensible makeExtensibleWithCustomName;
@@ -71,8 +71,8 @@ let
     inherit (lists) singleton foldr fold foldl foldl' imap0 imap1
       concatMap flatten remove findSingle findFirst any all count
       optional optionals toList range partition zipListsWith zipLists
-      reverseList listDfs toposort sort take drop sublist last init
-      crossLists unique intersectLists subtractLists
+      reverseList listDfs toposort sort compareLists take drop sublist
+      last init crossLists unique intersectLists subtractLists
       mutuallyExclusive;
     inherit (strings) concatStrings concatMapStrings concatImapStrings
       intersperse concatStringsSep concatMapStringsSep
diff --git a/lib/lists.nix b/lib/lists.nix
index 8f67c6bb0ca3..f7e09040a5aa 100644
--- a/lib/lists.nix
+++ b/lib/lists.nix
@@ -385,6 +385,30 @@ rec {
       if len < 2 then list
       else (sort strictLess pivot.left) ++  [ first ] ++  (sort strictLess pivot.right));
 
+  /* Compare two lists element-by-element.
+
+     Example:
+       compareLists compare [] []
+       => 0
+       compareLists compare [] [ "a" ]
+       => -1
+       compareLists compare [ "a" ] []
+       => 1
+       compareLists compare [ "a" "b" ] [ "a" "c" ]
+       => 1
+  */
+  compareLists = cmp: a: b:
+    if a == []
+    then if b == []
+         then 0
+         else -1
+    else if b == []
+         then 1
+         else let rel = cmp (head a) (head b); in
+              if rel == 0
+              then compareLists cmp (tail a) (tail b)
+              else rel;
+
   /* Return the first (at most) N elements of a list.
 
      Example:
diff --git a/lib/options.nix b/lib/options.nix
index 769d3cc55723..ab1201c718a0 100644
--- a/lib/options.nix
+++ b/lib/options.nix
@@ -14,6 +14,7 @@ rec {
     , defaultText ? null # Textual representation of the default, for in the manual.
     , example ? null # Example value used in the manual.
     , description ? null # String describing the option.
+    , relatedPackages ? null # Related packages used in the manual.
     , type ? null # Option type, providing type-checking and value merging.
     , apply ? null # Function that converts the option value to something else.
     , internal ? null # Whether the option is for NixOS developers only.
@@ -76,7 +77,6 @@ rec {
   getValues = map (x: x.value);
   getFiles = map (x: x.file);
 
-
   # Generate documentation template from the list of option declaration like
   # the set generated with filterOptionSets.
   optionAttrSetToDocList = optionAttrSetToDocList' [];
@@ -93,9 +93,10 @@ rec {
           readOnly = opt.readOnly or false;
           type = opt.type.description or null;
         }
-        // (if opt ? example then { example = scrubOptionValue opt.example; } else {})
-        // (if opt ? default then { default = scrubOptionValue opt.default; } else {})
-        // (if opt ? defaultText then { default = opt.defaultText; } else {});
+        // optionalAttrs (opt ? example) { example = scrubOptionValue opt.example; }
+        // optionalAttrs (opt ? default) { default = scrubOptionValue opt.default; }
+        // optionalAttrs (opt ? defaultText) { default = opt.defaultText; }
+        // optionalAttrs (opt ? relatedPackages && opt.relatedPackages != null) { inherit (opt) relatedPackages; };
 
         subOptions =
           let ss = opt.type.getSubOptions opt.loc;
diff --git a/lib/trivial.nix b/lib/trivial.nix
index c452c7b65bc1..5f18c0b61cc0 100644
--- a/lib/trivial.nix
+++ b/lib/trivial.nix
@@ -81,6 +81,31 @@ rec {
   */
   mod = base: int: base - (int * (builtins.div base int));
 
+  /* C-style comparisons
+
+     a < b  => -1
+     a == b => 0
+     a > b  => 1
+  */
+  compare = a: b:
+    if a < b
+    then -1
+    else if a > b
+         then 1
+         else 0;
+
+  /* Split type into two subtypes by predicate `p`, assume
+
+       forall x y . x < y if p x == true && p y == false
+
+     compare elements of the same subtype with `yes` and `no`
+     comparisons respectively.
+  */
+  splitByAndCompare = p: yes: no: a: b:
+    if p a
+    then if p b then yes a b else -1
+    else if p b then 1 else no a b;
+
   /* Reads a JSON file. */
   importJSON = path:
     builtins.fromJSON (builtins.readFile path);
diff --git a/nixos/doc/manual/default.nix b/nixos/doc/manual/default.nix
index 9bc83be66104..95363c2458f5 100644
--- a/nixos/doc/manual/default.nix
+++ b/nixos/doc/manual/default.nix
@@ -15,13 +15,27 @@ let
     else if builtins.isFunction x then "<function>"
     else x;
 
-  # Clean up declaration sites to not refer to the NixOS source tree.
+  # Generate DocBook documentation for a list of packages
+  genRelatedPackages = packages:
+    let
+      unpack = p: if lib.isString p then { name = p; } else p;
+      describe = { name, package ? pkgs.${name}, comment ? "" }:
+          "<listitem>"
+        + "<para><option>pkgs.${name}</option> (${package.name}): ${package.meta.description or "???"}.</para>"
+        + lib.optionalString (comment != "") "\n<para>${comment}</para>"
+        # Lots of `longDescription's break DocBook, so we just wrap them into <programlisting>
+        + lib.optionalString (package.meta ? longDescription) "\n<programlisting>${package.meta.longDescription}</programlisting>"
+        + "</listitem>";
+    in "<itemizedlist>${lib.concatStringsSep "\n" (map (p: describe (unpack p)) packages)}</itemizedlist>";
+
   optionsList' = lib.flip map optionsList (opt: opt // {
+    # Clean up declaration sites to not refer to the NixOS source tree.
     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 ? type) { type = substFunction opt.type; }
+  // lib.optionalAttrs (opt ? relatedPackages) { relatedPackages = genRelatedPackages opt.relatedPackages; });
 
   # We need to strip references to /nix/store/* from options,
   # including any `extraSources` if some modules came from elsewhere,
@@ -32,8 +46,22 @@ let
   prefixesToStrip = map (p: "${toString p}/") ([ ../../.. ] ++ extraSources);
   stripAnyPrefixes = lib.flip (lib.fold lib.removePrefix) prefixesToStrip;
 
+  # Custom "less" that pushes up all the things ending in ".enable*"
+  # and ".package"
+  optionListLess = a: b:
+    let
+      splt = lib.splitString ".";
+      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 (splt a) (splt b) < 0;
+
+  # Customly sort option list for the man page.
+  optionsList'' = lib.sort (a: b: optionListLess a.name b.name) optionsList';
+
   # Convert the list of options into an XML file.
-  optionsXML = builtins.toFile "options.xml" (builtins.toXML optionsList');
+  optionsXML = builtins.toFile "options.xml" (builtins.toXML optionsList'');
 
   optionsDocBook = runCommand "options-db.xml" {} ''
     optionsXML=${optionsXML}
diff --git a/nixos/doc/manual/options-to-docbook.xsl b/nixos/doc/manual/options-to-docbook.xsl
index 5387546b5982..7b45b233ab2a 100644
--- a/nixos/doc/manual/options-to-docbook.xsl
+++ b/nixos/doc/manual/options-to-docbook.xsl
@@ -70,6 +70,15 @@
                 </para>
               </xsl:if>
 
+              <xsl:if test="attr[@name = 'relatedPackages']">
+                <para>
+                  <emphasis>Related packages:</emphasis>
+                  <xsl:text> </xsl:text>
+                  <xsl:value-of disable-output-escaping="yes"
+                                select="attr[@name = 'relatedPackages']/string/@value" />
+                </para>
+              </xsl:if>
+
               <xsl:if test="count(attr[@name = 'declarations']/list/*) != 0">
                 <para>
                   <emphasis>Declared by:</emphasis>
diff --git a/nixos/modules/programs/tmux.nix b/nixos/modules/programs/tmux.nix
index ed1d88a420a2..967001845f02 100644
--- a/nixos/modules/programs/tmux.nix
+++ b/nixos/modules/programs/tmux.nix
@@ -61,7 +61,12 @@ in {
   options = {
     programs.tmux = {
 
-      enable = mkEnableOption "<command>tmux</command> - a <command>screen</command> replacement.";
+      enable = mkOption {
+        type = types.bool;
+        default = false;
+        description = "Whenever to configure <command>tmux</command> system-wide.";
+        relatedPackages = [ "tmux" ];
+      };
 
       aggressiveResize = mkOption {
         default = false;
diff --git a/nixos/modules/rename.nix b/nixos/modules/rename.nix
index 5e207a9509e2..00d55fc28cbb 100644
--- a/nixos/modules/rename.nix
+++ b/nixos/modules/rename.nix
@@ -207,6 +207,7 @@ with lib;
       "Set the option `services.xserver.displayManager.sddm.package' instead.")
     (mkRemovedOptionModule [ "fonts" "fontconfig" "forceAutohint" ] "")
     (mkRemovedOptionModule [ "fonts" "fontconfig" "renderMonoTTFAsBitmap" ] "")
+    (mkRemovedOptionModule [ "virtualisation" "xen" "qemu" ] "You don't need this option anymore, it will work without it.")
 
     # ZSH
     (mkRenamedOptionModule [ "programs" "zsh" "enableSyntaxHighlighting" ] [ "programs" "zsh" "syntaxHighlighting" "enable" ])
@@ -217,5 +218,8 @@ with lib;
     (mkRenamedOptionModule [ "programs" "zsh" "oh-my-zsh" "theme" ] [ "programs" "zsh" "ohMyZsh" "theme" ])
     (mkRenamedOptionModule [ "programs" "zsh" "oh-my-zsh" "custom" ] [ "programs" "zsh" "ohMyZsh" "custom" ])
     (mkRenamedOptionModule [ "programs" "zsh" "oh-my-zsh" "plugins" ] [ "programs" "zsh" "ohMyZsh" "plugins" ])
+
+    # Xen
+    (mkRenamedOptionModule [ "virtualisation" "xen" "qemu-package" ] [ "virtualisation" "xen" "package-qemu" ])
   ];
 }
diff --git a/nixos/modules/virtualisation/xen-dom0.nix b/nixos/modules/virtualisation/xen-dom0.nix
index c7656bc309c0..afc5a42f8b4e 100644
--- a/nixos/modules/virtualisation/xen-dom0.nix
+++ b/nixos/modules/virtualisation/xen-dom0.nix
@@ -35,24 +35,19 @@ in
       description = ''
         The package used for Xen binary.
       '';
+      relatedPackages = [ "xen" "xen-light" ];
     };
 
-    virtualisation.xen.qemu = mkOption {
-      type = types.path;
-      defaultText = "\${pkgs.xen}/lib/xen/bin/qemu-system-i386";
-      example = literalExample "''${pkgs.qemu_xen-light}/bin/qemu-system-i386";
-      description = ''
-        The qemu binary to use for Dom-0 backend.
-      '';
-    };
-
-    virtualisation.xen.qemu-package = mkOption {
+    virtualisation.xen.package-qemu = mkOption {
       type = types.package;
       defaultText = "pkgs.xen";
       example = literalExample "pkgs.qemu_xen-light";
       description = ''
-        The package with qemu binaries for xendomains.
+        The package with qemu binaries for dom0 qemu and xendomains.
       '';
+      relatedPackages = [ "xen"
+                          { name = "qemu_xen-light"; comment = "For use with pkgs.xen-light."; }
+                        ];
     };
 
     virtualisation.xen.bootParams =
@@ -158,8 +153,7 @@ in
     } ];
 
     virtualisation.xen.package = mkDefault pkgs.xen;
-    virtualisation.xen.qemu = mkDefault "${pkgs.xen}/lib/xen/bin/qemu-system-i386";
-    virtualisation.xen.qemu-package = mkDefault pkgs.xen;
+    virtualisation.xen.package-qemu = mkDefault pkgs.xen;
     virtualisation.xen.stored = mkDefault "${cfg.package}/bin/oxenstored";
 
     environment.systemPackages = [ cfg.package ];
@@ -339,7 +333,8 @@ in
       after = [ "xen-console.service" ];
       requires = [ "xen-store.service" ];
       serviceConfig.ExecStart = ''
-        ${cfg.qemu} -xen-attach -xen-domid 0 -name dom0 -M xenpv \
+        ${cfg.package-qemu}/${cfg.package-qemu.qemu-system-i386} \
+           -xen-attach -xen-domid 0 -name dom0 -M xenpv \
            -nographic -monitor /dev/null -serial /dev/null -parallel /dev/null
         '';
     };
@@ -448,7 +443,7 @@ in
       before = [ "dhcpd.service" ];
       restartIfChanged = false;
       serviceConfig.RemainAfterExit = "yes";
-      path = [ cfg.package cfg.qemu-package ];
+      path = [ cfg.package cfg.package-qemu ];
       environment.XENDOM_CONFIG = "${cfg.package}/etc/sysconfig/xendomains";
       preStart = "mkdir -p /var/lock/subsys -m 755";
       serviceConfig.ExecStart = "${cfg.package}/etc/init.d/xendomains start";
diff --git a/pkgs/applications/virtualization/qemu/default.nix b/pkgs/applications/virtualization/qemu/default.nix
index 91b02f7ad1f0..68ab979ecfbe 100644
--- a/pkgs/applications/virtualization/qemu/default.nix
+++ b/pkgs/applications/virtualization/qemu/default.nix
@@ -101,6 +101,10 @@ stdenv.mkDerivation rec {
     else if stdenv.isAarch64 then ''makeWrapper $out/bin/qemu-system-aarch64 $out/bin/qemu-kvm --add-flags "\$([ -e /dev/kvm ] && echo -enable-kvm)"''
     else "";
 
+  passthru = {
+    qemu-system-i386 = "bin/qemu-system-i386";
+  };
+
   meta = with stdenv.lib; {
     homepage = http://www.qemu.org/;
     description = "A generic and open source machine emulator and virtualizer";
diff --git a/pkgs/applications/virtualization/xen/4.5.nix b/pkgs/applications/virtualization/xen/4.5.nix
index ec3fe9ccf221..22799a7af8e7 100644
--- a/pkgs/applications/virtualization/xen/4.5.nix
+++ b/pkgs/applications/virtualization/xen/4.5.nix
@@ -248,4 +248,10 @@ callPackage (import ./generic.nix (rec {
       -i tools/libxl/libxl_device.c
   '';
 
+  passthru = {
+    qemu-system-i386 = if withInternalQemu
+      then "lib/xen/bin/qemu-system-i386"
+      else throw "this xen has no qemu builtin";
+  };
+
 })) ({ ocamlPackages = ocamlPackages_4_02; } // args)
diff --git a/pkgs/applications/virtualization/xen/4.8.nix b/pkgs/applications/virtualization/xen/4.8.nix
index 6eedca18960b..44a52a1026af 100644
--- a/pkgs/applications/virtualization/xen/4.8.nix
+++ b/pkgs/applications/virtualization/xen/4.8.nix
@@ -176,4 +176,10 @@ callPackage (import ./generic.nix (rec {
       -i tools/libxl/libxl_device.c
   '';
 
+  passthru = {
+    qemu-system-i386 = if withInternalQemu
+      then "lib/xen/bin/qemu-system-i386"
+      else throw "this xen has no qemu builtin";
+  };
+
 })) args