about summary refs log tree commit diff
path: root/nixpkgs/lib
diff options
context:
space:
mode:
authorAlyssa Ross <hi@alyssa.is>2021-09-08 17:57:14 +0000
committerAlyssa Ross <hi@alyssa.is>2021-09-13 11:31:47 +0000
commitee7984efa14902a2ddd820c937457667a4f40c6a (patch)
treec9c1d046733cefe5e21fdd8a52104175d47b2443 /nixpkgs/lib
parentffc9d4ba381da62fd08b361bacd1e71e2a3d934d (diff)
parentb3c692172e5b5241b028a98e1977f9fb12eeaf42 (diff)
downloadnixlib-ee7984efa14902a2ddd820c937457667a4f40c6a.tar
nixlib-ee7984efa14902a2ddd820c937457667a4f40c6a.tar.gz
nixlib-ee7984efa14902a2ddd820c937457667a4f40c6a.tar.bz2
nixlib-ee7984efa14902a2ddd820c937457667a4f40c6a.tar.lz
nixlib-ee7984efa14902a2ddd820c937457667a4f40c6a.tar.xz
nixlib-ee7984efa14902a2ddd820c937457667a4f40c6a.tar.zst
nixlib-ee7984efa14902a2ddd820c937457667a4f40c6a.zip
Merge commit 'b3c692172e5b5241b028a98e1977f9fb12eeaf42'
Diffstat (limited to 'nixpkgs/lib')
-rw-r--r--nixpkgs/lib/attrsets.nix21
-rw-r--r--nixpkgs/lib/default.nix4
-rw-r--r--nixpkgs/lib/deprecated.nix10
-rw-r--r--nixpkgs/lib/fixed-points.nix10
-rw-r--r--nixpkgs/lib/flake.nix2
-rw-r--r--nixpkgs/lib/generators.nix2
-rw-r--r--nixpkgs/lib/licenses.nix302
-rw-r--r--nixpkgs/lib/modules.nix1
-rw-r--r--nixpkgs/lib/options.nix3
-rw-r--r--nixpkgs/lib/strings.nix2
-rw-r--r--nixpkgs/lib/systems/doubles.nix17
-rw-r--r--nixpkgs/lib/systems/examples.nix8
-rw-r--r--nixpkgs/lib/systems/inspect.nix3
-rw-r--r--nixpkgs/lib/systems/parse.nix11
-rw-r--r--nixpkgs/lib/systems/platforms.nix8
-rw-r--r--nixpkgs/lib/tests/maintainers.nix4
-rw-r--r--nixpkgs/lib/tests/misc.nix10
-rw-r--r--nixpkgs/lib/tests/release.nix2
-rw-r--r--nixpkgs/lib/tests/systems.nix4
-rw-r--r--nixpkgs/lib/trivial.nix7
-rw-r--r--nixpkgs/lib/types.nix7
21 files changed, 253 insertions, 185 deletions
diff --git a/nixpkgs/lib/attrsets.nix b/nixpkgs/lib/attrsets.nix
index 5c787940cb0c..31fddc59e20e 100644
--- a/nixpkgs/lib/attrsets.nix
+++ b/nixpkgs/lib/attrsets.nix
@@ -5,7 +5,7 @@ let
   inherit (builtins) head tail length;
   inherit (lib.trivial) and;
   inherit (lib.strings) concatStringsSep sanitizeDerivationName;
