summary refs log tree commit diff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/asserts.nix44
-rw-r--r--lib/attrsets.nix16
-rw-r--r--lib/composable-derivation.nix2
-rw-r--r--lib/customisation.nix8
-rw-r--r--lib/debug.nix184
-rw-r--r--lib/default.nix74
-rw-r--r--lib/generators.nix121
-rw-r--r--lib/kernel.nix57
-rw-r--r--lib/licenses.nix61
-rw-r--r--lib/lists.nix69
-rw-r--r--lib/maintainers-list.nix3955
-rw-r--r--lib/meta.nix19
-rw-r--r--lib/minver.nix2
-rw-r--r--lib/modules.nix135
-rw-r--r--lib/options.nix15
-rw-r--r--lib/strings.nix67
-rw-r--r--lib/systems/default.nix10
-rw-r--r--lib/systems/doubles.nix13
-rw-r--r--lib/systems/examples.nix87
-rw-r--r--lib/systems/for-meta.nix37
-rw-r--r--lib/systems/inspect.nix86
-rw-r--r--lib/systems/parse.nix113
-rw-r--r--lib/systems/platforms.nix381
-rw-r--r--lib/tests/misc.nix81
-rwxr-xr-xlib/tests/modules.sh13
-rw-r--r--lib/tests/modules/declare-coerced-value-unsound.nix10
-rw-r--r--lib/tests/modules/define-value-string-arbitrary.nix3
-rw-r--r--lib/tests/modules/define-value-string-bigint.nix3
-rw-r--r--lib/tests/modules/loaOf-with-long-list.nix19
-rw-r--r--lib/tests/modules/loaOf-with-many-list-merges.nix19
-rw-r--r--lib/tests/release.nix3
-rw-r--r--lib/tests/systems.nix2
-rw-r--r--lib/trivial.nix110
-rw-r--r--lib/types.nix66
-rw-r--r--lib/versions.nix47
-rw-r--r--lib/zip-int-bits.nix39
36 files changed, 1438 insertions, 4533 deletions
diff --git a/lib/asserts.nix b/lib/asserts.nix
new file mode 100644
index 000000000000..8a5f1fb3feb7
--- /dev/null
+++ b/lib/asserts.nix
@@ -0,0 +1,44 @@
+{ lib }:
+
+rec {
+
+  /* Print a trace message if pred is false.
+     Intended to be used to augment asserts with helpful error messages.
+
+     Example:
+       assertMsg false "nope"
+       => false
+       stderr> trace: nope
+
+       assert (assertMsg ("foo" == "bar") "foo is not bar, silly"); ""
+       stderr> trace: foo is not bar, silly
+       stderr> assert failed at …
+
+     Type:
+       assertMsg :: Bool -> String -> Bool
+  */
+  # TODO(Profpatsch): add tests that check stderr
+  assertMsg = pred: msg:
+    if pred
+    then true
+    else builtins.trace msg false;
+
+  /* Specialized `assertMsg` for checking if val is one of the elements
+     of a list. Useful for checking enums.
+
+     Example:
+       let sslLibrary = "libressl"
+       in assertOneOf "sslLibrary" sslLibrary [ "openssl" "bearssl" ]
+       => false
+       stderr> trace: sslLibrary must be one of "openssl", "bearssl", but is: "libressl"
+
+     Type:
+       assertOneOf :: String -> ComparableVal -> List ComparableVal -> Bool
+  */
+  assertOneOf = name: val: xs: assertMsg
+    (lib.elem val xs)
+    "${name} must be one of ${
+      lib.generators.toPretty {} xs}, but is: ${
+        lib.generators.toPretty {} val}";
+
+}
diff --git a/lib/attrsets.nix b/lib/attrsets.nix
index 19218cfe8ecb..1e4142562fa6 100644
--- a/lib/attrsets.nix
+++ b/lib/attrsets.nix
@@ -3,9 +3,9 @@
 
 let
   inherit (builtins) head tail length;
-  inherit (lib.trivial) and or;
+  inherit (lib.trivial) and;
   inherit (lib.strings) concatStringsSep;
