diff options
Diffstat (limited to 'nixos/doc/manual/from_md/development/freeform-modules.section.xml')
-rw-r--r-- | nixos/doc/manual/from_md/development/freeform-modules.section.xml | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/nixos/doc/manual/from_md/development/freeform-modules.section.xml b/nixos/doc/manual/from_md/development/freeform-modules.section.xml new file mode 100644 index 00000000000..86a9cf3140d --- /dev/null +++ b/nixos/doc/manual/from_md/development/freeform-modules.section.xml @@ -0,0 +1,87 @@ +<section xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="sec-freeform-modules"> + <title>Freeform modules</title> + <para> + Freeform modules allow you to define values for option paths that + have not been declared explicitly. This can be used to add + attribute-specific types to what would otherwise have to be + <literal>attrsOf</literal> options in order to accept all attribute + names. + </para> + <para> + This feature can be enabled by using the attribute + <literal>freeformType</literal> to define a freeform type. By doing + this, all assignments without an associated option will be merged + using the freeform type and combined into the resulting + <literal>config</literal> set. Since this feature nullifies name + checking for entire option trees, it is only recommended for use in + submodules. + </para> + <anchor xml:id="ex-freeform-module" /> + <para> + <emphasis role="strong">Example: Freeform submodule</emphasis> + </para> + <para> + The following shows a submodule assigning a freeform type that + allows arbitrary attributes with <literal>str</literal> values below + <literal>settings</literal>, but also declares an option for the + <literal>settings.port</literal> attribute to have it type-checked + and assign a default value. See + <link linkend="ex-settings-typed-attrs">Example: Declaring a + type-checked <literal>settings</literal> attribute</link> for a more + complete example. + </para> + <programlisting language="bash"> +{ lib, config, ... }: { + + options.settings = lib.mkOption { + type = lib.types.submodule { + + freeformType = with lib.types; attrsOf str; + + # We want this attribute to be checked for the correct type + options.port = lib.mkOption { + type = lib.types.port; + # Declaring the option also allows defining a default value + default = 8080; + }; + + }; + }; +} +</programlisting> + <para> + And the following shows what such a module then allows + </para> + <programlisting language="bash"> +{ + # Not a declared option, but the freeform type allows this + settings.logLevel = "debug"; + + # Not allowed because the the freeform type only allows strings + # settings.enable = true; + + # Allowed because there is a port option declared + settings.port = 80; + + # Not allowed because the port option doesn't allow strings + # settings.port = "443"; +} +</programlisting> + <note> + <para> + Freeform attributes cannot depend on other attributes of the same + set without infinite recursion: + </para> + <programlisting language="bash"> +{ + # This throws infinite recursion encountered + settings.logLevel = lib.mkIf (config.settings.port == 80) "debug"; +} +</programlisting> + <para> + To prevent this, declare options for all attributes that need to + depend on others. For above example this means to declare + <literal>logLevel</literal> to be an option. + </para> + </note> +</section> |