-  inherit (lib.lists) fold concatMap concatLists;
+  inherit (lib.lists) foldr foldl' concatMap concatLists elemAt;
 in
 
 rec {
@@ -55,10 +55,13 @@ rec {
        => { a = { b = 3; }; }
   */
   setAttrByPath = attrPath: value:
-    if attrPath == [] then value
-    else listToAttrs
-      [ { name = head attrPath; value = setAttrByPath (tail attrPath) value; } ];
-
+    let
+      len = length attrPath;
+      atDepth = n:
+        if n == len
+        then value
+        else { ${elemAt attrPath n} = atDepth (n + 1); };
+    in atDepth 0;
 
   /* Like `attrByPath' without a default value. If it doesn't find the
      path it will throw.
@@ -152,8 +155,8 @@ rec {
        => { a = [ 2 3 ]; }
   */
   foldAttrs = op: nul: list_of_attrs:
-    fold (n: a:
-        fold (name: o:
+    foldr (n: a:
+        foldr (name: o:
           o // { ${name} = op n.${name} (a.${name} or nul); }
         ) a (attrNames n)
     ) {} list_of_attrs;
@@ -195,7 +198,7 @@ rec {
          ]
   */
   cartesianProductOfSets = attrsOfLists:
-    lib.foldl' (listOfAttrs: attrName:
+    foldl' (listOfAttrs: attrName:
       concatMap (attrs:
         map (listValue: attrs // { ${attrName} = listValue; }) attrsOfLists.${attrName}
       ) listOfAttrs
@@ -455,7 +458,7 @@ rec {
        => true
    */
   matchAttrs = pattern: attrs: assert isAttrs pattern;
-    fold and true (attrValues (zipAttrsWithNames (attrNames pattern) (n: values:
+    foldr and true (attrValues (zipAttrsWithNames (attrNames pattern) (n: values:
       let pat = head values; val = head (tail values); in
       if length values == 1 then false
       else if isAttrs pat then isAttrs val && matchAttrs pat val
diff --git a/nixpkgs/lib/default.nix b/nixpkgs/lib/default.nix
index 8e29ef5c4201..bb99a1be8a8c 100644
--- a/nixpkgs/lib/default.nix
+++ b/nixpkgs/lib/default.nix
@@ -91,7 +91,7 @@ let
       concatImapStringsSep makeSearchPath makeSearchPathOutput
       makeLibraryPath makeBinPath optionalString
       hasInfix hasPrefix hasSuffix stringToCharacters stringAsChars escape
-      escapeShellArg escapeShellArgs replaceChars lowerChars
+      escapeShellArg escapeShellArgs escapeRegex replaceChars lowerChars
       upperChars toLower toUpper addContextFrom splitString
       removePrefix removeSuffix versionOlder versionAtLeast
       getName getVersion
@@ -115,7 +115,7 @@ let
       mergeModules' mergeOptionDecls evalOptionValue mergeDefinitions
       pushDownProperties dischargeProperties filterOverrides
       sortProperties fixupOptionType mkIf mkAssert mkMerge mkOverride
-      mkOptionDefault mkDefault mkForce mkVMOverride
+      mkOptionDefault mkDefault mkImageMediaOverride mkForce mkVMOverride
       mkFixStrictness mkOrder mkBefore mkAfter mkAliasDefinitions
       mkAliasAndWrapDefinitions fixMergeModules mkRemovedOptionModule
       mkRenamedOptionModule mkMergedOptionModule mkChangedOptionModule
diff --git a/nixpkgs/lib/deprecated.nix b/nixpkgs/lib/deprecated.nix
index be0ef904c66d..ddce69f160cc 100644
--- a/nixpkgs/lib/deprecated.nix
+++ b/nixpkgs/lib/deprecated.nix
@@ -77,11 +77,11 @@ rec {
   # Output : are reqs satisfied? It's asserted.
   checkReqs = attrSet: argList: condList:
   (
-    fold lib.and true
+    foldr lib.and true
       (map (x: let name = (head x); in
 
         ((checkFlag attrSet name) ->
-        (fold lib.and true
+        (foldr lib.and true
         (map (y: let val=(getValue attrSet argList y); in
                 (val!=null) && (val!=false))
         (tail x))))) condList));
@@ -177,7 +177,7 @@ rec {
   # merge attributes with custom function handling the case that the attribute
   # exists in both sets
   mergeAttrsWithFunc = f: set1: set2:
-    fold (n: set: if set ? ${n}
+    foldr (n: set: if set ? ${n}
                         then setAttr set n (f set.${n} set2.${n})
                         else set )
            (set2 // set1) (attrNames set2);
@@ -196,7 +196,7 @@ rec {
   mergeAttrsNoOverride = { mergeLists ? ["buildInputs" "propagatedBuildInputs"],
                            overrideSnd ? [ "buildPhase" ]
                          }: attrs1: attrs2:
-    fold (n: set:
+    foldr (n: set:
         setAttr set n ( if set ? ${n}
             then # merge
               if elem n mergeLists # attribute contains list, merge them by concatenating
@@ -224,7 +224,7 @@ rec {
           mergeAttrBy2 = { mergeAttrBy = lib.mergeAttrs; }
                       // (maybeAttr "mergeAttrBy" {} x)
                       // (maybeAttr "mergeAttrBy" {} y); in
-    fold lib.mergeAttrs {} [
+    foldr lib.mergeAttrs {} [
       x y
       (mapAttrs ( a: v: # merge special names using given functions
           if x ? ${a}
diff --git a/nixpkgs/lib/fixed-points.nix b/nixpkgs/lib/fixed-points.nix
index f998bc74e1db..bf1567a22a66 100644
--- a/nixpkgs/lib/fixed-points.nix
+++ b/nixpkgs/lib/fixed-points.nix
@@ -72,10 +72,10 @@ rec {
   # into one where changes made in the first are available in the
   # 'super' of the second
   composeExtensions =
-    f: g: self: super:
-      let fApplied = f self super;
-          super' = super // fApplied;
-      in fApplied // g self super';
+    f: g: final: prev:
+      let fApplied = f final prev;
+          prev' = prev // fApplied;
+      in fApplied // g final prev';
 
   # Compose several extending functions of the type expected by 'extends' into
   # one where changes made in preceding functions are made available to
@@ -84,7 +84,7 @@ rec {
   # composeManyExtensions : [packageSet -> packageSet -> packageSet] -> packageSet -> packageSet -> packageSet
   #                          ^final        ^prev         ^overrides     ^final        ^prev         ^overrides
   composeManyExtensions =
-    lib.foldr (x: y: composeExtensions x y) (self: super: {});
+    lib.foldr (x: y: composeExtensions x y) (final: prev: {});
 
   # Create an overridable, recursive attribute set. For example:
   #
diff --git a/nixpkgs/lib/flake.nix b/nixpkgs/lib/flake.nix
index f05bd40960a8..0b5e54d547c5 100644
--- a/nixpkgs/lib/flake.nix
+++ b/nixpkgs/lib/flake.nix
@@ -1,5 +1,5 @@
 {
   description = "Library of low-level helper functions for nix expressions.";
 
-  outputs = { self }: { lib = import ./lib; };
+  outputs = { self }: { lib = import ./.; };
 }
diff --git a/nixpkgs/lib/generators.nix b/nixpkgs/lib/generators.nix
index c8144db50ac8..bcb0f371a9b5 100644
--- a/nixpkgs/lib/generators.nix
+++ b/nixpkgs/lib/generators.nix
@@ -248,7 +248,7 @@ rec {
          then v.__pretty v.val
       else if v == {} then "{ }"
       else if v ? type && v.type == "derivation" then
-        "<derivation ${v.drvPath}>"
+        "<derivation ${v.drvPath or "???"}>"
       else "{" + introSpace
           + libStr.concatStringsSep introSpace (libAttr.mapAttrsToList
               (name: value:
diff --git a/nixpkgs/lib/licenses.nix b/nixpkgs/lib/licenses.nix
index 4792f1cb5925..772985f9509d 100644
--- a/nixpkgs/lib/licenses.nix
+++ b/nixpkgs/lib/licenses.nix
@@ -1,44 +1,56 @@
 { lib }:
-let
 
-  spdx = lic: lic // {
-    url = "https://spdx.org/licenses/${lic.spdxId}.html";
-  };
-
-in
-
-lib.mapAttrs (n: v: v // { shortName = n; }) ({
+lib.mapAttrs (lname: lset: let
+  defaultLicense = rec {
+    shortName = lname;
+    free = true; # Most of our licenses are Free, explicitly declare unfree additions as such!
+    deprecated = false;
+  };
+
+  mkLicense = licenseDeclaration: let
+    applyDefaults = license: defaultLicense // license;
+    applySpdx = license:
+      if license ? spdxId
+      then license // { url = "https://spdx.org/licenses/${license.spdxId}.html"; }
+      else license;
+    applyRedistributable = license: { redistributable = license.free; } // license;
+  in lib.pipe licenseDeclaration [
+    applyDefaults
+    applySpdx
+    applyRedistributable
+  ];
+in mkLicense lset) ({
   /* License identifiers from spdx.org where possible.
    * If you cannot find your license here, then look for a similar license or
    * add it to this list. The URL mentioned above is a good source for inspiration.
    */
 
-  abstyles = spdx {
+  abstyles = {
     spdxId = "Abstyles";
     fullName = "Abstyles License";
   };
 
-  afl20 = spdx {
+  afl20 = {
     spdxId = "AFL-2.0";
     fullName = "Academic Free License v2.0";
   };
 
-  afl21 = spdx {
+  afl21 = {
     spdxId = "AFL-2.1";
     fullName = "Academic Free License v2.1";
   };
 
-  afl3 = spdx {
+  afl3 = {
     spdxId = "AFL-3.0";
     fullName = "Academic Free License v3.0";
   };
 
-  agpl3Only = spdx {
+  agpl3Only = {
     spdxId = "AGPL-3.0-only";
     fullName = "GNU Affero General Public License v3.0 only";
   };
 
-  agpl3Plus = spdx {
+  agpl3Plus = {
     spdxId = "AGPL-3.0-or-later";
     fullName = "GNU Affero General Public License v3.0 or later";
   };
@@ -55,7 +67,7 @@ lib.mapAttrs (n: v: v // { shortName = n; }) ({
     free = false;
   };
 
-  apsl20 = spdx {
+  apsl20 = {
     spdxId = "APSL-2.0";
     fullName = "Apple Public Source License 2.0";
   };
@@ -65,72 +77,72 @@ lib.mapAttrs (n: v: v // { shortName = n; }) ({
     url = "https://www.freedesktop.org/wiki/Arphic_Public_License/";
   };
 
-  artistic1 = spdx {
+  artistic1 = {
     spdxId = "Artistic-1.0";
     fullName = "Artistic License 1.0";
   };
 
-  artistic2 = spdx {
+  artistic2 = {
     spdxId = "Artistic-2.0";
     fullName = "Artistic License 2.0";
   };
 
-  asl20 = spdx {
+  asl20 = {
     spdxId = "Apache-2.0";
     fullName = "Apache License 2.0";
   };
 
-  boost = spdx {
+  boost = {
     spdxId = "BSL-1.0";
     fullName = "Boost Software License 1.0";
   };
 
-  beerware = spdx {
+  beerware = {
     spdxId = "Beerware";
     fullName = "Beerware License";
   };
 
-  blueOak100 = spdx {
+  blueOak100 = {
     spdxId = "BlueOak-1.0.0";
     fullName = "Blue Oak Model License 1.0.0";
   };
 
-  bsd0 = spdx {
+  bsd0 = {
     spdxId = "0BSD";
     fullName = "BSD Zero Clause License";
   };
 
-  bsd1 = spdx {
+  bsd1 = {
     spdxId = "BSD-1-Clause";
     fullName = "BSD 1-Clause License";
   };
 
-  bsd2 = spdx {
+  bsd2 = {
     spdxId = "BSD-2-Clause";
     fullName = ''BSD 2-clause "Simplified" License'';
   };
 
-  bsd2Patent = spdx {
+  bsd2Patent = {
     spdxId = "BSD-2-Clause-Patent";
     fullName = "BSD-2-Clause Plus Patent License";
   };
 
-  bsd3 = spdx {
+  bsd3 = {
     spdxId = "BSD-3-Clause";
     fullName = ''BSD 3-clause "New" or "Revised" License'';
   };
 
-  bsdOriginal = spdx {
+  bsdOriginal = {
     spdxId = "BSD-4-Clause";
     fullName = ''BSD 4-clause "Original" or "Old" License'';
   };
 
-  bsdOriginalUC = spdx {
+  bsdOriginalUC = {
     spdxId = "BSD-4-Clause-UC";
     fullName = "BSD 4-Clause University of California-Specific";
   };
 
-  bsdProtection = spdx {
+  bsdProtection = {
     spdxId = "BSD-Protection";
     fullName = "BSD Protection License";
   };
@@ -141,119 +153,119 @@ lib.mapAttrs (n: v: v // { shortName = n; }) ({
     free = false;
   };
 
-  clArtistic = spdx {
+  clArtistic = {
     spdxId = "ClArtistic";
     fullName = "Clarified Artistic License";
   };
 
-  cc0 = spdx {
+  cc0 = {
     spdxId = "CC0-1.0";
     fullName = "Creative Commons Zero v1.0 Universal";
   };
 
-  cc-by-nc-sa-20 = spdx {
+  cc-by-nc-sa-20 = {
     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 {
+  cc-by-nc-sa-25 = {
     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 {
+  cc-by-nc-sa-30 = {
     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 {
+  cc-by-nc-sa-40 = {
     spdxId = "CC-BY-NC-SA-4.0";
     fullName = "Creative Commons Attribution Non Commercial Share Alike 4.0";
     free = false;
   };
 
-  cc-by-nc-30 = spdx {
+  cc-by-nc-30 = {
     spdxId = "CC-BY-NC-3.0";
     fullName = "Creative Commons Attribution Non Commercial 3.0 Unported";
     free = false;
   };
 
-  cc-by-nc-40 = spdx {
+  cc-by-nc-40 = {
     spdxId = "CC-BY-NC-4.0";
     fullName = "Creative Commons Attribution Non Commercial 4.0 International";
     free = false;
   };
 
-  cc-by-nd-30 = spdx {
+  cc-by-nd-30 = {
     spdxId = "CC-BY-ND-3.0";
     fullName = "Creative Commons Attribution-No Derivative Works v3.00";
     free = false;
   };
 
-  cc-by-sa-25 = spdx {
+  cc-by-sa-25 = {
     spdxId = "CC-BY-SA-2.5";
     fullName = "Creative Commons Attribution Share Alike 2.5";
   };
 
-  cc-by-30 = spdx {
+  cc-by-30 = {
     spdxId = "CC-BY-3.0";
     fullName = "Creative Commons Attribution 3.0";
   };
 
-  cc-by-sa-30 = spdx {
+  cc-by-sa-30 = {
     spdxId = "CC-BY-SA-3.0";
     fullName = "Creative Commons Attribution Share Alike 3.0";
   };
 
-  cc-by-40 = spdx {
+  cc-by-40 = {
     spdxId = "CC-BY-4.0";
     fullName = "Creative Commons Attribution 4.0";
   };
 
-  cc-by-sa-40 = spdx {
+  cc-by-sa-40 = {
     spdxId = "CC-BY-SA-4.0";
     fullName = "Creative Commons Attribution Share Alike 4.0";
   };
 
-  cddl = spdx {
+  cddl = {
     spdxId = "CDDL-1.0";
     fullName = "Common Development and Distribution License 1.0";
   };
 
-  cecill20 = spdx {
+  cecill20 = {
     spdxId = "CECILL-2.0";
     fullName = "CeCILL Free Software License Agreement v2.0";
   };
 
-  cecill-b = spdx {
+  cecill-b = {
     spdxId = "CECILL-B";
     fullName  = "CeCILL-B Free Software License Agreement";
   };
 
-  cecill-c = spdx {
+  cecill-c = {
     spdxId = "CECILL-C";
     fullName  = "CeCILL-C Free Software License Agreement";
   };
 
-  cpal10 = spdx {
+  cpal10 = {
     spdxId = "CPAL-1.0";
     fullName = "Common Public Attribution License 1.0";
   };
 
-  cpl10 = spdx {
+  cpl10 = {
     spdxId = "CPL-1.0";
     fullName = "Common Public License 1.0";
   };
 
-  curl = spdx {
+  curl = {
     spdxId = "curl";
     fullName = "curl License";
   };
 
-  doc = spdx {
+  doc = {
     spdxId = "DOC";
     fullName = "DOC License";
   };
@@ -264,12 +276,12 @@ lib.mapAttrs (n: v: v // { shortName = n; }) ({
     free = false;
   };
 
-  efl10 = spdx {
+  efl10 = {
     spdxId = "EFL-1.0";
     fullName = "Eiffel Forum License v1.0";
   };
 
-  efl20 = spdx {
+  efl20 = {
     spdxId = "EFL-2.0";
     fullName = "Eiffel Forum License v2.0";
   };
@@ -280,12 +292,12 @@ lib.mapAttrs (n: v: v // { shortName = n; }) ({
     free = false;
   };
 
-  epl10 = spdx {
+  epl10 = {
     spdxId = "EPL-1.0";
     fullName = "Eclipse Public License 1.0";
   };
 
-  epl20 = spdx {
+  epl20 = {
     spdxId = "EPL-2.0";
     fullName = "Eclipse Public License 2.0";
   };
@@ -296,42 +308,42 @@ lib.mapAttrs (n: v: v // { shortName = n; }) ({
     free = false;
   };
 
-  eupl11 = spdx {
+  eupl11 = {
     spdxId = "EUPL-1.1";
     fullName = "European Union Public License 1.1";
   };
 
-  eupl12 = spdx {
+  eupl12 = {
     spdxId = "EUPL-1.2";
     fullName = "European Union Public License 1.2";
   };
 
-  fdl11Only = spdx {
+  fdl11Only = {
     spdxId = "GFDL-1.1-only";
     fullName = "GNU Free Documentation License v1.1 only";
   };
 
-  fdl11Plus = spdx {
+  fdl11Plus = {
     spdxId = "GFDL-1.1-or-later";
     fullName = "GNU Free Documentation License v1.1 or later";
   };
 
-  fdl12Only = spdx {
+  fdl12Only = {
     spdxId = "GFDL-1.2-only";
     fullName = "GNU Free Documentation License v1.2 only";
   };
 
-  fdl12Plus = spdx {
+  fdl12Plus = {
     spdxId = "GFDL-1.2-or-later";
     fullName = "GNU Free Documentation License v1.2 or later";
   };
 
-  fdl13Only = spdx {
+  fdl13Only = {
     spdxId = "GFDL-1.3-only";
     fullName = "GNU Free Documentation License v1.3 only";
   };
 
-  fdl13Plus = spdx {
+  fdl13Plus = {
     spdxId = "GFDL-1.3-or-later";
     fullName = "GNU Free Documentation License v1.3 or later";
   };
@@ -346,7 +358,7 @@ lib.mapAttrs (n: v: v // { shortName = n; }) ({
     fullName = "Unspecified free software license";
   };
 
-  ftl = spdx {
+  ftl = {
     spdxId = "FTL";
     fullName = "Freetype Project License";
   };
@@ -362,22 +374,22 @@ lib.mapAttrs (n: v: v // { shortName = n; }) ({
     free = false;
   };
 
-  gpl1Only = spdx {
+  gpl1Only = {
     spdxId = "GPL-1.0-only";
     fullName = "GNU General Public License v1.0 only";
   };
 
-  gpl1Plus = spdx {
+  gpl1Plus = {
     spdxId = "GPL-1.0-or-later";
     fullName = "GNU General Public License v1.0 or later";
   };
 
-  gpl2Only = spdx {
+  gpl2Only = {
     spdxId = "GPL-2.0-only";
     fullName = "GNU General Public License v2.0 only";
   };
 
-  gpl2Classpath = spdx {
+  gpl2Classpath = {
     spdxId = "GPL-2.0-with-classpath-exception";
     fullName = "GNU General Public License v2.0 only (with Classpath exception)";
   };
@@ -392,17 +404,17 @@ lib.mapAttrs (n: v: v // { shortName = n; }) ({
     url = "https://www.mysql.com/about/legal/licensing/foss-exception";
   };
 
-  gpl2Plus = spdx {
+  gpl2Plus = {
     spdxId = "GPL-2.0-or-later";
     fullName = "GNU General Public License v2.0 or later";
   };
 
-  gpl3Only = spdx {
+  gpl3Only = {
     spdxId = "GPL-3.0-only";
     fullName = "GNU General Public License v3.0 only";
   };
 
-  gpl3Plus = spdx {
+  gpl3Plus = {
     spdxId = "GPL-3.0-or-later";
     fullName = "GNU General Public License v3.0 or later";
   };
@@ -412,12 +424,12 @@ lib.mapAttrs (n: v: v // { shortName = n; }) ({
     url = "https://fedoraproject.org/wiki/Licensing/GPL_Classpath_Exception";
   };
 
-  hpnd = spdx {
+  hpnd = {
     spdxId = "HPND";
     fullName = "Historic Permission Notice and Disclaimer";
   };
 
-  hpndSellVariant = spdx {
+  hpndSellVariant = {
     fullName = "Historical Permission Notice and Disclaimer - sell variant";
     spdxId = "HPND-sell-variant";
   };
@@ -428,39 +440,39 @@ lib.mapAttrs (n: v: v // { shortName = n; }) ({
     url = "https://old.calculate-linux.org/packages/licenses/iASL";
   };
 
-  ijg = spdx {
+  ijg = {
     spdxId = "IJG";
     fullName = "Independent JPEG Group License";
   };
 
-  imagemagick = spdx {
+  imagemagick = {
     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"; # https is broken
+    url       = "https://compcert.org/doc/LICENSE.txt";
     free      = false;
   };
 
   inria-icesl = {
     fullName = "INRIA Non-Commercial License Agreement for IceSL";
-    url      = "http://shapeforge.loria.fr/icesl/EULA_IceSL_binary.pdf"; # https is broken
+    url      = "https://icesl.loria.fr/assets/pdf/EULA_IceSL_binary.pdf";
     free     = false;
   };
 
-  ipa = spdx {
+  ipa = {
     spdxId = "IPA";
     fullName = "IPA Font License";
   };
 
-  ipl10 = spdx {
+  ipl10 = {
     spdxId = "IPL-1.0";
     fullName = "IBM Public License v1.0";
   };
 
-  isc = spdx {
+  isc = {
     spdxId = "ISC";
     fullName = "ISC License";
   };
@@ -478,52 +490,52 @@ lib.mapAttrs (n: v: v // { shortName = n; }) ({
     free = false;
   };
 
-  lgpl2Only = spdx {
+  lgpl2Only = {
     spdxId = "LGPL-2.0-only";
     fullName = "GNU Library General Public License v2 only";
   };
 
-  lgpl2Plus = spdx {
+  lgpl2Plus = {
     spdxId = "LGPL-2.0-or-later";
     fullName = "GNU Library General Public License v2 or later";
   };
 
-  lgpl21Only = spdx {
+  lgpl21Only = {
     spdxId = "LGPL-2.1-only";
     fullName = "GNU Lesser General Public License v2.1 only";
   };
 
-  lgpl21Plus = spdx {
+  lgpl21Plus = {
     spdxId = "LGPL-2.1-or-later";
     fullName = "GNU Lesser General Public License v2.1 or later";
   };
 
-  lgpl3Only = spdx {
+  lgpl3Only = {
     spdxId = "LGPL-3.0-only";
     fullName = "GNU Lesser General Public License v3.0 only";
   };
 
-  lgpl3Plus = spdx {
+  lgpl3Plus = {
     spdxId = "LGPL-3.0-or-later";
     fullName = "GNU Lesser General Public License v3.0 or later";
   };
 
-  lgpllr = spdx {
+  lgpllr = {
     spdxId = "LGPLLR";
     fullName = "Lesser General Public License For Linguistic Resources";
   };
 
-  libpng = spdx {
+  libpng = {
     spdxId = "Libpng";
     fullName = "libpng License";
   };
 
-  libpng2 = spdx {
+  libpng2 = {
     spdxId = "libpng-2.0"; # Used since libpng 1.6.36.
     fullName = "PNG Reference Library version 2";
   };
 
-  libtiff = spdx {
+  libtiff = {
     spdxId = "libtiff";
     fullName = "libtiff License";
   };
@@ -533,22 +545,22 @@ lib.mapAttrs (n: v: v // { shortName = n; }) ({
     url = "https://opensource.franz.com/preamble.html";
   };
 
-  llvm-exception = spdx {
+  llvm-exception = {
     spdxId = "LLVM-exception";
     fullName = "LLVM Exception"; # LLVM exceptions to the Apache 2.0 License
   };
 
-  lppl12 = spdx {
+  lppl12 = {
     spdxId = "LPPL-1.2";
     fullName = "LaTeX Project Public License v1.2";
   };
 
-  lppl13c = spdx {
+  lppl13c = {
     spdxId = "LPPL-1.3c";
     fullName = "LaTeX Project Public License v1.3c";
   };
 
-  lpl-102 = spdx {
+  lpl-102 = {
     spdxId = "LPL-1.02";
     fullName = "Lucent Public License v1.02";
   };
@@ -560,43 +572,43 @@ lib.mapAttrs (n: v: v // { shortName = n; }) ({
 
   # spdx.org does not (yet) differentiate between the X11 and Expat versions
   # for details see https://en.wikipedia.org/wiki/MIT_License#Various_versions
-  mit = spdx {
+  mit = {
     spdxId = "MIT";
     fullName = "MIT License";
   };
 
-  mpl10 = spdx {
+  mpl10 = {
     spdxId = "MPL-1.0";
     fullName = "Mozilla Public License 1.0";
   };
 
-  mpl11 = spdx {
+  mpl11 = {
     spdxId = "MPL-1.1";
     fullName = "Mozilla Public License 1.1";
   };
 
-  mpl20 = spdx {
+  mpl20 = {
     spdxId = "MPL-2.0";
     fullName = "Mozilla Public License 2.0";
   };
 
-  mspl = spdx {
+  mspl = {
     spdxId = "MS-PL";
     fullName = "Microsoft Public License";
   };
 
-  nasa13 = spdx {
+  nasa13 = {
     spdxId = "NASA-1.3";
     fullName = "NASA Open Source Agreement 1.3";
     free = false;
   };
 
-  ncsa = spdx {
+  ncsa = {
     spdxId = "NCSA";
     fullName  = "University of Illinois/NCSA Open Source License";
   };
 
-  nposl3 = spdx {
+  nposl3 = {
     spdxId = "NPOSL-3.0";
     fullName = "Non-Profit Open Software License 3.0";
   };
@@ -613,53 +625,53 @@ lib.mapAttrs (n: v: v // { shortName = n; }) ({
     free = false;
   };
 
-  odbl = spdx {
+  odbl = {
     spdxId = "ODbL-1.0";
     fullName = "Open Data Commons Open Database License v1.0";
   };
 
-  ofl = spdx {
+  ofl = {
     spdxId = "OFL-1.1";
     fullName = "SIL Open Font License 1.1";
   };
 
-  openldap = spdx {
+  openldap = {
     spdxId = "OLDAP-2.8";
     fullName = "Open LDAP Public License v2.8";
   };
 
-  openssl = spdx {
+  openssl = {
     spdxId = "OpenSSL";
     fullName = "OpenSSL License";
   };
 
-  osl2 = spdx {
+  osl2 = {
     spdxId = "OSL-2.0";
     fullName = "Open Software License 2.0";
   };
 
-  osl21 = spdx {
+  osl21 = {
     spdxId = "OSL-2.1";
     fullName = "Open Software License 2.1";
   };
 
-  osl3 = spdx {
+  osl3 = {
     spdxId = "OSL-3.0";
     fullName = "Open Software License 3.0";
   };
 
-  parity70 = spdx {
+  parity70 = {
     spdxId = "Parity-7.0.0";
     fullName = "Parity Public License 7.0.0";
     url = "https://paritylicense.com/versions/7.0.0.html";
   };
 
-  php301 = spdx {
+  php301 = {
     spdxId = "PHP-3.01";
     fullName = "PHP License v3.01";
   };
 
-  postgresql = spdx {
+  postgresql = {
     spdxId = "PostgreSQL";
     fullName = "PostgreSQL License";
   };
@@ -670,7 +682,7 @@ lib.mapAttrs (n: v: v // { shortName = n; }) ({
     free = false;
   };
 
-  psfl = spdx {
+  psfl = {
     spdxId = "Python-2.0";
     fullName = "Python Software Foundation License version 2";
     url = "https://docs.python.org/license.html";
@@ -691,12 +703,12 @@ lib.mapAttrs (n: v: v // { shortName = n; }) ({
     url = "https://prosperitylicense.com/versions/3.0.0.html";
   };
 
-  qhull = spdx {
+  qhull = {
     spdxId = "Qhull";
     fullName = "Qhull License";
   };
 
-  qpl = spdx {
+  qpl = {
     spdxId = "QPL-1.0";
     fullName = "Q Public License 1.0";
   };
@@ -706,22 +718,22 @@ lib.mapAttrs (n: v: v // { shortName = n; }) ({
     url = "https://qwt.sourceforge.io/qwtlicense.html";
   };
 
-  ruby = spdx {
+  ruby = {
     spdxId = "Ruby";
     fullName = "Ruby License";
   };
 
-  sendmail = spdx {
+  sendmail = {
     spdxId = "Sendmail";
     fullName = "Sendmail License";
   };
 
-  sgi-b-20 = spdx {
+  sgi-b-20 = {
     spdxId = "SGI-B-2.0";
     fullName = "SGI Free Software License B v2.0";
   };
 
-  sleepycat = spdx {
+  sleepycat = {
     spdxId = "Sleepycat";
     fullName = "Sleepycat License";
   };
@@ -737,6 +749,10 @@ lib.mapAttrs (n: v: v // { shortName = n; }) ({
     fullName = "Server Side Public License";
     url = "https://www.mongodb.com/licensing/server-side-public-license";
     free = false;
+    # NOTE Debatable.
+    # The license a slightly modified AGPL but still considered unfree by the
+    # OSI for what seem like political reasons
+    redistributable = true; # Definitely redistributable though, it's an AGPL derivative
   };
 
   stk = {
@@ -745,7 +761,7 @@ lib.mapAttrs (n: v: v // { shortName = n; }) ({
     url = "https://github.com/thestk/stk/blob/master/LICENSE";
   };
 
-  tcltk = spdx {
+  tcltk = {
     spdxId = "TCL";
     fullName = "TCL/TK License";
   };
@@ -763,25 +779,27 @@ lib.mapAttrs (n: v: v // { shortName = n; }) ({
   unfreeRedistributable = {
     fullName = "Unfree redistributable";
     free = false;
+    redistributable = true;
   };
 
   unfreeRedistributableFirmware = {
     fullName = "Unfree redistributable firmware";
+    redistributable = true;
     # Note: we currently consider these "free" for inclusion in the
     # channel and NixOS images.
   };
 
-  unicode-dfs-2015 = spdx {
+  unicode-dfs-2015 = {
     spdxId = "Unicode-DFS-2015";
     fullName = "Unicode License Agreement - Data Files and Software (2015)";
   };
 
-  unicode-dfs-2016 = spdx {
+  unicode-dfs-2016 = {
     spdxId = "Unicode-DFS-2016";
     fullName = "Unicode License Agreement - Data Files and Software (2016)";
   };
 
-  unlicense = spdx {
+  unlicense = {
     spdxId = "Unlicense";
     fullName = "The Unlicense";
   };
@@ -791,7 +809,7 @@ lib.mapAttrs (n: v: v // { shortName = n; }) ({
     url = "https://oss.oracle.com/licenses/upl/";
   };
 
-  vim = spdx {
+  vim = {
     spdxId = "Vim";
     fullName = "Vim License";
   };
@@ -802,17 +820,17 @@ lib.mapAttrs (n: v: v // { shortName = n; }) ({
     free = false;
   };
 
-  vsl10 = spdx {
+  vsl10 = {
     spdxId = "VSL-1.0";
     fullName = "Vovida Software License v1.0";
   };
 
-  watcom = spdx {
+  watcom = {
     spdxId = "Watcom-1.0";
     fullName = "Sybase Open Watcom Public License 1.0";
   };
 
-  w3c = spdx {
+  w3c = {
     spdxId = "W3C";
     fullName = "W3C Software Notice and License";
   };
@@ -822,12 +840,12 @@ lib.mapAttrs (n: v: v // { shortName = n; }) ({
     url = "https://fedoraproject.org/wiki/Licensing:Wadalab?rd=Licensing/Wadalab";
   };
 
-  wtfpl = spdx {
+  wtfpl = {
     spdxId = "WTFPL";
     fullName = "Do What The F*ck You Want To Public License";
   };
 
-  wxWindows = spdx {
+  wxWindows = {
     spdxId = "wxWindows";
     fullName = "wxWindows Library Licence, Version 3.1";
   };
@@ -837,68 +855,68 @@ lib.mapAttrs (n: v: v // { shortName = n; }) ({
     url = "http://mcj.sourceforge.net/authors.html#xfig"; # https is broken
   };
 
-  zlib = spdx {
+  zlib = {
     spdxId = "Zlib";
     fullName = "zlib License";
   };
 
-  zpl20 = spdx {
+  zpl20 = {
     spdxId = "ZPL-2.0";
     fullName = "Zope Public License 2.0";
   };
 
-  zpl21 = spdx {
+  zpl21 = {
     spdxId = "ZPL-2.1";
     fullName = "Zope Public License 2.1";
   };
 } // {
   # TODO: remove legacy aliases
-  agpl3 = spdx {
+  agpl3 = {
     spdxId = "AGPL-3.0";
     fullName = "GNU Affero General Public License v3.0";
     deprecated = true;
   };
-  fdl11 = spdx {
+  fdl11 = {
     spdxId = "GFDL-1.1";
     fullName = "GNU Free Documentation License v1.1";
     deprecated = true;
   };
-  fdl12 = spdx {
+  fdl12 = {
     spdxId = "GFDL-1.2";
     fullName = "GNU Free Documentation License v1.2";
     deprecated = true;
   };
-  fdl13 = spdx {
+  fdl13 = {
     spdxId = "GFDL-1.3";
     fullName = "GNU Free Documentation License v1.3";
     deprecated = true;
   };
-  gpl1 = spdx {
+  gpl1 = {
     spdxId = "GPL-1.0";
     fullName = "GNU General Public License v1.0";
     deprecated = true;
   };
-  gpl2 = spdx {
+  gpl2 = {
     spdxId = "GPL-2.0";
     fullName = "GNU General Public License v2.0";
     deprecated = true;
   };
-  gpl3 = spdx {
+  gpl3 = {
     spdxId = "GPL-3.0";
     fullName = "GNU General Public License v3.0";
     deprecated = true;
   };
-  lgpl2 = spdx {
+  lgpl2 = {
     spdxId = "LGPL-2.0";
     fullName = "GNU Library General Public License v2";
     deprecated = true;
   };
-  lgpl21 = spdx {
+  lgpl21 = {
     spdxId = "LGPL-2.1";
     fullName = "GNU Lesser General Public License v2.1";
     deprecated = true;
   };
-  lgpl3 = spdx {
+  lgpl3 = {
     spdxId = "LGPL-3.0";
     fullName = "GNU Lesser General Public License v3.0";
     deprecated = true;
diff --git a/nixpkgs/lib/modules.nix b/nixpkgs/lib/modules.nix
index ab2bc4f7f8e2..b124ea000a2e 100644
--- a/nixpkgs/lib/modules.nix
+++ b/nixpkgs/lib/modules.nix
@@ -710,6 +710,7 @@ rec {
 
   mkOptionDefault = mkOverride 1500; # priority of option defaults
   mkDefault = mkOverride 1000; # used in config sections of non-user modules to set a default
+  mkImageMediaOverride = mkOverride 60; # image media profiles can be derived by inclusion into host config, hence needing to override host config, but do allow user to mkForce
   mkForce = mkOverride 50;
   mkVMOverride = mkOverride 10; # used by ‘nixos-rebuild build-vm’
 
diff --git a/nixpkgs/lib/options.nix b/nixpkgs/lib/options.nix
index 87cd8b797969..204c86df9f51 100644
--- a/nixpkgs/lib/options.nix
+++ b/nixpkgs/lib/options.nix
@@ -11,6 +11,7 @@ let
     filter
     foldl'
     head
+    tail
     isAttrs
     isBool
     isDerivation
@@ -144,7 +145,7 @@ rec {
       if def.value != first.value then
         throw "The option `${showOption loc}' has conflicting definition values:${showDefs [ first def ]}"
       else
-        first) (head defs) defs).value;
+        first) (head defs) (tail defs)).value;
 
   /* Extracts values of all "value" keys of the given list.
 
diff --git a/nixpkgs/lib/strings.nix b/nixpkgs/lib/strings.nix
index 86c92bdaa15b..a111e1e2597b 100644
--- a/nixpkgs/lib/strings.nix
+++ b/nixpkgs/lib/strings.nix
@@ -89,7 +89,7 @@ rec {
         => "usr/local/bin"
   */
   concatStringsSep = builtins.concatStringsSep or (separator: list:
-    concatStrings (intersperse separator list));
+    lib.foldl' (x: y: x + y) "" (intersperse separator list));
 
   /* Maps a function over a list of strings and then concatenates the
      result with the specified separator interspersed between
diff --git a/nixpkgs/lib/systems/doubles.nix b/nixpkgs/lib/systems/doubles.nix
index 61ba7dad7cc7..e577059687b0 100644
--- a/nixpkgs/lib/systems/doubles.nix
+++ b/nixpkgs/lib/systems/doubles.nix
@@ -26,21 +26,22 @@ let
 
     # Linux
     "aarch64-linux" "armv5tel-linux" "armv6l-linux" "armv7a-linux"
-    "armv7l-linux" "i686-linux" "mipsel-linux" "powerpc64-linux"
-    "powerpc64le-linux" "riscv32-linux" "riscv64-linux" "x86_64-linux"
+    "armv7l-linux" "i686-linux" "m68k-linux" "mipsel-linux"
+    "powerpc64-linux" "powerpc64le-linux" "riscv32-linux"
+    "riscv64-linux" "s390-linux" "x86_64-linux"
 
     # MMIXware
     "mmix-mmixware"
 
     # NetBSD
     "aarch64-netbsd" "armv6l-netbsd" "armv7a-netbsd" "armv7l-netbsd"
-    "i686-netbsd" "mipsel-netbsd" "powerpc-netbsd" "riscv32-netbsd"
-    "riscv64-netbsd" "x86_64-netbsd"
+    "i686-netbsd" "m68k-netbsd" "mipsel-netbsd" "powerpc-netbsd"
+    "riscv32-netbsd" "riscv64-netbsd" "x86_64-netbsd"
 
     # none
-    "aarch64-none" "arm-none" "armv6l-none" "avr-none" "i686-none" "msp430-none"
-    "or1k-none" "powerpc-none" "riscv32-none" "riscv64-none" "vc4-none"
-    "x86_64-none"
+    "aarch64-none" "arm-none" "armv6l-none" "avr-none" "i686-none"
+    "msp430-none" "or1k-none" "m68k-none" "powerpc-none"
+    "riscv32-none" "riscv64-none" "s390-none" "vc4-none" "x86_64-none"
 
     # OpenBSD
     "i686-openbsd" "x86_64-openbsd"
@@ -74,6 +75,8 @@ in {
   riscv         = filterDoubles predicates.isRiscV;
   vc4           = filterDoubles predicates.isVc4;
   or1k          = filterDoubles predicates.isOr1k;
+  m68k          = filterDoubles predicates.isM68k;
+  s390          = filterDoubles predicates.isS390;
   js            = filterDoubles predicates.isJavaScript;
 
   bigEndian     = filterDoubles predicates.isBigEndian;
diff --git a/nixpkgs/lib/systems/examples.nix b/nixpkgs/lib/systems/examples.nix
index 6a8f4e091aae..32b236d6960c 100644
--- a/nixpkgs/lib/systems/examples.nix
+++ b/nixpkgs/lib/systems/examples.nix
@@ -144,6 +144,14 @@ rec {
     libc = "newlib";
   };
 
+  m68k = {
+    config = "m68k-unknown-linux-gnu";
+  };
+
+  s390 = {
+    config = "s390-unknown-linux-gnu";
+  };
+
   arm-embedded = {
     config = "arm-none-eabi";
     libc = "newlib";
diff --git a/nixpkgs/lib/systems/inspect.nix b/nixpkgs/lib/systems/inspect.nix
index d2b7271210cd..718954e0839a 100644
--- a/nixpkgs/lib/systems/inspect.nix
+++ b/nixpkgs/lib/systems/inspect.nix
@@ -26,6 +26,8 @@ rec {
     isAvr          = { cpu = { family = "avr"; }; };
     isAlpha        = { cpu = { family = "alpha"; }; };
     isOr1k         = { cpu = { family = "or1k"; }; };
+    isM68k         = { cpu = { family = "m68k"; }; };
+    isS390         = { cpu = { family = "s390"; }; };
     isJavaScript   = { cpu = cpuTypes.js; };
 
     is32bit        = { cpu = { bits = 32; }; };
@@ -54,6 +56,7 @@ rec {
     isNone         = { kernel = kernels.none; };
 
     isAndroid      = [ { abi = abis.android; } { abi = abis.androideabi; } ];
+    isGnu          = with abis; map (a: { abi = a; }) [ gnuabi64 gnu gnueabi gnueabihf ];
     isMusl         = with abis; map (a: { abi = a; }) [ musl musleabi musleabihf ];
     isUClibc       = with abis; map (a: { abi = a; }) [ uclibc uclibceabi uclibceabihf ];
 
diff --git a/nixpkgs/lib/systems/parse.nix b/nixpkgs/lib/systems/parse.nix
index 2b789fd8ecb3..77e941a913cf 100644
--- a/nixpkgs/lib/systems/parse.nix
+++ b/nixpkgs/lib/systems/parse.nix
@@ -95,6 +95,8 @@ rec {
 
     mmix     = { bits = 64; significantByte = bigEndian;    family = "mmix"; };
 
+    m68k     = { bits = 32; significantByte = bigEndian; family = "m68k"; };
+
     powerpc  = { bits = 32; significantByte = bigEndian;    family = "power"; };
     powerpc64 = { bits = 64; significantByte = bigEndian; family = "power"; };
     powerpc64le = { bits = 64; significantByte = littleEndian; family = "power"; };
@@ -103,6 +105,8 @@ rec {
     riscv32  = { bits = 32; significantByte = littleEndian; family = "riscv"; };
     riscv64  = { bits = 64; significantByte = littleEndian; family = "riscv"; };
 
+    s390     = { bits = 32; significantByte = bigEndian; family = "s390"; };
+
     sparc    = { bits = 32; significantByte = bigEndian;    family = "sparc"; };
     sparc64  = { bits = 64; significantByte = bigEndian;    family = "sparc"; };
 
@@ -123,9 +127,10 @@ rec {
 
   # GNU build systems assume that older NetBSD architectures are using a.out.
   gnuNetBSDDefaultExecFormat = cpu:
-    if (cpu.family == "x86" && cpu.bits == 32) ||
-       (cpu.family == "arm" && cpu.bits == 32) ||
-       (cpu.family == "sparc" && cpu.bits == 32)
+    if (cpu.family == "arm" && cpu.bits == 32) ||
+       (cpu.family == "sparc" && cpu.bits == 32) ||
+       (cpu.family == "m68k" && cpu.bits == 32) ||
+       (cpu.family == "x86" && cpu.bits == 32)
     then execFormats.aout
     else execFormats.elf;
 
diff --git a/nixpkgs/lib/systems/platforms.nix b/nixpkgs/lib/systems/platforms.nix
index 92285346f754..2a5f630c3de9 100644
--- a/nixpkgs/lib/systems/platforms.nix
+++ b/nixpkgs/lib/systems/platforms.nix
@@ -233,7 +233,7 @@ rec {
     };
   };
 
-  scaleway-c1 = lib.recursiveUpdate armv7l-hf-multiplatform {
+  scaleway-c1 = armv7l-hf-multiplatform // {
     gcc = {
       cpu = "cortex-a9";
       fpu = "vfpv3";
@@ -315,6 +315,12 @@ rec {
         # Disable OABI to have seccomp_filter (required for systemd)
         # https://github.com/raspberrypi/firmware/issues/651
         OABI_COMPAT n
+
+        # >=5.12 fails with:
+        # drivers/net/ethernet/micrel/ks8851_common.o: in function `ks8851_probe_common':
+        # ks8851_common.c:(.text+0x179c): undefined reference to `__this_module'
+        # See: https://lore.kernel.org/netdev/20210116164828.40545-1-marex@denx.de/T/
+        KS8851_MLL y
       '';
     };
     gcc = {
diff --git a/nixpkgs/lib/tests/maintainers.nix b/nixpkgs/lib/tests/maintainers.nix
index d3ed398c80a1..2408a20af4b7 100644
--- a/nixpkgs/lib/tests/maintainers.nix
+++ b/nixpkgs/lib/tests/maintainers.nix
@@ -61,9 +61,9 @@ let
 
   missingGithubIds = lib.concatLists (lib.mapAttrsToList checkMaintainer lib.maintainers);
 
-  success = pkgs.runCommandNoCC "checked-maintainers-success" {} ">$out";
+  success = pkgs.runCommand "checked-maintainers-success" {} ">$out";
 
-  failure = pkgs.runCommandNoCC "checked-maintainers-failure" {
+  failure = pkgs.runCommand "checked-maintainers-failure" {
     nativeBuildInputs = [ pkgs.curl pkgs.jq ];
     outputHash = "sha256:${lib.fakeSha256}";
     outputHAlgo = "sha256";
diff --git a/nixpkgs/lib/tests/misc.nix b/nixpkgs/lib/tests/misc.nix
index 0d249968402d..4b2e5afc1d60 100644
--- a/nixpkgs/lib/tests/misc.nix
+++ b/nixpkgs/lib/tests/misc.nix
@@ -132,6 +132,16 @@ runTests {
     expected = [ 1 1 0 ];
   };
 
+  testFunctionArgsFunctor = {
+    expr = functionArgs { __functor = self: { a, b }: null; };
+    expected = { a = false; b = false; };
+  };
+
+  testFunctionArgsSetFunctionArgs = {
+    expr = functionArgs (setFunctionArgs (args: args.x) { x = false; });
+    expected = { x = false; };
+  };
+
 # STRINGS
 
   testConcatMapStrings = {
diff --git a/nixpkgs/lib/tests/release.nix b/nixpkgs/lib/tests/release.nix
index c3b05251f709..77e0e1af7555 100644
--- a/nixpkgs/lib/tests/release.nix
+++ b/nixpkgs/lib/tests/release.nix
@@ -3,7 +3,7 @@
   pkgs ? import ../.. {} // { lib = throw "pkgs.lib accessed, but the lib tests should use nixpkgs' lib path directly!"; }
 }:
 
-pkgs.runCommandNoCC "nixpkgs-lib-tests" {
+pkgs.runCommand "nixpkgs-lib-tests" {
   buildInputs = [
     pkgs.nix
     (import ./check-eval.nix)
diff --git a/nixpkgs/lib/tests/systems.nix b/nixpkgs/lib/tests/systems.nix
index 36f82b783b41..661b9bc8690c 100644
--- a/nixpkgs/lib/tests/systems.nix
+++ b/nixpkgs/lib/tests/systems.nix
@@ -28,8 +28,8 @@ with lib.systems.doubles; lib.runTests {
   testredox = mseteq redox [ "x86_64-redox" ];
   testgnu = mseteq gnu (linux /* ++ kfreebsd ++ ... */);
   testillumos = mseteq illumos [ "x86_64-solaris" ];
-  testlinux = mseteq linux [ "aarch64-linux" "armv5tel-linux" "armv6l-linux" "armv7a-linux" "armv7l-linux" "i686-linux" "mipsel-linux" "riscv32-linux" "riscv64-linux" "x86_64-linux" "powerpc64-linux" "powerpc64le-linux" ];
-  testnetbsd = mseteq netbsd [ "aarch64-netbsd" "armv6l-netbsd" "armv7a-netbsd" "armv7l-netbsd" "i686-netbsd" "mipsel-netbsd" "powerpc-netbsd" "riscv32-netbsd" "riscv64-netbsd" "x86_64-netbsd" ];
+  testlinux = mseteq linux [ "aarch64-linux" "armv5tel-linux" "armv6l-linux" "armv7a-linux" "armv7l-linux" "i686-linux" "mipsel-linux" "riscv32-linux" "riscv64-linux" "x86_64-linux" "powerpc64-linux" "powerpc64le-linux" "m68k-linux" "s390-linux" ];
+  testnetbsd = mseteq netbsd [ "aarch64-netbsd" "armv6l-netbsd" "armv7a-netbsd" "armv7l-netbsd" "i686-netbsd" "m68k-netbsd" "mipsel-netbsd" "powerpc-netbsd" "riscv32-netbsd" "riscv64-netbsd" "x86_64-netbsd" ];
   testopenbsd = mseteq openbsd [ "i686-openbsd" "x86_64-openbsd" ];
   testwindows = mseteq windows [ "i686-cygwin" "x86_64-cygwin" "i686-windows" "x86_64-windows" ];
   testunix = mseteq unix (linux ++ darwin ++ freebsd ++ openbsd ++ netbsd ++ illumos ++ cygwin ++ redox);
diff --git a/nixpkgs/lib/trivial.nix b/nixpkgs/lib/trivial.nix
index e1581f1e91d6..7956ba4bde6f 100644
--- a/nixpkgs/lib/trivial.nix
+++ b/nixpkgs/lib/trivial.nix
@@ -308,7 +308,7 @@ rec {
 
   info = msg: builtins.trace "INFO: ${msg}";
 
-  showWarnings = warnings: res: lib.fold (w: x: warn w x) res warnings;
+  showWarnings = warnings: res: lib.foldr (w: x: warn w x) res warnings;
 
   ## Function annotations
 
@@ -334,7 +334,10 @@ rec {
      has the same return type and semantics as builtins.functionArgs.
      setFunctionArgs : (a → b) → Map String Bool.
   */
-  functionArgs = f: f.__functionArgs or (builtins.functionArgs f);
+  functionArgs = f:
+    if f ? __functor
+    then f.__functionArgs or (lib.functionArgs (f.__functor f))
+    else builtins.functionArgs f;
 
   /* Check whether something is a function or something
      annotated with function args.
diff --git a/nixpkgs/lib/types.nix b/nixpkgs/lib/types.nix
index c35f055e17f5..a0be2ff3a452 100644
--- a/nixpkgs/lib/types.nix
+++ b/nixpkgs/lib/types.nix
@@ -287,6 +287,13 @@ rec {
       merge = mergeEqualOption;
     };
 
+    nonEmptyStr = mkOptionType {
+      name = "nonEmptyStr";
+      description = "non-empty string";
+      check = x: str.check x && builtins.match "[ \t\n]*" x == null;
+      inherit (str) merge;
+    };
+
     strMatching = pattern: mkOptionType {
       name = "strMatching ${escapeNixString pattern}";
       description = "string matching the pattern ${pattern}";