-  inherit (lib.lists) fold concatMap concatLists all deepSeqList;
+  inherit (lib.lists) fold concatMap concatLists;
 in
 
 rec {
@@ -145,7 +145,7 @@ rec {
   foldAttrs = op: nul: list_of_attrs:
     fold (n: a:
         fold (name: o:
-          o // (listToAttrs [{inherit name; value = op n.${name} (a.${name} or nul); }])
+          o // { ${name} = op n.${name} (a.${name} or nul); }
         ) a (attrNames n)
     ) {} list_of_attrs;
 
@@ -195,8 +195,9 @@ rec {
           { x = "foo"; y = "bar"; }
        => { x = "x-foo"; y = "y-bar"; }
   */
-  mapAttrs = f: set:
-    listToAttrs (map (attr: { name = attr; value = f attr set.${attr}; }) (attrNames set));
+  mapAttrs = builtins.mapAttrs or
+    (f: set:
+      listToAttrs (map (attr: { name = attr; value = f attr set.${attr}; }) (attrNames set)));
 
 
   /* Like `mapAttrs', but allows the name of each attribute to be
@@ -383,11 +384,12 @@ rec {
   recursiveUpdateUntil = pred: lhs: rhs:
     let f = attrPath:
       zipAttrsWith (n: values:
+        let here = attrPath ++ [n]; in
         if tail values == []
-        || pred attrPath (head (tail values)) (head values) then
+        || pred here (head (tail values)) (head values) then
           head values
         else
-          f (attrPath ++ [n]) values
+          f here values
       );
     in f [] [rhs lhs];
 
diff --git a/lib/composable-derivation.nix b/lib/composable-derivation.nix
index 5e55ac023f14..cb1fdc121e11 100644
--- a/lib/composable-derivation.nix
+++ b/lib/composable-derivation.nix
@@ -1,5 +1,5 @@
 {lib, pkgs}:
-let inherit (lib) nv nvs; in
+let inherit (lib) nvs; in
 {
 
   # composableDerivation basically mixes these features:
diff --git a/lib/customisation.nix b/lib/customisation.nix
index d942f54ee798..0107ed33d9e4 100644
--- a/lib/customisation.nix
+++ b/lib/customisation.nix
@@ -1,9 +1,4 @@
 { lib }:
-let
-
-  inherit (builtins) attrNames;
-
-in
 
 rec {
 
@@ -200,9 +195,10 @@ rec {
     let self = f self // {
           newScope = scope: newScope (self // scope);
           callPackage = self.newScope {};
+          # TODO(@Ericson2314): Haromonize argument order of `g` with everything else
           overrideScope = g:
             makeScope newScope
-            (self_: let super = f self_; in super // g super self_);
+            (lib.fixedPoints.extends (lib.flip g) f);
           packages = f;
         };
     in self;
diff --git a/lib/debug.nix b/lib/debug.nix
index d163e60b6957..383eb32d75d0 100644
--- a/lib/debug.nix
+++ b/lib/debug.nix
@@ -1,34 +1,67 @@
+/* Collection of functions useful for debugging
+   broken nix expressions.
+
+   * `trace`-like functions take two values, print
+     the first to stderr and return the second.
+   * `traceVal`-like functions take one argument
+     which both printed and returned.
+   * `traceSeq`-like functions fully evaluate their
+     traced value before printing (not just to “weak
+     head normal form” like trace does by default).
+   * Functions that end in `-Fn` take an additional
+     function as their first argument, which is applied
+     to the traced value before it is printed.
+*/
 { lib }:
-
 let
-
-inherit (builtins) trace attrNamesToStr isAttrs isList isInt
-        isString isBool head substring attrNames;
-
-inherit (lib) all id mapAttrsFlatten elem isFunction;
-
+  inherit (builtins) trace isAttrs isList isInt
+          head substring attrNames;
+  inherit (lib) id elem isFunction;
 in
 
 rec {
 
-  inherit (builtins) addErrorContext;
-
-  addErrorContextToAttrs = lib.mapAttrs (a: v: lib.addErrorContext "while evaluating ${a}" v);
+  # -- TRACING --
 
-  traceIf = p: msg: x: if p then trace msg x else x;
+  /* Trace msg, but only if pred is true.
 
-  traceVal = x: trace x x;
-  traceXMLVal = x: trace (builtins.toXML x) x;
-  traceXMLValMarked = str: x: trace (str + builtins.toXML x) x;
+     Example:
+       traceIf true "hello" 3
+       trace: hello
+       => 3
+  */
+  traceIf = pred: msg: x: if pred then trace msg x else x;
 
-  # strict trace functions (traced structure is fully evaluated and printed)
+  /* Trace the value and also return it.
 
-  /* `builtins.trace`, but the value is `builtins.deepSeq`ed first. */
+     Example:
+       traceValFn (v: "mystring ${v}") "foo"
+       trace: mystring foo
+       => "foo"
+  */
+  traceValFn = f: x: trace (f x) x;
+  traceVal = traceValFn id;
+
+  /* `builtins.trace`, but the value is `builtins.deepSeq`ed first.
+
+     Example:
+       trace { a.b.c = 3; } null
+       trace: { a = <CODE>; }
+       => null
+       traceSeq { a.b.c = 3; } null
+       trace: { a = { b = { c = 3; }; }; }
+       => null
+  */
   traceSeq = x: y: trace (builtins.deepSeq x x) y;
 
-  /* Like `traceSeq`, but only down to depth n.
-   * This is very useful because lots of `traceSeq` usages
-   * lead to an infinite recursion.
+  /* Like `traceSeq`, but only evaluate down to depth n.
+     This is very useful because lots of `traceSeq` usages
+     lead to an infinite recursion.
+
+     Example:
+       traceSeqN 2 { a.b.c = 3; } null
+       trace: { a = { b = {…}; }; }
+       => null
    */
   traceSeqN = depth: x: y: with lib;
     let snip = v: if      isList  v then noQuotes "[…]" v
@@ -43,39 +76,16 @@ rec {
     in trace (generators.toPretty { allowPrettyValues = true; }
                (modify depth snip x)) y;
 
-  /* `traceSeq`, but the same value is traced and returned */
-  traceValSeq = v: traceVal (builtins.deepSeq v v);
-  /* `traceValSeq` but with fixed depth */
-  traceValSeqN = depth: v: traceSeqN depth v v;
+  /* A combination of `traceVal` and `traceSeq` */
+  traceValSeqFn = f: v: traceValFn f (builtins.deepSeq v v);
+  traceValSeq = traceValSeqFn id;
 
+  /* A combination of `traceVal` and `traceSeqN`. */
+  traceValSeqNFn = f: depth: v: traceSeqN depth (f v) v;
+  traceValSeqN = traceValSeqNFn id;
 
-  # this can help debug your code as well - designed to not produce thousands of lines
-  traceShowVal = x: trace (showVal x) x;
-  traceShowValMarked = str: x: trace (str + showVal x) x;
-  attrNamesToStr = a: lib.concatStringsSep "; " (map (x: "${x}=") (attrNames a));
-  showVal = x:
-      if isAttrs x then
-          if x ? outPath then "x is a derivation, name ${if x ? name then x.name else "<no name>"}, { ${attrNamesToStr x} }"
-          else "x is attr set { ${attrNamesToStr x} }"
-      else if isFunction x then "x is a function"
-      else if x == [] then "x is an empty list"
-      else if isList x then "x is a list, first element is: ${showVal (head x)}"
-      else if x == true then "x is boolean true"
-      else if x == false then "x is boolean false"
-      else if x == null then "x is null"
-      else if isInt x then "x is an integer `${toString x}'"
-      else if isString x then "x is a string `${substring 0 50 x}...'"
-      else "x is probably a path `${substring 0 50 (toString x)}...'";
 
-  # trace the arguments passed to function and its result
-  # maybe rewrite these functions in a traceCallXml like style. Then one function is enough
-  traceCall  = n: f: a: let t = n2: x: traceShowValMarked "${n} ${n2}:" x; in t "result" (f (t "arg 1" a));
-  traceCall2 = n: f: a: b: let t = n2: x: traceShowValMarked "${n} ${n2}:" x; in t "result" (f (t "arg 1" a) (t "arg 2" b));
-  traceCall3 = n: f: a: b: c: let t = n2: x: traceShowValMarked "${n} ${n2}:" x; in t "result" (f (t "arg 1" a) (t "arg 2" b) (t "arg 3" c));
-
-  # FIXME: rename this?
-  traceValIfNot = c: x:
-    if c x then true else trace (showVal x) false;
+  # -- TESTING --
 
   /* Evaluate a set of tests.  A test is an attribute set {expr,
      expected}, denoting an expression and its expected result.  The
@@ -99,9 +109,68 @@ rec {
   # usage: { testX = allTrue [ true ]; }
   testAllTrue = expr: { inherit expr; expected = map (x: true) expr; };
 
-  strict = v:
-    trace "Warning: strict is deprecated and will be removed in the next release"
-      (builtins.seq v v);
+
+  # -- DEPRECATED --
+
+  traceShowVal = x: trace (showVal x) x;
+  traceShowValMarked = str: x: trace (str + showVal x) x;
+
+  attrNamesToStr = a:
+    trace ( "Warning: `attrNamesToStr` is deprecated "
+          + "and will be removed in the next release. "
+          + "Please use more specific concatenation "
+          + "for your uses (`lib.concat(Map)StringsSep`)." )
+    (lib.concatStringsSep "; " (map (x: "${x}=") (attrNames a)));
+
+  showVal = with lib;
+    trace ( "Warning: `showVal` is deprecated "
+          + "and will be removed in the next release, "
+          + "please use `traceSeqN`" )
+    (let
+      modify = v:
+        let pr = f: { __pretty = f; val = v; };
+        in   if isDerivation v then pr
+          (drv: "<δ:${drv.name}:${concatStringsSep ","
+                                 (attrNames drv)}>")
+        else if [] ==   v then pr (const "[]")
+        else if isList  v then pr (l: "[ ${go (head l)}, … ]")
+        else if isAttrs v then pr
+          (a: "{ ${ concatStringsSep ", " (attrNames a)} }")
+        else v;
+      go = x: generators.toPretty
+        { allowPrettyValues = true; }
+        (modify x);
+    in go);
+
+  traceXMLVal = x:
+    trace ( "Warning: `traceXMLVal` is deprecated "
+          + "and will be removed in the next release. "
+          + "Please use `traceValFn builtins.toXML`." )
+    (trace (builtins.toXML x) x);
+  traceXMLValMarked = str: x:
+    trace ( "Warning: `traceXMLValMarked` is deprecated "
+          + "and will be removed in the next release. "
+          + "Please use `traceValFn (x: str + builtins.toXML x)`." )
+    (trace (str + builtins.toXML x) x);
+
+  # trace the arguments passed to function and its result
+  # maybe rewrite these functions in a traceCallXml like style. Then one function is enough
+  traceCall  = n: f: a: let t = n2: x: traceShowValMarked "${n} ${n2}:" x; in t "result" (f (t "arg 1" a));
+  traceCall2 = n: f: a: b: let t = n2: x: traceShowValMarked "${n} ${n2}:" x; in t "result" (f (t "arg 1" a) (t "arg 2" b));
+  traceCall3 = n: f: a: b: c: let t = n2: x: traceShowValMarked "${n} ${n2}:" x; in t "result" (f (t "arg 1" a) (t "arg 2" b) (t "arg 3" c));
+
+  traceValIfNot = c: x:
+    trace ( "Warning: `traceValIfNot` is deprecated "
+          + "and will be removed in the next release. "
+          + "Please use `if/then/else` and `traceValSeq 1`.")
+    (if c x then true else traceSeq (showVal x) false);
+
+
+  addErrorContextToAttrs = attrs:
+    trace ( "Warning: `addErrorContextToAttrs` is deprecated "
+          + "and will be removed in the next release. "
+          + "Please use `builtins.addErrorContext` directly." )
+    (lib.mapAttrs (a: v: lib.addErrorContext "while evaluating ${a}" v) attrs);
 
   # example: (traceCallXml "myfun" id 3) will output something like
   # calling myfun arg 1: 3 result: 3
@@ -109,17 +178,20 @@ rec {
   # note: if result doesn't evaluate you'll get no trace at all (FIXME)
   #       args should be printed in any case
   traceCallXml = a:
-    if !isInt a then
+    trace ( "Warning: `traceCallXml` is deprecated "
+          + "and will be removed in the next release. "
+          + "Please complain if you use the function regularly." )
+    (if !isInt a then
       traceCallXml 1 "calling ${a}\n"
     else
       let nr = a;
       in (str: expr:
           if isFunction expr then
             (arg:
-              traceCallXml (builtins.add 1 nr) "${str}\n arg ${builtins.toString nr} is \n ${builtins.toXML (strict arg)}" (expr arg)
+              traceCallXml (builtins.add 1 nr) "${str}\n arg ${builtins.toString nr} is \n ${builtins.toXML (builtins.seq arg arg)}" (expr arg)
             )
           else
-            let r = strict expr;
+            let r = builtins.seq expr expr;
             in trace "${str}\n result:\n${builtins.toXML r}" r
-      );
+      ));
 }
diff --git a/lib/default.nix b/lib/default.nix
index 7716fe34dbab..d7a05fec8338 100644
--- a/lib/default.nix
+++ b/lib/default.nix
@@ -5,9 +5,11 @@
  */
 let
 
-  callLibs = file: import file { inherit lib; };
+  inherit (import ./fixed-points.nix {}) makeExtensible;
 
-  lib = rec {
+  lib = makeExtensible (self: let
+    callLibs = file: import file { lib = self; };
+  in with self; {
 
     # often used, or depending on very little
     trivial = callLibs ./trivial.nix;
@@ -21,10 +23,10 @@ let
 
     # packaging
     customisation = callLibs ./customisation.nix;
-    maintainers = import ./maintainers-list.nix;
+    maintainers = import ../maintainers/maintainer-list.nix;
     meta = callLibs ./meta.nix;
     sources = callLibs ./sources.nix;
-
+    versions = callLibs ./versions.nix;
 
     # module system
     modules = callLibs ./modules.nix;
@@ -36,10 +38,11 @@ let
     systems = callLibs ./systems;
 
     # misc
+    asserts = callLibs ./asserts.nix;
     debug = callLibs ./debug.nix;
-
     generators = callLibs ./generators.nix;
     misc = callLibs ./deprecated.nix;
+
     # domain-specific
     fetchers = callLibs ./fetchers.nix;
 
@@ -47,18 +50,17 @@ let
     filesystem = callLibs ./filesystem.nix;
 
     # back-compat aliases
-    platforms = systems.doubles;
-
-    inherit (builtins) add addErrorContext attrNames
-      concatLists deepSeq elem elemAt filter genericClosure genList
-      getAttr hasAttr head isAttrs isBool isInt isList
-      isString length lessThan listToAttrs pathExists readFile
-      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 compare splitByAndCompare
-      functionArgs setFunctionArgs isFunction;
+    platforms = systems.forMeta;
 
+    inherit (builtins) add addErrorContext attrNames concatLists
+      deepSeq elem elemAt filter genericClosure genList getAttr
+      hasAttr head isAttrs isBool isInt isList isString length
+      lessThan listToAttrs pathExists readFile replaceStrings seq
+      stringLength sub substring tail;
+    inherit (trivial) id const concat or and bitAnd bitOr bitXor bitNot
+      boolToString mergeAttrs flip mapNullable inNixShell min max
+      importJSON warn info nixpkgsVersion version mod compare
+      splitByAndCompare functionArgs setFunctionArgs isFunction;
     inherit (fixedPoints) fix fix' extends composeExtensions
       makeExtensible makeExtensibleWithCustomName;
     inherit (attrsets) attrByPath hasAttrByPath setAttrByPath
@@ -72,30 +74,32 @@ 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 compareLists take drop sublist
-      last init crossLists unique intersectLists subtractLists
-      mutuallyExclusive;
+      reverseList listDfs toposort sort naturalSort compareLists take
+      drop sublist last init crossLists unique intersectLists
+      subtractLists mutuallyExclusive groupBy groupBy';
     inherit (strings) concatStrings concatMapStrings concatImapStrings
       intersperse concatStringsSep concatMapStringsSep
       concatImapStringsSep makeSearchPath makeSearchPathOutput
-      makeLibraryPath makeBinPath makePerlPath optionalString
+      makeLibraryPath makeBinPath makePerlPath makeFullPerlPath optionalString
       hasPrefix hasSuffix stringToCharacters stringAsChars escape
-      escapeShellArg escapeShellArgs replaceChars lowerChars upperChars
-      toLower toUpper addContextFrom splitString removePrefix
-      removeSuffix versionOlder versionAtLeast getVersion nameFromURL
-      enableFeature fixedWidthString fixedWidthNumber isStorePath
+      escapeShellArg escapeShellArgs replaceChars lowerChars
+      upperChars toLower toUpper addContextFrom splitString
+      removePrefix removeSuffix versionOlder versionAtLeast getVersion
+      nameFromURL enableFeature enableFeatureAs withFeature
+      withFeatureAs fixedWidthString fixedWidthNumber isStorePath
       toInt readPathsFromFile fileContents;
     inherit (stringsWithDeps) textClosureList textClosureMap
       noDepEntry fullDepEntry packEntry stringAfter;
     inherit (customisation) overrideDerivation makeOverridable
-      callPackageWith callPackagesWith extendDerivation
-      hydraJob makeScope;
+      callPackageWith callPackagesWith extendDerivation hydraJob
+      makeScope;
     inherit (meta) addMetaAttrs dontDistribute setName updateName
       appendToName mapDerivationAttrset lowPrio lowPrioSet hiPrio
       hiPrioSet;
     inherit (sources) pathType pathIsDirectory cleanSourceFilter
       cleanSource sourceByRegex sourceFilesBySuffices
-      commitIdFromGitRepo cleanSourceWith pathHasContext canCleanSource;
+      commitIdFromGitRepo cleanSourceWith pathHasContext
+      canCleanSource;
     inherit (modules) evalModules closeModules unifyModuleSyntax
       applyIfFunction unpackSubmodule packSubmodule mergeModules
       mergeModules' mergeOptionDecls evalOptionValue mergeDefinitions
@@ -113,11 +117,13 @@ let
       unknownModule mkOption;
     inherit (types) isType setType defaultTypeMerge defaultFunctor
       isOptionType mkOptionType;
-    inherit (debug) addErrorContextToAttrs traceIf traceVal
+    inherit (asserts)
+      assertMsg assertOneOf;
+    inherit (debug) addErrorContextToAttrs traceIf traceVal traceValFn
       traceXMLVal traceXMLValMarked traceSeq traceSeqN traceValSeq
-      traceValSeqN traceShowVal traceShowValMarked
-      showVal traceCall traceCall2 traceCall3 traceValIfNot runTests
-      testAllTrue strict traceCallXml attrNamesToStr;
+      traceValSeqFn traceValSeqN traceValSeqNFn traceShowVal
+      traceShowValMarked showVal traceCall traceCall2 traceCall3
+      traceValIfNot runTests testAllTrue traceCallXml attrNamesToStr;
     inherit (misc) maybeEnv defaultMergeArg defaultMerge foldArgs
       defaultOverridableDelayableArgs composedArgsAndFun
       maybeAttrNullable maybeAttr ifEnable checkFlag getValue
@@ -126,7 +132,7 @@ let
       closePropagation mapAttrsFlatten nvs setAttr setAttrMerge
       mergeAttrsWithFunc mergeAttrsConcatenateValues
       mergeAttrsNoOverride mergeAttrByFunc mergeAttrsByFuncDefaults
-      mergeAttrsByFuncDefaultsClean mergeAttrBy
-      prepareDerivationArgs nixType imap overridableDelayableArgs;
-  };
+      mergeAttrsByFuncDefaultsClean mergeAttrBy prepareDerivationArgs
+      nixType imap overridableDelayableArgs;
+  });
 in lib
diff --git a/lib/generators.nix b/lib/generators.nix
index 73017f2c6796..f5faf7007860 100644
--- a/lib/generators.nix
+++ b/lib/generators.nix
@@ -4,6 +4,12 @@
  * They all follow a similar interface:
  * generator { config-attrs } data
  *
+ * `config-attrs` are “holes” in the generators
+ * with sensible default implementations that
+ * can be overwritten. The default implementations
+ * are mostly generators themselves, called with
+ * their respective default values; they can be reused.
+ *
  * Tests can be found in ./tests.nix
  * Documentation in the manual, #sec-generators
  */
@@ -13,13 +19,37 @@ let
   libStr = lib.strings;
   libAttr = lib.attrsets;
 
-  flipMapAttrs = flip libAttr.mapAttrs;
-
   inherit (lib) isFunction;
 in
 
 rec {
 
+  ## -- HELPER FUNCTIONS & DEFAULTS --
+
+  /* Convert a value to a sensible default string representation.
+   * The builtin `toString` function has some strange defaults,
+   * suitable for bash scripts but not much else.
+   */
+  mkValueStringDefault = {}: v: with builtins;
+    let err = t: v: abort
+          ("generators.mkValueStringDefault: " +
+           "${t} not supported: ${toPretty {} v}");
+    in   if isInt      v then toString v
+    # we default to not quoting strings
+    else if isString   v then v
+    # isString returns "1", which is not a good default
+    else if true  ==   v then "true"
+    # here it returns to "", which is even less of a good default
+    else if false ==   v then "false"
+    else if null  ==   v then "null"
+    # if you have lists you probably want to replace this
+    else if isList     v then err "lists" v
+    # same as for lists, might want to replace
+    else if isAttrs    v then err "attrsets" v
+    else if isFunction v then err "functions" v
+    else err "this value is" (toString v);
+
+
   /* Generate a line of key k and value v, separated by
    * character sep. If sep appears in k, it is escaped.
    * Helper for synaxes with different separators.
@@ -30,11 +60,14 @@ rec {
    * > "f\:oo:bar"
    */
   mkKeyValueDefault = {
-    mkValueString ? toString
+    mkValueString ? mkValueStringDefault {}
   }: sep: k: v:
     "${libStr.escape [sep] k}${sep}${mkValueString v}";
 
 
+  ## -- FILE FORMAT GENERATORS --
+
+
   /* Generate a key-value-style config file from an attrset.
    *
    * mkKeyValue is the same as in toINI.
@@ -98,6 +131,7 @@ rec {
     */
   toYAML = {}@args: toJSON args;
 
+
   /* Pretty print a value, akin to `builtins.trace`.
     * Should probably be a builtin as well.
     */
@@ -107,17 +141,13 @@ rec {
        (This means fn is type Val -> String.) */
     allowPrettyValues ? false
   }@args: v: with builtins;
-    if      isInt      v then toString v
-    else if isBool     v then (if v == true then "true" else "false")
-    else if isString   v then "\"" + v + "\""
-    else if null ==    v then "null"
-    else if isFunction v then
-      let fna = lib.functionArgs v;
-          showFnas = concatStringsSep "," (libAttr.mapAttrsToList
-                       (name: hasDefVal: if hasDefVal then "(${name})" else name)
-                       fna);
-      in if fna == {}    then "<λ>"
-                         else "<λ:{${showFnas}}>"
+    let     isPath   = v: typeOf v == "path";
+    in if   isInt      v then toString v
+    else if isString   v then ''"${libStr.escape [''"''] v}"''
+    else if true  ==   v then "true"
+    else if false ==   v then "false"
+    else if null  ==   v then "null"
+    else if isPath     v then toString v
     else if isList     v then "[ "
         + libStr.concatMapStringsSep " " (toPretty args) v
       + " ]"
@@ -126,12 +156,71 @@ rec {
       if attrNames v == [ "__pretty" "val" ] && allowPrettyValues
          then v.__pretty v.val
       # TODO: there is probably a better representation?
-      else if v ? type && v.type == "derivation" then "<δ>"
+      else if v ? type && v.type == "derivation" then
+        "<δ:${v.name}>"
+        # "<δ:${concatStringsSep "," (builtins.attrNames v)}>"
       else "{ "
           + libStr.concatStringsSep " " (libAttr.mapAttrsToList
               (name: value:
                 "${toPretty args name} = ${toPretty args value};") v)
         + " }"
-    else abort "toPretty: should never happen (v = ${v})";
+    else if isFunction v then
+      let fna = lib.functionArgs v;
+          showFnas = concatStringsSep "," (libAttr.mapAttrsToList
+                       (name: hasDefVal: if hasDefVal then "(${name})" else name)
+                       fna);
+      in if fna == {}    then "<λ>"
+                         else "<λ:{${showFnas}}>"
+    else abort "generators.toPretty: should never happen (v = ${v})";
+
+  # PLIST handling
+  toPlist = {}: v: let
+    isFloat = builtins.isFloat or (x: false);
+    expr = ind: x:  with builtins;
+      if isNull x   then "" else
+      if isBool x   then bool ind x else
+      if isInt x    then int ind x else
+      if isString x then str ind x else
+      if isList x   then list ind x else
+      if isAttrs x  then attrs ind x else
+      if isFloat x  then float ind x else
+      abort "generators.toPlist: should never happen (v = ${v})";
+
+    literal = ind: x: ind + x;
+
+    bool = ind: x: literal ind  (if x then "<true/>" else "<false/>");
+    int = ind: x: literal ind "<integer>${toString x}</integer>";
+    str = ind: x: literal ind "<string>${x}</string>";
+    key = ind: x: literal ind "<key>${x}</key>";
+    float = ind: x: literal ind "<real>${toString x}</real>";
+
+    indent = ind: expr "\t${ind}";
+
+    item = ind: libStr.concatMapStringsSep "\n" (indent ind);
+
+    list = ind: x: libStr.concatStringsSep "\n" [
+      (literal ind "<array>")
+      (item ind x)
+      (literal ind "</array>")
+    ];
+
+    attrs = ind: x: libStr.concatStringsSep "\n" [
+      (literal ind "<dict>")
+      (attr ind x)
+      (literal ind "</dict>")
+    ];
+
+    attr = let attrFilter = name: value: name != "_module" && value != null;
+    in ind: x: libStr.concatStringsSep "\n" (lib.flatten (lib.mapAttrsToList
+      (name: value: lib.optional (attrFilter name value) [
+      (key "\t${ind}" name)
+      (expr "\t${ind}" value)
+    ]) x));
+
+  in ''<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+${expr "" v}
+</plist>'';
 
 }
diff --git a/lib/kernel.nix b/lib/kernel.nix
new file mode 100644
index 000000000000..45b33aea7b87
--- /dev/null
+++ b/lib/kernel.nix
@@ -0,0 +1,57 @@
+{ lib
+# we pass the kernel version here to keep a nice syntax `whenOlder "4.13"`
+# kernelVersion, e.g., config.boot.kernelPackages.version
+, version
+, mkValuePreprocess ? null
+}:
+
+with lib;
+rec {
+  # Common patterns
+  when        = cond: opt: if cond then opt else null;
+  whenAtLeast = ver: when (versionAtLeast version ver);
+  whenOlder   = ver: when (versionOlder version ver);
+  whenBetween = verLow: verHigh: when (versionAtLeast version verLow && versionOlder version verHigh);
+
+  # Keeping these around in case we decide to change this horrible implementation :)
+  option = x: if x == null then null else "?${x}";
+  yes    = "y";
+  no     = "n";
+  module = "m";
+
+  mkValue = val:
+  let
+    isNumber = c: elem c ["0" "1" "2" "3" "4" "5" "6" "7" "8" "9"];
+  in
+    if val == "" then "\"\""
+    else if val == yes || val == module || val == no then val
+    else if all isNumber (stringToCharacters val) then val
+    else if substring 0 2 val == "0x" then val
+    else val; # FIXME: fix quoting one day
+
+
+  # generate nix intermediate kernel config file of the form
+  #
+  #       VIRTIO_MMIO m
+  #       VIRTIO_BLK y
+  #       VIRTIO_CONSOLE n
+  #       NET_9P_VIRTIO? y
+  #
+  # Use mkValuePreprocess to preprocess option values, aka mark 'modules' as
+  # 'yes' or vice-versa
+  # Borrowed from copumpkin https://github.com/NixOS/nixpkgs/pull/12158
+  # returns a string, expr should be an attribute set
+  generateNixKConf = exprs: mkValuePreprocess:
+  let
+    mkConfigLine = key: rawval:
+    let
+      val = if builtins.isFunction mkValuePreprocess then mkValuePreprocess rawval else rawval;
+    in
+      if val == null
+        then ""
+        else if hasPrefix "?" val
+          then "${key}? ${mkValue (removePrefix "?" val)}\n"
+          else "${key} ${mkValue val}\n";
+    mkConf = cfg: concatStrings (mapAttrsToList mkConfigLine cfg);
+  in mkConf exprs;
+}
diff --git a/lib/licenses.nix b/lib/licenses.nix
index 03af13b990e2..c4db280645a4 100644
--- a/lib/licenses.nix
+++ b/lib/licenses.nix
@@ -99,6 +99,16 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec {
     fullName = ''BSD 4-clause "Original" or "Old" License'';
   };
 
+  bsl10 = {
+    fullName = "Business Source License 1.0";
+    url = https://mariadb.com/bsl10;
+  };
+
+  bsl11 = {
+    fullName = "Business Source License 1.1";
+    url = https://mariadb.com/bsl11;
+  };
+
   clArtistic = spdx {
     spdxId = "ClArtistic";
     fullName = "Clarified Artistic License";
@@ -112,26 +122,37 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec {
   cc-by-nc-sa-20 = spdx {
     spdxId = "CC-BY-NC-SA-2.0";
     fullName = "Creative Commons Attribution Non Commercial Share Alike 2.0";
+    free = false;
   };
 
   cc-by-nc-sa-25 = spdx {
     spdxId = "CC-BY-NC-SA-2.5";
     fullName = "Creative Commons Attribution Non Commercial Share Alike 2.5";
+    free = false;
   };
 
   cc-by-nc-sa-30 = spdx {
     spdxId = "CC-BY-NC-SA-3.0";
     fullName = "Creative Commons Attribution Non Commercial Share Alike 3.0";
+    free = false;
   };
 
   cc-by-nc-sa-40 = spdx {
     spdxId = "CC-BY-NC-SA-4.0";
     fullName = "Creative Commons Attribution Non Commercial Share Alike 4.0";
+    free = false;
+  };
+
+  cc-by-nc-40 = spdx {
+    spdxId = "CC-BY-NC-4.0";
+    fullName = "Creative Commons Attribution Non Commercial 4.0 International";
+    free = false;
   };
 
   cc-by-nd-30 = spdx {
     spdxId = "CC-BY-ND-3.0";
     fullName = "Creative Commons Attribution-No Derivative Works v3.00";
+    free = false;
   };
 
   cc-by-sa-25 = spdx {
@@ -179,11 +200,21 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec {
     fullName  = "CeCILL-C Free Software License Agreement";
   };
 
+  cpal10 = spdx {
+    spdxId = "CPAL-1.0";
+    fullName = "Common Public Attribution License 1.0";
+  };
+
   cpl10 = spdx {
     spdxId = "CPL-1.0";
     fullName = "Common Public License 1.0";
   };
 
+  curl = {
+    fullName = "MIT/X11 derivate";
+    url = "https://curl.haxx.se/docs/copyright.html";
+  };
+
   doc = spdx {
     spdxId = "DOC";
     fullName = "DOC License";
@@ -205,6 +236,12 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec {
     fullName = "Eiffel Forum License v2.0";
   };
 
+  elastic = {
+    fullName = "ELASTIC LICENSE";
+    url = https://github.com/elastic/elasticsearch/blob/master/licenses/ELASTIC-LICENSE.txt;
+    free = false;
+  };
+
   epl10 = spdx {
     spdxId = "EPL-1.0";
     fullName = "Eclipse Public License 1.0";
@@ -279,7 +316,7 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec {
 
   gpl2Oss = {
     fullName = "GNU General Public License version 2 only (with OSI approved licenses linking exception)";
-    url = http://www.mysql.com/about/legal/licensing/foss-exception;
+    url = https://www.mysql.com/about/legal/licensing/foss-exception;
   };
 
   gpl2Plus = spdx {
@@ -318,6 +355,11 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec {
     fullName = "Independent JPEG Group License";
   };
 
+  imagemagick = spdx {
+    fullName = "ImageMagick License";
+    spdxId = "imagemagick";
+  };
+
   inria-compcert = {
     fullName  = "INRIA Non-Commercial License Agreement for the CompCert verified compiler";
     url       = "http://compcert.inria.fr/doc/LICENSE";
@@ -440,6 +482,7 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec {
   msrla = {
     fullName  = "Microsoft Research License Agreement";
     url       = "http://research.microsoft.com/en-us/projects/pex/msr-la.txt";
+    free = false;
   };
 
   ncsa = spdx {
@@ -508,6 +551,11 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec {
     fullName = "Public Domain";
   };
 
+  purdueBsd = {
+    fullName = " Purdue BSD-Style License"; # also know as lsof license
+    url = https://enterprise.dejacode.com/licenses/public/purdue-bsd;
+  };
+
   qpl = spdx {
     spdxId = "QPL-1.0";
     fullName = "Q Public License 1.0";
@@ -580,6 +628,12 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec {
     fullName = "Vim License";
   };
 
+  virtualbox-puel = {
+    fullName = "Oracle VM VirtualBox Extension Pack Personal Use and Evaluation License (PUEL)";
+    url = "https://www.virtualbox.org/wiki/VirtualBox_PUEL";
+    free = false;
+  };
+
   vsl10 = spdx {
     spdxId = "VSL-1.0";
     fullName = "Vovida Software License v1.0";
@@ -610,6 +664,11 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec {
     fullName = "wxWindows Library Licence, Version 3.1";
   };
 
+  xfig = {
+    fullName = "xfig";
+    url = "http://mcj.sourceforge.net/authors.html#xfig";
+  };
+
   zlib = spdx {
     spdxId = "Zlib";
     fullName = "zlib License";
diff --git a/lib/lists.nix b/lib/lists.nix
index 424d2c57f556..9ecd8f220038 100644
--- a/lib/lists.nix
+++ b/lib/lists.nix
@@ -1,7 +1,9 @@
 # General list operations.
 { lib }:
 with lib.trivial;
-
+let
+  inherit (lib.strings) toInt;
+in
 rec {
 
   inherit (builtins) head tail length isList elemAt concatLists filter elem genList;
@@ -62,7 +64,6 @@ rec {
   */
   foldl = op: nul: list:
     let
-      len = length list;
       foldl' = n:
         if n == -1
         then nul
@@ -99,7 +100,7 @@ rec {
        concatMap (x: [x] ++ ["z"]) ["a" "b"]
        => [ "a" "z" "b" "z" ]
   */
-  concatMap = f: list: concatLists (map f list);
+  concatMap = builtins.concatMap or (f: list: concatLists (map f list));
 
   /* Flatten the argument into a single list; that is, nested lists are
      spliced into the top-level lists.
@@ -248,6 +249,42 @@ rec {
       else { right = t.right; wrong = [h] ++ t.wrong; }
     ) { right = []; wrong = []; });
 
+  /* Splits the elements of a list into many lists, using the return value of a predicate.
+     Predicate should return a string which becomes keys of attrset `groupBy' returns.
+
+     `groupBy'' allows to customise the combining function and initial value
+
+     Example:
+       groupBy (x: boolToString (x > 2)) [ 5 1 2 3 4 ]
+       => { true = [ 5 3 4 ]; false = [ 1 2 ]; }
+       groupBy (x: x.name) [ {name = "icewm"; script = "icewm &";}
+                             {name = "xfce";  script = "xfce4-session &";}
+                             {name = "icewm"; script = "icewmbg &";}
+                             {name = "mate";  script = "gnome-session &";}
+                           ]
+       => { icewm = [ { name = "icewm"; script = "icewm &"; }
+                      { name = "icewm"; script = "icewmbg &"; } ];
+            mate  = [ { name = "mate";  script = "gnome-session &"; } ];
+            xfce  = [ { name = "xfce";  script = "xfce4-session &"; } ];
+          }
+
+
+     groupBy' allows to customise the combining function and initial value
+
+     Example:
+       groupBy' builtins.add 0 (x: boolToString (x > 2)) [ 5 1 2 3 4 ]
+       => { true = 12; false = 3; }
+  */
+  groupBy' = op: nul: pred: lst:
+    foldl' (r: e:
+              let
+                key = pred e;
+              in
+                r // { ${key} = op (r.${key} or nul) e; }
+           ) {} lst;
+
+  groupBy = groupBy' (sum: e: sum ++ [e]) [];
+
   /* Merges two lists of the same size together. If the sizes aren't the same
      the merging stops at the shortest. How both lists are merged is defined
      by the first argument.
@@ -409,6 +446,25 @@ rec {
               then compareLists cmp (tail a) (tail b)
               else rel;
 
+  /* Sort list using "Natural sorting".
+     Numeric portions of strings are sorted in numeric order.
+
+     Example:
+       naturalSort ["disk11" "disk8" "disk100" "disk9"]
+       => ["disk8" "disk9" "disk11" "disk100"]
+       naturalSort ["10.46.133.149" "10.5.16.62" "10.54.16.25"]
+       => ["10.5.16.62" "10.46.133.149" "10.54.16.25"]
+       naturalSort ["v0.2" "v0.15" "v0.0.9"]
+       => [ "v0.0.9" "v0.2" "v0.15" ]
+  */
+  naturalSort = lst:
+    let
+      vectorise = s: map (x: if isList x then toInt (head x) else x) (builtins.split "(0|[1-9][0-9]*)" s);
+      prepared = map (x: [ (vectorise x) x ]) lst; # remember vectorised version for O(n) regex splits
+      less = a: b: (compareLists compare (head a) (head b)) < 0;
+    in
+      map (x: elemAt x 1) (sort less prepared);
+
   /* Return the first (at most) N elements of a list.
 
      Example:
@@ -453,7 +509,8 @@ rec {
        => 3
   */
   last = list:
-    assert list != []; elemAt list (length list - 1);
+    assert lib.assertMsg (list != []) "lists.last: list must not be empty!";
+    elemAt list (length list - 1);
 
   /* Return all elements but the last
 
@@ -461,7 +518,9 @@ rec {
        init [ 1 2 3 ]
        => [ 1 2 ]
   */
-  init = list: assert list != []; take (length list - 1) list;
+  init = list:
+    assert lib.assertMsg (list != []) "lists.init: list must not be empty!";
+    take (length list - 1) list;
 
 
   /* return the image of the cross product of some lists by a function
diff --git a/lib/maintainers-list.nix b/lib/maintainers-list.nix
deleted file mode 100644
index f397ee0ddb8c..000000000000
--- a/lib/maintainers-list.nix
+++ /dev/null
@@ -1,3955 +0,0 @@
-/* List of NixOS maintainers.
-
-    handle = {
-      name = "Real name";
-      email = "address@example.org";
-      github = "GithubUsername";
-    };
-
-  where `name` is your real name, `email` is your maintainer email
-  address and `github` is your GitHub handle (as it appears in the
-  URL of your profile page, `https://github.com/<userhandle>`).
- address
-  The only required fields are `name` and `email`.
-  More fields may be added in the future.
-
-  Please keep the list alphabetically sorted.
-  See `../maintainers/scripts/check-maintainer-github-handles.sh`
-  for an example on how to work with this data.
-  */
-{
-  Adjective-Object = {
-    email = "mhuan13@gmail.com";
-    github = "Adjective-Object";
-    name = "Maxwell Huang-Hobbs";
-  };
-  AndersonTorres = {
-    email = "torres.anderson.85@gmail.com";
-    github = "AndersonTorres";
-    name = "Anderson Torres";
-  };
-  Baughn = {
-    email = "sveina@gmail.com";
-    github = "Baughn";
-    name = "Svein Ove Aas";
-  };
-  ChengCat = {
-    email = "yu@cheng.cat";
-    github = "ChengCat";
-    name = "Yucheng Zhang";
-  };
-  CrystalGamma = {
-    email = "nixos@crystalgamma.de";
-    github = "CrystalGamma";
-    name = "Jona Stubbe";
-  };
-  DamienCassou = {
-    email = "damien@cassou.me";
-    github = "DamienCassou";
-    name = "Damien Cassou";
-  };
-  DerGuteMoritz = {
-    email = "moritz@twoticketsplease.de";
-    github = "DerGuteMoritz";
-    name = "Moritz Heidkamp";
-  };
-  DerTim1 = {
-    email = "tim.digel@active-group.de";
-    github = "DerTim1";
-    name = "Tim Digel";
-  };
-  DmitryTsygankov = {
-    email = "dmitry.tsygankov@gmail.com";
-    github = "DmitryTsygankov";
-    name = "Dmitry Tsygankov";
-  };
-  FireyFly = {
-    email = "nix@firefly.nu";
-    github = "FireyFly";
-    name = "Jonas Höglund";
-  };
-  Gonzih = {
-    email = "gonzih@gmail.com";
-    github = "Gonzih";
-    name = "Max Gonzih";
-  };
-  Jo = {
-    email = "0x4A6F@shackspace.de";
-    name = "Joachim Ernst";
-  };
-  KibaFox = {
-    email = "kiba.fox@foxypossibilities.com";
-    github = "KibaFox";
-    name = "Kiba Fox";
-  };
-  MP2E = {
-    email = "MP2E@archlinux.us";
-    github = "MP2E";
-    name = "Cray Elliott";
-  };
-  MostAwesomeDude = {
-    email = "cds@corbinsimpson.com";
-    github = "MostAwesomeDude";
-    name = "Corbin Simpson";
-  };
-  Nate-Devv = {
-    email = "natedevv@gmail.com";
-    name = "Nathan Moore";
-  };
-  NikolaMandic = {
-    email = "nikola@mandic.email";
-    github = "NikolaMandic";
-    name = "Ratko Mladic";
-  };
-  Phlogistique = {
-    email = "noe.rubinstein@gmail.com";
-    github = "Phlogistique";
-    name = "Noé Rubinstein";
-  };
-  Profpatsch = {
-    email = "mail@profpatsch.de";
-    github = "Profpatsch";
-    name = "Profpatsch";
-  };
-  SShrike = {
-    email = "severen@shrike.me";
-    github = "severen";
-    name = "Severen Redwood";
-  };
-  SeanZicari = {
-    email = "sean.zicari@gmail.com";
-    github = "SeanZicari";
-    name = "Sean Zicari";
-  };
-  StijnDW = {
-    email = "stekke@airmail.cc";
-    github = "StijnDW";
-    name = "Stijn DW";
-  };
-  StillerHarpo = {
-    email = "florianengel39@gmail.com";
-    github = "StillerHarpo";
-    name = "Florian Engel";
-  };
-  SuprDewd = {
-    email = "suprdewd@gmail.com";
-    github = "SuprDewd";
-    name = "Bjarki Ágúst Guðmundsson";
-  };
-  TealG = {
-    email = "~@Teal.Gr";
-    github = "TealG";
-    name = "Teal Gaure";
-  };
-  ThomasMader = {
-    email = "thomas.mader@gmail.com";
-    github = "ThomasMader";
-    name = "Thomas Mader";
-  };
-  Zimmi48 = {
-    email = "theo.zimmermann@univ-paris-diderot.fr";
-    github = "Zimmi48";
-    name = "Théo Zimmermann";
-  };
-  a1russell = {
-    email = "adamlr6+pub@gmail.com";
-    github = "a1russell";
-    name = "Adam Russell";
-  };
-  aaronschif = {
-    email = "aaronschif@gmail.com";
-    github = "aaronschif";
-    name = "Aaron Schif";
-  };
-  abaldeau = {
-    email = "andreas@baldeau.net";
-    github = "baldo";
-    name = "Andreas Baldeau";
-  };
-  abbradar = {
-    email = "ab@fmap.me";
-    github = "abbradar";
-    name = "Nikolay Amiantov";
-  };
-  abigailbuccaneer = {
-    email = "abigailbuccaneer@gmail.com";
-    github = "abigailbuccaneer";
-    name = "Abigail Bunyan";
-  };
-  aboseley = {
-    email = "adam.boseley@gmail.com";
-    github = "aboseley";
-    name = "Adam Boseley";
-  };
-  abuibrahim = {
-    email = "ruslan@babayev.com";
-    github = "abuibrahim";
-    name = "Ruslan Babayev";
-  };
-  acowley = {
-    email = "acowley@gmail.com";
-    github = "acowley";
-    name = "Anthony Cowley";
-  };
-  adelbertc = {
-    email = "adelbertc@gmail.com";
-    github = "adelbertc";
-    name = "Adelbert Chang";
-  };
-  adev = {
-    email = "adev@adev.name";
-    github = "adevress";
-    name = "Adrien Devresse";
-  };
-  adisbladis = {
-    email = "adis@blad.is";
-    github = "adisbladis";
-    name = "Adam Hose";
-  };
-  adnelson = {
-    email = "ithinkican@gmail.com";
-    github = "adnelson";
-    name = "Allen Nelson";
-  };
-  adolfogc = {
-    email = "adolfo.garcia.cr@gmail.com";
-    github = "adolfogc";
-    name = "Adolfo E. García Castro";
-  };
-  aespinosa = {
-    email = "allan.espinosa@outlook.com";
-    github = "aespinosa";
-    name = "Allan Espinosa";
-  };
-  aflatter = {
-    email = "flatter@fastmail.fm";
-    github = "aflatter";
-    name = "Alexander Flatter";
-  };
-  afldcr = {
-    email = "alex@fldcr.com";
-    github = "afldcr";
-    name = "James Alexander Feldman-Crough";
-  };
-  aforemny = {
-    email = "alexanderforemny@googlemail.com";
-    github = "aforemny";
-    name = "Alexander Foremny";
-  };
-  afranchuk = {
-    email = "alex.franchuk@gmail.com";
-    github = "afranchuk";
-    name = "Alex Franchuk";
-  };
-  aherrmann = {
-    email = "andreash87@gmx.ch";
-    github = "aherrmann";
-    name = "Andreas Herrmann";
-  };
-  ahmedtd = {
-    email = "ahmed.taahir@gmail.com";
-    github = "ahmedtd";
-    name = "Taahir Ahmed";
-  };
-  aij = {
-    email = "aij+git@mrph.org";
-    github = "aij";
-    name = "Ivan Jager";
-  };
-  ajgrf = {
-    email = "a@ajgrf.com";
-    github = "ajgrf";
-    name = "Alex Griffin";
-  };
-  ak = {
-    email = "ak@formalprivacy.com";
-    github = "alexanderkjeldaas";
-    name = "Alexander Kjeldaas";
-  };
-  akaWolf = {
-    email = "akawolf0@gmail.com";
-    github = "akaWolf";
-    name = "Artjom Vejsel";
-  };
-  akc = {
-    email = "akc@akc.is";
-    github = "akc";
-    name = "Anders Claesson";
-  };
-  alexvorobiev = {
-    email = "alexander.vorobiev@gmail.com";
-    github = "alexvorobiev";
-    name = "Alex Vorobiev";
-  };
-  algorith = {
-    email = "dries_van_daele@telenet.be";
-    name = "Dries Van Daele";
-  };
-  alibabzo = {
-    email = "alistair.bill@gmail.com";
-    github = "alibabzo";
-    name = "Alistair Bill";
-  };
-  all = {
-    email = "nix-commits@lists.science.uu.nl";
-    name = "Nix Committers";
-  };
-  alunduil = {
-    email = "alunduil@alunduil.com";
-    github = "alunduil";
-    name = "Alex Brandt";
-  };
-  ambrop72 = {
-    email = "ambrop7@gmail.com";
-    github = "ambrop72";
-    name = "Ambroz Bizjak";
-  };
-  amiddelk = {
-    email = "amiddelk@gmail.com";
-    github = "amiddelk";
-    name = "Arie Middelkoop";
-  };
-  amiloradovsky = {
-    email = "miloradovsky@gmail.com";
-    github = "amiloradovsky";
-    name = "Andrew Miloradovsky";
-  };
-  amorsillo = {
-    email = "andrew.morsillo@gmail.com";
-    github = "AndrewMorsillo";
-    name = "Andrew Morsillo";
-  };
-  anderspapitto = {
-    email = "anderspapitto@gmail.com";
-    github = "anderspapitto";
-    name = "Anders Papitto";
-  };
-  andir = {
-    email = "andreas@rammhold.de";
-    github = "andir";
-    name = "Andreas Rammhold";
-  };
-  andres = {
-    email = "ksnixos@andres-loeh.de";
-    github = "kosmikus";
-    name = "Andres Loeh";
-  };
-  andrestylianos = {
-    email = "andre.stylianos@gmail.com";
-    github = "andrestylianos";
-    name = "Andre S. Ramos";
-  };
-  andrew-d = {
-    email = "andrew@du.nham.ca";
-    github = "andrew-d";
-    name = "Andrew Dunham";
-  };
-  andrewrk = {
-    email = "superjoe30@gmail.com";
-    github = "andrewrk";
-    name = "Andrew Kelley";
-  };
-  andsild = {
-    email = "andsild@gmail.com";
-    github = "andsild";
-    name = "Anders Sildnes";
-  };
-  aneeshusa = {
-    email = "aneeshusa@gmail.com";
-    github = "aneeshusa";
-    name = "Aneesh Agrawal";
-  };
-  ankhers = {
-    email = "justin.k.wood@gmail.com";
-    github = "ankhers";
-    name = "Justin Wood";
-  };
-  antono = {
-    email = "self@antono.info";
-    github = "antono";
-    name = "Antono Vasiljev";
-  };
-  antonxy = {
-    email = "anton.schirg@posteo.de";
-    github = "antonxy";
-    name = "Anton Schirg";
-  };
-  apeschar = {
-    email = "albert@peschar.net";
-    github = "apeschar";
-    name = "Albert Peschar";
-  };
-  apeyroux = {
-    email = "alex@px.io";
-    github = "apeyroux";
-    name = "Alexandre Peyroux";
-  };
-  arcadio = {
-    email = "arc@well.ox.ac.uk";
-    github = "arcadio";
-    name = "Arcadio Rubio García";
-  };
-  ardumont = {
-    email = "eniotna.t@gmail.com";
-    github = "ardumont";
-    name = "Antoine R. Dumont";
-  };
-  aristid = {
-    email = "aristidb@gmail.com";
-    github = "aristidb";
-    name = "Aristid Breitkreuz";
-  };
-  arobyn = {
-    email = "shados@shados.net";
-    github = "shados";
-    name = "Alexei Robyn";
-  };
-  artuuge = {
-    email = "artuuge@gmail.com";
-    github = "artuuge";
-    name = "Artur E. Ruuge";
-  };
-  ashalkhakov = {
-    email = "artyom.shalkhakov@gmail.com";
-    github = "ashalkhakov";
-    name = "Artyom Shalkhakov";
-  };
-  ashgillman = {
-    email = "gillmanash@gmail.com";
-    github = "ashgillman";
-    name = "Ashley Gillman";
-  };
-  aske = {
-    email = "aske@fmap.me";
-    github = "aske";
-    name = "Kirill Boltaev";
-  };
-  asppsa = {
-    email = "asppsa@gmail.com";
-    github = "asppsa";
-    name = "Alastair Pharo";
-  };
-  astsmtl = {
-    email = "astsmtl@yandex.ru";
-    github = "astsmtl";
-    name = "Alexander Tsamutali";
-  };
-  asymmetric = {
-    email = "lorenzo@mailbox.org";
-    github = "asymmetric";
-    name = "Lorenzo Manacorda";
-  };
-  aszlig = {
-    email = "aszlig@nix.build";
-    github = "aszlig";
-    name = "aszlig";
-  };
-  auntie = {
-    email = "auntieNeo@gmail.com";
-    github = "auntie";
-    name = "Jonathan Glines";
-  };
-  avnik = {
-    email = "avn@avnik.info";
-    github = "avnik";
-    name = "Alexander V. Nikolaev";
-  };
-  aycanirican = {
-    email = "iricanaycan@gmail.com";
-    github = "aycanirican";
-    name = "Aycan iRiCAN";
-  };
-  babariviere = {
-    email = "babariviere@protonmail.com";
-    github = "babariviere";
-    name = "babariviere";
-  };
-  bachp = {
-    email = "pascal.bach@nextrem.ch";
-    github = "bachp";
-    name = "Pascal Bach";
-  };
-  backuitist = {
-    email = null;
-    github = "backuitist";
-    name = "Bruno Bieth";
-  };
-  badi = {
-    email = "abdulwahidc@gmail.com";
-    github = "badi";
-    name = "Badi' Abdul-Wahid";
-  };
-  balajisivaraman = {
-    email = "sivaraman.balaji@gmail.com";
-    name = "Balaji Sivaraman";
-  };
-  barrucadu = {
-    email = "mike@barrucadu.co.uk";
-    github = "barrucadu";
-    name = "Michael Walker";
-  };
-  basvandijk = {
-    email = "v.dijk.bas@gmail.com";
-    github = "basvandijk";
-    name = "Bas van Dijk";
-  };
-  bcarrell = {
-    email = "brandoncarrell@gmail.com";
-    github = "bcarrell";
-    name = "Brandon Carrell";
-  };
-  bcdarwin = {
-    email = "bcdarwin@gmail.com";
-    github = "bcdarwin";
-    name = "Ben Darwin";
-  };
-  bdimcheff = {
-    email = "brandon@dimcheff.com";
-    github = "bdimcheff";
-    name = "Brandon Dimcheff";
-  };
-  bendlas = {
-    email = "herwig@bendlas.net";
-    github = "bendlas";
-    name = "Herwig Hochleitner";
-  };
-  benley = {
-    email = "benley@gmail.com";
-    github = "benley";
-    name = "Benjamin Staffin";
-  };
-  bennofs = {
-    email = "benno.fuenfstueck@gmail.com";
-    github = "bennofs";
-    name = "Benno Fünfstück";
-  };
-  benwbooth = {
-    email = "benwbooth@gmail.com";
-    github = "benwbooth";
-    name = "Ben Booth";
-  };
-  berce = {
-    email = "bert.moens@gmail.com";
-    github = "berce";
-    name = "Bert Moens";
-  };
-  berdario = {
-    email = "berdario@gmail.com";
-    github = "berdario";
-    name = "Dario Bertini";
-  };
-  bergey = {
-    email = "bergey@teallabs.org";
-    github = "bergey";
-    name = "Daniel Bergey";
-  };
-  bhipple = {
-    email = "bhipple@protonmail.com";
-    github = "bhipple";
-    name = "Benjamin Hipple";
-  };
-  binarin = {
-    email = "binarin@binarin.ru";
-    github = "binarin";
-    name = "Alexey Lebedeff";
-  };
-  bjg = {
-    email = "bjg@gnu.org";
-    github = "civodul";
-    name = "Brian Gough";
-  };
-  bjornfor = {
-    email = "bjorn.forsman@gmail.com";
-    github = "bjornfor";
-    name = "Bjørn Forsman";
-  };
-  bluescreen303 = {
-    email = "mathijs@bluescreen303.nl";
-    github = "bluescreen303";
-    name = "Mathijs Kwik";
-  };
-  bobakker = {
-    email = "bobakk3r@gmail.com";
-    github = "bobakker";
-    name = "Bo Bakker";
-  };
-  bobvanderlinden = {
-    email = "bobvanderlinden@gmail.com";
-    github = "bobvanderlinden";
-    name = "Bob van der Linden";
-  };
-  bodil = {
-    email = "nix@bodil.org";
-    github = "bodil";
-    name = "Bodil Stokke";
-  };
-  boothead = {
-    email = "ben@perurbis.com";
-    github = "boothead";
-    name = "Ben Ford";
-  };
-  bosu = {
-    email = "boriss@gmail.com";
-    github = "bosu";
-    name = "Boris Sukholitko";
-  };
-  bradediger = {
-    email = "brad@bradediger.com";
-    github = "bradediger";
-    name = "Brad Ediger";
-  };
-  bramd = {
-    email = "bram@bramd.nl";
-    github = "bramd";
-    name = "Bram Duvigneau";
-  };
-  bstrik = {
-    email = "dutchman55@gmx.com";
-    github = "bstrik";
-    name = "Berno Strik";
-  };
-  bugworm = {
-    email = "bugworm@zoho.com";
-    github = "bugworm";
-    name = "Roman Gerasimenko";
-  };
-  bzizou = {
-    email = "Bruno@bzizou.net";
-    github = "bzizou";
-    name = "Bruno Bzeznik";
-  };
-  c0bw3b = {
-    email = "c0bw3b@gmail.com";
-    github = "c0bw3b";
-    name = "Renaud";
-  };
-  c0dehero = {
-    email = "codehero@nerdpol.ch";
-    name = "CodeHero";
-  };
-  calbrecht = {
-    email = "christian.albrecht@mayflower.de";
-    github = "calbrecht";
-    name = "Christian Albrecht";
-  };
-  calrama = {
-    email = "moritz@ucworks.org";
-    github = "MoritzMaxeiner";
-    name = "Moritz Maxeiner";
-  };
-  calvertvl = {
-    email = "calvertvl@gmail.com";
-    github = "calvertvl";
-    name = "Victor Calvert";
-  };
-  campadrenalin = {
-    email = "campadrenalin@gmail.com";
-    github = "campadrenalin";
-    name = "Philip Horger";
-  };
-  canndrew = {
-    email = "shum@canndrew.org";
-    github = "canndrew";
-    name = "Andrew Cann";
-  };
-  carlsverre = {
-    email = "accounts@carlsverre.com";
-    github = "carlsverre";
-    name = "Carl Sverre";
-  };
-  casey = {
-    email = "casey@rodarmor.net";
-    github = "casey";
-    name = "Casey Rodarmor";
-  };
-  catern = {
-    email = "sbaugh@catern.com";
-    github = "catern";
-    name = "Spencer Baugh";
-  };
-  caugner = {
-    email = "nixos@caugner.de";
-    github = "caugner";
-    name = "Claas Augner";
-  };
-  cdepillabout = {
-    email = "cdep.illabout@gmail.com";
-    github = "cdepillabout";
-    name = "Dennis Gosnell";
-  };
-  cfouche = {
-    email = "chaddai.fouche@gmail.com";
-    github = "Chaddai";
-    name = "Chaddaï Fouché";
-  };
-  changlinli = {
-    email = "mail@changlinli.com";
-    github = "changlinli";
-    name = "Changlin Li";
-  };
-  chaoflow = {
-    email = "flo@chaoflow.net";
-    github = "chaoflow";
-    name = "Florian Friesdorf";
-  };
-  chattered = {
-    email = "me@philscotted.com";
-    name = "Phil Scott";
-  };
-  chiiruno = {
-    email = "okinan@protonmail.com";
-    github = "chiiruno";
-    name = "Okina Matara";
-  };
-  choochootrain = {
-    email = "hurshal@imap.cc";
-    github = "choochootrain";
-    name = "Hurshal Patel";
-  };
-  chpatrick = {
-    email = "chpatrick@gmail.com";
-    github = "chpatrick";
-    name = "Patrick Chilton";
-  };
-  chreekat = {
-    email = "b@chreekat.net";
-    github = "chreekat";
-    name = "Bryan Richter";
-  };
-  chris-martin = {
-    email = "ch.martin@gmail.com";
-    github = "chris-martin";
-    name = "Chris Martin";
-  };
-  chrisjefferson = {
-    email = "chris@bubblescope.net";
-    github = "chrisjefferson";
-    name = "Christopher Jefferson";
-  };
-  chrisrosset = {
-    email = "chris@rosset.org.uk";
-    github = "chrisrosset";
-    name = "Christopher Rosset";
-  };
-  christopherpoole = {
-    email = "mail@christopherpoole.net";
-    github = "christopherpoole";
-    name = "Christopher Mark Poole";
-  };
-  ciil = {
-    email = "simon@lackerbauer.com";
-    github = "ciil";
-    name = "Simon Lackerbauer";
-  };
-  ck3d = {
-    email = "ck3d@gmx.de";
-    github = "ck3d";
-    name = "Christian Kögler";
-  };
-  ckampka = {
-    email = "christian@kampka.net";
-    github = "kampka";
-    name = "Christian Kampka";
-  };
-  ckauhaus = {
-    email = "kc@flyingcircus.io";
-    github = "ckauhaus";
-    name = "Christian Kauhaus";
-  };
-  cko = {
-    email = "christine.koppelt@gmail.com";
-    github = "cko";
-    name = "Christine Koppelt";
-  };
-  cleverca22 = {
-    email = "cleverca22@gmail.com";
-    github = "cleverca22";
-    name = "Michael Bishop";
-  };
-  cmcdragonkai = {
-    email = "roger.qiu@matrix.ai";
-    github = "cmcdragonkai";
-    name = "Roger Qiu";
-  };
-  cmfwyp = {
-    email = "cmfwyp@riseup.net";
-    github = "cmfwyp";
-    name = "cmfwyp";
-  };
-  cobbal = {
-    email = "andrew.cobb@gmail.com";
-    github = "cobbal";
-    name = "Andrew Cobb";
-  };
-  coconnor = {
-    email = "coreyoconnor@gmail.com";
-    github = "coreyoconnor";
-    name = "Corey O'Connor";
-  };
-  codsl = {
-    email = "codsl@riseup.net";
-    github = "codsl";
-    name = "codsl";
-  };
-  codyopel = {
-    email = "codyopel@gmail.com";
-    github = "codyopel";
-    name = "Cody Opel";
-  };
-  colemickens = {
-    email = "cole.mickens@gmail.com";
-    github = "colemickens";
-    name = "Cole Mickens";
-  };
-  colescott = {
-    email = "colescottsf@gmail.com";
-    github = "colescott";
-    name = "Cole Scott";
-  };
-  copumpkin = {
-    email = "pumpkingod@gmail.com";
-    github = "copumpkin";
-    name = "Dan Peebles";
-  };
-  corngood = {
-    email = "corngood@gmail.com";
-    github = "corngood";
-    name = "David McFarland";
-  };
-  coroa = {
-    email = "jonas@chaoflow.net";
-    github = "coroa";
-    name = "Jonas Hörsch";
-  };
-  couchemar = {
-    email = "couchemar@yandex.ru";
-    github = "couchemar";
-    name = "Andrey Pavlov";
-  };
-  cpages = {
-    email = "page@ruiec.cat";
-    github = "cpages";
-    name = "Carles Pagès";
-  };
-  cransom = {
-    email = "cransom@hubns.net";
-    github = "cransom";
-    name = "Casey Ransom";
-  };
-  cryptix = {
-    email = "cryptix@riseup.net";
-    github = "cryptix";
-    name = "Henry Bubert";
-  };
-  csingley = {
-    email = "csingley@gmail.com";
-    github = "csingley";
-    name = "Christopher Singley";
-  };
-  cstrahan = {
-    email = "charles@cstrahan.com";
-    github = "cstrahan";
-    name = "Charles Strahan";
-  };
-  cwoac = {
-    email = "oliver@codersoffortune.net";
-    github = "cwoac";
-    name = "Oliver Matthews";
-  };
-  danbst = {
-    email = "abcz2.uprola@gmail.com";
-    github = "danbst";
-    name = "Danylo Hlynskyi";
-  };
-  dancek = {
-    email = "hannu.hartikainen@gmail.com";
-    github = "dancek";
-    name = "Hannu Hartikainen";
-  };
-  danharaj = {
-    email = "dan@obsidian.systems";
-    github = "danharaj";
-    name = "Dan Haraj";
-  };
-  danielfullmer = {
-    email = "danielrf12@gmail.com";
-    github = "danielfullmer";
-    name = "Daniel Fullmer";
-  };
-  dasuxullebt = {
-    email = "christoph.senjak@googlemail.com";
-    name = "Christoph-Simon Senjak";
-  };
-  david50407 = {
-    email = "me@davy.tw";
-    github = "david50407";
-    name = "David Kuo";
-  };
-  davidak = {
-    email = "post@davidak.de";
-    github = "davidak";
-    name = "David Kleuker";
-  };
-  davidrusu = {
-    email = "davidrusu.me@gmail.com";
-    github = "davidrusu";
-    name = "David Rusu";
-  };
-  davorb = {
-    email = "davor@davor.se";
-    github = "davorb";
-    name = "Davor Babic";
-  };
-  dbohdan = {
-    email = "danyil.bohdan@gmail.com";
-    github = "dbohdan";
-    name = "Danyil Bohdan";
-  };
-  dbrock = {
-    email = "daniel@brockman.se";
-    github = "dbrock";
-    name = "Daniel Brockman";
-  };
-  deepfire = {
-    email = "_deepfire@feelingofgreen.ru";
-    github = "deepfire";
-    name = "Kosyrev Serge";
-  };
-  demin-dmitriy = {
-    email = "demindf@gmail.com";
-    github = "demin-dmitriy";
-    name = "Dmitriy Demin";
-  };
-  derchris = {
-    email = "derchris@me.com";
-    github = "derchrisuk";
-    name = "Christian Gerbrandt";
-  };
-  dermetfan = {
-    email = "serverkorken@gmail.com";
-    github = "dermetfan";
-    name = "Robin Stumm";
-  };
-  desiderius = {
-    email = "didier@devroye.name";
-    github = "desiderius";
-    name = "Didier J. Devroye";
-  };
-  devhell = {
-    email = "\"^\"@regexmail.net";
-    github = "devhell";
-    name = "devhell";
-  };
-  dezgeg = {
-    email = "tuomas.tynkkynen@iki.fi";
-    github = "dezgeg";
-    name = "Tuomas Tynkkynen";
-  };
-  dfordivam = {
-    email = "dfordivam+nixpkgs@gmail.com";
-    github = "dfordivam";
-    name = "Divam";
-  };
-  dfoxfranke = {
-    email = "dfoxfranke@gmail.com";
-    github = "dfoxfranke";
-    name = "Daniel Fox Franke";
-  };
-  dgonyeo = {
-    email = "derek@gonyeo.com";
-    github = "dgonyeo";
-    name = "Derek Gonyeo";
-  };
-  dipinhora = {
-    email = "dipinhora+github@gmail.com";
-    github = "dipinhora";
-    name = "Dipin Hora";
-  };
-  disassembler = {
-    email = "disasm@gmail.com";
-    github = "disassembler";
-    name = "Samuel Leathers";
-  };
-  dizfer = {
-    email = "david@izquierdofernandez.com";
-    github = "dizfer";
-    name = "David Izquierdo";
-  };
-  dmalikov = {
-    email = "malikov.d.y@gmail.com";
-    github = "dmalikov";
-    name = "Dmitry Malikov";
-  };
-  dmjio = {
-    email = "djohnson.m@gmail.com";
-    github = "dmjio";
-    name = "David Johnson";
-  };
-  dochang = {
-    email = "dochang@gmail.com";
-    github = "dochang";
-    name = "Desmond O. Chang";
-  };
-  domenkozar = {
-    email = "domen@dev.si";
-    github = "domenkozar";
-    name = "Domen Kozar";
-  };
-  dotlambda = {
-    email = "rschuetz17@gmail.com";
-    github = "dotlambda";
-    name = "Robert Schütz";
-  };
-  doublec = {
-    email = "chris.double@double.co.nz";
-    github = "doublec";
-    name = "Chris Double";
-  };
-  dpaetzel = {
-    email = "david.a.paetzel@gmail.com";
-    github = "dpaetzel";
-    name = "David Pätzel";
-  };
-  dpflug = {
-    email = "david@pflug.email";
-    github = "dpflug";
-    name = "David Pflug";
-  };
-  drets = {
-    email = "dmitryrets@gmail.com";
-    github = "drets";
-    name = "Dmytro Rets";
-  };
-  drewkett = {
-    email = "burkett.andrew@gmail.com";
-    name = "Andrew Burkett";
-  };
-  dsferruzza = {
-    email = "david.sferruzza@gmail.com";
-    github = "dsferruzza";
-    name = "David Sferruzza";
-  };
-  dtzWill = {
-    email = "nix@wdtz.org";
-    github = "dtzWill";
-    name = "Will Dietz";
-  };
-  dupgit = {
-    email = "olivier.delhomme@free.fr";
-    github = "dupgit";
-    name = "Olivier Delhomme";
-  };
-  dywedir = {
-    email = "dywedir@protonmail.ch";
-    github = "dywedir";
-    name = "Vladyslav M.";
-  };
-  dzabraev = {
-    email = "dzabraew@gmail.com";
-    github = "dzabraev";
-    name = "Maksim Dzabraev";
-  };
-  e-user = {
-    email = "nixos@sodosopa.io";
-    github = "e-user";
-    name = "Alexander Kahl";
-  };
-  earldouglas = {
-    email = "james@earldouglas.com";
-    github = "earldouglas";
-    name = "James Earl Douglas";
-  };
-  earvstedt = {
-    email = "erik.arvstedt@gmail.com";
-    github = "erikarvstedt";
-    name = "Erik Arvstedt";
-  };
-  ebzzry = {
-    email = "ebzzry@ebzzry.io";
-    github = "ebzzry";
-    name = "Rommel Martinez";
-  };
-  edanaher = {
-    email = "nixos@edanaher.net";
-    github = "edanaher";
-    name = "Evan Danaher";
-  };
-  edef = {
-    email = "edef@edef.eu";
-    github = "edef1c";
-    name = "edef";
-  };
-  ederoyd46 = {
-    email = "matt@ederoyd.co.uk";
-    github = "ederoyd46";
-    name = "Matthew Brown";
-  };
-  eduarrrd = {
-    email = "e.bachmakov@gmail.com";
-    github = "eduarrrd";
-    name = "Eduard Bachmakov";
-  };
-  edwtjo = {
-    email = "ed@cflags.cc";
-    github = "edwtjo";
-    name = "Edward Tjörnhammar";
-  };
-  eelco = {
-    email = "eelco.dolstra@logicblox.com";
-    github = "edolstra";
-    name = "Eelco Dolstra";
-  };
-  ehegnes = {
-    email = "eric.hegnes@gmail.com";
-    github = "ehegnes";
-    name = "Eric Hegnes";
-  };
-  ehmry = {
-    email = "emery@vfemail.net";
-    name = "Emery Hemingway";
-  };
-  eikek = {
-    email = "eike.kettner@posteo.de";
-    github = "eikek";
-    name = "Eike Kettner";
-  };
-  ekleog = {
-    email = "leo@gaspard.io";
-    github = "ekleog";
-    name = "Leo Gaspard";
-  };
-  elasticdog = {
-    email = "aaron@elasticdog.com";
-    github = "elasticdog";
-    name = "Aaron Bull Schaefer";
-  };
-  eleanor = {
-    email = "dejan@proteansec.com";
-    github = "proteansec";
-    name = "Dejan Lukan";
-  };
-  elijahcaine = {
-    email = "elijahcainemv@gmail.com";
-    github = "pop";
-    name = "Elijah Caine";
-  };
-  elitak = {
-    email = "elitak@gmail.com";
-    github = "elitak";
-    name = "Eric Litak";
-  };
-  ellis = {
-    email = "nixos@ellisw.net";
-    github = "ellis";
-    name = "Ellis Whitehead";
-  };
-  enzime = {
-    email = "enzime@users.noreply.github.com";
-    github = "enzime";
-    name = "Michael Hoang";
-  };
-  eperuffo = {
-    email = "info@emanueleperuffo.com";
-    github = "emanueleperuffo";
-    name = "Emanuele Peruffo";
-  };
-  epitrochoid = {
-    email = "mpcervin@uncg.edu";
-    name = "Mabry Cervin";
-  };
-  eqyiel = {
-    email = "r@rkm.id.au";
-    github = "eqyiel";
-    name = "Ruben Maher";
-  };
-  ericbmerritt = {
-    email = "eric@afiniate.com";
-    github = "ericbmerritt";
-    name = "Eric Merritt";
-  };
-  erosennin = {
-    email = "ag@sologoc.com";
-    github = "erosennin";
-    name = "Andrey Golovizin";
-  };
-  ericsagnes = {
-    email = "eric.sagnes@gmail.com";
-    github = "ericsagnes";
-    name = "Eric Sagnes";
-  };
-  ericson2314 = {
-    email = "John.Ericson@Obsidian.Systems";
-    github = "ericson2314";
-    name = "John Ericson";
-  };
-  erictapen = {
-    email = "justin.humm@posteo.de";
-    github = "erictapen";
-    name = "Justin Humm";
-  };
-  erikryb = {
-    email = "erik.rybakken@math.ntnu.no";
-    github = "erikryb";
-    name = "Erik Rybakken";
-  };
-  ertes = {
-    email = "esz@posteo.de";
-    github = "ertes";
-    name = "Ertugrul Söylemez";
-  };
-  ethercrow = {
-    email = "ethercrow@gmail.com";
-    github = "ethercrow";
-    name = "Dmitry Ivanov";
-  };
-  etu = {
-    email = "elis@hirwing.se";
-    github = "etu";
-    name = "Elis Hirwing";
-  };
-  exfalso = {
-    email = "0slemi0@gmail.com";
-    github = "exfalso";
-    name = "Andras Slemmer";
-  };
-  exi = {
-    email = "nixos@reckling.org";
-    github = "exi";
-    name = "Reno Reckling";
-  };
-  exlevan = {
-    email = "exlevan@gmail.com";
-    github = "exlevan";
-    name = "Alexey Levan";
-  };
-  expipiplus1 = {
-    email = "nix@monoid.al";
-    github = "expipiplus1";
-    name = "Joe Hermaszewski";
-  };
-  f-breidenstein = {
-    email = "mail@felixbreidenstein.de";
-    github = "f-breidenstein";
-    name = "Felix Breidenstein";
-  };
-  fadenb = {
-    email = "tristan.helmich+nixos@gmail.com";
-    github = "fadenb";
-    name = "Tristan Helmich";
-  };
-  falsifian = {
-    email = "james.cook@utoronto.ca";
-    github = "falsifian";
-    name = "James Cook";
-  };
-  fare = {
-    email = "fahree@gmail.com";
-    github = "fare";
-    name = "Francois-Rene Rideau";
-  };
-  fgaz = {
-    email = "francygazz@gmail.com";
-    github = "fgaz";
-    name = "Francesco Gazzetta";
-  };
-  flokli = {
-    email = "flokli@flokli.de";
-    github = "flokli";
-    name = "Florian Klink";
-  };
-  florianjacob = {
-    email = "projects+nixos@florianjacob.de";
-    github = "florianjacob";
-    name = "Florian Jacob";
-  };
-  flosse = {
-    email = "mail@markus-kohlhase.de";
-    github = "flosse";
-    name = "Markus Kohlhase";
-  };
-  fluffynukeit = {
-    email = "dan@fluffynukeit.com";
-    github = "fluffynukeit";
-    name = "Daniel Austin";
-  };
-  fmthoma = {
-    email = "f.m.thoma@googlemail.com";
-    github = "fmthoma";
-    name = "Franz Thoma";
-  };
-  forkk = {
-    email = "forkk@forkk.net";
-    github = "forkk";
-    name = "Andrew Okin";
-  };
-  fornever = {
-    email = "friedrich@fornever.me";
-    github = "fornever";
-    name = "Friedrich von Never";
-  };
-  fpletz = {
-    email = "fpletz@fnordicwalking.de";
-    github = "fpletz";
-    name = "Franz Pletz";
-  };
-  fps = {
-    email = "mista.tapas@gmx.net";
-    github = "fps";
-    name = "Florian Paul Schmidt";
-  };
-  fridh = {
-    email = "fridh@fridh.nl";
-    github = "fridh";
-    name = "Frederik Rietdijk";
-  };
-  frlan = {
-    email = "frank@frank.uvena.de";
-    github = "frlan";
-    name = "Frank Lanitz";
-  };
-  fro_ozen = {
-    email = "fro_ozen@gmx.de";
-    github = "froozen";
-    name = "fro_ozen";
-  };
-  ftrvxmtrx = {
-    email = "ftrvxmtrx@gmail.com";
-    github = "ftrvxmtrx";
-    name = "Siarhei Zirukin";
-  };
-  funfunctor = {
-    email = "eocallaghan@alterapraxis.com";
-    name = "Edward O'Callaghan";
-  };
-  fuuzetsu = {
-    email = "fuuzetsu@fuuzetsu.co.uk";
-    github = "fuuzetsu";
-    name = "Mateusz Kowalczyk";
-  };
-  fuzzy-id = {
-    email = "hacking+nixos@babibo.de";
-    name = "Thomas Bach";
-  };
-  fxfactorial = {
-    email = "edgar.factorial@gmail.com";
-    github = "fxfactorial";
-    name = "Edgar Aroutiounian";
-  };
-  gabesoft = {
-    email = "gabesoft@gmail.com";
-    github = "gabesoft";
-    name = "Gabriel Adomnicai";
-  };
-  gal_bolle = {
-    email = "florent.becker@ens-lyon.org";
-    github = "FlorentBecker";
-    name = "Florent Becker";
-  };
-  garbas = {
-    email = "rok@garbas.si";
-    github = "garbas";
-    name = "Rok Garbas";
-  };
-  garrison = {
-    email = "jim@garrison.cc";
-    github = "garrison";
-    name = "Jim Garrison";
-  };
-  gavin = {
-    email = "gavin@praxeology.co.uk";
-    github = "gavinrogers";
-    name = "Gavin Rogers";
-  };
-  gebner = {
-    email = "gebner@gebner.org";
-    github = "gebner";
-    name = "Gabriel Ebner";
-  };
-  geistesk = {
-    email = "post@0x21.biz";
-    github = "geistesk";
-    name = "Alvar Penning";
-  };
-  genesis = {
-    email = "ronan@aimao.org";
-    github = "bignaux";
-    name = "Ronan Bignaux";
-  };
-  georgewhewell = {
-    email = "georgerw@gmail.com";
-    github = "georgewhewell";
-    name = "George Whewell";
-  };
-  gilligan = {
-    email = "tobias.pflug@gmail.com";
-    github = "gilligan";
-    name = "Tobias Pflug";
-  };
-  giogadi = {
-    email = "lgtorres42@gmail.com";
-    github = "giogadi";
-    name = "Luis G. Torres";
-  };
-  gleber = {
-    email = "gleber.p@gmail.com";
-    github = "gleber";
-    name = "Gleb Peregud";
-  };
-  glenns = {
-    email = "glenn.searby@gmail.com";
-    github = "glenns";
-    name = "Glenn Searby";
-  };
-  globin = {
-    email = "mail@glob.in";
-    github = "globin";
-    name = "Robin Gloster";
-  };
-  gnidorah = {
-    email = "yourbestfriend@opmbx.org";
-    github = "gnidorah";
-    name = "Alex Ivanov";
-  };
-  goibhniu = {
-    email = "cillian.deroiste@gmail.com";
-    github = "cillianderoiste";
-    name = "Cillian de Róiste";
-  };
-  goodrone = {
-    email = "goodrone@gmail.com";
-    github = "goodrone";
-    name = "Andrew Trachenko";
-  };
-  gpyh = {
-    email = "yacine.hmito@gmail.com";
-    github = "yacinehmito";
-    name = "Yacine Hmito";
-  };
-  grahamc = {
-    email = "graham@grahamc.com";
-    github = "grahamc";
-    name = "Graham Christensen";
-  };
-  grburst = {
-    email = "grburst@openmailbox.org";
-    github = "grburst";
-    name = "Julius Elias";
-  };
-  gridaphobe = {
-    email = "eric@seidel.io";
-    github = "gridaphobe";
-    name = "Eric Seidel";
-  };
-  guibert = {
-    email = "david.guibert@gmail.com";
-    github = "dguibert";
-    name = "David Guibert";
-  };
-  guibou = {
-    email = "guillaum.bouchard@gmail.com";
-    github = "guibou";
-    name = "Guillaume Bouchard";
-  };
-  guillaumekoenig = {
-    email = "guillaume.edward.koenig@gmail.com";
-    github = "guillaumekoenig";
-    name = "Guillaume Koenig";
-  };
-  guyonvarch = {
-    email = "joris@guyonvarch.me";
-    github = "guyonvarch";
-    name = "Joris Guyonvarch";
-  };
-  hakuch = {
-    email = "hakuch@gmail.com";
-    github = "hakuch";
-    name = "Jesse Haber-Kucharsky";
-  };
-  hamhut1066 = {
-    email = "github@hamhut1066.com";
-    github = "hamhut1066";
-    name = "Hamish Hutchings";
-  };
-  havvy = {
-    email = "ryan.havvy@gmail.com";
-    github = "havvy";
-    name = "Ryan Scheel";
-  };
-  hbunke = {
-    email = "bunke.hendrik@gmail.com";
-    github = "hbunke";
-    name = "Hendrik Bunke";
-  };
-  hce = {
-    email = "hc@hcesperer.org";
-    github = "hce";
-    name = "Hans-Christian Esperer";
-  };
-  hectorj = {
-    email = "hector.jusforgues+nixos@gmail.com";
-    github = "hectorj";
-    name = "Hector Jusforgues";
-  };
-  hedning = {
-    email = "torhedinbronner@gmail.com";
-    github = "hedning";
-    name = "Tor Hedin Brønner";
-  };
-  heel = {
-    email = "parizhskiy@gmail.com";
-    github = "heel";
-    name = "Sergii Paryzhskyi";
-  };
-  henrytill = {
-    email = "henrytill@gmail.com";
-    github = "henrytill";
-    name = "Henry Till";
-  };
-  hhm = {
-    email = "heehooman+nixpkgs@gmail.com";
-    github = "hhm0";
-    name = "hhm";
-  };
-  hinton = {
-    email = "t@larkery.com";
-    name = "Tom Hinton";
-  };
-  hodapp = {
-    email = "hodapp87@gmail.com";
-    github = "Hodapp87";
-    name = "Chris Hodapp";
-  };
-  hrdinka = {
-    email = "c.nix@hrdinka.at";
-    github = "hrdinka";
-    name = "Christoph Hrdinka";
-  };
-  htr = {
-    email = "hugo@linux.com";
-    github = "htr";
-    name = "Hugo Tavares Reis";
-  };
-  hyphon81 = {
-    email = "zero812n@gmail.com";
-    github = "hyphon81";
-    name = "Masato Yonekawa";
-  };
-  iand675 = {
-    email = "ian@iankduncan.com";
-    github = "iand675";
-    name = "Ian Duncan";
-  };
-  ianwookim = {
-    email = "ianwookim@gmail.com";
-    github = "wavewave";
-    name = "Ian-Woo Kim";
-  };
-  iblech = {
-    email = "iblech@speicherleck.de";
-    github = "iblech";
-    name = "Ingo Blechschmidt";
-  };
-  igsha = {
-    email = "igor.sharonov@gmail.com";
-    github = "igsha";
-    name = "Igor Sharonov";
-  };
-  ikervagyok = {
-    email = "ikervagyok@gmail.com";
-    github = "ikervagyok";
-    name = "Balázs Lengyel";
-  };
-  ilya-kolpakov = {
-    email = "ilya.kolpakov@gmail.com";
-    github = "ilya-kolpakov";
-    name = "Ilya Kolpakov";
-  };
-  infinisil = {
-    email = "infinisil@icloud.com";
-    github = "infinisil";
-    name = "Silvan Mosberger";
-  };
-  ironpinguin = {
-    email = "michele@catalano.de";
-    github = "ironpinguin";
-    name = "Michele Catalano";
-  };
-  ivan-tkatchev = {
-    email = "tkatchev@gmail.com";
-    name = "Ivan Tkatchev";
-  };
-  ixmatus = {
-    email = "parnell@digitalmentat.com";
-    github = "ixmatus";
-    name = "Parnell Springmeyer";
-  };
-  ixxie = {
-    email = "matan@fluxcraft.net";
-    github = "ixxie";
-    name = "Matan Bendix Shenhav";
-  };
-  izorkin = {
-    email = "Izorkin@gmail.com";
-    github = "izorkin";
-    name = "Yurii Izorkin";
-  };
-  j-keck = {
-    email = "jhyphenkeck@gmail.com";
-    github = "j-keck";
-    name = "Jürgen Keck";
-  };
-  jagajaga = {
-    email = "ars.seroka@gmail.com";
-    github = "jagajaga";
-    name = "Arseniy Seroka";
-  };
-  jammerful = {
-    email = "jammerful@gmail.com";
-    github = "jammerful";
-    name = "jammerful";
-  };
-  jansol = {
-    email = "jan.solanti@paivola.fi";
-    github = "jansol";
-    name = "Jan Solanti";
-  };
-  javaguirre = {
-    email = "contacto@javaguirre.net";
-    github = "javaguirre";
-    name = "Javier Aguirre";
-  };
-  jb55 = {
-    email = "jb55@jb55.com";
-    github = "jb55";
-    name = "William Casarin";
-  };
-  jbedo = {
-    email = "cu@cua0.org";
-    github = "jbedo";
-    name = "Justin Bedő";
-  };
-  jcumming = {
-    email = "jack@mudshark.org";
-    name = "Jack Cummings";
-  };
-  jdagilliland = {
-    email = "jdagilliland@gmail.com";
-    github = "jdagilliland";
-    name = "Jason Gilliland";
-  };
-  jefdaj = {
-    email = "jefdaj@gmail.com";
-    github = "jefdaj";
-    name = "Jeffrey David Johnson";
-  };
-  jensbin = {
-    email = "jensbin@protonmail.com";
-    github = "jensbin";
-    name = "Jens Binkert";
-  };
-  jerith666 = {
-    email = "github@matt.mchenryfamily.org";
-    github = "jerith666";
-    name = "Matt McHenry";
-  };
-  jfb = {
-    email = "james@yamtime.com";
-    github = "tftio";
-    name = "James Felix Black";
-  };
-  jfrankenau = {
-    email = "johannes@frankenau.net";
-    github = "jfrankenau";
-    name = "Johannes Frankenau";
-  };
-  jgeerds = {
-    email = "jascha@jgeerds.name";
-    github = "jgeerds";
-    name = "Jascha Geerds";
-  };
-  jgertm = {
-    email = "jger.tm@gmail.com";
-    github = "jgertm";
-    name = "Tim Jaeger";
-  };
-  jgillich = {
-    email = "jakob@gillich.me";
-    github = "jgillich";
-    name = "Jakob Gillich";
-  };
-  jhhuh = {
-    email = "jhhuh.note@gmail.com";
-    github = "jhhuh";
-    name = "Ji-Haeng Huh";
-  };
-  jirkamarsik = {
-    email = "jiri.marsik89@gmail.com";
-    github = "jirkamarsik";
-    name = "Jirka Marsik";
-  };
-  jlesquembre = {
-    email = "jl@lafuente.me";
-    github = "jlesquembre";
-    name = "José Luis Lafuente";
-  };
-  jluttine = {
-    email = "jaakko.luttinen@iki.fi";
-    github = "jluttine";
-    name = "Jaakko Luttinen";
-  };
-  joachifm = {
-    email = "joachifm@fastmail.fm";
-    github = "joachifm";
-    name = "Joachim Fasting";
-  };
-  joamaki = {
-    email = "joamaki@gmail.com";
-    github = "joamaki";
-    name = "Jussi Maki";
-  };
-  joelmo = {
-    email = "joel.moberg@gmail.com";
-    github = "joelmo";
-    name = "Joel Moberg";
-  };
-  joelteon = {
-    email = "me@joelt.io";
-    name = "Joel Taylor";
-  };
-  johbo = {
-    email = "johannes@bornhold.name";
-    github = "johbo";
-    name = "Johannes Bornhold";
-  };
-  johnazoidberg = {
-    email = "git@danielschaefer.me";
-    github = "johnazoidberg";
-    name = "Daniel Schäfer";
-  };
-  johnmh = {
-    email = "johnmh@openblox.org";
-    github = "johnmh";
-    name = "John M. Harris, Jr.";
-  };
-  johnramsden = {
-    email = "johnramsden@riseup.net";
-    github = "johnramsden";
-    name = "John Ramsden";
-  };
-  joko = {
-    email = "ioannis.koutras@gmail.com";
-    github = "jokogr";
-    name = "Ioannis Koutras";
-  };
-  jonafato = {
-    email = "jon@jonafato.com";
-    github = "jonafato";
-    name = "Jon Banafato";
-  };
-  joncojonathan = {
-    email = "joncojonathan@gmail.com";
-    github = "joncojonathan";
-    name = "Jonathan Haddock";
-  };
-  jpdoyle = {
-    email = "joethedoyle@gmail.com";
-    github = "jpdoyle";
-    name = "Joe Doyle";
-  };
-  jpierre03 = {
-    email = "nix@prunetwork.fr";
-    github = "jpierre03";
-    name = "Jean-Pierre PRUNARET";
-  };
-  jpotier = {
-    email = "jpo.contributes.to.nixos@marvid.fr";
-    github = "jpotier";
-    name = "Martin Potier";
-  };
-  jraygauthier = {
-    email = "jraygauthier@gmail.com";
-    github = "jraygauthier";
-    name = "Raymond Gauthier";
-  };
-  jtojnar = {
-    email = "jtojnar@gmail.com";
-    github = "jtojnar";
-    name = "Jan Tojnar";
-  };
-  juliendehos = {
-    email = "dehos@lisic.univ-littoral.fr";
-    github = "juliendehos";
-    name = "Julien Dehos";
-  };
-  jwiegley = {
-    email = "johnw@newartisans.com";
-    github = "jwiegley";
-    name = "John Wiegley";
-  };
-  jwilberding = {
-    email = "jwilberding@afiniate.com";
-    name = "Jordan Wilberding";
-  };
-  jyp = {
-    email = "jeanphilippe.bernardy@gmail.com";
-    github = "jyp";
-    name = "Jean-Philippe Bernardy";
-  };
-  jzellner = {
-    email = "jeffz@eml.cc";
-    github = "sofuture";
-    name = "Jeff Zellner";
-  };
-  kaiha = {
-    email = "kai.harries@gmail.com";
-    github = "kaiha";
-    name = "Kai Harries";
-  };
-  kamilchm = {
-    email = "kamil.chm@gmail.com";
-    github = "kamilchm";
-    name = "Kamil Chmielewski";
-  };
-  kampfschlaefer = {
-    email = "arnold@arnoldarts.de";
-    github = "kampfschlaefer";
-    name = "Arnold Krille";
-  };
-  karolchmist = {
-    email = "info+nix@chmist.com";
-    name = "karolchmist";
-  };
-  kentjames = {
-    email = "jameschristopherkent@gmail.com";
-    github = "kentjames";
-    name = "James Kent";
-  };
-  kevincox = {
-    email = "kevincox@kevincox.ca";
-    github = "kevincox";
-    name = "Kevin Cox";
-  };
-  khumba = {
-    email = "bog@khumba.net";
-    github = "khumba";
-    name = "Bryan Gardiner";
-  };
-  kierdavis = {
-    email = "kierdavis@gmail.com";
-    github = "kierdavis";
-    name = "Kier Davis";
-  };
-  kiloreux = {
-    email = "kiloreux@gmail.com";
-    github = "kiloreux";
-    name = "Kiloreux Emperex";
-  };
-  kini = {
-    email = "keshav.kini@gmail.com";
-    github = "kini";
-    name = "Keshav Kini";
-  };
-  kkallio = {
-    email = "tierpluspluslists@gmail.com";
-    name = "Karn Kallio";
-  };
-  knedlsepp = {
-    email = "josef.kemetmueller@gmail.com";
-    github = "knedlsepp";
-    name = "Josef Kemetmüller";
-  };
-  konimex = {
-    email = "herdiansyah@netc.eu";
-    github = "konimex";
-    name = "Muhammad Herdiansyah";
-  };
-  koral = {
-    email = "koral@mailoo.org";
-    github = "k0ral";
-    name = "Koral";
-  };
-  kovirobi = {
-    email = "kovirobi@gmail.com";
-    github = "kovirobi";
-    name = "Kovacsics Robert";
-  };
-  kquick = {
-    email = "quick@sparq.org";
-    github = "kquick";
-    name = "Kevin Quick";
-  };
-  kragniz = {
-    email = "louis@kragniz.eu";
-    github = "kragniz";
-    name = "Louis Taylor";
-  };
-  kristoff3r = {
-    email = "k.soeholm@gmail.com";
-    github = "kristoff3r";
-    name = "Kristoffer Søholm";
-  };
-  ktosiek = {
-    email = "tomasz.kontusz@gmail.com";
-    github = "ktosiek";
-    name = "Tomasz Kontusz";
-  };
-  kuznero = {
-    email = "roman@kuznero.com";
-    github = "kuznero";
-    name = "Roman Kuznetsov";
-  };
-  lasandell = {
-    email = "lasandell@gmail.com";
-    github = "lasandell";
-    name = "Luke Sandell";
-  };
-  lassulus = {
-    email = "lassulus@gmail.com";
-    github = "Lassulus";
-    name = "Lassulus";
-  };
-  layus = {
-    email = "layus.on@gmail.com";
-    github = "layus";
-    name = "Guillaume Maudoux";
-  };
-  lblasc = {
-    email = "lblasc@znode.net";
-    github = "lblasc";
-    name = "Luka Blaskovic";
-  };
-  ldesgoui = {
-    email = "ldesgoui@gmail.com";
-    github = "ldesgoui";
-    name = "Lucas Desgouilles";
-  };
-  league = {
-    email = "league@contrapunctus.net";
-    github = "league";
-    name = "Christopher League";
-  };
-  lebastr = {
-    email = "lebastr@gmail.com";
-    github = "lebastr";
-    name = "Alexander Lebedev";
-  };
-  ledif = {
-    email = "refuse@gmail.com";
-    github = "ledif";
-    name = "Adam Fidel";
-  };
-  leemachin = {
-    email = "me@mrl.ee";
-    github = "leemachin";
-    name = "Lee Machin";
-  };
-  leenaars = {
-    email = "ml.software@leenaa.rs";
-    github = "leenaars";
-    name = "Michiel Leenaars";
-  };
-  leonardoce = {
-    email = "leonardo.cecchi@gmail.com";
-    github = "leonardoce";
-    name = "Leonardo Cecchi";
-  };
-  lejonet = {
-    email = "daniel@kuehn.se";
-    github = "lejonet";
-    name = "Daniel Kuehn";
-  };
-  lethalman = {
-    email = "lucabru@src.gnome.org";
-    github = "lethalman";
-    name = "Luca Bruno";
-  };
-  lewo = {
-    email = "lewo@abesis.fr";
-    github = "nlewo";
-    name = "Antoine Eiche";
-  };
-  lheckemann = {
-    email = "git@sphalerite.org";
-    github = "lheckemann";
-    name = "Linus Heckemann";
-  };
-  lhvwb = {
-    email = "nathaniel.baxter@gmail.com";
-    github = "nathanielbaxter";
-    name = "Nathaniel Baxter";
-  };
-  lihop = {
-    email = "nixos@leroy.geek.nz";
-    github = "lihop";
-    name = "Leroy Hopson";
-  };
-  limeytexan = {
-    email = "limeytexan@gmail.com";
-    github = "limeytexan";
-    name = "Michael Brantley";
-  };
-  linquize = {
-    email = "linquize@yahoo.com.hk";
-    github = "linquize";
-    name = "Linquize";
-  };
-  linus = {
-    email = "linusarver@gmail.com";
-    github = "listx";
-    name = "Linus Arver";
-  };
-  lluchs = {
-    email = "lukas.werling@gmail.com";
-    github = "lluchs";
-    name = "Lukas Werling";
-  };
-  lnl7 = {
-    email = "daiderd@gmail.com";
-    github = "lnl7";
-    name = "Daiderd Jordan";
-  };
-  lo1tuma = {
-    email = "schreck.mathias@gmail.com";
-    github = "lo1tuma";
-    name = "Mathias Schreck";
-  };
-  loskutov = {
-    email = "ignat.loskutov@gmail.com";
-    github = "loskutov";
-    name = "Ignat Loskutov";
-  };
-  lovek323 = {
-    email = "jason@oconal.id.au";
-    github = "lovek323";
-    name = "Jason O'Conal";
-  };
-  lowfatcomputing = {
-    email = "andreas.wagner@lowfatcomputing.org";
-    github = "lowfatcomputing";
-    name = "Andreas Wagner";
-  };
-  lschuermann = {
-    email = "leon.git@is.currently.online";
-    github = "lschuermann";
-    name = "Leon Schuermann";
-  };
-  lsix = {
-    email = "lsix@lancelotsix.com";
-    github = "lsix";
-    name = "Lancelot SIX";
-  };
-  ltavard = {
-    email = "laure.tavard@univ-grenoble-alpes.fr";
-    github = "ltavard";
-    name = "Laure Tavard";
-  };
-  lucas8 = {
-    email = "luc.linux@mailoo.org";
-    github = "lucas8";
-    name = "Luc Chabassier";
-  };
-  ludo = {
-    email = "ludo@gnu.org";
-    github = "civodul";
-    name = "Ludovic Courtès";
-  };
-  lufia = {
-    email = "lufia@lufia.org";
-    github = "lufia";
-    name = "Kyohei Kadota";
-  };
-  luispedro = {
-    email = "luis@luispedro.org";
-    github = "luispedro";
-    name = "Luis Pedro Coelho";
-  };
-  lukego = {
-    email = "luke@snabb.co";
-    github = "lukego";
-    name = "Luke Gorrie";
-  };
-  luz = {
-    email = "luz666@daum.net";
-    github = "Luz";
-    name = "Luz";
-  };
-  lw = {
-    email = "lw@fmap.me";
-    github = "lolwat97";
-    name = "Sergey Sofeychuk";
-  };
-  lyt = {
-    email = "wheatdoge@gmail.com";
-    name = "Tim Liou";
-  };
-  m3tti = {
-    email = "mathaeus.peter.sander@gmail.com";
-    name = "Mathaeus Sander";
-  };
-  ma27 = {
-    email = "maximilian@mbosch.me";
-    github = "ma27";
-    name = "Maximilian Bosch";
-  };
-  madjar = {
-    email = "georges.dubus@compiletoi.net";
-    github = "madjar";
-    name = "Georges Dubus";
-  };
-  magnetophon = {
-    email = "bart@magnetophon.nl";
-    github = "magnetophon";
-    name = "Bart Brouns";
-  };
-  mahe = {
-    email = "matthias.mh.herrmann@gmail.com";
-    github = "2chilled";
-    name = "Matthias Herrmann";
-  };
-  makefu = {
-    email = "makefu@syntax-fehler.de";
-    github = "makefu";
-    name = "Felix Richter";
-  };
-  malyn = {
-    email = "malyn@strangeGizmo.com";
-    github = "malyn";
-    name = "Michael Alyn Miller";
-  };
-  manveru = {
-    email = "m.fellinger@gmail.com";
-    github = "manveru";
-    name = "Michael Fellinger";
-  };
-  marcweber = {
-    email = "marco-oweber@gmx.de";
-    github = "marcweber";
-    name = "Marc Weber";
-  };
-  markWot = {
-    email = "markus@wotringer.de";
-    name = "Markus Wotringer";
-  };
-  markus1189 = {
-    email = "markus1189@gmail.com";
-    github = "markus1189";
-    name = "Markus Hauck";
-  };
-  markuskowa = {
-    email = "markus.kowalewski@gmail.com";
-    github = "markuskowa";
-    name = "Markus Kowalewski";
-  };
-  martijnvermaat = {
-    email = "martijn@vermaat.name";
-    github = "martijnvermaat";
-    name = "Martijn Vermaat";
-  };
-  martingms = {
-    email = "martin@mg.am";
-    github = "martingms";
-    name = "Martin Gammelsæter";
-  };
-  matejc = {
-    email = "cotman.matej@gmail.com";
-    github = "matejc";
-    name = "Matej Cotman";
-  };
-  mathnerd314 = {
-    email = "mathnerd314.gph+hs@gmail.com";
-    github = "mathnerd314";
-    name = "Mathnerd314";
-  };
-  matthewbauer = {
-    email = "mjbauer95@gmail.com";
-    github = "matthewbauer";
-    name = "Matthew Bauer";
-  };
-  matthiasbeyer = {
-    email = "mail@beyermatthias.de";
-    github = "matthiasbeyer";
-    name = "Matthias Beyer";
-  };
-  maurer = {
-    email = "matthew.r.maurer+nix@gmail.com";
-    github = "maurer";
-    name = "Matthew Maurer";
-  };
-  mbakke = {
-    email = "mbakke@fastmail.com";
-    github = "mbakke";
-    name = "Marius Bakke";
-  };
-  mbbx6spp = {
-    email = "me@susanpotter.net";
-    github = "mbbx6spp";
-    name = "Susan Potter";
-  };
-  mbe = {
-    email = "brandonedens@gmail.com";
-    github = "brandonedens";
-    name = "Brandon Edens";
-  };
-  mbode = {
-    email = "maxbode@gmail.com";
-    github = "mbode";
-    name = "Maximilian Bode";
-  };
-  mboes = {
-    email = "mboes@tweag.net";
-    github = "mboes";
-    name = "Mathieu Boespflug";
-  };
-  mbrgm = {
-    email = "marius@yeai.de";
-    github = "mbrgm";
-    name = "Marius Bergmann";
-  };
-  mcmtroffaes = {
-    email = "matthias.troffaes@gmail.com";
-    github = "mcmtroffaes";
-    name = "Matthias C. M. Troffaes";
-  };
-  mdaiter = {
-    email = "mdaiter8121@gmail.com";
-    github = "mdaiter";
-    name = "Matthew S. Daiter";
-  };
-  meditans = {
-    email = "meditans@gmail.com";
-    github = "meditans";
-    name = "Carlo Nucera";
-  };
-  mehandes = {
-    email = "niewskici@gmail.com";
-    github = "mehandes";
-    name = "Matt Deming";
-  };
-  meisternu = {
-    email = "meister@krutt.org";
-    github = "meisternu";
-    name = "Matt Miemiec";
-  };
-  metabar = {
-    email = "softs@metabarcoding.org";
-    name = "Celine Mercier";
-  };
-  mgdelacroix = {
-    email = "mgdelacroix@gmail.com";
-    github = "mgdelacroix";
-    name = "Miguel de la Cruz";
-  };
-  mgttlinger = {
-    email = "megoettlinger@gmail.com";
-    github = "mgttlinger";
-    name = "Merlin Göttlinger";
-  };
-  mguentner = {
-    email = "code@klandest.in";
-    github = "mguentner";
-    name = "Maximilian Güntner";
-  };
-  mic92 = {
-    email = "joerg@thalheim.io";
-    github = "mic92";
-    name = "Jörg Thalheim";
-  };
-  michaelpj = {
-    email = "michaelpj@gmail.com";
-    github = "michaelpj";
-    name = "Michael Peyton Jones";
-  };
-  michalrus = {
-    email = "m@michalrus.com";
-    github = "michalrus";
-    name = "Michal Rus";
-  };
-  michelk = {
-    email = "michel@kuhlmanns.info";
-    github = "michelk";
-    name = "Michel Kuhlmann";
-  };
-  mickours = {
-    email = "mickours@gmail.com<";
-    github = "mickours";
-    name = "Michael Mercier";
-  };
-  midchildan = {
-    email = "midchildan+nix@gmail.com";
-    github = "midchildan";
-    name = "midchildan";
-  };
-  mikefaille = {
-    email = "michael@faille.io";
-    github = "mikefaille";
-    name = "Michaël Faille";
-  };
-  mikoim = {
-    email = "ek@esh.ink";
-    github = "mikoim";
-    name = "Eshin Kunishima";
-  };
-  miltador = {
-    email = "miltador@yandex.ua";
-    name = "Vasiliy Solovey";
-  };
-  mimadrid = {
-    email = "mimadrid@ucm.es";
-    github = "mimadrid";
-    name = "Miguel Madrid";
-  };
-  mirdhyn = {
-    email = "mirdhyn@gmail.com";
-    github = "mirdhyn";
-    name = "Merlin Gaillard";
-  };
-  mirrexagon = {
-    email = "mirrexagon@mirrexagon.com";
-    github = "mirrexagon";
-    name = "Andrew Abbott";
-  };
-  mjanczyk = {
-    email = "m@dragonvr.pl";
-    github = "mjanczyk";
-    name = "Marcin Janczyk";
-  };
-  mjp = {
-    email = "mike@mythik.co.uk";
-    github = "MikePlayle";
-    name = "Mike Playle";
-  };
-  mkg = {
-    email = "mkg@vt.edu";
-    github = "mkgvt";
-    name = "Mark K Gardner";
-  };
-  mlieberman85 = {
-    email = "mlieberman85@gmail.com";
-    github = "mlieberman85";
-    name = "Michael Lieberman";
-  };
-  mmahut = {
-    email = "marek.mahut@gmail.com";
-    github = "mmahut";
-    name = "Marek Mahut";
-  };
-  moaxcp = {
-    email = "moaxcp@gmail.com";
-    github = "moaxcp";
-    name = "John Mercier";
-  };
-  modulistic = {
-    email = "modulistic@gmail.com";
-    github = "modulistic";
-    name = "Pablo Costa";
-  };
-  mog = {
-    email = "mog-lists@rldn.net";
-    github = "mogorman";
-    name = "Matthew O'Gorman";
-  };
-  montag451 = {
-    email = "montag451@laposte.net";
-    github = "montag451";
-    name = "montag451";
-  };
-  moosingin3space = {
-    email = "moosingin3space@gmail.com";
-    github = "moosingin3space";
-    name = "Nathan Moos";
-  };
-  moredread = {
-    email = "code@apb.name";
-    github = "moredread";
-    name = "André-Patrick Bubel";
-  };
-  moretea = {
-    email = "maarten@moretea.nl";
-    github = "moretea";
-    name = "Maarten Hoogendoorn";
-  };
-  mounium = {
-    email = "muoniurn@gmail.com";
-    github = "mounium";
-    name = "Katona László";
-  };
-  mpcsh = {
-    email = "m@mpc.sh";
-    github = "mpcsh";
-    name = "Mark Cohen";
-  };
-  mpickering = {
-    email = "matthewtpickering@gmail.com";
-    github = "mpickering";
-    name = "Matthew Pickering";
-  };
-  mpscholten = {
-    email = "marc@mpscholten.de";
-    github = "mpscholten";
-    name = "Marc Scholten";
-  };
-  mpsyco = {
-    email = "fr.st-amour@gmail.com";
-    github = "fstamour";
-    name = "Francis St-Amour";
-  };
-  mrVanDalo = {
-    email = "contact@ingolf-wagner.de";
-    github = "mrVanDalo";
-    name = "Ingolf Wanger";
-  };
-  msackman = {
-    email = "matthew@wellquite.org";
-    name = "Matthew Sackman";
-  };
-  mschristiansen = {
-    email = "mikkel@rheosystems.com";
-    github = "mschristiansen";
-    name = "Mikkel Christiansen";
-  };
-  mstarzyk = {
-    email = "mstarzyk@gmail.com";
-    github = "mstarzyk";
-    name = "Maciek Starzyk";
-  };
-  msteen = {
-    email = "emailmatthijs@gmail.com";
-    github = "msteen";
-    name = "Matthijs Steen";
-  };
-  mt-caret = {
-    email = "mtakeda.enigsol@gmail.com";
-    github = "mt-caret";
-    name = "Masayuki Takeda";
-  };
-  mtreskin = {
-    email = "zerthurd@gmail.com";
-    github = "Zert";
-    name = "Max Treskin";
-  };
-  mudri = {
-    email = "lamudri@gmail.com";
-    github = "laMudri";
-    name = "James Wood";
-  };
-  muflax = {
-    email = "mail@muflax.com";
-    github = "muflax";
-    name = "Stefan Dorn";
-  };
-  myrl = {
-    email = "myrl.0xf@gmail.com";
-    github = "myrl";
-    name = "Myrl Hex";
-  };
-  nadrieril = {
-    email = "nadrieril@gmail.com";
-    github = "nadrieril";
-    name = "Nadrieril Feneanar";
-  };
-  namore = {
-    email = "namor@hemio.de";
-    github = "namore";
-    name = "Roman Naumann";
-  };
-  nand0p = {
-    email = "nando@hex7.com";
-    github = "nand0p";
-    name = "Fernando Jose Pando";
-  };
-  nathan-gs = {
-    email = "nathan@nathan.gs";
-    github = "nathan-gs";
-    name = "Nathan Bijnens";
-  };
-  nckx = {
-    email = "github@tobias.gr";
-    github = "nckx";
-    name = "Tobias Geerinckx-Rice";
-  };
-  ndowens = {
-    email = "ndowens04@gmail.com";
-    github = "ndowens";
-    name = "Nathan Owens";
-  };
-  neeasade = {
-    email = "nathanisom27@gmail.com";
-    github = "neeasade";
-    name = "Nathan Isom";
-  };
-  nequissimus = {
-    email = "tim@nequissimus.com";
-    github = "nequissimus";
-    name = "Tim Steinbach";
-  };
-  nfjinjing = {
-    email = "nfjinjing@gmail.com";
-    github = "nfjinjing";
-    name = "Jinjing Wang";
-  };
-  nh2 = {
-    email = "mail@nh2.me";
-    github = "nh2";
-    name = "Niklas Hambüchen";
-  };
-  nhooyr = {
-    email = "anmol@aubble.com";
-    github = "nhooyr";
-    name = "Anmol Sethi";
-  };
-  nickhu = {
-    email = "me@nickhu.co.uk";
-    github = "nickhu";
-    name = "Nick Hu";
-  };
-  nicknovitski = {
-    email = "nixpkgs@nicknovitski.com";
-    github = "nicknovitski";
-    name = "Nick Novitski";
-  };
-  nico202 = {
-    email = "anothersms@gmail.com";
-    github = "nico202";
-    name = "Nicolò Balzarotti";
-  };
-  ninjatrappeur = {
-    email = "felix@alternativebit.fr";
-    github = "ninjatrappeur";
-    name = "Félix Baylac-Jacqué";
-  };
-  nipav = {
-    email = "niko.pavlinek@gmail.com";
-    github = "nipav";
-    name = "Niko Pavlinek";
-  };
-  nixy = {
-    email = "nixy@nixy.moe";
-    github = "nixy";
-    name = "Andrew R. M.";
-  };
-  nmattia = {
-    email = "nicolas@nmattia.com";
-    github = "nmattia";
-    name = "Nicolas Mattia";
-  };
-  nocoolnametom = {
-    email = "nocoolnametom@gmail.com";
-    github = "nocoolnametom";
-    name = "Tom Doggett";
-  };
-  notthemessiah = {
-    email = "brian.cohen.88@gmail.com";
-    github = "notthemessiah";
-    name = "Brian Cohen";
-  };
-  np = {
-    email = "np.nix@nicolaspouillard.fr";
-    github = "np";
-    name = "Nicolas Pouillard";
-  };
-  nslqqq = {
-    email = "nslqqq@gmail.com";
-    name = "Nikita Mikhailov";
-  };
-  nthorne = {
-    email = "notrupertthorne@gmail.com";
-    github = "nthorne";
-    name = "Niklas Thörne";
-  };
-  nyarly = {
-    email = "nyarly@gmail.com";
-    github = "nyarly";
-    name = "Judson Lester";
-  };
-  obadz = {
-    email = "obadz-nixos@obadz.com";
-    github = "obadz";
-    name = "obadz";
-  };
-  ocharles = {
-    email = "ollie@ocharles.org.uk";
-    github = "ocharles";
-    name = "Oliver Charles";
-  };
-  odi = {
-    email = "oliver.dunkl@gmail.com";
-    github = "odi";
-    name = "Oliver Dunkl";
-  };
-  offline = {
-    email = "jakahudoklin@gmail.com";
-    github = "offlinehacker";
-    name = "Jaka Hudoklin";
-  };
-  oida = {
-    email = "oida@posteo.de";
-    github = "oida";
-    name = "oida";
-  };
-  okasu = {
-    email = "oka.sux@gmail.com";
-    name = "Okasu";
-  };
-  olcai = {
-    email = "dev@timan.info";
-    github = "olcai";
-    name = "Erik Timan";
-  };
-  olejorgenb = {
-    email = "olejorgenb@yahoo.no";
-    github = "olejorgenb";
-    name = "Ole Jørgen Brønner";
-  };
-  olynch = {
-    email = "owen@olynch.me";
-    github = "olynch";
-    name = "Owen Lynch";
-  };
-  orbekk = {
-    email = "kjetil.orbekk@gmail.com";
-    github = "orbekk";
-    name = "KJ Ørbekk";
-  };
-  orbitz = {
-    email = "mmatalka@gmail.com";
-    github = "orbitz";
-    name = "Malcolm Matalka";
-  };
-  orivej = {
-    email = "orivej@gmx.fr";
-    github = "orivej";
-    name = "Orivej Desh";
-  };
-  osener = {
-    email = "ozan@ozansener.com";
-    github = "osener";
-    name = "Ozan Sener";
-  };
-  otwieracz = {
-    email = "slawek@otwiera.cz";
-    github = "otwieracz";
-    name = "Slawomir Gonet";
-  };
-  oxij = {
-    email = "oxij@oxij.org";
-    github = "oxij";
-    name = "Jan Malakhovski";
-  };
-  pSub = {
-    email = "mail@pascal-wittmann.de";
-    github = "pSub";
-    name = "Pascal Wittmann";
-  };
-  paholg = {
-    email = "paho@paholg.com";
-    github = "paholg";
-    name = "Paho Lurie-Gregg";
-  };
-  pakhfn = {
-    email = "pakhfn@gmail.com";
-    github = "pakhfn";
-    name = "Fedor Pakhomov";
-  };
-  panaeon = {
-    email = "vitalii.voloshyn@gmail.com";
-    github = "panaeon";
-    name = "Vitalii Voloshyn";
-  };
-  paperdigits = {
-    email = "mica@silentumbrella.com";
-    github = "paperdigits";
-    name = "Mica Semrick";
-  };
-  paraseba = {
-    email = "paraseba@gmail.com";
-    github = "paraseba";
-    name = "Sebastian Galkin";
-  };
-  pashev = {
-    email = "pashev.igor@gmail.com";
-    github = "ip1981";
-    name = "Igor Pashev";
-  };
-  patternspandemic = {
-    email = "patternspandemic@live.com";
-    github = "patternspandemic";
-    name = "Brad Christensen";
-  };
-  pawelpacana = {
-    email = "pawel.pacana@gmail.com";
-    github = "pawelpacana";
-    name = "Paweł Pacana";
-  };
-  pbogdan = {
-    email = "ppbogdan@gmail.com";
-    github = "pbogdan";
-    name = "Piotr Bogdan";
-  };
-  pcarrier = {
-    email = "pc@rrier.ca";
-    github = "pcarrier";
-    name = "Pierre Carrier";
-  };
-  periklis = {
-    email = null;
-    github = "periklis";
-    name = "theopompos@gmail.com";
-  };
-  pesterhazy = {
-    email = "pesterhazy@gmail.com";
-    github = "pesterhazy";
-    name = "Paulus Esterhazy";
-  };
-  peterhoeg = {
-    email = "peter@hoeg.com";
-    github = "peterhoeg";
-    name = "Peter Hoeg";
-  };
-  peterromfeldhk = {
-    email = "peter.romfeld.hk@gmail.com";
-    github = "peterromfeldhk";
-    name = "Peter Romfeld";
-  };
-  peti = {
-    email = "simons@cryp.to";
-    github = "peti";
-    name = "Peter Simons";
-  };
-  philandstuff = {
-    email = "philip.g.potter@gmail.com";
-    github = "philandstuff";
-    name = "Philip Potter";
-  };
-  phile314 = {
-    email = "nix@314.ch";
-    github = "phile314";
-    name = "Philipp Hausmann";
-  };
-  phreedom = {
-    email = "phreedom@yandex.ru";
-    github = "phreedom";
-    name = "Evgeny Egorochkin";
-  };
-  phunehehe = {
-    email = "phunehehe@gmail.com";
-    github = "phunehehe";
-    name = "Hoang Xuan Phu";
-  };
-  pierrechevalier83 = {
-    email = "pierrechevalier83@gmail.com";
-    github = "pierrechevalier83";
-    name = "Pierre Chevalier";
-  };
-  pierrer = {
-    email = "pierrer@pi3r.be";
-    github = "pierrer";
-    name = "Pierre Radermecker";
-  };
-  pierron = {
-    email = "nixos@nbp.name";
-    github = "nbp";
-    name = "Nicolas B. Pierron";
-  };
-  piotr = {
-    email = "ppietrasa@gmail.com";
-    name = "Piotr Pietraszkiewicz";
-  };
-  pjbarnoy = {
-    email = "pjbarnoy@gmail.com";
-    github = "pjbarnoy";
-    name = "Perry Barnoy";
-  };
-  pjones = {
-    email = "pjones@devalot.com";
-    github = "pjones";
-    name = "Peter Jones";
-  };
-  pkmx = {
-    email = "pkmx.tw@gmail.com";
-    github = "pkmx";
-    name = "Chih-Mao Chen";
-  };
-  plcplc = {
-    email = "plcplc@gmail.com";
-    github = "plcplc";
-    name = "Philip Lykke Carlsen";
-  };
-  plumps = {
-    email = "maks.bronsky@web.de";
-    github = "plumps";
-    name = "Maksim Bronsky";
-  };
-  pmahoney = {
-    email = "pat@polycrystal.org";
-    github = "pmahoney";
-    name = "Patrick Mahoney";
-  };
-  pmeunier = {
-    email = "pierre-etienne.meunier@inria.fr";
-    github = "P-E-Meunier";
-    name = "Pierre-Étienne Meunier";
-  };
-  pmiddend = {
-    email = "pmidden@secure.mailbox.org";
-    github = "pmiddend";
-    name = "Philipp Middendorf";
-  };
-  pneumaticat = {
-    email = "kevin@potatofrom.space";
-    github = "pneumaticat";
-    name = "Kevin Liu";
-  };
-  polyrod = {
-    email = "dc1mdp@gmail.com";
-    github = "polyrod";
-    name = "Maurizio Di Pietro";
-  };
-  pradeepchhetri = {
-    email = "pradeep.chhetri89@gmail.com";
-    github = "pradeepchhetri";
-    name = "Pradeep Chhetri";
-  };
-  prikhi = {
-    email = "pavan.rikhi@gmail.com";
-    github = "prikhi";
-    name = "Pavan Rikhi";
-  };
-  primeos = {
-    email = "dev.primeos@gmail.com";
-    github = "primeos";
-    name = "Michael Weiss";
-  };
-  proglodyte = {
-    email = "proglodyte23@gmail.com";
-    github = "proglodyte";
-    name = "Proglodyte";
-  };
-  pshendry = {
-    email = "paul@pshendry.com";
-    github = "pshendry";
-    name = "Paul Hendry";
-  };
-  psibi = {
-    email = "sibi@psibi.in";
-    github = "psibi";
-    name = "Sibi";
-  };
-  pstn = {
-    email = "philipp@xndr.de";
-    name = "Philipp Steinpaß";
-  };
-  puffnfresh = {
-    email = "brian@brianmckenna.org";
-    github = "puffnfresh";
-    name = "Brian McKenna";
-  };
-  pxc = {
-    email = "patrick.callahan@latitudeengineering.com";
-    name = "Patrick Callahan";
-  };
-  qknight = {
-    email = "js@lastlog.de";
-    github = "qknight";
-    name = "Joachim Schiele";
-  };
-  ragge = {
-    email = "r.dahlen@gmail.com";
-    github = "ragnard";
-    name = "Ragnar Dahlen";
-  };
-  ralith = {
-    email = "ben.e.saunders@gmail.com";
-    github = "ralith";
-    name = "Benjamin Saunders";
-  };
-  ramkromberg = {
-    email = "ramkromberg@mail.com";
-    github = "ramkromberg";
-    name = "Ram Kromberg";
-  };
-  rardiol = {
-    email = "ricardo.ardissone@gmail.com";
-    github = "rardiol";
-    name = "Ricardo Ardissone";
-  };
-  rasendubi = {
-    email = "rasen.dubi@gmail.com";
-    github = "rasendubi";
-    name = "Alexey Shmalko";
-  };
-  raskin = {
-    email = "7c6f434c@mail.ru";
-    github = "7c6f434c";
-    name = "Michael Raskin";
-  };
-  ravloony = {
-    email = "ravloony@gmail.com";
-    name = "Tom Macdonald";
-  };
-  razvan = {
-    email = "razvan.panda@gmail.com";
-    github = "razvan-panda";
-    name = "Răzvan Flavius Panda";
-  };
-  rbasso = {
-    email = "rbasso@sharpgeeks.net";
-    github = "rbasso";
-    name = "Rafael Basso";
-  };
-  redbaron = {
-    email = "ivanov.maxim@gmail.com";
-    github = "redbaron";
-    name = "Maxim Ivanov";
-  };
-  redvers = {
-    email = "red@infect.me";
-    github = "redvers";
-    name = "Redvers Davies";
-  };
-  refnil = {
-    email = "broemartino@gmail.com";
-    github = "refnil";
-    name = "Martin Lavoie";
-  };
-  regnat = {
-    email = "regnat@regnat.ovh";
-    github = "regnat";
-    name = "Théophane Hufschmitt";
-  };
-  relrod = {
-    email = "ricky@elrod.me";
-    github = "relrod";
-    name = "Ricky Elrod";
-  };
-  renzo = {
-    email = "renzocarbonara@gmail.com";
-    github = "k0001";
-    name = "Renzo Carbonara";
-  };
-  retrry = {
-    email = "retrry@gmail.com";
-    github = "retrry";
-    name = "Tadas Barzdžius";
-  };
-  rht = {
-    email = "rhtbot@protonmail.com";
-    github = "rht";
-    name = "rht";
-  };
-  richardipsum = {
-    email = "richardipsum@fastmail.co.uk";
-    github = "richardipsum";
-    name = "Richard Ipsum";
-  };
-  rick68 = {
-    email = "rick68@gmail.com";
-    github = "rick68";
-    name = "Wei-Ming Yang";
-  };
-  rickynils = {
-    email = "rickynils@gmail.com";
-    github = "rickynils";
-    name = "Rickard Nilsson";
-  };
-  ris = {
-    email = "code@humanleg.org.uk";
-    github = "risicle";
-    name = "Robert Scott";
-  };
-  rlupton20 = {
-    email = "richard.lupton@gmail.com";
-    github = "rlupton20";
-    name = "Richard Lupton";
-  };
-  rnhmjoj = {
-    email = "micheleguerinirocco@me.com";
-    github = "rnhmjoj";
-    name = "Michele Guerini Rocco";
-  };
-  rob = {
-    email = "rob.vermaas@gmail.com";
-    github = "rbvermaa";
-    name = "Rob Vermaas";
-  };
-  robberer = {
-    email = "robberer@freakmail.de";
-    github = "robberer";
-    name = "Longrin Wischnewski";
-  };
-  robbinch = {
-    email = "robbinch33@gmail.com";
-    github = "robbinch";
-    name = "Robbin C.";
-  };
-  roberth = {
-    email = "nixpkgs@roberthensing.nl";
-    github = "roberth";
-    name = "Robert Hensing";
-  };
-  robertodr = {
-    email = "roberto.diremigio@gmail.com";
-    github = "robertodr";
-    name = "Roberto Di Remigio";
-  };
-  robgssp = {
-    email = "robgssp@gmail.com";
-    github = "robgssp";
-    name = "Rob Glossop";
-  };
-  roblabla = {
-    email = "robinlambertz+dev@gmail.com";
-    github = "roblabla";
-    name = "Robin Lambertz";
-  };
-  roconnor = {
-    email = "roconnor@theorem.ca";
-    github = "roconnor";
-    name = "Russell O'Connor";
-  };
-  romildo = {
-    email = "malaquias@gmail.com";
-    github = "romildo";
-    name = "José Romildo Malaquias";
-  };
-  rongcuid = {
-    email = "rongcuid@outlook.com";
-    github = "rongcuid";
-    name = "Rongcui Dong";
-  };
-  rszibele = {
-    email = "richard@szibele.com";
-    github = "rszibele";
-    name = "Richard Szibele";
-  };
-  rtreffer = {
-    email = "treffer+nixos@measite.de";
-    github = "rtreffer";
-    name = "Rene Treffer";
-  };
-  rushmorem = {
-    email = "rushmore@webenchanter.com";
-    github = "rushmorem";
-    name = "Rushmore Mushambi";
-  };
-  rvl = {
-    email = "dev+nix@rodney.id.au";
-    github = "rvl";
-    name = "Rodney Lorrimar";
-  };
-  rvlander = {
-    email = "rvlander@gaetanandre.eu";
-    github = "rvlander";
-    name = "Gaëtan André";
-  };
-  rvolosatovs = {
-    email = "rvolosatovs@riseup.net";
-    github = "rvolosatovs";
-    name = "Roman Volosatovs";
-  };
-  ryanartecona = {
-    email = "ryanartecona@gmail.com";
-    github = "ryanartecona";
-    name = "Ryan Artecona";
-  };
-  ryansydnor = {
-    email = "ryan.t.sydnor@gmail.com";
-    github = "ryansydnor";
-    name = "Ryan Sydnor";
-  };
-  ryantm = {
-    email = "ryan@ryantm.com";
-    github = "ryantm";
-    name = "Ryan Mulligan";
-  };
-  ryantrinkle = {
-    email = "ryan.trinkle@gmail.com";
-    github = "ryantrinkle";
-    name = "Ryan Trinkle";
-  };
-  rybern = {
-    email = "ryan.bernstein@columbia.edu";
-    github = "rybern";
-    name = "Ryan Bernstein";
-  };
-  rycee = {
-    email = "robert@rycee.net";
-    github = "rycee";
-    name = "Robert Helgesson";
-  };
-  ryneeverett = {
-    email = "ryneeverett@gmail.com";
-    github = "ryneeverett";
-    name = "Ryne Everett";
-  };
-  rzetterberg = {
-    email = "richard.zetterberg@gmail.com";
-    github = "rzetterberg";
-    name = "Richard Zetterberg";
-  };
-  s1lvester = {
-    email = "s1lvester@bockhacker.me";
-    github = "s1lvester";
-    name = "Markus Silvester";
-  };
-  samdroid-apps = {
-    email = "sam@sam.today";
-    github = "samdroid-apps";
-    name = "Sam Parkinson";
-  };
-  samueldr = {
-    email = "samuel@dionne-riel.com";
-    github = "samueldr";
-    name = "Samuel Dionne-Riel";
-  };
-  samuelrivas = {
-    email = "samuelrivas@gmail.com";
-    github = "samuelrivas";
-    name = "Samuel Rivas";
-  };
-  sander = {
-    email = "s.vanderburg@tudelft.nl";
-    github = "svanderburg";
-    name = "Sander van der Burg";
-  };
-  sargon = {
-    email = "danielehlers@mindeye.net";
-    github = "sargon";
-    name = "Daniel Ehlers";
-  };
-  sauyon = {
-    email = "s@uyon.co";
-    github = "sauyon";
-    name = "Sauyon Lee";
-  };
-  schmitthenner = {
-    email = "development@schmitthenner.eu";
-    github = "fkz";
-    name = "Fabian Schmitthenner";
-  };
-  schneefux = {
-    email = "schneefux+nixos_pkg@schneefux.xyz";
-    github = "schneefux";
-    name = "schneefux";
-  };
-  schristo = {
-    email = "schristopher@konputa.com";
-    name = "Scott Christopher";
-  };
-  scode = {
-    email = "peter.schuller@infidyne.com";
-    github = "scode";
-    name = "Peter Schuller";
-  };
-  scolobb = {
-    email = "sivanov@colimite.fr";
-    github = "scolobb";
-    name = "Sergiu Ivanov";
-  };
-  sdll = {
-    email = "sasha.delly@gmail.com";
-    github = "sdll";
-    name = "Sasha Illarionov";
-  };
-  sellout = {
-    email = "greg@technomadic.org";
-    github = "sellout";
-    name = "Greg Pfeil";
-  };
-  sepi = {
-    email = "raffael@mancini.lu";
-    github = "sepi";
-    name = "Raffael Mancini";
-  };
-  seppeljordan = {
-    email = "sebastian.jordan.mail@googlemail.com";
-    github = "seppeljordan";
-    name = "Sebastian Jordan";
-  };
-  sfrijters = {
-    email = "sfrijters@gmail.com";
-    github = "sfrijters";
-    name = "Stefan Frijters";
-  };
-  shanemikel = {
-    email = "shanemikel1@gmail.com";
-    github = "shanemikel";
-    name = "Shane Pearlman";
-  };
-  shawndellysse = {
-    email = "sdellysse@gmail.com";
-    github = "shawndellysse";
-    name = "Shawn Dellysse";
-  };
-  sheenobu = {
-    email = "sheena.artrip@gmail.com";
-    github = "sheenobu";
-    name = "Sheena Artrip";
-  };
-  sheganinans = {
-    email = "sheganinans@gmail.com";
-    github = "sheganinans";
-    name = "Aistis Raulinaitis";
-  };
-  shell = {
-    email = "cam.turn@gmail.com";
-    github = "VShell";
-    name = "Shell Turner";
-  };
-  shlevy = {
-    email = "shea@shealevy.com";
-    github = "shlevy";
-    name = "Shea Levy";
-  };
-  siddharthist = {
-    email = "langston.barrett@gmail.com";
-    github = "siddharthist";
-    name = "Langston Barrett";
-  };
-  sifmelcara = {
-    email = "ming@culpring.com";
-    github = "sifmelcara";
-    name = "Ming Chuan";
-  };
-  sigma = {
-    email = "yann.hodique@gmail.com";
-    github = "sigma";
-    name = "Yann Hodique";
-  };
-  simonvandel = {
-    email = "simon.vandel@gmail.com";
-    github = "simonvandel";
-    name = "Simon Vandel Sillesen";
-  };
-  sivteck = {
-    email = "sivaram1992@gmail.com";
-    github = "sivteck";
-    name = "Sivaram Balakrishnan";
-  };
-  sjagoe = {
-    email = "simon@simonjagoe.com";
-    github = "sjagoe";
-    name = "Simon Jagoe";
-  };
-  sjmackenzie = {
-    email = "setori88@gmail.com";
-    github = "sjmackenzie";
-    name = "Stewart Mackenzie";
-  };
-  sjourdois = {
-    email = "sjourdois@gmail.com";
-    name = "Stéphane ‘kwisatz’ Jourdois";
-  };
-  skeidel = {
-    email = "svenkeidel@gmail.com";
-    github = "svenkeidel";
-    name = "Sven Keidel";
-  };
-  skrzyp = {
-    email = "jot.skrzyp@gmail.com";
-    name = "Jakub Skrzypnik";
-  };
-  sleexyz = {
-    email = "freshdried@gmail.com";
-    github = "sleexyz";
-    name = "Sean Lee";
-  };
-  smironov = {
-    email = "grrwlf@gmail.com";
-    github = "grwlf";
-    name = "Sergey Mironov";
-  };
-  snyh = {
-    email = "snyh@snyh.org";
-    github = "snyh";
-    name = "Xia Bin";
-  };
-  solson = {
-    email = "scott@solson.me";
-    github = "solson";
-    name = "Scott Olson";
-  };
-  sorki = {
-    email = "srk@48.io";
-    github = "sorki";
-    name = "Richard Marko";
-  };
-  sorpaas = {
-    email = "hi@that.world";
-    github = "sorpaas";
-    name = "Wei Tang";
-  };
-  spacefrogg = {
-    email = "spacefrogg-nixos@meterriblecrew.net";
-    github = "spacefrogg";
-    name = "Michael Raitza";
-  };
-  spencerjanssen = {
-    email = "spencerjanssen@gmail.com";
-    github = "spencerjanssen";
-    name = "Spencer Janssen";
-  };
-  spinus = {
-    email = "tomasz.czyz@gmail.com";
-    github = "spinus";
-    name = "Tomasz Czyż";
-  };
-  sprock = {
-    email = "rmason@mun.ca";
-    github = "sprock";
-    name = "Roger Mason";
-  };
-  spwhitt = {
-    email = "sw@swhitt.me";
-    github = "spwhitt";
-    name = "Spencer Whitt";
-  };
-  srhb = {
-    email = "sbrofeldt@gmail.com";
-    github = "srhb";
-    name = "Sarah Brofeldt";
-  };
-  stephenmw = {
-    email = "stephen@q5comm.com";
-    github = "stephenmw";
-    name = "Stephen Weinberg";
-  };
-  sternenseemann = {
-    email = "post@lukasepple.de";
-    github = "sternenseemann";
-    name = "Lukas Epple";
-  };
-  stesie = {
-    email = "stesie@brokenpipe.de";
-    github = "stesie";
-    name = "Stefan Siegl";
-  };
-  steveej = {
-    email = "mail@stefanjunker.de";
-    github = "steveej";
-    name = "Stefan Junker";
-  };
-  stumoss = {
-    email = "samoss@gmail.com";
-    github = "stumoss";
-    name = "Stuart Moss";
-  };
-  suvash = {
-    email = "suvash+nixpkgs@gmail.com";
-    github = "suvash";
-    name = "Suvash Thapaliya";
-  };
-  svsdep = {
-    email = "svsdep@gmail.com";
-    github = "svsdep";
-    name = "Vasyl Solovei";
-  };
-  swarren83 = {
-    email = "shawn.w.warren@gmail.com";
-    github = "swarren83";
-    name = "Shawn Warren";
-  };
-  swflint = {
-    email = "swflint@flintfam.org";
-    github = "swflint";
-    name = "Samuel W. Flint";
-  };
-  swistak35 = {
-    email = "me@swistak35.com";
-    github = "swistak35";
-    name = "Rafał Łasocha";
-  };
-  symphorien = {
-    email = "symphorien_nixpkgs@xlumurb.eu";
-    github = "symphorien";
-    name = "Guillaume Girol";
-  };
-  szczyp = {
-    email = "qb@szczyp.com";
-    github = "szczyp";
-    name = "Szczyp";
-  };
-  sztupi = {
-    email = "attila.sztupak@gmail.com";
-    github = "sztupi";
-    name = "Attila Sztupak";
-  };
-  tadfisher = {
-    email = "tadfisher@gmail.com";
-    github = "tadfisher";
-    name = "Tad Fisher";
-  };
-  taeer = {
-    email = "taeer@necsi.edu";
-    github = "Radvendii";
-    name = "Taeer Bar-Yam";
-  };
-  tailhook = {
-    email = "paul@colomiets.name";
-    github = "tailhook";
-    name = "Paul Colomiets";
-  };
-  taketwo = {
-    email = "alexandrov88@gmail.com";
-    github = "taketwo";
-    name = "Sergey Alexandrov";
-  };
-  takikawa = {
-    email = "asumu@igalia.com";
-    github = "takikawa";
-    name = "Asumu Takikawa";
-  };
-  taktoa = {
-    email = "taktoa@gmail.com";
-    github = "taktoa";
-    name = "Remy Goldschmidt";
-  };
-  taku0 = {
-    email = "mxxouy6x3m_github@tatapa.org";
-    github = "taku0";
-    name = "Takuo Yonezawa";
-  };
-  tari = {
-    email = "peter@taricorp.net";
-    github = "tari";
-    name = "Peter Marheine";
-  };
-  tavyc = {
-    email = "octavian.cerna@gmail.com";
-    github = "tavyc";
-    name = "Octavian Cerna";
-  };
-  teh = {
-    email = "tehunger@gmail.com";
-    github = "teh";
-    name = "Tom Hunger";
-  };
-  telotortium = {
-    email = "rirelan@gmail.com";
-    github = "telotortium";
-    name = "Robert Irelan";
-  };
-  teozkr = {
-    email = "teo@nullable.se";
-    github = "teozkr";
-    name = "Teo Klestrup Röijezon";
-  };
-  teto = {
-    email = "mcoudron@hotmail.com";
-    github = "teto";
-    name = "Matthieu Coudron";
-  };
-  tex = {
-    email = "milan.svoboda@centrum.cz";
-    github = "tex";
-    name = "Milan Svoboda";
-  };
-  thall = {
-    email = "niclas.thall@gmail.com";
-    github = "thall";
-    name = "Niclas Thall";
-  };
-  thammers = {
-    email = "jawr@gmx.de";
-    github = "tobias-hammerschmidt";
-    name = "Tobias Hammerschmidt";
-  };
-  thanegill = {
-    email = "me@thanegill.com";
-    github = "thanegill";
-    name = "Thane Gill";
-  };
-  the-kenny = {
-    email = "moritz@tarn-vedra.de";
-    github = "the-kenny";
-    name = "Moritz Ulrich";
-  };
-  theuni = {
-    email = "ct@flyingcircus.io";
-    github = "ctheune";
-    name = "Christian Theune";
-  };
-  thoughtpolice = {
-    email = "aseipp@pobox.com";
-    github = "thoughtpolice";
-    name = "Austin Seipp";
-  };
-  thpham = {
-    email = "thomas.pham@ithings.ch";
-    github = "thpham";
-    name = "Thomas Pham";
-  };
-  tilpner = {
-    email = "till@hoeppner.ws";
-    github = "tilpner";
-    name = "Till Höppner";
-  };
-  timbertson = {
-    email = "tim@gfxmonk.net";
-    github = "timbertson";
-    name = "Tim Cuthbertson";
-  };
-  timokau = {
-    email = "timokau@zoho.com";
-    github = "timokau";
-    name = "Timo Kaufmann";
-  };
-  timor = {
-    email = "timor.dd@googlemail.com";
-    github = "timor";
-    name = "timor";
-  };
-  tiramiseb = {
-    email = "sebastien@maccagnoni.eu";
-    github = "tiramiseb";
-    name = "Sébastien Maccagnoni";
-  };
-  titanous = {
-    email = "jonathan@titanous.com";
-    github = "titanous";
-    name = "Jonathan Rudenberg";
-  };
-  tnias = {
-    email = "phil@grmr.de";
-    github = "tnias";
-    name = "Philipp Bartsch";
-  };
-  tohl = {
-    email = "tom@logand.com";
-    github = "tohl";
-    name = "Tomas Hlavaty";
-  };
-  tokudan = {
-    email = "git@danielfrank.net";
-    github = "tokudan";
-    name = "Daniel Frank";
-  };
-  tomberek = {
-    email = "tomberek@gmail.com";
-    github = "tomberek";
-    name = "Thomas Bereknyei";
-  };
-  tomsmeets = {
-    email = "tom@tsmeets.nl";
-    github = "tomsmeets";
-    name = "Tom Smeets";
-  };
-  travisbhartwell = {
-    email = "nafai@travishartwell.net";
-    github = "travisbhartwell";
-    name = "Travis B. Hartwell";
-  };
-  treemo = {
-    email = "matthieu.chevrier@treemo.fr";
-    github = "treemo";
-    name = "Matthieu Chevrier";
-  };
-  trevorj = {
-    email = "nix@trevor.joynson.io";
-    github = "akatrevorjay";
-    name = "Trevor Joynson";
-  };
-  trino = {
-    email = "muehlhans.hubert@ekodia.de";
-    github = "hmuehlhans";
-    name = "Hubert Mühlhans";
-  };
-  troydm = {
-    email = "d.geurkov@gmail.com";
-    github = "troydm";
-    name = "Dmitry Geurkov";
-  };
-  tstrobel = {
-    email = "4ZKTUB6TEP74PYJOPWIR013S2AV29YUBW5F9ZH2F4D5UMJUJ6S@hash.domains";
-    name = "Thomas Strobel";
-  };
-  ttuegel = {
-    email = "ttuegel@mailbox.org";
-    github = "ttuegel";
-    name = "Thomas Tuegel";
-  };
-  tv = {
-    email = "tv@shackspace.de";
-    github = "4z3";
-    name = "Tomislav Viljetić";
-  };
-  tvestelind = {
-    email = "tomas.vestelind@fripost.org";
-    github = "tvestelind";
-    name = "Tomas Vestelind";
-  };
-  tvorog = {
-    email = "marszaripov@gmail.com";
-    github = "tvorog";
-    name = "Marsel Zaripov";
-  };
-  tweber = {
-    email = "tw+nixpkgs@360vier.de";
-    github = "thorstenweber83";
-    name = "Thorsten Weber";
-  };
-  twey = {
-    email = "twey@twey.co.uk";
-    github = "twey";
-    name = "James ‘Twey’ Kay";
-  };
-  unode = {
-    email = "alves.rjc@gmail.com";
-    github = "unode";
-    name = "Renato Alves";
-  };
-  uralbash = {
-    email = "root@uralbash.ru";
-    github = "uralbash";
-    name = "Svintsov Dmitry";
-  };
-  utdemir = {
-    email = "me@utdemir.com";
-    github = "utdemir";
-    name = "Utku Demir";
-  };
-  uwap = {
-    email = "me@uwap.name";
-    github = "uwap";
-    name = "uwap";
-  };
-  va1entin = {
-    email = "github@valentinsblog.com";
-    github = "va1entin";
-    name = "Valentin Heidelberger";
-  };
-  vaibhavsagar = {
-    email = "vaibhavsagar@gmail.com";
-    github = "vaibhavsagar";
-    name = "Vaibhav Sagar";
-  };
-  valeriangalliat = {
-    email = "val@codejam.info";
-    github = "valeriangalliat";
-    name = "Valérian Galliat";
-  };
-  vandenoever = {
-    email = "jos@vandenoever.info";
-    github = "vandenoever";
-    name = "Jos van den Oever";
-  };
-  vanschelven = {
-    email = "klaas@vanschelven.com";
-    github = "vanschelven";
-    name = "Klaas van Schelven";
-  };
-  vanzef = {
-    email = "vanzef@gmail.com";
-    github = "vanzef";
-    name = "Ivan Solyankin";
-  };
-  varunpatro = {
-    email = "varun.kumar.patro@gmail.com";
-    github = "varunpatro";
-    name = "Varun Patro";
-  };
-  vbgl = {
-    email = "Vincent.Laporte@gmail.com";
-    github = "vbgl";
-    name = "Vincent Laporte";
-  };
-  vbmithr = {
-    email = "vb@luminar.eu.org";
-    github = "vbmithr";
-    name = "Vincent Bernardoff";
-  };
-  vcunat = {
-    email = "vcunat@gmail.com";
-    github = "vcunat";
-    name = "Vladimír Čunát";
-  };
-  vdemeester = {
-    email = "vincent@sbr.pm";
-    github = "vdemeester";
-    name = "Vincent Demeester";
-  };
-  velovix = {
-    email = "xaviosx@gmail.com";
-    github = "velovix";
-    name = "Tyler Compton";
-  };
-  veprbl = {
-    email = "veprbl@gmail.com";
-    github = "veprbl";
-    name = "Dmitry Kalinkin";
-  };
-  vidbina = {
-    email = "vid@bina.me";
-    github = "vidbina";
-    name = "David Asabina";
-  };
-  vifino = {
-    email = "vifino@tty.sh";
-    github = "vifino";
-    name = "Adrian Pistol";
-  };
-  vinymeuh = {
-    email = "vinymeuh@gmail.com";
-    github = "vinymeuh";
-    name = "VinyMeuh";
-  };
-  viric = {
-    email = "viric@viric.name";
-    github = "viric";
-    name = "Lluís Batlle i Rossell";
-  };
-  vizanto = {
-    email = "danny@prime.vc";
-    github = "vizanto";
-    name = "Danny Wilson";
-  };
-  vklquevs = {
-    email = "vklquevs@gmail.com";
-    github = "vklquevs";
-    name = "vklquevs";
-  };
-  vlstill = {
-    email = "xstill@fi.muni.cz";
-    github = "vlstill";
-    name = "Vladimír Štill";
-  };
-  vmandela = {
-    email = "venkat.mandela@gmail.com";
-    github = "vmandela";
-    name = "Venkateswara Rao Mandela";
-  };
-  vmchale = {
-    email = "tmchale@wisc.edu";
-    github = "vmchale";
-    name = "Vanessa McHale";
-  };
-  volhovm = {
-    email = "volhovm.cs@gmail.com";
-    github = "volhovm";
-    name = "Mikhail Volkhov";
-  };
-  volth = {
-    email = "jaroslavas@volth.com";
-    github = "volth";
-    name = "Jaroslavas Pocepko";
-  };
-  vozz = {
-    email = "oliver.huntuk@gmail.com";
-    name = "Oliver Hunt";
-  };
-  vrthra = {
-    email = "rahul@gopinath.org";
-    github = "vrthra";
-    name = "Rahul Gopinath";
-  };
-  vyp = {
-    email = "elisp.vim@gmail.com";
-    github = "vyp";
-    name = "vyp";
-  };
-  wedens = {
-    email = "kirill.wedens@gmail.com";
-    name = "wedens";
-  };
-  willibutz = {
-    email = "willibutz@posteo.de";
-    github = "willibutz";
-    name = "Willi Butz";
-  };
-  willtim = {
-    email = "tim.williams.public@gmail.com";
-    name = "Tim Philip Williams";
-  };
-  winden = {
-    email = "windenntw@gmail.com";
-    name = "Antonio Vargas Gonzalez";
-  };
-  wizeman = {
-    email = "rcorreia@wizy.org";
-    github = "wizeman";
-    name = "Ricardo M. Correia";
-  };
-  wjlroe = {
-    email = "willroe@gmail.com";
-    github = "wjlroe";
-    name = "William Roe";
-  };
-  wkennington = {
-    email = "william@wkennington.com";
-    github = "wkennington";
-    name = "William A. Kennington III";
-  };
-  wmertens = {
-    email = "Wout.Mertens@gmail.com";
-    github = "wmertens";
-    name = "Wout Mertens";
-  };
-  woffs = {
-    email = "github@woffs.de";
-    github = "woffs";
-    name = "Frank Doepper";
-  };
-  womfoo = {
-    email = "kranium@gikos.net";
-    github = "womfoo";
-    name = "Kranium Gikos Mendoza";
-  };
-  wscott = {
-    email = "wsc9tt@gmail.com";
-    github = "wscott";
-    name = "Wayne Scott";
-  };
-  wyvie = {
-    email = "elijahrum@gmail.com";
-    github = "wyvie";
-    name = "Elijah Rum";
-  };
-  xaverdh = {
-    email = "hoe.dom@gmx.de";
-    github = "xaverdh";
-    name = "Dominik Xaver Hörl";
-  };
-  xeji = {
-    email = "xeji@cat3.de";
-    github = "xeji";
-    name = "xeji";
-  };
-  xnaveira = {
-    email = "xnaveira@gmail.com";
-    github = "xnaveira";
-    name = "Xavier Naveira";
-  };
-  xnwdd = {
-    email = "nwdd+nixos@no.team";
-    github = "xnwdd";
-    name = "Guillermo NWDD";
-  };
-  xurei = {
-    email = "olivier.bourdoux@gmail.com";
-    github = "xurei";
-    name = "Olivier Bourdoux";
-  };
-  xvapx = {
-    email = "marti.serra.coscollano@gmail.com";
-    github = "xvapx";
-    name = "Marti Serra";
-  };
-  xwvvvvwx = {
-    email = "davidterry@posteo.de";
-    github = "xwvvvvwx";
-    name = "David Terry";
-  };
-  xzfc = {
-    email = "xzfcpw@gmail.com";
-    github = "xzfc";
-    name = "Albert Safin";
-  };
-  y0no = {
-    email = "y0no@y0no.fr";
-    github = "y0no";
-    name = "Yoann Ono";
-  };
-  yarr = {
-    email = "savraz@gmail.com";
-    github = "Eternity-Yarr";
-    name = "Dmitry V.";
-  };
-  yegortimoshenko = {
-    email = "yegortimoshenko@gmail.com";
-    github = "yegortimoshenko";
-    name = "Yegor Timoshenko";
-  };
-  yesbox = {
-    email = "jesper.geertsen.jonsson@gmail.com";
-    github = "yesbox";
-    name = "Jesper Geertsen Jonsson";
-  };
-  ylwghst = {
-    email = "ylwghst@onionmail.info";
-    github = "ylwghst";
-    name = "Burim Augustin Berisa";
-  };
-  yochai = {
-    email = "yochai@titat.info";
-    github = "yochai";
-    name = "Yochai";
-  };
-  yorickvp = {
-    email = "yorickvanpelt@gmail.com";
-    github = "yorickvp";
-    name = "Yorick van Pelt";
-  };
-  yrashk = {
-    email = "yrashk@gmail.com";
-    github = "yrashk";
-    name = "Yurii Rashkovskii";
-  };
-  yuriaisaka = {
-    email = "yuri.aisaka+nix@gmail.com";
-    github = "yuriaisaka";
-    name = "Yuri Aisaka";
-  };
-  yurrriq = {
-    email = "eric@ericb.me";
-    github = "yurrriq";
-    name = "Eric Bailey";
-  };
-  z77z = {
-    email = "maggesi@math.unifi.it";
-    github = "maggesi";
-    name = "Marco Maggesi";
-  };
-  zagy = {
-    email = "cz@flyingcircus.io";
-    github = "zagy";
-    name = "Christian Zagrodnick";
-  };
-  zalakain = {
-    email = "contact@unaizalakain.info";
-    github = "umazalakain";
-    name = "Unai Zalakain";
-  };
-  zarelit = {
-    email = "david@zarel.net";
-    github = "zarelit";
-    name = "David Costa";
-  };
-  zauberpony = {
-    email = "elmar@athmer.org";
-    github = "zauberpony";
-    name = "Elmar Athmer";
-  };
-  zef = {
-    email = "zef@zef.me";
-    name = "Zef Hemel";
-  };
-  zimbatm = {
-    email = "zimbatm@zimbatm.com";
-    github = "zimbatm";
-    name = "zimbatm";
-  };
-  zohl = {
-    email = "zohl@fmap.me";
-    github = "zohl";
-    name = "Al Zohali";
-  };
-  zoomulator = {
-    email = "zoomulator@gmail.com";
-    github = "zoomulator";
-    name = "Kim Simmons";
-  };
-  zraexy = {
-    email = "zraexy@gmail.com";
-    github = "zraexy";
-    name = "David Mell";
-  };
-  zx2c4 = {
-    email = "Jason@zx2c4.com";
-    github = "zx2c4";
-    name = "Jason A. Donenfeld";
-  };
-  zzamboni = {
-    email = "diego@zzamboni.org";
-    github = "zzamboni";
-    name = "Diego Zamboni";
-  };
-}
diff --git a/lib/meta.nix b/lib/meta.nix
index 07b1710fff70..199030c103af 100644
--- a/lib/meta.nix
+++ b/lib/meta.nix
@@ -67,4 +67,23 @@ rec {
   */
   hiPrioSet = set: mapDerivationAttrset hiPrio set;
 
+
+  /* Check to see if a platform is matched by the given `meta.platforms`
+     element.
+
+     A `meta.platform` pattern is either
+
+       1. (legacy) a system string.
+
+       2. (modern) a pattern for the platform `parsed` field.
+
+     We can inject these into a patten for the whole of a structured platform,
+     and then match that.
+  */
+  platformMatch = platform: elem: let
+      pattern =
+        if builtins.isString elem
+        then { system = elem; }
+        else { parsed = elem; };
+    in lib.matchAttrs pattern platform;
 }
diff --git a/lib/minver.nix b/lib/minver.nix
index 2147820c0e49..fee6b65a2447 100644
--- a/lib/minver.nix
+++ b/lib/minver.nix
@@ -1,2 +1,2 @@
 # Expose the minimum required version for evaluating Nixpkgs
-"1.11"
+"2.0"
diff --git a/lib/modules.nix b/lib/modules.nix
index 654c4c588de6..5fb83a4a538c 100644
--- a/lib/modules.nix
+++ b/lib/modules.nix
@@ -59,7 +59,7 @@ rec {
         };
       };
 
-      closed = closeModules (modules ++ [ internalModule ]) ({ inherit config options; lib = import ./.; } // specialArgs);
+      closed = closeModules (modules ++ [ internalModule ]) ({ inherit config options lib; } // specialArgs);
 
       options = mergeModules prefix (reverseList (filterModules (specialArgs.modulesPath or "") closed));
 
@@ -159,7 +159,7 @@ rec {
       context = name: ''while evaluating the module argument `${name}' in "${key}":'';
       extraArgs = builtins.listToAttrs (map (name: {
         inherit name;
-        value = addErrorContext (context name)
+        value = builtins.addErrorContext (context name)
           (args.${name} or config._module.args.${name});
       }) requiredArgs);
 
@@ -192,29 +192,53 @@ rec {
       (concatMap (m: map (config: { inherit (m) file; inherit config; }) (pushDownProperties m.config)) modules);
 
   mergeModules' = prefix: options: configs:
-    listToAttrs (map (name: {
+    let
+     /* byName is like foldAttrs, but will look for attributes to merge in the
+        specified attribute name.
+
+        byName "foo" (module: value: ["module.hidden=${module.hidden},value=${value}"])
+        [
+          {
+            hidden="baz";
+            foo={qux="bar"; gla="flop";};
+          }
+          {
+            hidden="fli";
+            foo={qux="gne"; gli="flip";};
+          }
+        ]
+        ===>
+        {
+          gla = [ "module.hidden=baz,value=flop" ];
+          gli = [ "module.hidden=fli,value=flip" ];
+          qux = [ "module.hidden=baz,value=bar" "module.hidden=fli,value=gne" ];
+        }
+      */
+      byName = attr: f: modules: foldl' (acc: module:
+        foldl' (inner: name:
+          inner // { ${name} = (acc.${name} or []) ++ (f module module.${attr}.${name}); }
+          ) acc (attrNames module.${attr})
+        ) {} modules;
+      # an attrset 'name' => list of submodules that declare ‘name’.
+      declsByName = byName "options"
+        (module: option: [{ inherit (module) file; options = option; }])
+        options;
+      # an attrset 'name' => list of submodules that define ‘name’.
+      defnsByName = byName "config" (module: value:
+        map (config: { inherit (module) file; inherit config; }) (pushDownProperties value)
+        ) configs;
+      # extract the definitions for each loc
+      defnsByName' = byName "config"
+        (module: value: [{ inherit (module) file; inherit value; }])
+        configs;
+    in
+    (flip mapAttrs declsByName (name: decls:
       # We're descending into attribute ‘name’.
-      inherit name;
-      value =
         let
           loc = prefix ++ [name];
-          # Get all submodules that declare ‘name’.
-          decls = concatMap (m:
-            if m.options ? ${name}
-              then [ { inherit (m) file; options = m.options.${name}; } ]
-              else []
-            ) options;
-          # Get all submodules that define ‘name’.
-          defns = concatMap (m:
-            if m.config ? ${name}
-              then map (config: { inherit (m) file; inherit config; })
-                (pushDownProperties m.config.${name})
-              else []
-            ) configs;
+          defns = defnsByName.${name} or [];
+          defns' = defnsByName'.${name} or [];
           nrOptions = count (m: isOption m.options) decls;
-          # Extract the definitions for this loc
-          defns' = map (m: { inherit (m) file; value = m.config.${name}; })
-            (filter (m: m.config ? ${name}) configs);
         in
           if nrOptions == length decls then
             let opt = fixupOptionType loc (mergeOptionDecls loc decls);
@@ -226,8 +250,8 @@ rec {
             in
               throw "The option `${showOption loc}' in `${firstOption.file}' is a prefix of options in `${firstNonOption.file}'."
           else
-            mergeModules' loc decls defns;
-    }) (concatMap (m: attrNames m.options) options))
+            mergeModules' loc decls defns
+      ))
     // { _definedNames = map (m: { inherit (m) file; names = attrNames m.config; }) configs; };
 
   /* Merge multiple option declarations into a single declaration.  In
@@ -309,7 +333,8 @@ rec {
           res.mergedValue;
 
     in opt //
-      { value = addErrorContext "while evaluating the option `${showOption loc}':" value;
+      { value = builtins.addErrorContext "while evaluating the option `${showOption loc}':" value;
+        inherit (res.defsFinal') highestPrio;
         definitions = map (def: def.value) res.defsFinal;
         files = map (def: def.file) res.defsFinal;
         inherit (res) isDefined;
@@ -317,7 +342,7 @@ rec {
 
   # Merge definitions of a value of a given type.
   mergeDefinitions = loc: type: defs: rec {
-    defsFinal =
+    defsFinal' =
       let
         # Process mkMerge and mkIf properties.
         defs' = concatMap (m:
@@ -325,15 +350,20 @@ rec {
         ) defs;
 
         # Process mkOverride properties.
-        defs'' = filterOverrides defs';
+        defs'' = filterOverrides' defs';
 
         # Sort mkOrder properties.
         defs''' =
           # Avoid sorting if we don't have to.
-          if any (def: def.value._type or "" == "order") defs''
-          then sortProperties defs''
-          else defs'';
-      in defs''';
+          if any (def: def.value._type or "" == "order") defs''.values
+          then sortProperties defs''.values
+          else defs''.values;
+      in {
+        values = defs''';
+        inherit (defs'') highestPrio;
+      };
+
+    defsFinal = defsFinal'.values;
 
     # Type-check the remaining definitions, and merge them.
     mergedValue = foldl' (res: def:
@@ -416,13 +446,18 @@ rec {
 
      Note that "z" has the default priority 100.
   */
-  filterOverrides = defs:
+  filterOverrides = defs: (filterOverrides' defs).values;
+
+  filterOverrides' = defs:
     let
       defaultPrio = 100;
       getPrio = def: if def.value._type or "" == "override" then def.value.priority else defaultPrio;
       highestPrio = foldl' (prio: def: min (getPrio def) prio) 9999 defs;
       strip = def: if def.value._type or "" == "override" then def // { value = def.value.content; } else def;
-    in concatMap (def: if getPrio def == highestPrio then [(strip def)] else []) defs;
+    in {
+      values = concatMap (def: if getPrio def == highestPrio then [(strip def)] else []) defs;
+      inherit highestPrio;
+    };
 
   /* Sort a list of properties.  The sort priority of a property is
      1000 by default, but can be overridden by wrapping the property
@@ -482,7 +517,7 @@ rec {
       inherit priority content;
     };
 
-  mkOptionDefault = mkOverride 1001; # priority of option defaults
+  mkOptionDefault = mkOverride 1500; # priority of option defaults
   mkDefault = mkOverride 1000; # used in config sections of non-user modules to set a default
   mkForce = mkOverride 50;
   mkVMOverride = mkOverride 10; # used by ‘nixos-rebuild build-vm’
@@ -521,9 +556,7 @@ rec {
   #
   mkAliasDefinitions = mkAliasAndWrapDefinitions id;
   mkAliasAndWrapDefinitions = wrap: option:
-    mkMerge
-      (optional (isOption option && option.isDefined)
-        (wrap (mkMerge option.definitions)));
+    mkIf (isOption option && option.isDefined) (wrap (mkMerge option.definitions));
 
 
   /* Compatibility. */
@@ -658,21 +691,25 @@ rec {
   };
 
   doRename = { from, to, visible, warn, use }:
+    { config, options, ... }:
     let
+      fromOpt = getAttrFromPath from options;
       toOf = attrByPath to
-        (abort "Renaming error: option `${showOption to}' does not exists.");
+        (abort "Renaming error: option `${showOption to}' does not exist.");
     in
-      { config, options, ... }:
-      { options = setAttrByPath from (mkOption {
-          description = "Alias of <option>${showOption to}</option>.";
-          apply = x: use (toOf config);
-        });
-        config = {
-          warnings =
-            let opt = getAttrFromPath from options; in
-            optional (warn && opt.isDefined)
-              "The option `${showOption from}' defined in ${showFiles opt.files} has been renamed to `${showOption to}'.";
-        } // setAttrByPath to (mkAliasDefinitions (getAttrFromPath from options));
-      };
+    {
+      options = setAttrByPath from (mkOption {
+        inherit visible;
+        description = "Alias of <option>${showOption to}</option>.";
+        apply = x: use (toOf config);
+      });
+      config = mkMerge [
+        {
+          warnings = optional (warn && fromOpt.isDefined)
+            "The option `${showOption from}' defined in ${showFiles fromOpt.files} has been renamed to `${showOption to}'.";
+        }
+        (mkAliasAndWrapDefinitions (setAttrByPath to) fromOpt)
+      ];
+    };
 
 }
diff --git a/lib/options.nix b/lib/options.nix
index 9446eca36778..01160b48ec01 100644
--- a/lib/options.nix
+++ b/lib/options.nix
@@ -127,7 +127,20 @@ rec {
 
 
   /* Helper functions. */
-  showOption = concatStringsSep ".";
+
+  # Convert an option, described as a list of the option parts in to a
+  # safe, human readable version. ie:
+  #
+  # (showOption ["foo" "bar" "baz"]) == "foo.bar.baz"
+  # (showOption ["foo" "bar.baz" "tux"]) == "foo.\"bar.baz\".tux"
+  showOption = parts: let
+    escapeOptionPart = part:
+      let
+        escaped = lib.strings.escapeNixString part;
+      in if escaped == "\"${part}\""
+         then part
+         else escaped;
+    in (concatStringsSep ".") (map escapeOptionPart parts);
   showFiles = files: concatStringsSep " and " (map (f: "`${f}'") files);
   unknownModule = "<unknown-file>";
 
diff --git a/lib/strings.nix b/lib/strings.nix
index 9cbd1494a2b5..0c4095bb55cd 100644
--- a/lib/strings.nix
+++ b/lib/strings.nix
@@ -82,7 +82,7 @@ rec {
        => "//bin"
   */
   makeSearchPath = subDir: packages:
-    concatStringsSep ":" (map (path: path + "/" + subDir) packages);
+    concatStringsSep ":" (map (path: path + "/" + subDir) (builtins.filter (x: x != null) packages));
 
   /* Construct a Unix-style search path, using given package output.
      If no output is found, fallback to `.out` and then to the default.
@@ -121,11 +121,20 @@ rec {
 
      Example:
        pkgs = import <nixpkgs> { }
-       makePerlPath [ pkgs.perlPackages.NetSMTP ]
+       makePerlPath [ pkgs.perlPackages.libnet ]
        => "/nix/store/n0m1fk9c960d8wlrs62sncnadygqqc6y-perl-Net-SMTP-1.25/lib/perl5/site_perl"
   */
   makePerlPath = makeSearchPathOutput "lib" "lib/perl5/site_perl";
 
+  /* Construct a perl search path recursively including all dependencies (such as $PERL5LIB)
+
+     Example:
+       pkgs = import <nixpkgs> { }
+       makeFullPerlPath [ pkgs.perlPackages.CGI ]
+       => "/nix/store/fddivfrdc1xql02h9q500fpnqy12c74n-perl-CGI-4.38/lib/perl5/site_perl:/nix/store/8hsvdalmsxqkjg0c5ifigpf31vc4vsy2-perl-HTML-Parser-3.72/lib/perl5/site_perl:/nix/store/zhc7wh0xl8hz3y3f71nhlw1559iyvzld-perl-HTML-Tagset-3.20/lib/perl5/site_perl"
+  */
+  makeFullPerlPath = deps: makePerlPath (lib.misc.closePropagation deps);
+
   /* Depending on the boolean `cond', return either the given string
      or the empty string. Useful to concatenate against a bigger string.
 
@@ -401,7 +410,7 @@ rec {
       components = splitString "/" url;
       filename = lib.last components;
       name = builtins.head (splitString sep filename);
-    in assert name !=  filename; name;
+    in assert name != filename; name;
 
   /* Create an --{enable,disable}-<feat> string that can be passed to
      standard GNU Autoconf scripts.
@@ -414,6 +423,39 @@ rec {
   */
   enableFeature = enable: feat: "--${if enable then "enable" else "disable"}-${feat}";
 
+  /* Create an --{enable-<feat>=<value>,disable-<feat>} string that can be passed to
+     standard GNU Autoconf scripts.
+
+     Example:
+       enableFeature true "shared" "foo"
+       => "--enable-shared=foo"
+       enableFeature false "shared" (throw "ignored")
+       => "--disable-shared"
+  */
+  enableFeatureAs = enable: feat: value: enableFeature enable feat + optionalString enable "=${value}";
+
+  /* Create an --{with,without}-<feat> string that can be passed to
+     standard GNU Autoconf scripts.
+
+     Example:
+       withFeature true "shared"
+       => "--with-shared"
+       withFeature false "shared"
+       => "--without-shared"
+  */
+  withFeature = with_: feat: "--${if with_ then "with" else "without"}-${feat}";
+
+  /* Create an --{with-<feat>=<value>,without-<feat>} string that can be passed to
+     standard GNU Autoconf scripts.
+
+     Example:
+       with_Feature true "shared" "foo"
+       => "--with-shared=foo"
+       with_Feature false "shared" (throw "ignored")
+       => "--without-shared"
+  */
+  withFeatureAs = with_: feat: value: withFeature with_ feat + optionalString with_ "=${value}";
+
   /* Create a fixed width string with additional prefix to match
      required width.
 
@@ -426,7 +468,10 @@ rec {
       strw = lib.stringLength str;
       reqWidth = width - (lib.stringLength filler);
     in
-      assert strw <= width;
+      assert lib.assertMsg (strw <= width)
+        "fixedWidthString: requested string length (${
+          toString width}) must not be shorter than actual length (${
+            toString strw})";
       if strw == width then str else filler + fixedWidthString reqWidth filler str;
 
   /* Format a number adding leading zeroes up to fixed width.
@@ -437,6 +482,13 @@ rec {
   */
   fixedWidthNumber = width: n: fixedWidthString width "0" (toString n);
 
+  /* Check whether a value can be coerced to a string */
+  isCoercibleToString = x:
+    builtins.elem (builtins.typeOf x) [ "path" "string" "null" "int" "float" "bool" ] ||
+    (builtins.isList x && lib.all isCoercibleToString x) ||
+    x ? outPath ||
+    x ? __toString;
+
   /* Check whether a value is a store path.
 
      Example:
@@ -450,9 +502,9 @@ rec {
        => false
   */
   isStorePath = x:
-       builtins.isString x
+       isCoercibleToString x
     && builtins.substring 0 1 (toString x) == "/"
-    && dirOf (builtins.toPath x) == builtins.storeDir;
+    && dirOf x == builtins.storeDir;
 
   /* Convert string to int
      Obviously, it is a bit hacky to use fromJSON that way.
@@ -488,11 +540,10 @@ rec {
   */
   readPathsFromFile = rootPath: file:
     let
-      root = toString rootPath;
       lines = lib.splitString "\n" (builtins.readFile file);
       removeComments = lib.filter (line: line != "" && !(lib.hasPrefix "#" line));
       relativePaths = removeComments lines;
-      absolutePaths = builtins.map (path: builtins.toPath (root + "/" + path)) relativePaths;
+      absolutePaths = builtins.map (path: rootPath + "/${path}") relativePaths;
     in
       absolutePaths;
 
diff --git a/lib/systems/default.nix b/lib/systems/default.nix
index d5a206e620c8..5eacc9eb23e1 100644
--- a/lib/systems/default.nix
+++ b/lib/systems/default.nix
@@ -3,6 +3,7 @@
 
 rec {
   doubles = import ./doubles.nix { inherit lib; };
+  forMeta = import ./for-meta.nix { inherit lib; };
   parse = import ./parse.nix { inherit lib; };
   inspect = import ./inspect.nix { inherit lib; };
   platforms = import ./platforms.nix { inherit lib; };
@@ -28,6 +29,7 @@ rec {
         /**/ if final.isDarwin              then "libSystem"
         else if final.isMinGW               then "msvcrt"
         else if final.isMusl                then "musl"
+        else if final.isUClibc              then "uclibc"
         else if final.isAndroid             then "bionic"
         else if final.isLinux /* default */ then "glibc"
         # TODO(@Ericson2314) think more about other operating systems
@@ -43,8 +45,16 @@ rec {
       };
       # Misc boolean options
       useAndroidPrebuilt = false;
+      useiOSPrebuilt = false;
     } // mapAttrs (n: v: v final.parsed) inspect.predicates
       // args;
   in assert final.useAndroidPrebuilt -> final.isAndroid;
+     assert lib.foldl
+       (pass: { assertion, message }:
+         if assertion final
+         then pass
+         else throw message)
+       true
+       (final.parsed.abi.assertions or []);
     final;
 }
diff --git a/lib/systems/doubles.nix b/lib/systems/doubles.nix
index 20294a28a110..a00165db1716 100644
--- a/lib/systems/doubles.nix
+++ b/lib/systems/doubles.nix
@@ -24,24 +24,25 @@ let
 in rec {
   inherit all;
 
-  allBut = platforms: lists.filter (x: !(builtins.elem x platforms)) all;
   none = [];
 
-  arm     = filterDoubles predicates.isArm;
+  arm     = filterDoubles predicates.isAarch32;
+  aarch64 = filterDoubles predicates.isAarch64;
+  x86     = filterDoubles predicates.isx86;
   i686    = filterDoubles predicates.isi686;
-  mips    = filterDoubles predicates.isMips;
   x86_64  = filterDoubles predicates.isx86_64;
+  mips    = filterDoubles predicates.isMips;
 
   cygwin  = filterDoubles predicates.isCygwin;
   darwin  = filterDoubles predicates.isDarwin;
   freebsd = filterDoubles predicates.isFreeBSD;
-  # Should be better, but MinGW is unclear, and HURD is bit-rotted.
-  gnu     = filterDoubles (matchAttrs { kernel = parse.kernels.linux;  abi = parse.abis.gnu; });
+  # Should be better, but MinGW is unclear.
+  gnu     = filterDoubles (matchAttrs { kernel = parse.kernels.linux; abi = parse.abis.gnu; });
   illumos = filterDoubles predicates.isSunOS;
   linux   = filterDoubles predicates.isLinux;
   netbsd  = filterDoubles predicates.isNetBSD;
   openbsd = filterDoubles predicates.isOpenBSD;
   unix    = filterDoubles predicates.isUnix;
 
-  mesaPlatforms = ["i686-linux" "x86_64-linux" "x86_64-darwin" "armv5tel-linux" "armv6l-linux" "armv7l-linux" "aarch64-linux"];
+  mesaPlatforms = ["i686-linux" "x86_64-linux" "x86_64-darwin" "armv5tel-linux" "armv6l-linux" "armv7l-linux" "aarch64-linux" "powerpc64le-linux"];
 }
diff --git a/lib/systems/examples.nix b/lib/systems/examples.nix
index 848737700b0b..3828b2f84c64 100644
--- a/lib/systems/examples.nix
+++ b/lib/systems/examples.nix
@@ -8,39 +8,55 @@ rec {
   #
   # Linux
   #
+  powernv = {
+    config = "powerpc64le-unknown-linux-gnu";
+    platform = platforms.powernv;
+  };
+  musl-power = {
+    config = "powerpc64le-unknown-linux-musl";
+    platform = platforms.powernv;
+  };
 
   sheevaplug = rec {
     config = "armv5tel-unknown-linux-gnueabi";
-    arch = "armv5tel";
-    float = "soft";
     platform = platforms.sheevaplug;
   };
 
   raspberryPi = rec {
     config = "armv6l-unknown-linux-gnueabihf";
-    arch = "armv6l";
-    float = "hard";
-    fpu = "vfp";
     platform = platforms.raspberrypi;
   };
 
   armv7l-hf-multiplatform = rec {
-    config = "arm-unknown-linux-gnueabihf";
-    arch = "armv7-a";
-    float = "hard";
-    fpu = "vfpv3-d16";
+    config = "armv7a-unknown-linux-gnueabihf";
     platform = platforms.armv7l-hf-multiplatform;
   };
 
   aarch64-multiplatform = rec {
     config = "aarch64-unknown-linux-gnu";
-    arch = "aarch64";
     platform = platforms.aarch64-multiplatform;
   };
 
+  armv5te-android-prebuilt = rec {
+    config = "armv5tel-unknown-linux-androideabi";
+    sdkVer = "21";
+    ndkVer = "10e";
+    platform = platforms.armv5te-android;
+    useAndroidPrebuilt = true;
+  };
+
+  armv7a-android-prebuilt = rec {
+    config = "armv7a-unknown-linux-androideabi";
+    sdkVer = "24";
+    ndkVer = "17";
+    platform = platforms.armv7a-android;
+    useAndroidPrebuilt = true;
+  };
+
   aarch64-android-prebuilt = rec {
     config = "aarch64-unknown-linux-android";
-    arch = "aarch64";
+    sdkVer = "24";
+    ndkVer = "17";
     platform = platforms.aarch64-multiplatform;
     useAndroidPrebuilt = true;
   };
@@ -51,16 +67,17 @@ rec {
   };
 
   pogoplug4 = rec {
-    arch = "armv5tel";
     config = "armv5tel-unknown-linux-gnueabi";
-    float = "soft";
     platform = platforms.pogoplug4;
   };
 
+  ben-nanonote = rec {
+    config = "mipsel-unknown-linux-uclibc";
+    platform = platforms.ben_nanonote;
+  };
+
   fuloongminipc = rec {
     config = "mipsel-unknown-linux-gnu";
-    arch = "mips";
-    float = "hard";
     platform = platforms.fuloong2f_n32;
   };
 
@@ -88,16 +105,42 @@ rec {
   #
 
   iphone64 = {
-    config = "aarch64-apple-darwin14";
-    arch = "arm64";
-    libc = "libSystem";
+    config = "aarch64-apple-ios";
+    # config = "aarch64-apple-darwin14";
+    sdkVer = "10.2";
+    xcodeVer = "8.2";
+    xcodePlatform = "iPhoneOS";
+    useiOSPrebuilt = true;
     platform = {};
   };
 
   iphone32 = {
-    config = "arm-apple-darwin10";
-    arch = "armv7-a";
-    libc = "libSystem";
+    config = "armv7a-apple-ios";
+    # config = "arm-apple-darwin10";
+    sdkVer = "10.2";
+    xcodeVer = "8.2";
+    xcodePlatform = "iPhoneOS";
+    useiOSPrebuilt = true;
+    platform = {};
+  };
+
+  iphone64-simulator = {
+    config = "x86_64-apple-ios";
+    # config = "x86_64-apple-darwin14";
+    sdkVer = "10.2";
+    xcodeVer = "8.2";
+    xcodePlatform = "iPhoneSimulator";
+    useiOSPrebuilt = true;
+    platform = {};
+  };
+
+  iphone32-simulator = {
+    config = "i686-apple-ios";
+    # config = "i386-apple-darwin11";
+    sdkVer = "10.2";
+    xcodeVer = "8.2";
+    xcodePlatform = "iPhoneSimulator";
+    useiOSPrebuilt = true;
     platform = {};
   };
 
@@ -108,7 +151,6 @@ rec {
   # 32 bit mingw-w64
   mingw32 = {
     config = "i686-pc-mingw32";
-    arch = "x86"; # Irrelevant
     libc = "msvcrt"; # This distinguishes the mingw (non posix) toolchain
     platform = {};
   };
@@ -117,7 +159,6 @@ rec {
   mingwW64 = {
     # That's the triplet they use in the mingw-w64 docs.
     config = "x86_64-pc-mingw32";
-    arch = "x86_64"; # Irrelevant
     libc = "msvcrt"; # This distinguishes the mingw (non posix) toolchain
     platform = {};
   };
diff --git a/lib/systems/for-meta.nix b/lib/systems/for-meta.nix
new file mode 100644
index 000000000000..51fb6ae760d1
--- /dev/null
+++ b/lib/systems/for-meta.nix
@@ -0,0 +1,37 @@
+{ lib }:
+let
+  inherit (lib.systems) parse;
+  inherit (lib.systems.inspect) patterns;
+
+  abis = lib.mapAttrs (_: abi: builtins.removeAttrs abi [ "assertions" ]) parse.abis;
+
+in rec {
+  all     = [ {} ]; # `{}` matches anything
+  none    = [];
+
+  arm     = [ patterns.isAarch32 ];
+  aarch64 = [ patterns.isAarch64 ];
+  x86     = [ patterns.isx86 ];
+  i686    = [ patterns.isi686 ];
+  x86_64  = [ patterns.isx86_64 ];
+  mips    = [ patterns.isMips ];
+  riscv   = [ patterns.isRiscV ];
+
+  cygwin  = [ patterns.isCygwin ];
+  darwin  = [ patterns.isDarwin ];
+  freebsd = [ patterns.isFreeBSD ];
+  # Should be better, but MinGW is unclear.
+  gnu     = [
+    { kernel = parse.kernels.linux; abi = abis.gnu; }
+    { kernel = parse.kernels.linux; abi = abis.gnueabi; }
+    { kernel = parse.kernels.linux; abi = abis.gnueabihf; }
+  ];
+  illumos = [ patterns.isSunOS ];
+  linux   = [ patterns.isLinux ];
+  netbsd  = [ patterns.isNetBSD ];
+  openbsd = [ patterns.isOpenBSD ];
+  unix    = patterns.isUnix; # Actually a list
+  windows = [ patterns.isWindows ];
+
+  inherit (lib.systems.doubles) mesaPlatforms;
+}
diff --git a/lib/systems/inspect.nix b/lib/systems/inspect.nix
index ab220af46e30..65f560328af5 100644
--- a/lib/systems/inspect.nix
+++ b/lib/systems/inspect.nix
@@ -3,53 +3,57 @@ with import ./parse.nix { inherit lib; };
 with lib.attrsets;
 with lib.lists;
 
+let abis_ = abis; in
+let abis = lib.mapAttrs (_: abi: builtins.removeAttrs abi [ "assertions" ]) abis_; in
+
 rec {
   patterns = rec {
-    i686         = { cpu = cpuTypes.i686; };
-    x86_64       = { cpu = cpuTypes.x86_64; };
-    PowerPC      = { cpu = cpuTypes.powerpc; };
-    x86          = { cpu = { family = "x86"; }; };
-    Arm          = { cpu = { family = "arm"; }; };
-    Aarch64      = { cpu = { family = "aarch64"; }; };
-    Mips         = { cpu = { family = "mips"; }; };
-    RiscV        = { cpu = { family = "riscv"; }; };
-    Wasm         = { cpu = { family = "wasm"; }; };
-
-    "32bit"      = { cpu = { bits = 32; }; };
-    "64bit"      = { cpu = { bits = 64; }; };
-    BigEndian    = { cpu = { significantByte = significantBytes.bigEndian; }; };
-    LittleEndian = { cpu = { significantByte = significantBytes.littleEndian; }; };
-
-    BSD          = { kernel = { families = { inherit (kernelFamilies) bsd; }; }; };
-    Unix         = [ BSD Darwin Linux SunOS Hurd Cygwin ];
-
-    Darwin       = { kernel = kernels.darwin; };
-    Linux        = { kernel = kernels.linux; };
-    SunOS        = { kernel = kernels.solaris; };
-    FreeBSD      = { kernel = kernels.freebsd; };
-    Hurd         = { kernel = kernels.hurd; };
-    NetBSD       = { kernel = kernels.netbsd; };
-    OpenBSD      = { kernel = kernels.openbsd; };
-    Windows      = { kernel = kernels.windows; };
-    Cygwin       = { kernel = kernels.windows; abi = abis.cygnus; };
-    MinGW        = { kernel = kernels.windows; abi = abis.gnu; };
-
-    Android      = [ { abi = abis.android; } { abi = abis.androideabi; } ];
-    Musl         = with abis; map (a: { abi = a; }) [ musl musleabi musleabihf ];
-
-    Kexecable    = map (family: { kernel = kernels.linux; cpu.family = family; })
-                     [ "x86" "arm" "aarch64" "mips" ];
-    Efi          = map (family: { cpu.family = family; })
-                     [ "x86" "arm" "aarch64" ];
-    Seccomputable = map (family: { kernel = kernels.linux; cpu.family = family; })
-                      [ "x86" "arm" "aarch64" "mips" ];
+    isi686         = { cpu = cpuTypes.i686; };
+    isx86_64       = { cpu = cpuTypes.x86_64; };
+    isPowerPC      = { cpu = cpuTypes.powerpc; };
+    isPower = { cpu = { family = "power"; }; };
+    isx86          = { cpu = { family = "x86"; }; };
+    isAarch32      = { cpu = { family = "arm"; bits = 32; }; };
+    isAarch64      = { cpu = { family = "arm"; bits = 64; }; };
+    isMips         = { cpu = { family = "mips"; }; };
+    isRiscV        = { cpu = { family = "riscv"; }; };
+    isSparc        = { cpu = { family = "sparc"; }; };
+    isWasm         = { cpu = { family = "wasm"; }; };
+
+    is32bit        = { cpu = { bits = 32; }; };
+    is64bit        = { cpu = { bits = 64; }; };
+    isBigEndian    = { cpu = { significantByte = significantBytes.bigEndian; }; };
+    isLittleEndian = { cpu = { significantByte = significantBytes.littleEndian; }; };
+
+    isBSD          = { kernel = { families = { inherit (kernelFamilies) bsd; }; }; };
+    isDarwin       = { kernel = { families = { inherit (kernelFamilies) darwin; }; }; };
+    isUnix         = [ isBSD isDarwin isLinux isSunOS isCygwin ];
+
+    isMacOS        = { kernel = kernels.macos; };
+    isiOS          = { kernel = kernels.ios; };
+    isLinux        = { kernel = kernels.linux; };
+    isSunOS        = { kernel = kernels.solaris; };
+    isFreeBSD      = { kernel = kernels.freebsd; };
+    isNetBSD       = { kernel = kernels.netbsd; };
+    isOpenBSD      = { kernel = kernels.openbsd; };
+    isWindows      = { kernel = kernels.windows; };
+    isCygwin       = { kernel = kernels.windows; abi = abis.cygnus; };
+    isMinGW        = { kernel = kernels.windows; abi = abis.gnu; };
+
+    isAndroid      = [ { abi = abis.android; } { abi = abis.androideabi; } ];
+    isMusl         = with abis; map (a: { abi = a; }) [ musl musleabi musleabihf ];
+    isUClibc       = with abis; map (a: { abi = a; }) [ uclibc uclibceabi uclibceabihf ];
+
+    isEfi          = map (family: { cpu.family = family; })
+                       [ "x86" "arm" "aarch64" ];
+
+    # Deprecated after 18.03
+    isArm = isAarch32;
   };
 
   matchAnyAttrs = patterns:
     if builtins.isList patterns then attrs: any (pattern: matchAttrs pattern attrs) patterns
     else matchAttrs patterns;
 
-  predicates = mapAttrs'
-    (name: value: nameValuePair ("is" + name) (matchAnyAttrs value))
-    patterns;
+  predicates = mapAttrs (_: matchAnyAttrs) patterns;
 }
diff --git a/lib/systems/parse.nix b/lib/systems/parse.nix
index 03d052f5f192..bb26c93f3d7a 100644
--- a/lib/systems/parse.nix
+++ b/lib/systems/parse.nix
@@ -18,6 +18,7 @@
 with lib.lists;
 with lib.types;
 with lib.attrsets;
+with lib.strings;
 with (import ./inspect.nix { inherit lib; }).predicates;
 
 let
@@ -34,7 +35,7 @@ rec {
 
   ################################################################################
 
-  types.openSignifiantByte = mkOptionType {
+  types.openSignificantByte = mkOptionType {
     name = "significant-byte";
     description = "Endianness";
     merge = mergeOneOption;
@@ -42,7 +43,7 @@ rec {
 
   types.significantByte = enum (attrValues significantBytes);
 
-  significantBytes = setTypes types.openSignifiantByte {
+  significantBytes = setTypes types.openSignificantByte {
     bigEndian = {};
     littleEndian = {};
   };
@@ -68,20 +69,36 @@ rec {
 
   cpuTypes = with significantBytes; setTypes types.openCpuType {
     arm      = { bits = 32; significantByte = littleEndian; family = "arm"; };
-    armv5tel = { bits = 32; significantByte = littleEndian; family = "arm"; };
-    armv6l   = { bits = 32; significantByte = littleEndian; family = "arm"; };
-    armv7a   = { bits = 32; significantByte = littleEndian; family = "arm"; };
-    armv7l   = { bits = 32; significantByte = littleEndian; family = "arm"; };
-    aarch64  = { bits = 64; significantByte = littleEndian; family = "aarch64"; };
+    armv5tel = { bits = 32; significantByte = littleEndian; family = "arm"; version = "5"; };
+    armv6m   = { bits = 32; significantByte = littleEndian; family = "arm"; version = "6"; };
+    armv6l   = { bits = 32; significantByte = littleEndian; family = "arm"; version = "6"; };
+    armv7a   = { bits = 32; significantByte = littleEndian; family = "arm"; version = "7"; };
+    armv7r   = { bits = 32; significantByte = littleEndian; family = "arm"; version = "7"; };
+    armv7m   = { bits = 32; significantByte = littleEndian; family = "arm"; version = "7"; };
+    armv7l   = { bits = 32; significantByte = littleEndian; family = "arm"; version = "7"; };
+    armv8a   = { bits = 32; significantByte = littleEndian; family = "arm"; version = "8"; };
+    armv8r   = { bits = 32; significantByte = littleEndian; family = "arm"; version = "8"; };
+    armv8m   = { bits = 32; significantByte = littleEndian; family = "arm"; version = "8"; };
+    aarch64  = { bits = 64; significantByte = littleEndian; family = "arm"; version = "8"; };
+
     i686     = { bits = 32; significantByte = littleEndian; family = "x86"; };
     x86_64   = { bits = 64; significantByte = littleEndian; family = "x86"; };
+
     mips     = { bits = 32; significantByte = bigEndian;    family = "mips"; };
     mipsel   = { bits = 32; significantByte = littleEndian; family = "mips"; };
     mips64   = { bits = 64; significantByte = bigEndian;    family = "mips"; };
     mips64el = { bits = 64; significantByte = littleEndian; family = "mips"; };
+
     powerpc  = { bits = 32; significantByte = bigEndian;    family = "power"; };
+    powerpc64 = { bits = 64; significantByte = bigEndian; family = "power"; };
+    powerpc64le = { bits = 64; significantByte = littleEndian; family = "power"; };
+
     riscv32  = { bits = 32; significantByte = littleEndian; family = "riscv"; };
     riscv64  = { bits = 64; significantByte = littleEndian; family = "riscv"; };
+
+    sparc    = { bits = 32; significantByte = bigEndian;    family = "sparc"; };
+    sparc64  = { bits = 64; significantByte = bigEndian;    family = "sparc"; };
+
     wasm32   = { bits = 32; significantByte = littleEndian; family = "wasm"; };
     wasm64   = { bits = 64; significantByte = littleEndian; family = "wasm"; };
   };
@@ -134,6 +151,7 @@ rec {
 
   kernelFamilies = setTypes types.openKernelFamily {
     bsd = {};
+    darwin = {};
   };
 
   ################################################################################
@@ -149,9 +167,11 @@ rec {
   types.kernel = enum (attrValues kernels);
 
   kernels = with execFormats; with kernelFamilies; setTypes types.openKernel {
-    darwin  = { execFormat = macho;   families = { }; };
+    # TODO(@Ericson2314): Don't want to mass-rebuild yet to keeping 'darwin' as
+    # the nnormalized name for macOS.
+    macos   = { execFormat = macho;   families = { inherit darwin; }; name = "darwin"; };
+    ios     = { execFormat = macho;   families = { inherit darwin; }; };
     freebsd = { execFormat = elf;     families = { inherit bsd; }; };
-    hurd    = { execFormat = elf;     families = { }; };
     linux   = { execFormat = elf;     families = { }; };
     netbsd  = { execFormat = elf;     families = { inherit bsd; }; };
     none    = { execFormat = unknown; families = { }; };
@@ -159,9 +179,10 @@ rec {
     solaris = { execFormat = elf;     families = { }; };
     windows = { execFormat = pe;      families = { }; };
   } // { # aliases
-    # TODO(@Ericson2314): Handle these Darwin version suffixes more generally.
-    darwin10 = kernels.darwin;
-    darwin14 = kernels.darwin;
+    # 'darwin' is the kernel for all of them. We choose macOS by default.
+    darwin = kernels.macos;
+    watchos = kernels.ios;
+    tvos = kernels.ios;
     win32 = kernels.windows;
   };
 
@@ -176,24 +197,47 @@ rec {
   types.abi = enum (attrValues abis);
 
   abis = setTypes types.openAbi {
-    android = {};
-    cygnus = {};
-    gnu = {};
-    msvc = {};
-    eabi = {};
-    androideabi = {};
-    gnueabi = {};
-    gnueabihf = {};
-    musleabi = {};
-    musleabihf = {};
-    musl = {};
+    cygnus       = {};
+    msvc         = {};
+    eabi         = {};
+
+    androideabi  = {};
+    android      = {
+      assertions = [
+        { assertion = platform: !platform.isAarch32;
+          message = ''
+            The "android" ABI is not for 32-bit ARM. Use "androideabi" instead.
+          '';
+        }
+      ];
+    };
+
+    gnueabi      = { float = "soft"; };
+    gnueabihf    = { float = "hard"; };
+    gnu          = {
+      assertions = [
+        { assertion = platform: !platform.isAarch32;
+          message = ''
+            The "gnu" ABI is ambiguous on 32-bit ARM. Use "gnueabi" or "gnueabihf" instead.
+          '';
+        }
+      ];
+    };
+
+    musleabi     = { float = "soft"; };
+    musleabihf   = { float = "hard"; };
+    musl         = {};
+
+    uclibceabihf = { float = "soft"; };
+    uclibceabi   = { float = "hard"; };
+    uclibc       = {};
 
     unknown = {};
   };
 
   ################################################################################
 
-  types.system = mkOptionType {
+  types.parsedPlatform = mkOptionType {
     name = "system";
     description = "fully parsed representation of llvm- or nix-style platform tuple";
     merge = mergeOneOption;
@@ -207,15 +251,13 @@ rec {
   isSystem = isType "system";
 
   mkSystem = components:
-    assert types.system.check components;
+    assert types.parsedPlatform.check components;
     setType "system" components;
 
   mkSkeletonFromList = l: {
     "2" = # We only do 2-part hacks for things Nix already supports
       if elemAt l 1 == "cygwin"
         then { cpu = elemAt l 0;                      kernel = "windows";  abi = "cygnus";   }
-      else if elemAt l 1 == "gnu"
-        then { cpu = elemAt l 0;                      kernel = "hurd";     abi = "gnu";      }
       else   { cpu = elemAt l 0;                      kernel = elemAt l 1;                   };
     "3" = # Awkwards hacks, beware!
       if elemAt l 1 == "apple"
@@ -224,6 +266,8 @@ rec {
         then { cpu = elemAt l 0;                      kernel = elemAt l 1; abi = elemAt l 2; }
       else if (elemAt l 2 == "mingw32") # autotools breaks on -gnu for window
         then { cpu = elemAt l 0; vendor = elemAt l 1; kernel = "windows";  abi = "gnu"; }
+      else if hasPrefix "netbsd" (elemAt l 2)
+        then { cpu = elemAt l 0; vendor = elemAt l 1;    kernel = elemAt l 2;                }
       else throw "Target specification with 3 components is ambiguous";
     "4" =    { cpu = elemAt l 0; vendor = elemAt l 1; kernel = elemAt l 2; abi = elemAt l 3; };
   }.${toString (length l)}
@@ -250,10 +294,17 @@ rec {
         else if isDarwin  parsed then vendors.apple
         else if isWindows parsed then vendors.pc
         else                     vendors.unknown;
-      kernel = getKernel args.kernel;
+      kernel = if hasPrefix "darwin" args.kernel      then getKernel "darwin"
+               else if hasPrefix "netbsd" args.kernel then getKernel "netbsd"
+               else                                   getKernel args.kernel;
       abi =
         /**/ if args ? abi       then getAbi args.abi
-        else if isLinux   parsed then abis.gnu
+        else if isLinux   parsed then
+          if isAarch32 parsed then
+            if lib.versionAtLeast (parsed.cpu.version or "0") "6"
+            then abis.gnueabihf
+            else abis.gnueabi
+          else abis.gnu
         else if isWindows parsed then abis.gnu
         else                     abis.unknown;
     };
@@ -263,8 +314,8 @@ rec {
   mkSystemFromString = s: mkSystemFromSkeleton (mkSkeletonFromList (lib.splitString "-" s));
 
   doubleFromSystem = { cpu, vendor, kernel, abi, ... }:
-    if abi == abis.cygnus
-    then "${cpu.name}-cygwin"
+    /**/ if abi == abis.cygnus       then "${cpu.name}-cygwin"
+    else if kernel.families ? darwin then "${cpu.name}-darwin"
     else "${cpu.name}-${kernel.name}";
 
   tripleFromSystem = { cpu, vendor, kernel, abi, ... } @ sys: assert isSystem sys; let
diff --git a/lib/systems/platforms.nix b/lib/systems/platforms.nix
index f39e890fbf1c..56783d99e3d4 100644
--- a/lib/systems/platforms.nix
+++ b/lib/systems/platforms.nix
@@ -20,12 +20,31 @@ rec {
     kernelAutoModules = false;
   };
 
+  powernv = {
+    name = "PowerNV";
+    kernelArch = "powerpc";
+    kernelBaseConfig = "powernv_defconfig";
+    kernelTarget = "zImage";
+    kernelInstallTarget = "install";
+    kernelFile = "vmlinux";
+    kernelAutoModules = true;
+    # avoid driver/FS trouble arising from unusual page size
+    kernelExtraConfig = ''
+      PPC_64K_PAGES n
+      PPC_4K_PAGES y
+      IPV6 y
+    '';
+  };
+
+  ##
+  ## ARM
+  ##
+
   pogoplug4 = {
     name = "pogoplug4";
 
     gcc = {
       arch = "armv5te";
-      float = "soft";
     };
 
     kernelMajor = "2.6";
@@ -158,185 +177,36 @@ rec {
     kernelDTB = true; # Beyond 3.10
     gcc = {
       arch = "armv5te";
-      float = "soft";
     };
   };
 
   raspberrypi = {
     name = "raspberrypi";
     kernelMajor = "2.6";
-    kernelBaseConfig = "bcmrpi_defconfig";
+    kernelBaseConfig = "bcm2835_defconfig";
     kernelDTB = true;
     kernelArch = "arm";
-    kernelAutoModules = false;
+    kernelAutoModules = true;
+    kernelPreferBuiltin = true;
     kernelExtraConfig = ''
-      BLK_DEV_RAM y
-      BLK_DEV_INITRD y
-      BLK_DEV_CRYPTOLOOP m
-      BLK_DEV_DM m
-      DM_CRYPT m
-      MD y
-      REISERFS_FS m
-      BTRFS_FS y
-      XFS_FS m
-      JFS_FS y
-      EXT4_FS y
-
-      IP_PNP y
-      IP_PNP_DHCP y
-      NFS_FS y
-      ROOT_NFS y
-      TUN m
-      NFS_V4 y
-      NFS_V4_1 y
-      NFS_FSCACHE y
-      NFSD m
-      NFSD_V2_ACL y
-      NFSD_V3 y
-      NFSD_V3_ACL y
-      NFSD_V4 y
-      NETFILTER y
-      IP_NF_IPTABLES y
-      IP_NF_FILTER y
-      IP_NF_MATCH_ADDRTYPE y
-      IP_NF_TARGET_LOG y
-      IP_NF_MANGLE y
-      IPV6 m
-      VLAN_8021Q m
-
-      CIFS y
-      CIFS_XATTR y
-      CIFS_POSIX y
-      CIFS_FSCACHE y
-      CIFS_ACL y
-
-      ZRAM m
-
       # Disable OABI to have seccomp_filter (required for systemd)
       # https://github.com/raspberrypi/firmware/issues/651
       OABI_COMPAT n
-
-      # Fail to build
-      DRM n
-      SCSI_ADVANSYS n
-      USB_ISP1362_HCD n
-      SND_SOC n
-      SND_ALI5451 n
-      FB_SAVAGE n
-      SCSI_NSP32 n
-      ATA_SFF n
-      SUNGEM n
-      IRDA n
-      ATM_HE n
-      SCSI_ACARD n
-      BLK_DEV_CMD640_ENHANCED n
-
-      FUSE_FS m
-
-      # nixos mounts some cgroup
-      CGROUPS y
-
-      # Latencytop
-      LATENCYTOP y
     '';
     kernelTarget = "zImage";
     gcc = {
       arch = "armv6";
       fpu = "vfp";
-      float = "hard";
-      # TODO(@Ericson2314) what is this and is it a good idea? It was
-      # used in some cross compilation examples but not others.
-      #
-      # abi = "aapcs-linux";
     };
   };
 
-  raspberrypi2 = armv7l-hf-multiplatform // {
-    name = "raspberrypi2";
-    kernelBaseConfig = "bcm2709_defconfig";
-    kernelDTB = true;
-    kernelAutoModules = false;
-    kernelExtraConfig = ''
-      BLK_DEV_RAM y
-      BLK_DEV_INITRD y
-      BLK_DEV_CRYPTOLOOP m
-      BLK_DEV_DM m
-      DM_CRYPT m
-      MD y
-      REISERFS_FS m
-      BTRFS_FS y
-      XFS_FS m
-      JFS_FS y
-      EXT4_FS y
-
-      IP_PNP y
-      IP_PNP_DHCP y
-      NFS_FS y
-      ROOT_NFS y
-      TUN m
-      NFS_V4 y
-      NFS_V4_1 y
-      NFS_FSCACHE y
-      NFSD m
-      NFSD_V2_ACL y
-      NFSD_V3 y
-      NFSD_V3_ACL y
-      NFSD_V4 y
-      NETFILTER y
-      IP_NF_IPTABLES y
-      IP_NF_FILTER y
-      IP_NF_MATCH_ADDRTYPE y
-      IP_NF_TARGET_LOG y
-      IP_NF_MANGLE y
-      IPV6 m
-      VLAN_8021Q m
-
-      CIFS y
-      CIFS_XATTR y
-      CIFS_POSIX y
-      CIFS_FSCACHE y
-      CIFS_ACL y
-
-      ZRAM m
-
-      # Disable OABI to have seccomp_filter (required for systemd)
-      # https://github.com/raspberrypi/firmware/issues/651
-      OABI_COMPAT n
-
-      # Fail to build
-      DRM n
-      SCSI_ADVANSYS n
-      USB_ISP1362_HCD n
-      SND_SOC n
-      SND_ALI5451 n
-      FB_SAVAGE n
-      SCSI_NSP32 n
-      ATA_SFF n
-      SUNGEM n
-      IRDA n
-      ATM_HE n
-      SCSI_ACARD n
-      BLK_DEV_CMD640_ENHANCED n
-
-      FUSE_FS m
-
-      # nixos mounts some cgroup
-      CGROUPS y
-
-      # Latencytop
-      LATENCYTOP y
-
-      # Disable the common config Xen, it doesn't build on ARM
-      XEN? n
-    '';
-    kernelTarget = "zImage";
-  };
+  # Legacy attribute, for compatibility with existing configs only.
+  raspberrypi2 = armv7l-hf-multiplatform;
 
   scaleway-c1 = armv7l-hf-multiplatform // {
     gcc = {
       cpu = "cortex-a9";
       fpu = "vfpv3";
-      float = "hard";
     };
   };
 
@@ -363,7 +233,6 @@ rec {
     gcc = {
       cpu = "cortex-a9";
       fpu = "neon";
-      float = "hard";
     };
   };
 
@@ -376,83 +245,6 @@ rec {
     kernelBaseConfig = "guruplug_defconfig";
   };
 
-  fuloong2f_n32 = {
-    name = "fuloong2f_n32";
-    kernelMajor = "2.6";
-    kernelBaseConfig = "lemote2f_defconfig";
-    kernelArch = "mips";
-    kernelAutoModules = false;
-    kernelExtraConfig = ''
-      MIGRATION n
-      COMPACTION n
-
-      # nixos mounts some cgroup
-      CGROUPS y
-
-      BLK_DEV_RAM y
-      BLK_DEV_INITRD y
-      BLK_DEV_CRYPTOLOOP m
-      BLK_DEV_DM m
-      DM_CRYPT m
-      MD y
-      REISERFS_FS m
-      EXT4_FS m
-      USB_STORAGE_CYPRESS_ATACB m
-
-      IP_PNP y
-      IP_PNP_DHCP y
-      IP_PNP_BOOTP y
-      NFS_FS y
-      ROOT_NFS y
-      TUN m
-      NFS_V4 y
-      NFS_V4_1 y
-      NFS_FSCACHE y
-      NFSD m
-      NFSD_V2_ACL y
-      NFSD_V3 y
-      NFSD_V3_ACL y
-      NFSD_V4 y
-
-      # Fail to build
-      DRM n
-      SCSI_ADVANSYS n
-      USB_ISP1362_HCD n
-      SND_SOC n
-      SND_ALI5451 n
-      FB_SAVAGE n
-      SCSI_NSP32 n
-      ATA_SFF n
-      SUNGEM n
-      IRDA n
-      ATM_HE n
-      SCSI_ACARD n
-      BLK_DEV_CMD640_ENHANCED n
-
-      FUSE_FS m
-
-      # Needed for udev >= 150
-      SYSFS_DEPRECATED_V2 n
-
-      VGA_CONSOLE n
-      VT_HW_CONSOLE_BINDING y
-      SERIAL_8250_CONSOLE y
-      FRAMEBUFFER_CONSOLE y
-      EXT2_FS y
-      EXT3_FS y
-      REISERFS_FS y
-      MAGIC_SYSRQ y
-
-      # The kernel doesn't boot at all, with FTRACE
-      FTRACE n
-    '';
-    kernelTarget = "vmlinux";
-    gcc = {
-      arch = "loongson2f";
-      abi = "n32";
-    };
-  };
-
   beaglebone = armv7l-hf-multiplatform // {
     name = "beaglebone";
     kernelBaseConfig = "bb.org_defconfig";
@@ -461,6 +253,27 @@ rec {
     kernelTarget = "zImage";
   };
 
+  # https://developer.android.com/ndk/guides/abis#armeabi
+  armv5te-android = {
+    name = "armeabi";
+    gcc = {
+      arch = "armv5te";
+      float = "soft";
+      float-abi = "soft";
+    };
+  };
+
+  # https://developer.android.com/ndk/guides/abis#v7a
+  armv7a-android =  {
+    name = "armeabi-v7a";
+    gcc = {
+      arch = "armv7-a";
+      float = "hard";
+      float-abi = "softfp";
+      fpu = "vfpv3-d16";
+    };
+  };
+
   armv7l-hf-multiplatform = {
     name = "armv7l-hf-multiplatform";
     kernelMajor = "2.6"; # Using "2.6" enables 2.6 kernel syscalls in glibc.
@@ -481,6 +294,10 @@ rec {
 
       # Hangs ODROID-XU4
       ARM_BIG_LITTLE_CPUIDLE n
+
+      # Disable OABI to have seccomp_filter (required for systemd)
+      # https://github.com/raspberrypi/firmware/issues/651
+      OABI_COMPAT n
     '';
     gcc = {
       # Some table about fpu flags:
@@ -498,7 +315,6 @@ rec {
       # and the above page suggests NEON is only an improvement with hand-written assembly.
       arch = "armv7-a";
       fpu = "vfpv3-d16";
-      float = "hard";
 
       # For Raspberry Pi the 2 the best would be:
       #   cpu = "cortex-a7";
@@ -541,6 +357,102 @@ rec {
     };
   };
 
+  ##
+  ## MIPS
+  ##
+
+  ben_nanonote = {
+    name = "ben_nanonote";
+    kernelMajor = "2.6";
+    kernelArch = "mips";
+    gcc = {
+      arch = "mips32";
+      float = "soft";
+    };
+  };
+
+  fuloong2f_n32 = {
+    name = "fuloong2f_n32";
+    kernelMajor = "2.6";
+    kernelBaseConfig = "lemote2f_defconfig";
+    kernelArch = "mips";
+    kernelAutoModules = false;
+    kernelExtraConfig = ''
+      MIGRATION n
+      COMPACTION n
+
+      # nixos mounts some cgroup
+      CGROUPS y
+
+      BLK_DEV_RAM y
+      BLK_DEV_INITRD y
+      BLK_DEV_CRYPTOLOOP m
+      BLK_DEV_DM m
+      DM_CRYPT m
+      MD y
+      REISERFS_FS m
+      EXT4_FS m
+      USB_STORAGE_CYPRESS_ATACB m
+
+      IP_PNP y
+      IP_PNP_DHCP y
+      IP_PNP_BOOTP y
+      NFS_FS y
+      ROOT_NFS y
+      TUN m
+      NFS_V4 y
+      NFS_V4_1 y
+      NFS_FSCACHE y
+      NFSD m
+      NFSD_V2_ACL y
+      NFSD_V3 y
+      NFSD_V3_ACL y
+      NFSD_V4 y
+
+      # Fail to build
+      DRM n
+      SCSI_ADVANSYS n
+      USB_ISP1362_HCD n
+      SND_SOC n
+      SND_ALI5451 n
+      FB_SAVAGE n
+      SCSI_NSP32 n
+      ATA_SFF n
+      SUNGEM n
+      IRDA n
+      ATM_HE n
+      SCSI_ACARD n
+      BLK_DEV_CMD640_ENHANCED n
+
+      FUSE_FS m
+
+      # Needed for udev >= 150
+      SYSFS_DEPRECATED_V2 n
+
+      VGA_CONSOLE n
+      VT_HW_CONSOLE_BINDING y
+      SERIAL_8250_CONSOLE y
+      FRAMEBUFFER_CONSOLE y
+      EXT2_FS y
+      EXT3_FS y
+      REISERFS_FS y
+      MAGIC_SYSRQ y
+
+      # The kernel doesn't boot at all, with FTRACE
+      FTRACE n
+    '';
+    kernelTarget = "vmlinux";
+    gcc = {
+      arch = "loongson2f";
+      float = "hard";
+      abi = "n32";
+    };
+  };
+
+  ##
+  ## Other
+  ##
+
   riscv-multiplatform = bits: {
     name = "riscv-multiplatform";
     kernelArch = "riscv";
@@ -562,5 +474,6 @@ rec {
       "armv7l-linux" = armv7l-hf-multiplatform;
       "aarch64-linux" = aarch64-multiplatform;
       "mipsel-linux" = fuloong2f_n32;
+      "powerpc64le-linux" = powernv;
     }.${system} or pcBase;
 }
diff --git a/lib/tests/misc.nix b/lib/tests/misc.nix
index 1657ec33a46c..d3bd7746d89c 100644
--- a/lib/tests/misc.nix
+++ b/lib/tests/misc.nix
@@ -45,6 +45,21 @@ runTests {
     expected = true;
   };
 
+  testBitAnd = {
+    expr = (bitAnd 3 10);
+    expected = 2;
+  };
+
+  testBitOr = {
+    expr = (bitOr 3 10);
+    expected = 11;
+  };
+
+  testBitXor = {
+    expr = (bitXor 3 10);
+    expected = 9;
+  };
+
 # STRINGS
 
   testConcatMapStrings = {
@@ -93,10 +108,11 @@ runTests {
             "${builtins.storeDir}/d945ibfx9x185xf04b890y4f9g3cbb63-python-2.7.11";
       in {
         storePath = isStorePath goodPath;
+        storePathDerivation = isStorePath (import ../.. {}).hello;
         storePathAppendix = isStorePath
           "${goodPath}/bin/python";
         nonAbsolute = isStorePath (concatStrings (tail (stringToCharacters goodPath)));
-        asPath = isStorePath (builtins.toPath goodPath);
+        asPath = isStorePath goodPath;
         otherPath = isStorePath "/something/else";
         otherVals = {
           attrset = isStorePath {};
@@ -106,6 +122,7 @@ runTests {
       };
     expected = {
       storePath = true;
+      storePathDerivation = true;
       storePathAppendix = false;
       nonAbsolute = false;
       asPath = true;
@@ -196,6 +213,30 @@ runTests {
   };
 
 
+# ATTRSETS
+
+  # code from the example
+  testRecursiveUpdateUntil = {
+    expr = recursiveUpdateUntil (path: l: r: path == ["foo"]) {
+      # first attribute set
+      foo.bar = 1;
+      foo.baz = 2;
+      bar = 3;
+    } {
+      #second attribute set
+      foo.bar = 1;
+      foo.quz = 2;
+      baz = 4;
+    };
+    expected = {
+      foo.bar = 1; # 'foo.*' from the second set
+      foo.quz = 2; #
+      bar = 3;     # 'bar' from the first set
+      baz = 4;     # 'baz' from the second set
+    };
+  };
+
+
 # GENERATORS
 # these tests assume attributes are converted to lists
 # in alphabetical order
@@ -205,6 +246,29 @@ runTests {
     expected = ''f\:oo:bar'';
   };
 
+  testMkValueString = {
+    expr = let
+      vals = {
+        int = 42;
+        string = ''fo"o'';
+        bool = true;
+        bool2 = false;
+        null = null;
+        # float = 42.23; # floats are strange
+      };
+      in mapAttrs
+        (const (generators.mkValueStringDefault {}))
+        vals;
+    expected = {
+      int = "42";
+      string = ''fo"o'';
+      bool = "true";
+      bool2 = "false";
+      null = "null";
+      # float = "42.23" true false [ "bar" ] ]'';
+    };
+  };
+
   testToKeyValue = {
     expr = generators.toKeyValue {} {
       key = "value";
@@ -247,6 +311,8 @@ runTests {
       "section 1" = {
         attribute1 = 5;
         x = "Me-se JarJar Binx";
+        # booleans are converted verbatim by default
+        boolean = false;
       };
       "foo[]" = {
         "he\\h=he" = "this is okay";
@@ -258,6 +324,7 @@ runTests {
 
       [section 1]
       attribute1=5
+      boolean=false
       x=Me-se JarJar Binx
     '';
   };
@@ -289,7 +356,8 @@ runTests {
     expr = mapAttrs (const (generators.toPretty {})) rec {
       int = 42;
       bool = true;
-      string = "fnord";
+      string = ''fno"rd'';
+      path = /. + "/foo";
       null_ = null;
       function = x: x;
       functionArgs = { arg ? 4, foo }: arg;
@@ -300,13 +368,14 @@ runTests {
     expected = rec {
       int = "42";
       bool = "true";
-      string = "\"fnord\"";
+      string = ''"fno\"rd"'';
+      path = "/foo";
       null_ = "null";
       function = "<λ>";
       functionArgs = "<λ:{(arg),foo}>";
       list = "[ 3 4 ${function} [ false ] ]";
       attrs = "{ \"foo\" = null; \"foo bar\" = \"baz\"; }";
-      drv = "<δ>";
+      drv = "<δ:test>";
     };
   };
 
@@ -335,10 +404,6 @@ runTests {
 
           resRem7 = res6.replace (a: removeAttrs a ["a"]);
 
-          resReplace6 = let x = defaultOverridableDelayableArgs id { a = 7; mergeAttrBy = { a = builtins.add; }; };
-                            x2 = x.merge { a = 20; }; # now we have 27
-                        in (x2.replace) { a = 10; }; # and override the value by 10
-
           # fixed tests (delayed args): (when using them add some comments, please)
           resFixed1 =
                 let x = defaultOverridableDelayableArgs id ( x: { a = 7; c = x.fixed.b; });
diff --git a/lib/tests/modules.sh b/lib/tests/modules.sh
index 96a91c0fffbc..b83e1eb7d82d 100755
--- a/lib/tests/modules.sh
+++ b/lib/tests/modules.sh
@@ -136,7 +136,18 @@ checkConfigOutput "true" "$@" ./define-module-check.nix
 # Check coerced value.
 checkConfigOutput "\"42\"" config.value ./declare-coerced-value.nix
 checkConfigOutput "\"24\"" config.value ./declare-coerced-value.nix ./define-value-string.nix
-checkConfigError 'The option value .* in .* is not.*string or signed integer.*' config.value ./declare-coerced-value.nix ./define-value-list.nix
+checkConfigError 'The option value .* in .* is not.*string or signed integer convertible to it' config.value ./declare-coerced-value.nix ./define-value-list.nix
+
+# Check coerced value with unsound coercion
+checkConfigOutput "12" config.value ./declare-coerced-value-unsound.nix
+checkConfigError 'The option value .* in .* is not.*8 bit signed integer.* or string convertible to it' config.value ./declare-coerced-value-unsound.nix ./define-value-string-bigint.nix
+checkConfigError 'unrecognised JSON value' config.value ./declare-coerced-value-unsound.nix ./define-value-string-arbitrary.nix
+
+# Check loaOf with long list.
+checkConfigOutput "1 2 3 4 5 6 7 8 9 10" config.result ./loaOf-with-long-list.nix
+
+# Check loaOf with many merges of lists.
+checkConfigOutput "1 2 3 4 5 6 7 8 9 10" config.result ./loaOf-with-many-list-merges.nix
 
 cat <<EOF
 ====== module tests ======
diff --git a/lib/tests/modules/declare-coerced-value-unsound.nix b/lib/tests/modules/declare-coerced-value-unsound.nix
new file mode 100644
index 000000000000..7a017f24e77d
--- /dev/null
+++ b/lib/tests/modules/declare-coerced-value-unsound.nix
@@ -0,0 +1,10 @@
+{ lib, ... }:
+
+{
+  options = {
+    value = lib.mkOption {
+      default = "12";
+      type = lib.types.coercedTo lib.types.str lib.toInt lib.types.ints.s8;
+    };
+  };
+}
diff --git a/lib/tests/modules/define-value-string-arbitrary.nix b/lib/tests/modules/define-value-string-arbitrary.nix
new file mode 100644
index 000000000000..8e3abaf536a0
--- /dev/null
+++ b/lib/tests/modules/define-value-string-arbitrary.nix
@@ -0,0 +1,3 @@
+{
+  value = "foobar";
+}
diff --git a/lib/tests/modules/define-value-string-bigint.nix b/lib/tests/modules/define-value-string-bigint.nix
new file mode 100644
index 000000000000..f27e31985c92
--- /dev/null
+++ b/lib/tests/modules/define-value-string-bigint.nix
@@ -0,0 +1,3 @@
+{
+  value = "1000";
+}
diff --git a/lib/tests/modules/loaOf-with-long-list.nix b/lib/tests/modules/loaOf-with-long-list.nix
new file mode 100644
index 000000000000..f30903c47e50
--- /dev/null
+++ b/lib/tests/modules/loaOf-with-long-list.nix
@@ -0,0 +1,19 @@
+{ config, lib, ... }:
+
+{
+  options = {
+    loaOfInt = lib.mkOption {
+      type = lib.types.loaOf lib.types.int;
+    };
+
+    result = lib.mkOption {
+      type = lib.types.str;
+    };
+  };
+
+  config = {
+    loaOfInt = [ 1 2 3 4 5 6 7 8 9 10 ];
+
+    result = toString (lib.attrValues config.loaOfInt);
+  };
+}
diff --git a/lib/tests/modules/loaOf-with-many-list-merges.nix b/lib/tests/modules/loaOf-with-many-list-merges.nix
new file mode 100644
index 000000000000..f8f8a8da82bc
--- /dev/null
+++ b/lib/tests/modules/loaOf-with-many-list-merges.nix
@@ -0,0 +1,19 @@
+{ config, lib, ... }:
+
+{
+  options = {
+    loaOfInt = lib.mkOption {
+      type = lib.types.loaOf lib.types.int;
+    };
+
+    result = lib.mkOption {
+      type = lib.types.str;
+    };
+  };
+
+  config = {
+    loaOfInt = lib.mkMerge (map lib.singleton [ 1 2 3 4 5 6 7 8 9 10 ]);
+
+    result = toString (lib.attrValues config.loaOfInt);
+  };
+}
diff --git a/lib/tests/release.nix b/lib/tests/release.nix
index a6184041682f..d9a8a0067253 100644
--- a/lib/tests/release.nix
+++ b/lib/tests/release.nix
@@ -13,7 +13,6 @@ pkgs.stdenv.mkDerivation {
     export NIX_DB_DIR=$TEST_ROOT/db
     export NIX_LOCALSTATE_DIR=$TEST_ROOT/var
     export NIX_LOG_DIR=$TEST_ROOT/var/log/nix
-    export NIX_MANIFESTS_DIR=$TEST_ROOT/var/nix/manifests
     export NIX_STATE_DIR=$TEST_ROOT/var/nix
     export NIX_STORE_DIR=$TEST_ROOT/store
     export PAGER=cat
@@ -21,7 +20,7 @@ pkgs.stdenv.mkDerivation {
     nix-store --init
 
     cd ${pkgs.path}/lib/tests
-    ./modules.sh
+    bash ./modules.sh
 
     [[ "$(nix-instantiate --eval --strict misc.nix)" == "[ ]" ]]
 
diff --git a/lib/tests/systems.nix b/lib/tests/systems.nix
index ffdd8ae929c8..91604280e4e7 100644
--- a/lib/tests/systems.nix
+++ b/lib/tests/systems.nix
@@ -22,7 +22,7 @@ in with lib.systems.doubles; lib.runTests {
   cygwin = assertTrue (mseteq cygwin [ "i686-cygwin" "x86_64-cygwin" ]);
   darwin = assertTrue (mseteq darwin [ "x86_64-darwin" ]);
   freebsd = assertTrue (mseteq freebsd [ "i686-freebsd" "x86_64-freebsd" ]);
-  gnu = assertTrue (mseteq gnu (linux /* ++ hurd ++ kfreebsd ++ ... */));
+  gnu = assertTrue (mseteq gnu (linux /* ++ kfreebsd ++ ... */));
   illumos = assertTrue (mseteq illumos [ "x86_64-solaris" ]);
   linux = assertTrue (mseteq linux [ "i686-linux" "x86_64-linux" "armv5tel-linux" "armv6l-linux" "armv7l-linux" "aarch64-linux" "mipsel-linux" ]);
   netbsd = assertTrue (mseteq netbsd [ "i686-netbsd" "x86_64-netbsd" ]);
diff --git a/lib/trivial.nix b/lib/trivial.nix
index a928e1dbca98..b1eea0bf1247 100644
--- a/lib/trivial.nix
+++ b/lib/trivial.nix
@@ -1,6 +1,9 @@
 { lib }:
+
 rec {
 
+  ## Simple (higher order) functions
+
   /* The identity function
      For when you need a function that does “nothing”.
 
@@ -22,7 +25,7 @@ rec {
 
   ## Named versions corresponding to some builtin operators.
 
-  /* Concat two strings */
+  /* Concatenate two lists */
   concat = x: y: x ++ y;
 
   /* boolean “or” */
@@ -31,6 +34,24 @@ rec {
   /* boolean “and” */
   and = x: y: x && y;
 
+  /* bitwise “and” */
+  bitAnd = builtins.bitAnd
+    or (import ./zip-int-bits.nix
+        (a: b: if a==1 && b==1 then 1 else 0));
+
+  /* bitwise “or” */
+  bitOr = builtins.bitOr
+    or (import ./zip-int-bits.nix
+        (a: b: if a==1 || b==1 then 1 else 0));
+
+  /* bitwise “xor” */
+  bitXor = builtins.bitXor
+    or (import ./zip-int-bits.nix
+        (a: b: if a!=b then 1 else 0));
+
+  /* bitwise “not” */
+  bitNot = builtins.sub (-1);
+
   /* Convert a boolean to a string.
      Note that toString on a bool returns "1" and "".
   */
@@ -44,29 +65,54 @@ rec {
   */
   mergeAttrs = x: y: x // y;
 
-  # Flip the order of the arguments of a binary function.
+  /* Flip the order of the arguments of a binary function.
+
+     Example:
+       flip concat [1] [2]
+       => [ 2 1 ]
+  */
   flip = f: a: b: f b a;
 
-  # Apply function if argument is non-null
+  /* Apply function if argument is non-null.
+
+     Example:
+       mapNullable (x: x+1) null
+       => null
+       mapNullable (x: x+1) 22
+       => 23
+  */
   mapNullable = f: a: if isNull a then a else f a;
 
   # Pull in some builtins not included elsewhere.
   inherit (builtins)
     pathExists readFile isBool
-    isInt add sub lessThan
+    isInt isFloat add sub lessThan
     seq deepSeq genericClosure;
 
-  inherit (lib.strings) fileContents;
 
-  # Return the Nixpkgs version number.
-  nixpkgsVersion =
-    let suffixFile = ../.version-suffix; in
-    fileContents ../.version
-    + (if pathExists suffixFile then fileContents suffixFile else "pre-git");
+  ## nixpks version strings
+
+  # The current full nixpkgs version number.
+  version = release + versionSuffix;
+
+  # The current nixpkgs version number as string.
+  release = lib.strings.fileContents ../.version;
+
+  # The current nixpkgs version suffix as string.
+  versionSuffix =
+    let suffixFile = ../.version-suffix;
+    in if pathExists suffixFile
+    then lib.strings.fileContents suffixFile
+    else "pre-git";
+
+  nixpkgsVersion = builtins.trace "`lib.nixpkgsVersion` is deprecated, use `lib.version` instead!" version;
 
   # Whether we're being called by nix-shell.
   inNixShell = builtins.getEnv "IN_NIX_SHELL" != "";
 
+
+  ## Integer operations
+
   # Return minimum/maximum of two numbers.
   min = x: y: if x < y then x else y;
   max = x: y: if x > y then x else y;
@@ -81,6 +127,9 @@ rec {
   */
   mod = base: int: base - (int * (builtins.div base int));
 
+
+  ## Comparisons
+
   /* C-style comparisons
 
      a < b,  compare a b => -1
@@ -110,17 +159,20 @@ rec {
        cmp "fooa" "a" => -1
        # while
        compare "fooa" "a" => 1
-
   */
   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);
 
+
+  ## Warnings
+
   /* See https://github.com/NixOS/nix/issues/749. Eventually we'd like these
      to expand to Nix builtins that carry metadata so that Nix can filter out
      the INFO messages without parsing the message string.
@@ -136,28 +188,36 @@ rec {
   warn = msg: builtins.trace "WARNING: ${msg}";
   info = msg: builtins.trace "INFO: ${msg}";
 
-  # | Add metadata about expected function arguments to a function.
-  # The metadata should match the format given by
-  # builtins.functionArgs, i.e. a set from expected argument to a bool
-  # representing whether that argument has a default or not.
-  # setFunctionArgs : (a → b) → Map String Bool → (a → b)
-  #
-  # This function is necessary because you can't dynamically create a
-  # function of the { a, b ? foo, ... }: format, but some facilities
-  # like callPackage expect to be able to query expected arguments.
+
+  ## Function annotations
+
+  /* Add metadata about expected function arguments to a function.
+     The metadata should match the format given by
+     builtins.functionArgs, i.e. a set from expected argument to a bool
+     representing whether that argument has a default or not.
+     setFunctionArgs : (a → b) → Map String Bool → (a → b)
+
+     This function is necessary because you can't dynamically create a
+     function of the { a, b ? foo, ... }: format, but some facilities
+     like callPackage expect to be able to query expected arguments.
+  */
   setFunctionArgs = f: args:
     { # TODO: Should we add call-time "type" checking like built in?
       __functor = self: f;
       __functionArgs = args;
     };
 
-  # | Extract the expected function arguments from a function.
-  # This works both with nix-native { a, b ? foo, ... }: style
-  # functions and functions with args set with 'setFunctionArgs'. It
-  # has the same return type and semantics as builtins.functionArgs.
-  # setFunctionArgs : (a → b) → Map String Bool.
+  /* Extract the expected function arguments from a function.
+     This works both with nix-native { a, b ? foo, ... }: style
+     functions and functions with args set with 'setFunctionArgs'. It
+     has the same return type and semantics as builtins.functionArgs.
+     setFunctionArgs : (a → b) → Map String Bool.
+  */
   functionArgs = f: f.__functionArgs or (builtins.functionArgs f);
 
+  /* Check whether something is a function or something
+     annotated with function args.
+  */
   isFunction = f: builtins.isFunction f ||
     (f ? __functor && isFunction (f.__functor f));
 }
diff --git a/lib/types.nix b/lib/types.nix
index a334db5c7247..4e44e7521c4b 100644
--- a/lib/types.nix
+++ b/lib/types.nix
@@ -8,7 +8,7 @@ with lib.trivial;
 with lib.strings;
 let
 
-  inherit (lib.modules) mergeDefinitions filterOverrides;
+  inherit (lib.modules) mergeDefinitions;
   outer_types =
 rec {
   isType = type: x: (x._type or "") == type;
@@ -119,7 +119,9 @@ rec {
       let
         betweenDesc = lowest: highest:
           "${toString lowest} and ${toString highest} (both inclusive)";
-        between = lowest: highest: assert lowest <= highest;
+        between = lowest: highest:
+          assert lib.assertMsg (lowest <= highest)
+            "ints.between: lowest must be smaller than highest";
           addCheck int (x: x >= lowest && x <= highest) // {
             name = "intBetween";
             description = "integer between ${betweenDesc lowest highest}";
@@ -167,6 +169,13 @@ rec {
         # s32 = sign 32 4294967296;
       };
 
+    float = mkOptionType rec {
+        name = "float";
+        description = "floating point number";
+        check = isFloat;
+        merge = mergeOneOption;
+    };
+
     str = mkOptionType {
       name = "str";
       description = "string";
@@ -256,7 +265,7 @@ rec {
       functor = (defaultFunctor name) // { wrapped = elemType; };
     };
 
-    nonEmptyListOf = elemType: 
+    nonEmptyListOf = elemType:
       let list = addCheck (types.listOf elemType) (l: l != []);
       in list // { description = "non-empty " + list.description; };
 
@@ -280,24 +289,34 @@ rec {
     # List or attribute set of ...
     loaOf = elemType:
       let
-        convertIfList = defIdx: def:
+        convertAllLists = defs:
+          let
+            padWidth = stringLength (toString (length defs));
+            unnamedPrefix = i: "unnamed-" + fixedWidthNumber padWidth i + ".";
+          in
+            imap1 (i: convertIfList (unnamedPrefix i)) defs;
+
+        convertIfList = unnamedPrefix: def:
           if isList def.value then
-            { inherit (def) file;
-              value = listToAttrs (
-                imap1 (elemIdx: elem:
-                  { name = elem.name or "unnamed-${toString defIdx}.${toString elemIdx}";
-                    value = elem;
-                  }) def.value);
-            }
+            let
+              padWidth = stringLength (toString (length def.value));
+              unnamed = i: unnamedPrefix + fixedWidthNumber padWidth i;
+            in
+              { inherit (def) file;
+                value = listToAttrs (
+                  imap1 (elemIdx: elem:
+                    { name = elem.name or (unnamed elemIdx);
+                      value = elem;
+                    }) def.value);
+              }
           else
             def;
-        listOnly = listOf elemType;
         attrOnly = attrsOf elemType;
       in mkOptionType rec {
         name = "loaOf";
         description = "list or attribute set of ${elemType.description}s";
         check = x: isList x || isAttrs x;
-        merge = loc: defs: attrOnly.merge loc (imap1 convertIfList defs);
+        merge = loc: defs: attrOnly.merge loc (convertAllLists defs);
         getSubOptions = prefix: elemType.getSubOptions (prefix ++ ["<name?>"]);
         getSubModules = elemType.getSubModules;
         substSubModules = m: loaOf (elemType.substSubModules m);
@@ -361,7 +380,13 @@ rec {
             # This is mandatory as some option declaration might use the
             # "name" attribute given as argument of the submodule and use it
             # as the default of option declarations.
-            args.name = "&lt;name&gt;";
+            #
+            # Using lookalike unicode single angle quotation marks because
+            # of the docbook transformation the options receive. In all uses
+            # &gt; and &lt; wouldn't be encoded correctly so the encoded values
+            # would be used, and use of `<` and `>` would break the XML document.
+            # It shouldn't cause an issue since this is cosmetic for the manual.
+            args.name = "‹name›";
           }).options;
         getSubModules = opts';
         substSubModules = m: submodule m;
@@ -416,19 +441,18 @@ rec {
     # Either value of type `finalType` or `coercedType`, the latter is
     # converted to `finalType` using `coerceFunc`.
     coercedTo = coercedType: coerceFunc: finalType:
-      assert coercedType.getSubModules == null;
+      assert lib.assertMsg (coercedType.getSubModules == null)
+        "coercedTo: coercedType must not have submodules (it’s a ${
+          coercedType.description})";
       mkOptionType rec {
         name = "coercedTo";
-        description = "${finalType.description} or ${coercedType.description}";
-        check = x: finalType.check x || coercedType.check x;
+        description = "${finalType.description} or ${coercedType.description} convertible to it";
+        check = x: finalType.check x || (coercedType.check x && finalType.check (coerceFunc x));
         merge = loc: defs:
           let
             coerceVal = val:
               if finalType.check val then val
-              else let
-                coerced = coerceFunc val;
-              in assert finalType.check coerced; coerced;
-
+              else coerceFunc val;
           in finalType.merge loc (map (def: def // { value = coerceVal def.value; }) defs);
         getSubOptions = finalType.getSubOptions;
         getSubModules = finalType.getSubModules;
diff --git a/lib/versions.nix b/lib/versions.nix
new file mode 100644
index 000000000000..8f7f98ff5e1e
--- /dev/null
+++ b/lib/versions.nix
@@ -0,0 +1,47 @@
+/* Version string functions. */
+{ lib }:
+
+let
+
+  splitVersion = builtins.splitVersion or (lib.splitString ".");
+
+in
+
+rec {
+
+  /* Get the major version string from a string.
+
+    Example:
+      major "1.2.3"
+      => "1"
+  */
+  major = v: builtins.elemAt (splitVersion v) 0;
+
+  /* Get the minor version string from a string.
+
+    Example:
+      minor "1.2.3"
+      => "2"
+  */
+  minor = v: builtins.elemAt (splitVersion v) 1;
+
+  /* Get the patch version string from a string.
+
+    Example:
+      patch "1.2.3"
+      => "3"
+  */
+  patch = v: builtins.elemAt (splitVersion v) 2;
+
+  /* Get string of the first two parts (major and minor)
+     of a version string.
+
+     Example:
+       majorMinor "1.2.3"
+       => "1.2"
+  */
+  majorMinor = v:
+    builtins.concatStringsSep "."
+    (lib.take 2 (splitVersion v));
+
+}
diff --git a/lib/zip-int-bits.nix b/lib/zip-int-bits.nix
new file mode 100644
index 000000000000..edbcdfe1e682
--- /dev/null
+++ b/lib/zip-int-bits.nix
@@ -0,0 +1,39 @@
+/* Helper function to implement a fallback for the bit operators
+   `bitAnd`, `bitOr` and `bitXOr` on older nix version.
+   See ./trivial.nix
+*/
+f: x: y:
+  let
+    # (intToBits 6) -> [ 0 1 1 ]
+    intToBits = x:
+      if x == 0 || x == -1 then
+        []
+      else
+        let
+          headbit  = if (x / 2) * 2 != x then 1 else 0;          # x & 1
+          tailbits = if x < 0 then ((x + 1) / 2) - 1 else x / 2; # x >> 1
+        in
+          [headbit] ++ (intToBits tailbits);
+
+    # (bitsToInt [ 0 1 1 ] 0) -> 6
+    # (bitsToInt [ 0 1 0 ] 1) -> -6
+    bitsToInt = l: signum:
+      if l == [] then
+        (if signum == 0 then 0 else -1)
+      else
+        (builtins.head l) + (2 * (bitsToInt (builtins.tail l) signum));
+
+    xsignum = if x < 0 then 1 else 0;
+    ysignum = if y < 0 then 1 else 0;
+    zipListsWith' = fst: snd:
+      if fst==[] && snd==[] then
+        []
+      else if fst==[] then
+        [(f xsignum             (builtins.head snd))] ++ (zipListsWith' []                  (builtins.tail snd))
+      else if snd==[] then
+        [(f (builtins.head fst) ysignum            )] ++ (zipListsWith' (builtins.tail fst) []                 )
+      else
+        [(f (builtins.head fst) (builtins.head snd))] ++ (zipListsWith' (builtins.tail fst) (builtins.tail snd));
+  in
+    assert (builtins.isInt x) && (builtins.isInt y);
+    bitsToInt (zipListsWith' (intToBits x) (intToBits y)) (f xsignum ysignum)