summary refs log tree commit diff
path: root/lib/types.nix
diff options
context:
space:
mode:
authorRobert Hensing <robert@roberthensing.nl>2021-10-27 20:42:05 +0200
committerRobert Hensing <robert@roberthensing.nl>2021-11-01 09:34:07 +0100
commitdece37b83a46d488787859332e18286727b96cc4 (patch)
tree979d27f2821373269bf00f13912b2b02a7ebb234 /lib/types.nix
parent9ec8a16c7908c7807e46fa4f38479ccc0af2b64e (diff)
downloadnixpkgs-dece37b83a46d488787859332e18286727b96cc4.tar
nixpkgs-dece37b83a46d488787859332e18286727b96cc4.tar.gz
nixpkgs-dece37b83a46d488787859332e18286727b96cc4.tar.bz2
nixpkgs-dece37b83a46d488787859332e18286727b96cc4.tar.lz
nixpkgs-dece37b83a46d488787859332e18286727b96cc4.tar.xz
nixpkgs-dece37b83a46d488787859332e18286727b96cc4.tar.zst
nixpkgs-dece37b83a46d488787859332e18286727b96cc4.zip
lib.evalModules: Add extendModules and type to result
Allows the simultaneous construction of top-level invocations and
submodule types.

This helps structure configuration systems integration code.
Diffstat (limited to 'lib/types.nix')
-rw-r--r--lib/types.nix56
1 files changed, 28 insertions, 28 deletions
diff --git a/lib/types.nix b/lib/types.nix
index c2532065d7e..244cbb6b535 100644
--- a/lib/types.nix
+++ b/lib/types.nix
@@ -505,17 +505,36 @@ rec {
           then setFunctionArgs (args: unify (value args)) (functionArgs value)
           else unify (if shorthandOnlyDefinesConfig then { config = value; } else value);
 
-        allModules = defs: modules ++ imap1 (n: { value, file }:
+        allModules = defs: imap1 (n: { value, file }:
           if isAttrs value || isFunction value then
             # Annotate the value with the location of its definition for better error messages
             coerce (lib.modules.unifyModuleSyntax file "${toString file}-${toString n}") value
           else value
         ) defs;
 
-        freeformType = (evalModules {
-          inherit modules specialArgs;
-          args.name = "‹name›";
-        })._module.freeformType;
+        base = evalModules {
+          inherit specialArgs;
+          modules = [{
+            # This is a work-around for the fact that some sub-modules,
+            # such as the one included in an attribute set, expects an "args"
+            # attribute to be given to the sub-module. As the option
+            # evaluation does not have any specific attribute name yet, we
+            # provide a default for the documentation and the freeform type.
+            #
+            # This is necessary as some option declaration might use the
+            # "name" attribute given as argument of the submodule and use it
+            # as the default of option declarations.
+            #
+            # We use 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.
+            _module.args.name = lib.mkOptionDefault "‹name›";
+          }] ++ modules;
+        };
+
+        freeformType = base._module.freeformType;
 
       in
       mkOptionType rec {
@@ -523,32 +542,13 @@ rec {
         description = freeformType.description or name;
         check = x: isAttrs x || isFunction x || path.check x;
         merge = loc: defs:
-          (evalModules {
-            modules = allModules defs;
-            inherit specialArgs;
-            args.name = last loc;
+          (base.extendModules {
+            modules = [ { _module.args.name = last loc; } ] ++ allModules defs;
             prefix = loc;
           }).config;
         emptyValue = { value = {}; };
-        getSubOptions = prefix: (evalModules
-          { inherit modules prefix specialArgs;
-            # This is a work-around due to the fact that some sub-modules,
-            # such as the one included in an attribute set, expects a "args"
-            # attribute to be given to the sub-module. As the option
-            # evaluation does not have any specific attribute name, we
-            # provide a default one for the documentation.
-            #
-            # 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.
-            #
-            # 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 // optionalAttrs (freeformType != null) {
+        getSubOptions = prefix: (base.extendModules
+          { inherit prefix; }).options // optionalAttrs (freeformType != null) {
             # Expose the sub options of the freeform type. Note that the option
             # discovery doesn't care about the attribute name used here, so this
             # is just to avoid conflicts with potential options from the submodule