diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/attrsets.nix | 14 | ||||
-rw-r--r-- | lib/customisation.nix | 7 | ||||
-rw-r--r-- | lib/default.nix | 7 | ||||
-rw-r--r-- | lib/generators.nix | 18 | ||||
-rw-r--r-- | lib/kernel.nix | 17 | ||||
-rw-r--r-- | lib/modules.nix | 15 | ||||
-rw-r--r-- | lib/options.nix | 2 | ||||
-rw-r--r-- | lib/tests/misc.nix | 12 | ||||
-rwxr-xr-x | lib/tests/modules.sh | 13 | ||||
-rw-r--r-- | lib/tests/modules/declare-enable-nested.nix | 14 | ||||
-rw-r--r-- | lib/tests/modules/declare-int-positive-value-nested.nix | 9 | ||||
-rw-r--r-- | lib/tests/modules/define-option-dependently-nested.nix | 16 | ||||
-rw-r--r-- | lib/tests/modules/define-option-dependently.nix | 16 | ||||
-rw-r--r-- | lib/trivial.nix | 2 |
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 = |