summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/attrsets.nix14
-rw-r--r--lib/customisation.nix7
-rw-r--r--lib/default.nix7
-rw-r--r--lib/generators.nix18
-rw-r--r--lib/kernel.nix17
-rw-r--r--lib/modules.nix15
-rw-r--r--lib/options.nix2
-rw-r--r--lib/tests/misc.nix12
-rwxr-xr-xlib/tests/modules.sh13
-rw-r--r--lib/tests/modules/declare-enable-nested.nix14
-rw-r--r--lib/tests/modules/declare-int-positive-value-nested.nix9
-rw-r--r--lib/tests/modules/define-option-dependently-nested.nix16
-rw-r--r--lib/tests/modules/define-option-dependently.nix16
-rw-r--r--lib/trivial.nix2
14 files changed, 140 insertions, 22 deletions
diff --git a/lib/attrsets.nix b/lib/attrsets.nix
index 32994432d53d..72430522f7d8 100644
--- a/lib/attrsets.nix
+++ b/lib/attrsets.nix
@@ -473,6 +473,20 @@ rec {
/* Pick the outputs of packages to place in buildInputs */
chooseDevOutputs = drvs: builtins.map getDev drvs;
+ /* Make various Nix tools consider the contents of the resulting
+ attribute set when looking for what to build, find, etc.
+
+ This function only affects a single attribute set; it does not
+ apply itself recursively for nested attribute sets.
+ */
+ recurseIntoAttrs =
+ attrs: attrs // { recurseForDerivations = true; };
+
+ /* Undo the effect of recurseIntoAttrs.
+ */
+ dontRecurseIntoAttrs =
+ attrs: attrs // { recurseForDerivations = false; };
+
/*** deprecated stuff ***/
zipWithNames = zipAttrsWithNames;
diff --git a/lib/customisation.nix b/lib/customisation.nix
index ac234e3b8c6f..dc5dd7691976 100644
--- a/lib/customisation.nix
+++ b/lib/customisation.nix
@@ -131,7 +131,12 @@ rec {
origArgs = auto // args;
pkgs = f origArgs;
mkAttrOverridable = name: _: makeOverridable (newArgs: (f newArgs).${name}) origArgs;
- in lib.mapAttrs mkAttrOverridable pkgs;
+ in
+ if lib.isDerivation pkgs then throw
+ ("function `callPackages` was called on a *single* derivation "
+ + ''"${pkgs.name or "<unknown-name>"}";''
+ + " did you mean to use `callPackage` instead?")
+ else lib.mapAttrs mkAttrOverridable pkgs;
/* Add attributes to each output of a derivation without changing
diff --git a/lib/default.nix b/lib/default.nix
index d2fe018aa6af..a909cefd60f1 100644
--- a/lib/default.nix
+++ b/lib/default.nix
@@ -24,6 +24,7 @@ let
# packaging
customisation = callLibs ./customisation.nix;
maintainers = import ../maintainers/maintainer-list.nix;
+ teams = callLibs ../maintainers/team-list.nix;
meta = callLibs ./meta.nix;
sources = callLibs ./sources.nix;
versions = callLibs ./versions.nix;
@@ -55,6 +56,9 @@ let
# back-compat aliases
platforms = systems.doubles;
+ # linux kernel configuration
+ kernel = callLibs ./kernel.nix;
+
inherit (builtins) add addErrorContext attrNames concatLists
deepSeq elem elemAt filter genericClosure genList getAttr
hasAttr head isAttrs isBool isInt isList isString length
@@ -73,7 +77,8 @@ let
genAttrs isDerivation toDerivation optionalAttrs
zipAttrsWithNames zipAttrsWith zipAttrs recursiveUpdateUntil
recursiveUpdate matchAttrs overrideExisting getOutput getBin
- getLib getDev chooseDevOutputs zipWithNames zip;
+ getLib getDev chooseDevOutputs zipWithNames zip
+ recurseIntoAttrs dontRecurseIntoAttrs;
inherit (lists) singleton forEach foldr fold foldl foldl' imap0 imap1
concatMap flatten remove findSingle findFirst any all count
optional optionals toList range partition zipListsWith zipLists
diff --git a/lib/generators.nix b/lib/generators.nix
index a64e94bd5cbd..240a19789b54 100644
--- a/lib/generators.nix
+++ b/lib/generators.nix
@@ -76,10 +76,14 @@ rec {
* mkKeyValue is the same as in toINI.
*/
toKeyValue = {
- mkKeyValue ? mkKeyValueDefault {} "="
- }: attrs:
- let mkLine = k: v: mkKeyValue k v + "\n";
- in libStr.concatStrings (libAttr.mapAttrsToList mkLine attrs);
+ mkKeyValue ? mkKeyValueDefault {} "=",
+ listsAsDuplicateKeys ? false
+ }:
+ let mkLine = k: v: mkKeyValue k v + "\n";
+ mkLines = if listsAsDuplicateKeys
+ then k: v: map (mkLine k) (if lib.isList v then v else [v])
+ else k: v: [ (mkLine k v) ];
+ in attrs: libStr.concatStrings (lib.concatLists (libAttr.mapAttrsToList mkLines attrs));
/* Generate an INI-style config file from an
@@ -106,7 +110,9 @@ rec {
# apply transformations (e.g. escapes) to section names
mkSectionName ? (name: libStr.escape [ "[" "]" ] name),
# format a setting line from key and value
- mkKeyValue ? mkKeyValueDefault {} "="
+ mkKeyValue ? mkKeyValueDefault {} "=",
+ # allow lists as values for duplicate keys
+ listsAsDuplicateKeys ? false
}: attrsOfAttrs:
let
# map function to string for each key val
@@ -115,7 +121,7 @@ rec {
(libAttr.mapAttrsToList mapFn attrs);
mkSection = sectName: sectValues: ''
[${mkSectionName sectName}]
- '' + toKeyValue { inherit mkKeyValue; } sectValues;
+ '' + toKeyValue { inherit mkKeyValue listsAsDuplicateKeys; } sectValues;
in
# map input to ini sections
mapAttrsToStringsSep "\n" mkSection attrsOfAttrs;
diff --git a/lib/kernel.nix b/lib/kernel.nix
index 36ea30838289..2ce19f8cb68c 100644
--- a/lib/kernel.nix
+++ b/lib/kernel.nix
@@ -1,12 +1,7 @@
-{ lib, version }:
+{ lib }:
with lib;
{
- # Common patterns/legacy
- whenAtLeast = ver: mkIf (versionAtLeast version ver);
- whenOlder = ver: mkIf (versionOlder version ver);
- # range is (inclusive, exclusive)
- whenBetween = verLow: verHigh: mkIf (versionAtLeast version verLow && versionOlder version verHigh);
# Keeping these around in case we decide to change this horrible implementation :)
@@ -18,4 +13,14 @@ with lib;
module = { tristate = "m"; };
freeform = x: { freeform = x; };
+ /*
+ Common patterns/legacy used in common-config/hardened-config.nix
+ */
+ whenHelpers = version: {
+ whenAtLeast = ver: mkIf (versionAtLeast version ver);
+ whenOlder = ver: mkIf (versionOlder version ver);
+ # range is (inclusive, exclusive)
+ whenBetween = verLow: verHigh: mkIf (versionAtLeast version verLow && versionOlder version verHigh);
+ };
+
}
diff --git a/lib/modules.nix b/lib/modules.nix
index 2b1faf4f0c28..c18fec66c705 100644
--- a/lib/modules.nix
+++ b/lib/modules.nix
@@ -93,7 +93,11 @@ rec {
res set._definedNames
else
res;
- result = { inherit options config; };
+ result = {
+ inherit options;
+ config = removeAttrs config [ "_module" ];
+ inherit (config) _module;
+ };
in result;
# collectModules :: (modulesPath: String) -> (modules: [ Module ]) -> (args: Attrs) -> [ Module ]
@@ -389,7 +393,7 @@ rec {
let
# Process mkMerge and mkIf properties.
defs' = concatMap (m:
- map (value: { inherit (m) file; inherit value; }) (dischargeProperties m.value)
+ map (value: { inherit (m) file; inherit value; }) (builtins.addErrorContext "while evaluating definitions from `${m.file}':" (dischargeProperties m.value))
) defs;
# Process mkOverride properties.
@@ -410,10 +414,9 @@ rec {
# Type-check the remaining definitions, and merge them. Or throw if no definitions.
mergedValue =
if isDefined then
- foldl' (res: def:
- if type.check def.value then res
- else throw "The option value `${showOption loc}' in `${def.file}' is not of type `${type.description}'."
- ) (type.merge loc defsFinal) defsFinal
+ if all (def: type.check def.value) defsFinal then type.merge loc defsFinal
+ else let firstInvalid = findFirst (def: ! type.check def.value) null defsFinal;
+ in throw "The option value `${showOption loc}' in `${firstInvalid.file}' is not of type `${type.description}'."
else
# (nixos-option detects this specific error message and gives it special
# handling. If changed here, please change it there too.)
diff --git a/lib/options.nix b/lib/options.nix
index e5c0631a5437..71481c9250ab 100644
--- a/lib/options.nix
+++ b/lib/options.nix
@@ -159,7 +159,7 @@ rec {
let ss = opt.type.getSubOptions opt.loc;
in if ss != {} then optionAttrSetToDocList' opt.loc ss else [];
in
- [ docOption ] ++ subOptions) (collect isOption options);
+ [ docOption ] ++ optionals docOption.visible subOptions) (collect isOption options);
/* This function recursively removes all derivation attributes from
diff --git a/lib/tests/misc.nix b/lib/tests/misc.nix
index 01ff5ecf1485..739c5d5fe15d 100644
--- a/lib/tests/misc.nix
+++ b/lib/tests/misc.nix
@@ -348,6 +348,18 @@ runTests {
'';
};
+ testToINIDuplicateKeys = {
+ expr = generators.toINI { listsAsDuplicateKeys = true; } { foo.bar = true; baz.qux = [ 1 false ]; };
+ expected = ''
+ [baz]
+ qux=1
+ qux=false
+
+ [foo]
+ bar=true
+ '';
+ };
+
testToINIDefaultEscapes = {
expr = generators.toINI {} {
"no [ and ] allowed unescaped" = {
diff --git a/lib/tests/modules.sh b/lib/tests/modules.sh
index 8cd632a439cd..e81cf016ee9a 100755
--- a/lib/tests/modules.sh
+++ b/lib/tests/modules.sh
@@ -185,6 +185,14 @@ checkConfigError 'The option .* defined in .* does not exist' config.enable ./di
# Check that imports can depend on derivations
checkConfigOutput "true" config.enable ./import-from-store.nix
+# Check that configs can be conditional on option existence
+checkConfigOutput true config.enable ./define-option-dependently.nix ./declare-enable.nix ./declare-int-positive-value.nix
+checkConfigOutput 360 config.value ./define-option-dependently.nix ./declare-enable.nix ./declare-int-positive-value.nix
+checkConfigOutput 7 config.value ./define-option-dependently.nix ./declare-int-positive-value.nix
+checkConfigOutput true config.set.enable ./define-option-dependently-nested.nix ./declare-enable-nested.nix ./declare-int-positive-value-nested.nix
+checkConfigOutput 360 config.set.value ./define-option-dependently-nested.nix ./declare-enable-nested.nix ./declare-int-positive-value-nested.nix
+checkConfigOutput 7 config.set.value ./define-option-dependently-nested.nix ./declare-int-positive-value-nested.nix
+
# Check attrsOf and lazyAttrsOf. Only lazyAttrsOf should be lazy, and only
# attrsOf should work with conditional definitions
# In addition, lazyAttrsOf should honor an options emptyValue
@@ -194,6 +202,11 @@ checkConfigOutput "true" config.conditionalWorks ./declare-attrsOf.nix ./attrsOf
checkConfigOutput "false" config.conditionalWorks ./declare-lazyAttrsOf.nix ./attrsOf-conditional-check.nix
checkConfigOutput "empty" config.value.foo ./declare-lazyAttrsOf.nix ./attrsOf-conditional-check.nix
+
+# Even with multiple assignments, a type error should be thrown if any of them aren't valid
+checkConfigError 'The option value .* in .* is not of type .*' \
+ config.value ./declare-int-unsigned-value.nix ./define-value-list.nix ./define-value-int-positive.nix
+
cat <<EOF
====== module tests ======
$pass Pass
diff --git a/lib/tests/modules/declare-enable-nested.nix b/lib/tests/modules/declare-enable-nested.nix
new file mode 100644
index 000000000000..c8da8273cba1
--- /dev/null
+++ b/lib/tests/modules/declare-enable-nested.nix
@@ -0,0 +1,14 @@
+{ lib, ... }:
+
+{
+ options.set = {
+ enable = lib.mkOption {
+ default = false;
+ example = true;
+ type = lib.types.bool;
+ description = ''
+ Some descriptive text
+ '';
+ };
+ };
+}
diff --git a/lib/tests/modules/declare-int-positive-value-nested.nix b/lib/tests/modules/declare-int-positive-value-nested.nix
new file mode 100644
index 000000000000..72d2fb89fc3b
--- /dev/null
+++ b/lib/tests/modules/declare-int-positive-value-nested.nix
@@ -0,0 +1,9 @@
+{ lib, ... }:
+
+{
+ options.set = {
+ value = lib.mkOption {
+ type = lib.types.ints.positive;
+ };
+ };
+}
diff --git a/lib/tests/modules/define-option-dependently-nested.nix b/lib/tests/modules/define-option-dependently-nested.nix
new file mode 100644
index 000000000000..69ee4255534a
--- /dev/null
+++ b/lib/tests/modules/define-option-dependently-nested.nix
@@ -0,0 +1,16 @@
+{ lib, options, ... }:
+
+# Some modules may be distributed separately and need to adapt to other modules
+# that are distributed and versioned separately.
+{
+
+ # Always defined, but the value depends on the presence of an option.
+ config.set = {
+ value = if options ? set.enable then 360 else 7;
+ }
+ # Only define if possible.
+ // lib.optionalAttrs (options ? set.enable) {
+ enable = true;
+ };
+
+}
diff --git a/lib/tests/modules/define-option-dependently.nix b/lib/tests/modules/define-option-dependently.nix
new file mode 100644
index 000000000000..6abce29366ae
--- /dev/null
+++ b/lib/tests/modules/define-option-dependently.nix
@@ -0,0 +1,16 @@
+{ lib, options, ... }:
+
+# Some modules may be distributed separately and need to adapt to other modules
+# that are distributed and versioned separately.
+{
+
+ # Always defined, but the value depends on the presence of an option.
+ config = {
+ value = if options ? enable then 360 else 7;
+ }
+ # Only define if possible.
+ // lib.optionalAttrs (options ? enable) {
+ enable = true;
+ };
+
+}
diff --git a/lib/trivial.nix b/lib/trivial.nix
index a281cd70fb0e..5788dd435e59 100644
--- a/lib/trivial.nix
+++ b/lib/trivial.nix
@@ -171,7 +171,7 @@ rec {
On each release the first letter is bumped and a new animal is chosen
starting with that new letter.
*/
- codeName = "Markhor";
+ codeName = "Nightingale";
/* Returns the current nixpkgs version suffix as string. */
versionSuffix =