nixos: nixos/doc/manual/development/freeform-modules.xml to CommonMark

Changed files
+166 -68
nixos
+79
nixos/doc/manual/development/freeform-modules.section.md
···
+
# Freeform modules {#sec-freeform-modules}
+
+
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 `attrsOf` options in order to
+
accept all attribute names.
+
+
This feature can be enabled by using the attribute `freeformType` 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 `config` set. Since this feature nullifies name
+
checking for entire option trees, it is only recommended for use in
+
submodules.
+
+
::: {#ex-freeform-module .example}
+
::: {.title}
+
**Example: Freeform submodule**
+
:::
+
The following shows a submodule assigning a freeform type that allows
+
arbitrary attributes with `str` values below `settings`, but also
+
declares an option for the `settings.port` attribute to have it
+
type-checked and assign a default value. See
+
[Example: Declaring a type-checked `settings` attribute](#ex-settings-typed-attrs)
+
for a more complete example.
+
+
```nix
+
{ 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;
+
};
+
+
};
+
};
+
}
+
```
+
+
And the following shows what such a module then allows
+
+
```nix
+
{
+
# 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";
+
}
+
```
+
:::
+
+
::: {.note}
+
Freeform attributes cannot depend on other attributes of the same set
+
without infinite recursion:
+
+
```nix
+
{
+
# This throws infinite recursion encountered
+
settings.logLevel = lib.mkIf (config.settings.port == 80) "debug";
+
}
+
```
+
+
To prevent this, declare options for all attributes that need to depend
+
on others. For above example this means to declare `logLevel` to be an
+
option.
+
:::
-68
nixos/doc/manual/development/freeform-modules.xml
···
-
<section xmlns="http://docbook.org/ns/docbook"
-
xmlns:xlink="http://www.w3.org/1999/xlink"
-
xmlns:xi="http://www.w3.org/2001/XInclude"
-
version="5.0"
-
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>
-
<example xml:id="ex-freeform-module">
-
<title>Freeform submodule</title>
-
<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 <xref linkend="ex-settings-typed-attrs"/> for a more complete example.
-
</para>
-
<programlisting>
-
{ 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>
-
{
-
# 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>
-
</example>
-
<note>
-
<para>
-
Freeform attributes cannot depend on other attributes of the same set without infinite recursion:
-
<programlisting>
-
{
-
# This throws infinite recursion encountered
-
settings.logLevel = lib.mkIf (config.settings.port == 80) "debug";
-
}
-
</programlisting>
-
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>
+87
nixos/doc/manual/from_md/development/freeform-modules.section.xml
···
+
<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 = &quot;debug&quot;;
+
+
# 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 = &quot;443&quot;;
+
}
+
</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) &quot;debug&quot;;
+
}
+
</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>