diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/customisation.nix | 8 | ||||
-rw-r--r-- | lib/modules.nix | 14 | ||||
-rwxr-xr-x | lib/tests/modules.sh | 3 | ||||
-rw-r--r-- | lib/tests/modules/declare-submoduleWith-modules.nix | 4 | ||||
-rw-r--r-- | lib/types.nix | 19 |
5 files changed, 35 insertions, 13 deletions
diff --git a/lib/customisation.nix b/lib/customisation.nix index 37a7951896b0e..c17cb0d0f8e51 100644 --- a/lib/customisation.nix +++ b/lib/customisation.nix @@ -219,16 +219,17 @@ rec { /* Like the above, but aims to support cross compilation. It's still ugly, but hopefully it helps a little bit. */ - makeScopeWithSplicing = splicePackages: newScope: otherSplices: keep: f: + makeScopeWithSplicing = splicePackages: newScope: otherSplices: keep: extra: f: let - spliced = splicePackages { + spliced0 = splicePackages { pkgsBuildBuild = otherSplices.selfBuildBuild; pkgsBuildHost = otherSplices.selfBuildHost; pkgsBuildTarget = otherSplices.selfBuildTarget; pkgsHostHost = otherSplices.selfHostHost; pkgsHostTarget = self; # Not `otherSplices.selfHostTarget`; pkgsTargetTarget = otherSplices.selfTargetTarget; - } // keep self; + }; + spliced = extra spliced0 // spliced0 // keep self; self = f self // { newScope = scope: newScope (spliced // scope); callPackage = newScope spliced; # == self.newScope {}; @@ -239,6 +240,7 @@ rec { newScope otherSplices keep + extra (lib.fixedPoints.extends g f); packages = f; }; diff --git a/lib/modules.nix b/lib/modules.nix index cc38e4cba87a5..99b9a8a31eace 100644 --- a/lib/modules.nix +++ b/lib/modules.nix @@ -23,6 +23,7 @@ let isAttrs isBool isFunction + isList isString length mapAttrs @@ -188,6 +189,9 @@ rec { loadModule = args: fallbackFile: fallbackKey: m: if isFunction m || isAttrs m then unifyModuleSyntax fallbackFile fallbackKey (applyIfFunction fallbackKey m args) + else if isList m then + let defs = [{ file = fallbackFile; value = m; }]; in + throw "Module imports can't be nested lists. Perhaps you meant to remove one level of lists? Definitions: ${showDefs defs}" else unifyModuleSyntax (toString m) (toString m) (applyIfFunction (toString m) (import m) args); /* @@ -295,13 +299,11 @@ rec { # a module will resolve strictly the attributes used as argument but # not their values. The values are forwarding the result of the # evaluation of the option. - requiredArgs = builtins.attrNames (lib.functionArgs f); context = name: ''while evaluating the module argument `${name}' in "${key}":''; - extraArgs = builtins.listToAttrs (map (name: { - inherit name; - value = builtins.addErrorContext (context name) - (args.${name} or config._module.args.${name}); - }) requiredArgs); + extraArgs = builtins.mapAttrs (name: _: + builtins.addErrorContext (context name) + (args.${name} or config._module.args.${name}) + ) (lib.functionArgs f); # Note: we append in the opposite order such that we can add an error # context on the explicited arguments of "args" too. This update diff --git a/lib/tests/modules.sh b/lib/tests/modules.sh index 2eddeec07b1a3..2e57c2f8e2a13 100755 --- a/lib/tests/modules.sh +++ b/lib/tests/modules.sh @@ -175,6 +175,9 @@ checkConfigOutput "true" config.submodule.config ./declare-submoduleWith-noshort ## submoduleWith should merge all modules in one swoop checkConfigOutput "true" config.submodule.inner ./declare-submoduleWith-modules.nix checkConfigOutput "true" config.submodule.outer ./declare-submoduleWith-modules.nix +# Should also be able to evaluate the type name (which evaluates freeformType, +# which evaluates all the modules defined by the type) +checkConfigOutput "submodule" options.submodule.type.description ./declare-submoduleWith-modules.nix ## Paths should be allowed as values and work as expected checkConfigOutput "true" config.submodule.enable ./declare-submoduleWith-path.nix diff --git a/lib/tests/modules/declare-submoduleWith-modules.nix b/lib/tests/modules/declare-submoduleWith-modules.nix index 4736ab41751bd..a8b82d176881b 100644 --- a/lib/tests/modules/declare-submoduleWith-modules.nix +++ b/lib/tests/modules/declare-submoduleWith-modules.nix @@ -8,9 +8,6 @@ default = false; }; } - { - outer = true; - } ]; }; default = {}; @@ -25,6 +22,7 @@ }) { inner = true; + outer = true; } ]; } diff --git a/lib/types.nix b/lib/types.nix index 31ce440bcb48e..d709791d6d0e5 100644 --- a/lib/types.nix +++ b/lib/types.nix @@ -147,9 +147,13 @@ rec { , # The deprecation message to display when this type is used by an option # If null, the type isn't deprecated deprecationMessage ? null + , # The types that occur in the definition of this type. This is used to + # issue deprecation warnings recursively. Can also be used to reuse + # nested types + nestedTypes ? {} }: { _type = "option-type"; - inherit name check merge emptyValue getSubOptions getSubModules substSubModules typeMerge functor deprecationMessage; + inherit name check merge emptyValue getSubOptions getSubModules substSubModules typeMerge functor deprecationMessage nestedTypes; description = if description == null then name else description; }; @@ -365,6 +369,7 @@ rec { getSubModules = elemType.getSubModules; substSubModules = m: listOf (elemType.substSubModules m); functor = (defaultFunctor name) // { wrapped = elemType; }; + nestedTypes.elemType = elemType; }; nonEmptyListOf = elemType: @@ -389,6 +394,7 @@ rec { getSubModules = elemType.getSubModules; substSubModules = m: attrsOf (elemType.substSubModules m); functor = (defaultFunctor name) // { wrapped = elemType; }; + nestedTypes.elemType = elemType; }; # A version of attrsOf that's lazy in its values at the expense of @@ -413,6 +419,7 @@ rec { getSubModules = elemType.getSubModules; substSubModules = m: lazyAttrsOf (elemType.substSubModules m); functor = (defaultFunctor name) // { wrapped = elemType; }; + nestedTypes.elemType = elemType; }; # TODO: drop this in the future: @@ -421,6 +428,7 @@ rec { deprecationMessage = "Mixing lists with attribute values is no longer" + " possible; please use `types.attrsOf` instead. See" + " https://github.com/NixOS/nixpkgs/issues/1800 for the motivation."; + nestedTypes.elemType = elemType; }; # Value of given type but with no merging (i.e. `uniq list`s are not concatenated). @@ -433,6 +441,7 @@ rec { getSubModules = elemType.getSubModules; substSubModules = m: uniq (elemType.substSubModules m); functor = (defaultFunctor name) // { wrapped = elemType; }; + nestedTypes.elemType = elemType; }; # Null or value of ... @@ -451,6 +460,7 @@ rec { getSubModules = elemType.getSubModules; substSubModules = m: nullOr (elemType.substSubModules m); functor = (defaultFunctor name) // { wrapped = elemType; }; + nestedTypes.elemType = elemType; }; functionTo = elemType: mkOptionType { @@ -535,6 +545,9 @@ rec { substSubModules = m: submoduleWith (attrs // { modules = m; }); + nestedTypes = lib.optionalAttrs (freeformType != null) { + freeformType = freeformType; + }; functor = defaultFunctor name // { type = types.submoduleWith; payload = { @@ -596,6 +609,8 @@ rec { then functor.type mt1 mt2 else null; functor = (defaultFunctor name) // { wrapped = [ t1 t2 ]; }; + nestedTypes.left = t1; + nestedTypes.right = t2; }; # Any of the types in the given list @@ -627,6 +642,8 @@ rec { substSubModules = m: coercedTo coercedType coerceFunc (finalType.substSubModules m); typeMerge = t1: t2: null; functor = (defaultFunctor name) // { wrapped = finalType; }; + nestedTypes.coercedType = coercedType; + nestedTypes.finalType = finalType; }; # Obsolete alternative to configOf. It takes its option |