at 23.05-pre 3.0 kB view raw
1<section xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="sec-freeform-modules"> 2 <title>Freeform modules</title> 3 <para> 4 Freeform modules allow you to define values for option paths that 5 have not been declared explicitly. This can be used to add 6 attribute-specific types to what would otherwise have to be 7 <literal>attrsOf</literal> options in order to accept all attribute 8 names. 9 </para> 10 <para> 11 This feature can be enabled by using the attribute 12 <literal>freeformType</literal> to define a freeform type. By doing 13 this, all assignments without an associated option will be merged 14 using the freeform type and combined into the resulting 15 <literal>config</literal> set. Since this feature nullifies name 16 checking for entire option trees, it is only recommended for use in 17 submodules. 18 </para> 19 <anchor xml:id="ex-freeform-module" /> 20 <para> 21 <emphasis role="strong">Example: Freeform submodule</emphasis> 22 </para> 23 <para> 24 The following shows a submodule assigning a freeform type that 25 allows arbitrary attributes with <literal>str</literal> values below 26 <literal>settings</literal>, but also declares an option for the 27 <literal>settings.port</literal> attribute to have it type-checked 28 and assign a default value. See 29 <link linkend="ex-settings-typed-attrs">Example: Declaring a 30 type-checked <literal>settings</literal> attribute</link> for a more 31 complete example. 32 </para> 33 <programlisting language="bash"> 34{ lib, config, ... }: { 35 36 options.settings = lib.mkOption { 37 type = lib.types.submodule { 38 39 freeformType = with lib.types; attrsOf str; 40 41 # We want this attribute to be checked for the correct type 42 options.port = lib.mkOption { 43 type = lib.types.port; 44 # Declaring the option also allows defining a default value 45 default = 8080; 46 }; 47 48 }; 49 }; 50} 51</programlisting> 52 <para> 53 And the following shows what such a module then allows 54 </para> 55 <programlisting language="bash"> 56{ 57 # Not a declared option, but the freeform type allows this 58 settings.logLevel = &quot;debug&quot;; 59 60 # Not allowed because the the freeform type only allows strings 61 # settings.enable = true; 62 63 # Allowed because there is a port option declared 64 settings.port = 80; 65 66 # Not allowed because the port option doesn't allow strings 67 # settings.port = &quot;443&quot;; 68} 69</programlisting> 70 <note> 71 <para> 72 Freeform attributes cannot depend on other attributes of the same 73 set without infinite recursion: 74 </para> 75 <programlisting language="bash"> 76{ 77 # This throws infinite recursion encountered 78 settings.logLevel = lib.mkIf (config.settings.port == 80) &quot;debug&quot;; 79} 80</programlisting> 81 <para> 82 To prevent this, declare options for all attributes that need to 83 depend on others. For above example this means to declare 84 <literal>logLevel</literal> to be an option. 85 </para> 86 </note> 87</section>