You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1081 lines
37 KiB
1081 lines
37 KiB
<section xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="sec-option-types">
|
|
<title>Options Types</title>
|
|
<para>
|
|
Option types are a way to put constraints on the values a module
|
|
option can take. Types are also responsible of how values are merged
|
|
in case of multiple value definitions.
|
|
</para>
|
|
<section xml:id="sec-option-types-basic">
|
|
<title>Basic Types</title>
|
|
<para>
|
|
Basic types are the simplest available types in the module system.
|
|
Basic types include multiple string types that mainly differ in
|
|
how definition merging is handled.
|
|
</para>
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term>
|
|
<literal>types.bool</literal>
|
|
</term>
|
|
<listitem>
|
|
<para>
|
|
A boolean, its values can be <literal>true</literal> or
|
|
<literal>false</literal>.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>
|
|
<literal>types.path</literal>
|
|
</term>
|
|
<listitem>
|
|
<para>
|
|
A filesystem path is anything that starts with a slash when
|
|
coerced to a string. Even if derivations can be considered
|
|
as paths, the more specific <literal>types.package</literal>
|
|
should be preferred.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>
|
|
<literal>types.package</literal>
|
|
</term>
|
|
<listitem>
|
|
<para>
|
|
A top-level store path. This can be an attribute set
|
|
pointing to a store path, like a derivation or a flake
|
|
input.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>
|
|
<literal>types.anything</literal>
|
|
</term>
|
|
<listitem>
|
|
<para>
|
|
A type that accepts any value and recursively merges
|
|
attribute sets together. This type is recommended when the
|
|
option type is unknown.
|
|
</para>
|
|
<anchor xml:id="ex-types-anything" />
|
|
<para>
|
|
<emphasis role="strong">Example:
|
|
<literal>types.anything</literal> Example</emphasis>
|
|
</para>
|
|
<para>
|
|
Two definitions of this type like
|
|
</para>
|
|
<programlisting language="bash">
|
|
{
|
|
str = lib.mkDefault "foo";
|
|
pkg.hello = pkgs.hello;
|
|
fun.fun = x: x + 1;
|
|
}
|
|
</programlisting>
|
|
<programlisting language="bash">
|
|
{
|
|
str = lib.mkIf true "bar";
|
|
pkg.gcc = pkgs.gcc;
|
|
fun.fun = lib.mkForce (x: x + 2);
|
|
}
|
|
</programlisting>
|
|
<para>
|
|
will get merged to
|
|
</para>
|
|
<programlisting language="bash">
|
|
{
|
|
str = "bar";
|
|
pkg.gcc = pkgs.gcc;
|
|
pkg.hello = pkgs.hello;
|
|
fun.fun = x: x + 2;
|
|
}
|
|
</programlisting>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>
|
|
<literal>types.raw</literal>
|
|
</term>
|
|
<listitem>
|
|
<para>
|
|
A type which doesn’t do any checking, merging or nested
|
|
evaluation. It accepts a single arbitrary value that is not
|
|
recursed into, making it useful for values coming from
|
|
outside the module system, such as package sets or arbitrary
|
|
data. Options of this type are still evaluated according to
|
|
priorities and conditionals, so <literal>mkForce</literal>,
|
|
<literal>mkIf</literal> and co. still work on the option
|
|
value itself, but not for any value nested within it. This
|
|
type should only be used when checking, merging and nested
|
|
evaluation are not desirable.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>
|
|
<literal>types.optionType</literal>
|
|
</term>
|
|
<listitem>
|
|
<para>
|
|
The type of an option’s type. Its merging operation ensures
|
|
that nested options have the correct file location
|
|
annotated, and that if possible, multiple option definitions
|
|
are correctly merged together. The main use case is as the
|
|
type of the <literal>_module.freeformType</literal> option.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>
|
|
<literal>types.attrs</literal>
|
|
</term>
|
|
<listitem>
|
|
<para>
|
|
A free-form attribute set.
|
|
</para>
|
|
<warning>
|
|
<para>
|
|
This type will be deprecated in the future because it
|
|
doesn't recurse into attribute sets, silently drops
|
|
earlier attribute definitions, and doesn't discharge
|
|
<literal>lib.mkDefault</literal>,
|
|
<literal>lib.mkIf</literal> and co. For allowing arbitrary
|
|
attribute sets, prefer
|
|
<literal>types.attrsOf types.anything</literal> instead
|
|
which doesn't have these problems.
|
|
</para>
|
|
</warning>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
<para>
|
|
Integer-related types:
|
|
</para>
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term>
|
|
<literal>types.int</literal>
|
|
</term>
|
|
<listitem>
|
|
<para>
|
|
A signed integer.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>
|
|
<literal>types.ints.{s8, s16, s32}</literal>
|
|
</term>
|
|
<listitem>
|
|
<para>
|
|
Signed integers with a fixed length (8, 16 or 32 bits). They
|
|
go from −2^n/2 to 2^n/2−1 respectively (e.g.
|
|
<literal>−128</literal> to <literal>127</literal> for 8
|
|
bits).
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>
|
|
<literal>types.ints.unsigned</literal>
|
|
</term>
|
|
<listitem>
|
|
<para>
|
|
An unsigned integer (that is >= 0).
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>
|
|
<literal>types.ints.{u8, u16, u32}</literal>
|
|
</term>
|
|
<listitem>
|
|
<para>
|
|
Unsigned integers with a fixed length (8, 16 or 32 bits).
|
|
They go from 0 to 2^n−1 respectively (e.g.
|
|
<literal>0</literal> to <literal>255</literal> for 8 bits).
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>
|
|
<literal>types.ints.positive</literal>
|
|
</term>
|
|
<listitem>
|
|
<para>
|
|
A positive integer (that is > 0).
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>
|
|
<literal>types.port</literal>
|
|
</term>
|
|
<listitem>
|
|
<para>
|
|
A port number. This type is an alias to
|
|
<literal>types.ints.u16</literal>.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
<para>
|
|
String-related types:
|
|
</para>
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term>
|
|
<literal>types.str</literal>
|
|
</term>
|
|
<listitem>
|
|
<para>
|
|
A string. Multiple definitions cannot be merged.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>
|
|
<literal>types.lines</literal>
|
|
</term>
|
|
<listitem>
|
|
<para>
|
|
A string. Multiple definitions are concatenated with a new
|
|
line <literal>"\n"</literal>.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>
|
|
<literal>types.commas</literal>
|
|
</term>
|
|
<listitem>
|
|
<para>
|
|
A string. Multiple definitions are concatenated with a comma
|
|
<literal>","</literal>.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>
|
|
<literal>types.envVar</literal>
|
|
</term>
|
|
<listitem>
|
|
<para>
|
|
A string. Multiple definitions are concatenated with a
|
|
collon <literal>":"</literal>.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>
|
|
<literal>types.strMatching</literal>
|
|
</term>
|
|
<listitem>
|
|
<para>
|
|
A string matching a specific regular expression. Multiple
|
|
definitions cannot be merged. The regular expression is
|
|
processed using <literal>builtins.match</literal>.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
</section>
|
|
<section xml:id="sec-option-types-value">
|
|
<title>Value Types</title>
|
|
<para>
|
|
Value types are types that take a value parameter.
|
|
</para>
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term>
|
|
<literal>types.enum</literal>
|
|
<emphasis><literal>l</literal></emphasis>
|
|
</term>
|
|
<listitem>
|
|
<para>
|
|
One element of the list
|
|
<emphasis><literal>l</literal></emphasis>, e.g.
|
|
<literal>types.enum [ "left" "right" ]</literal>.
|
|
Multiple definitions cannot be merged.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>
|
|
<literal>types.separatedString</literal>
|
|
<emphasis><literal>sep</literal></emphasis>
|
|
</term>
|
|
<listitem>
|
|
<para>
|
|
A string with a custom separator
|
|
<emphasis><literal>sep</literal></emphasis>, e.g.
|
|
<literal>types.separatedString "|"</literal>.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>
|
|
<literal>types.ints.between</literal>
|
|
<emphasis><literal>lowest highest</literal></emphasis>
|
|
</term>
|
|
<listitem>
|
|
<para>
|
|
An integer between
|
|
<emphasis><literal>lowest</literal></emphasis> and
|
|
<emphasis><literal>highest</literal></emphasis> (both
|
|
inclusive). Useful for creating types like
|
|
<literal>types.port</literal>.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>
|
|
<literal>types.submodule</literal>
|
|
<emphasis><literal>o</literal></emphasis>
|
|
</term>
|
|
<listitem>
|
|
<para>
|
|
A set of sub options
|
|
<emphasis><literal>o</literal></emphasis>.
|
|
<emphasis><literal>o</literal></emphasis> can be an
|
|
attribute set, a function returning an attribute set, or a
|
|
path to a file containing such a value. Submodules are used
|
|
in composed types to create modular options. This is
|
|
equivalent to
|
|
<literal>types.submoduleWith { modules = toList o; shorthandOnlyDefinesConfig = true; }</literal>.
|
|
Submodules are detailed in
|
|
<link linkend="section-option-types-submodule">Submodule</link>.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>
|
|
<literal>types.submoduleWith</literal> {
|
|
<emphasis><literal>modules</literal></emphasis>,
|
|
<emphasis><literal>specialArgs</literal></emphasis> ? {},
|
|
<emphasis><literal>shorthandOnlyDefinesConfig</literal></emphasis>
|
|
? false }
|
|
</term>
|
|
<listitem>
|
|
<para>
|
|
Like <literal>types.submodule</literal>, but more flexible
|
|
and with better defaults. It has parameters
|
|
</para>
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para>
|
|
<emphasis><literal>modules</literal></emphasis> A list
|
|
of modules to use by default for this submodule type.
|
|
This gets combined with all option definitions to build
|
|
the final list of modules that will be included.
|
|
</para>
|
|
<note>
|
|
<para>
|
|
Only options defined with this argument are included
|
|
in rendered documentation.
|
|
</para>
|
|
</note>
|
|
</listitem>
|
|
<listitem>
|
|
<para>
|
|
<emphasis><literal>specialArgs</literal></emphasis> An
|
|
attribute set of extra arguments to be passed to the
|
|
module functions. The option
|
|
<literal>_module.args</literal> should be used instead
|
|
for most arguments since it allows overriding.
|
|
<emphasis><literal>specialArgs</literal></emphasis>
|
|
should only be used for arguments that can't go through
|
|
the module fixed-point, because of infinite recursion or
|
|
other problems. An example is overriding the
|
|
<literal>lib</literal> argument, because
|
|
<literal>lib</literal> itself is used to define
|
|
<literal>_module.args</literal>, which makes using
|
|
<literal>_module.args</literal> to define it impossible.
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para>
|
|
<emphasis><literal>shorthandOnlyDefinesConfig</literal></emphasis>
|
|
Whether definitions of this type should default to the
|
|
<literal>config</literal> section of a module (see
|
|
<link linkend="ex-module-syntax">Example: Structure of
|
|
NixOS Modules</link>) if it is an attribute set.
|
|
Enabling this only has a benefit when the submodule
|
|
defines an option named <literal>config</literal> or
|
|
<literal>options</literal>. In such a case it would
|
|
allow the option to be set with
|
|
<literal>the-submodule.config = "value"</literal>
|
|
instead of requiring
|
|
<literal>the-submodule.config.config = "value"</literal>.
|
|
This is because only when modules
|
|
<emphasis>don't</emphasis> set the
|
|
<literal>config</literal> or <literal>options</literal>
|
|
keys, all keys are interpreted as option definitions in
|
|
the <literal>config</literal> section. Enabling this
|
|
option implicitly puts all attributes in the
|
|
<literal>config</literal> section.
|
|
</para>
|
|
<para>
|
|
With this option enabled, defining a
|
|
non-<literal>config</literal> section requires using a
|
|
function:
|
|
<literal>the-submodule = { ... }: { options = { ... }; }</literal>.
|
|
</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>
|
|
<literal>types.deferredModule</literal>
|
|
</term>
|
|
<listitem>
|
|
<para>
|
|
Whereas <literal>submodule</literal> represents an option
|
|
tree, <literal>deferredModule</literal> represents a module
|
|
value, such as a module file or a configuration.
|
|
</para>
|
|
<para>
|
|
It can be set multiple times.
|
|
</para>
|
|
<para>
|
|
Module authors can use its value in
|
|
<literal>imports</literal>, in
|
|
<literal>submoduleWith</literal><quote>s
|
|
<literal>modules</literal> or in
|
|
<literal>evalModules</literal></quote>
|
|
<literal>modules</literal> parameter, among other places.
|
|
</para>
|
|
<para>
|
|
Note that <literal>imports</literal> must be evaluated
|
|
before the module fixpoint. Because of this, deferred
|
|
modules can only be imported into <quote>other</quote>
|
|
fixpoints, such as submodules.
|
|
</para>
|
|
<para>
|
|
One use case for this type is the type of a
|
|
<quote>default</quote> module that allow the user to affect
|
|
all submodules in an <literal>attrsOf submodule</literal> at
|
|
once. This is more convenient and discoverable than
|
|
expecting the module user to type-merge with the
|
|
<literal>attrsOf submodule</literal> option.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
</section>
|
|
<section xml:id="sec-option-types-composed">
|
|
<title>Composed Types</title>
|
|
<para>
|
|
Composed types are types that take a type as parameter.
|
|
<literal>listOf int</literal> and
|
|
<literal>either int str</literal> are examples of composed types.
|
|
</para>
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term>
|
|
<literal>types.listOf</literal>
|
|
<emphasis><literal>t</literal></emphasis>
|
|
</term>
|
|
<listitem>
|
|
<para>
|
|
A list of <emphasis><literal>t</literal></emphasis> type,
|
|
e.g. <literal>types.listOf int</literal>. Multiple
|
|
definitions are merged with list concatenation.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>
|
|
<literal>types.attrsOf</literal>
|
|
<emphasis><literal>t</literal></emphasis>
|
|
</term>
|
|
<listitem>
|
|
<para>
|
|
An attribute set of where all the values are of
|
|
<emphasis><literal>t</literal></emphasis> type. Multiple
|
|
definitions result in the joined attribute set.
|
|
</para>
|
|
<note>
|
|
<para>
|
|
This type is <emphasis>strict</emphasis> in its values,
|
|
which in turn means attributes cannot depend on other
|
|
attributes. See <literal> types.lazyAttrsOf</literal> for
|
|
a lazy version.
|
|
</para>
|
|
</note>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>
|
|
<literal>types.lazyAttrsOf</literal>
|
|
<emphasis><literal>t</literal></emphasis>
|
|
</term>
|
|
<listitem>
|
|
<para>
|
|
An attribute set of where all the values are of
|
|
<emphasis><literal>t</literal></emphasis> type. Multiple
|
|
definitions result in the joined attribute set. This is the
|
|
lazy version of <literal>types.attrsOf </literal>, allowing
|
|
attributes to depend on each other.
|
|
</para>
|
|
<warning>
|
|
<para>
|
|
This version does not fully support conditional
|
|
definitions! With an option <literal>foo</literal> of this
|
|
type and a definition
|
|
<literal>foo.attr = lib.mkIf false 10</literal>,
|
|
evaluating <literal>foo ? attr</literal> will return
|
|
<literal>true</literal> even though it should be false.
|
|
Accessing the value will then throw an error. For types
|
|
<emphasis><literal>t</literal></emphasis> that have an
|
|
<literal>emptyValue</literal> defined, that value will be
|
|
returned instead of throwing an error. So if the type of
|
|
<literal>foo.attr</literal> was
|
|
<literal>lazyAttrsOf (nullOr int)</literal>,
|
|
<literal>null</literal> would be returned instead for the
|
|
same <literal>mkIf false</literal> definition.
|
|
</para>
|
|
</warning>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>
|
|
<literal>types.nullOr</literal>
|
|
<emphasis><literal>t</literal></emphasis>
|
|
</term>
|
|
<listitem>
|
|
<para>
|
|
<literal>null</literal> or type
|
|
<emphasis><literal>t</literal></emphasis>. Multiple
|
|
definitions are merged according to type
|
|
<emphasis><literal>t</literal></emphasis>.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>
|
|
<literal>types.uniq</literal>
|
|
<emphasis><literal>t</literal></emphasis>
|
|
</term>
|
|
<listitem>
|
|
<para>
|
|
Ensures that type <emphasis><literal>t</literal></emphasis>
|
|
cannot be merged. It is used to ensure option definitions
|
|
are declared only once.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>
|
|
<literal>types.unique</literal>
|
|
<literal>{ message = m }</literal>
|
|
<emphasis><literal>t</literal></emphasis>
|
|
</term>
|
|
<listitem>
|
|
<para>
|
|
Ensures that type <emphasis><literal>t</literal></emphasis>
|
|
cannot be merged. Prints the message
|
|
<emphasis><literal>m</literal></emphasis>, after the line
|
|
<literal>The option <option path> is defined multiple times.</literal>
|
|
and before a list of definition locations.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>
|
|
<literal>types.either</literal>
|
|
<emphasis><literal>t1 t2</literal></emphasis>
|
|
</term>
|
|
<listitem>
|
|
<para>
|
|
Type <emphasis><literal>t1</literal></emphasis> or type
|
|
<emphasis><literal>t2</literal></emphasis>, e.g.
|
|
<literal>with types; either int str</literal>. Multiple
|
|
definitions cannot be merged.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>
|
|
<literal>types.oneOf</literal> [
|
|
<emphasis><literal>t1 t2</literal></emphasis> ... ]
|
|
</term>
|
|
<listitem>
|
|
<para>
|
|
Type <emphasis><literal>t1</literal></emphasis> or type
|
|
<emphasis><literal>t2</literal></emphasis> and so forth,
|
|
e.g. <literal>with types; oneOf [ int str bool ]</literal>.
|
|
Multiple definitions cannot be merged.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>
|
|
<literal>types.coercedTo</literal>
|
|
<emphasis><literal>from f to</literal></emphasis>
|
|
</term>
|
|
<listitem>
|
|
<para>
|
|
Type <emphasis><literal>to</literal></emphasis> or type
|
|
<emphasis><literal>from</literal></emphasis> which will be
|
|
coerced to type <emphasis><literal>to</literal></emphasis>
|
|
using function <emphasis><literal>f</literal></emphasis>
|
|
which takes an argument of type
|
|
<emphasis><literal>from</literal></emphasis> and return a
|
|
value of type <emphasis><literal>to</literal></emphasis>.
|
|
Can be used to preserve backwards compatibility of an option
|
|
if its type was changed.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
</section>
|
|
<section xml:id="section-option-types-submodule">
|
|
<title>Submodule</title>
|
|
<para>
|
|
<literal>submodule</literal> is a very powerful type that defines
|
|
a set of sub-options that are handled like a separate module.
|
|
</para>
|
|
<para>
|
|
It takes a parameter <emphasis><literal>o</literal></emphasis>,
|
|
that should be a set, or a function returning a set with an
|
|
<literal>options</literal> key defining the sub-options. Submodule
|
|
option definitions are type-checked accordingly to the
|
|
<literal>options</literal> declarations. Of course, you can nest
|
|
submodule option definitons for even higher modularity.
|
|
</para>
|
|
<para>
|
|
The option set can be defined directly
|
|
(<link linkend="ex-submodule-direct">Example: Directly defined
|
|
submodule</link>) or as reference
|
|
(<link linkend="ex-submodule-reference">Example: Submodule defined
|
|
as a reference</link>).
|
|
</para>
|
|
<para>
|
|
Note that even if your submodule’s options all have a default
|
|
value, you will still need to provide a default value (e.g. an
|
|
empty attribute set) if you want to allow users to leave it
|
|
undefined.
|
|
</para>
|
|
<anchor xml:id="ex-submodule-direct" />
|
|
<para>
|
|
<emphasis role="strong">Example: Directly defined
|
|
submodule</emphasis>
|
|
</para>
|
|
<programlisting language="bash">
|
|
options.mod = mkOption {
|
|
description = "submodule example";
|
|
type = with types; submodule {
|
|
options = {
|
|
foo = mkOption {
|
|
type = int;
|
|
};
|
|
bar = mkOption {
|
|
type = str;
|
|
};
|
|
};
|
|
};
|
|
};
|
|
</programlisting>
|
|
<anchor xml:id="ex-submodule-reference" />
|
|
<para>
|
|
<emphasis role="strong">Example: Submodule defined as a
|
|
reference</emphasis>
|
|
</para>
|
|
<programlisting language="bash">
|
|
let
|
|
modOptions = {
|
|
options = {
|
|
foo = mkOption {
|
|
type = int;
|
|
};
|
|
bar = mkOption {
|
|
type = int;
|
|
};
|
|
};
|
|
};
|
|
in
|
|
options.mod = mkOption {
|
|
description = "submodule example";
|
|
type = with types; submodule modOptions;
|
|
};
|
|
</programlisting>
|
|
<para>
|
|
The <literal>submodule</literal> type is especially interesting
|
|
when used with composed types like <literal>attrsOf</literal> or
|
|
<literal>listOf</literal>. When composed with
|
|
<literal>listOf</literal>
|
|
(<link linkend="ex-submodule-listof-declaration">Example:
|
|
Declaration of a list of submodules</link>),
|
|
<literal>submodule</literal> allows multiple definitions of the
|
|
submodule option set
|
|
(<link linkend="ex-submodule-listof-definition">Example:
|
|
Definition of a list of submodules</link>).
|
|
</para>
|
|
<anchor xml:id="ex-submodule-listof-declaration" />
|
|
<para>
|
|
<emphasis role="strong">Example: Declaration of a list of
|
|
submodules</emphasis>
|
|
</para>
|
|
<programlisting language="bash">
|
|
options.mod = mkOption {
|
|
description = "submodule example";
|
|
type = with types; listOf (submodule {
|
|
options = {
|
|
foo = mkOption {
|
|
type = int;
|
|
};
|
|
bar = mkOption {
|
|
type = str;
|
|
};
|
|
};
|
|
});
|
|
};
|
|
</programlisting>
|
|
<anchor xml:id="ex-submodule-listof-definition" />
|
|
<para>
|
|
<emphasis role="strong">Example: Definition of a list of
|
|
submodules</emphasis>
|
|
</para>
|
|
<programlisting language="bash">
|
|
config.mod = [
|
|
{ foo = 1; bar = "one"; }
|
|
{ foo = 2; bar = "two"; }
|
|
];
|
|
</programlisting>
|
|
<para>
|
|
When composed with <literal>attrsOf</literal>
|
|
(<link linkend="ex-submodule-attrsof-declaration">Example:
|
|
Declaration of attribute sets of submodules</link>),
|
|
<literal>submodule</literal> allows multiple named definitions of
|
|
the submodule option set
|
|
(<link linkend="ex-submodule-attrsof-definition">Example:
|
|
Definition of attribute sets of submodules</link>).
|
|
</para>
|
|
<anchor xml:id="ex-submodule-attrsof-declaration" />
|
|
<para>
|
|
<emphasis role="strong">Example: Declaration of attribute sets of
|
|
submodules</emphasis>
|
|
</para>
|
|
<programlisting language="bash">
|
|
options.mod = mkOption {
|
|
description = "submodule example";
|
|
type = with types; attrsOf (submodule {
|
|
options = {
|
|
foo = mkOption {
|
|
type = int;
|
|
};
|
|
bar = mkOption {
|
|
type = str;
|
|
};
|
|
};
|
|
});
|
|
};
|
|
</programlisting>
|
|
<anchor xml:id="ex-submodule-attrsof-definition" />
|
|
<para>
|
|
<emphasis role="strong">Example: Definition of attribute sets of
|
|
submodules</emphasis>
|
|
</para>
|
|
<programlisting language="bash">
|
|
config.mod.one = { foo = 1; bar = "one"; };
|
|
config.mod.two = { foo = 2; bar = "two"; };
|
|
</programlisting>
|
|
</section>
|
|
<section xml:id="sec-option-types-extending">
|
|
<title>Extending types</title>
|
|
<para>
|
|
Types are mainly characterized by their <literal>check</literal>
|
|
and <literal>merge</literal> functions.
|
|
</para>
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term>
|
|
<literal>check</literal>
|
|
</term>
|
|
<listitem>
|
|
<para>
|
|
The function to type check the value. Takes a value as
|
|
parameter and return a boolean. It is possible to extend a
|
|
type check with the <literal>addCheck</literal> function
|
|
(<link linkend="ex-extending-type-check-1">Example: Adding a
|
|
type check</link>), or to fully override the check function
|
|
(<link linkend="ex-extending-type-check-2">Example:
|
|
Overriding a type check</link>).
|
|
</para>
|
|
<anchor xml:id="ex-extending-type-check-1" />
|
|
<para>
|
|
<emphasis role="strong">Example: Adding a type
|
|
check</emphasis>
|
|
</para>
|
|
<programlisting language="bash">
|
|
byte = mkOption {
|
|
description = "An integer between 0 and 255.";
|
|
type = types.addCheck types.int (x: x >= 0 && x <= 255);
|
|
};
|
|
</programlisting>
|
|
<anchor xml:id="ex-extending-type-check-2" />
|
|
<para>
|
|
<emphasis role="strong">Example: Overriding a type
|
|
check</emphasis>
|
|
</para>
|
|
<programlisting language="bash">
|
|
nixThings = mkOption {
|
|
description = "words that start with 'nix'";
|
|
type = types.str // {
|
|
check = (x: lib.hasPrefix "nix" x)
|
|
};
|
|
};
|
|
</programlisting>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>
|
|
<literal>merge</literal>
|
|
</term>
|
|
<listitem>
|
|
<para>
|
|
Function to merge the options values when multiple values
|
|
are set. The function takes two parameters,
|
|
<literal>loc</literal> the option path as a list of strings,
|
|
and <literal>defs</literal> the list of defined values as a
|
|
list. It is possible to override a type merge function for
|
|
custom needs.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
</section>
|
|
<section xml:id="sec-option-types-custom">
|
|
<title>Custom Types</title>
|
|
<para>
|
|
Custom types can be created with the
|
|
<literal>mkOptionType</literal> function. As type creation
|
|
includes some more complex topics such as submodule handling, it
|
|
is recommended to get familiar with <literal>types.nix</literal>
|
|
code before creating a new type.
|
|
</para>
|
|
<para>
|
|
The only required parameter is <literal>name</literal>.
|
|
</para>
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term>
|
|
<literal>name</literal>
|
|
</term>
|
|
<listitem>
|
|
<para>
|
|
A string representation of the type function name.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>
|
|
<literal>definition</literal>
|
|
</term>
|
|
<listitem>
|
|
<para>
|
|
Description of the type used in documentation. Give
|
|
information of the type and any of its arguments.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>
|
|
<literal>check</literal>
|
|
</term>
|
|
<listitem>
|
|
<para>
|
|
A function to type check the definition value. Takes the
|
|
definition value as a parameter and returns a boolean
|
|
indicating the type check result, <literal>true</literal>
|
|
for success and <literal>false</literal> for failure.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>
|
|
<literal>merge</literal>
|
|
</term>
|
|
<listitem>
|
|
<para>
|
|
A function to merge multiple definitions values. Takes two
|
|
parameters:
|
|
</para>
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term>
|
|
<emphasis><literal>loc</literal></emphasis>
|
|
</term>
|
|
<listitem>
|
|
<para>
|
|
The option path as a list of strings, e.g.
|
|
<literal>["boot" "loader "grub" "enable"]</literal>.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>
|
|
<emphasis><literal>defs</literal></emphasis>
|
|
</term>
|
|
<listitem>
|
|
<para>
|
|
The list of sets of defined <literal>value</literal>
|
|
and <literal>file</literal> where the value was
|
|
defined, e.g.
|
|
<literal>[ { file = "/foo.nix"; value = 1; } { file = "/bar.nix"; value = 2 } ]</literal>.
|
|
The <literal>merge</literal> function should return
|
|
the merged value or throw an error in case the values
|
|
are impossible or not meant to be merged.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>
|
|
<literal>getSubOptions</literal>
|
|
</term>
|
|
<listitem>
|
|
<para>
|
|
For composed types that can take a submodule as type
|
|
parameter, this function generate sub-options documentation.
|
|
It takes the current option prefix as a list and return the
|
|
set of sub-options. Usually defined in a recursive manner by
|
|
adding a term to the prefix, e.g.
|
|
<literal>prefix: elemType.getSubOptions (prefix ++ ["prefix"])</literal>
|
|
where
|
|
<emphasis><literal>"prefix"</literal></emphasis>
|
|
is the newly added prefix.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>
|
|
<literal>getSubModules</literal>
|
|
</term>
|
|
<listitem>
|
|
<para>
|
|
For composed types that can take a submodule as type
|
|
parameter, this function should return the type parameters
|
|
submodules. If the type parameter is called
|
|
<literal>elemType</literal>, the function should just
|
|
recursively look into submodules by returning
|
|
<literal>elemType.getSubModules;</literal>.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>
|
|
<literal>substSubModules</literal>
|
|
</term>
|
|
<listitem>
|
|
<para>
|
|
For composed types that can take a submodule as type
|
|
parameter, this function can be used to substitute the
|
|
parameter of a submodule type. It takes a module as
|
|
parameter and return the type with the submodule options
|
|
substituted. It is usually defined as a type function call
|
|
with a recursive call to <literal>substSubModules</literal>,
|
|
e.g for a type <literal>composedType</literal> that take an
|
|
<literal>elemtype</literal> type parameter, this function
|
|
should be defined as
|
|
<literal>m: composedType (elemType.substSubModules m)</literal>.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>
|
|
<literal>typeMerge</literal>
|
|
</term>
|
|
<listitem>
|
|
<para>
|
|
A function to merge multiple type declarations. Takes the
|
|
type to merge <literal>functor</literal> as parameter. A
|
|
<literal>null</literal> return value means that type cannot
|
|
be merged.
|
|
</para>
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term>
|
|
<emphasis><literal>f</literal></emphasis>
|
|
</term>
|
|
<listitem>
|
|
<para>
|
|
The type to merge <literal>functor</literal>.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
<para>
|
|
Note: There is a generic <literal>defaultTypeMerge</literal>
|
|
that work with most of value and composed types.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>
|
|
<literal>functor</literal>
|
|
</term>
|
|
<listitem>
|
|
<para>
|
|
An attribute set representing the type. It is used for type
|
|
operations and has the following keys:
|
|
</para>
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term>
|
|
<literal>type</literal>
|
|
</term>
|
|
<listitem>
|
|
<para>
|
|
The type function.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>
|
|
<literal>wrapped</literal>
|
|
</term>
|
|
<listitem>
|
|
<para>
|
|
Holds the type parameter for composed types.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>
|
|
<literal>payload</literal>
|
|
</term>
|
|
<listitem>
|
|
<para>
|
|
Holds the value parameter for value types. The types
|
|
that have a <literal>payload</literal> are the
|
|
<literal>enum</literal>,
|
|
<literal>separatedString</literal> and
|
|
<literal>submodule</literal> types.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>
|
|
<literal>binOp</literal>
|
|
</term>
|
|
<listitem>
|
|
<para>
|
|
A binary operation that can merge the payloads of two
|
|
same types. Defined as a function that take two
|
|
payloads as parameters and return the payloads merged.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
</section>
|
|
</section>
|
|
|