mirror of
https://github.com/NixOS/nixpkgs.git
synced 2025-06-10 03:23:29 +03:00
nixos: nixos/doc/manual/development/option-types.xml to CommonMark
This commit is contained in:
parent
6877012179
commit
bfd21cd2c1
4 changed files with 1546 additions and 915 deletions
558
nixos/doc/manual/development/option-types.section.md
Normal file
558
nixos/doc/manual/development/option-types.section.md
Normal file
|
@ -0,0 +1,558 @@
|
||||||
|
# Options Types {#sec-option-types}
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
## Basic Types {#sec-option-types-basic}
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
`types.bool`
|
||||||
|
|
||||||
|
: A boolean, its values can be `true` or `false`.
|
||||||
|
|
||||||
|
`types.path`
|
||||||
|
|
||||||
|
: A filesystem path, defined as anything that when coerced to a string
|
||||||
|
starts with a slash. Even if derivations can be considered as path,
|
||||||
|
the more specific `types.package` should be preferred.
|
||||||
|
|
||||||
|
`types.package`
|
||||||
|
|
||||||
|
: A derivation or a store path.
|
||||||
|
|
||||||
|
`types.anything`
|
||||||
|
|
||||||
|
: A type that accepts any value and recursively merges attribute sets
|
||||||
|
together. This type is recommended when the option type is unknown.
|
||||||
|
|
||||||
|
::: {#ex-types-anything .example}
|
||||||
|
::: {.title}
|
||||||
|
**Example: `types.anything` Example**
|
||||||
|
:::
|
||||||
|
Two definitions of this type like
|
||||||
|
|
||||||
|
```nix
|
||||||
|
{
|
||||||
|
str = lib.mkDefault "foo";
|
||||||
|
pkg.hello = pkgs.hello;
|
||||||
|
fun.fun = x: x + 1;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```nix
|
||||||
|
{
|
||||||
|
str = lib.mkIf true "bar";
|
||||||
|
pkg.gcc = pkgs.gcc;
|
||||||
|
fun.fun = lib.mkForce (x: x + 2);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
will get merged to
|
||||||
|
|
||||||
|
```nix
|
||||||
|
{
|
||||||
|
str = "bar";
|
||||||
|
pkg.gcc = pkgs.gcc;
|
||||||
|
pkg.hello = pkgs.hello;
|
||||||
|
fun.fun = x: x + 2;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
|
`types.attrs`
|
||||||
|
|
||||||
|
: A free-form attribute set.
|
||||||
|
|
||||||
|
::: {.warning}
|
||||||
|
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 `lib.mkDefault`, `lib.mkIf`
|
||||||
|
and co. For allowing arbitrary attribute sets, prefer
|
||||||
|
`types.attrsOf types.anything` instead which doesn\'t have these
|
||||||
|
problems.
|
||||||
|
:::
|
||||||
|
|
||||||
|
Integer-related types:
|
||||||
|
|
||||||
|
`types.int`
|
||||||
|
|
||||||
|
: A signed integer.
|
||||||
|
|
||||||
|
`types.ints.{s8, s16, s32}`
|
||||||
|
|
||||||
|
: 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. `−128` to
|
||||||
|
`127` for 8 bits).
|
||||||
|
|
||||||
|
`types.ints.unsigned`
|
||||||
|
|
||||||
|
: An unsigned integer (that is >= 0).
|
||||||
|
|
||||||
|
`types.ints.{u8, u16, u32}`
|
||||||
|
|
||||||
|
: Unsigned integers with a fixed length (8, 16 or 32 bits). They go
|
||||||
|
from 0 to 2^n−1 respectively (e.g. `0`
|
||||||
|
to `255` for 8 bits).
|
||||||
|
|
||||||
|
`types.ints.positive`
|
||||||
|
|
||||||
|
: A positive integer (that is > 0).
|
||||||
|
|
||||||
|
`types.port`
|
||||||
|
|
||||||
|
: A port number. This type is an alias to
|
||||||
|
`types.ints.u16`.
|
||||||
|
|
||||||
|
String-related types:
|
||||||
|
|
||||||
|
`types.str`
|
||||||
|
|
||||||
|
: A string. Multiple definitions cannot be merged.
|
||||||
|
|
||||||
|
`types.lines`
|
||||||
|
|
||||||
|
: A string. Multiple definitions are concatenated with a new line
|
||||||
|
`"\n"`.
|
||||||
|
|
||||||
|
`types.commas`
|
||||||
|
|
||||||
|
: A string. Multiple definitions are concatenated with a comma `","`.
|
||||||
|
|
||||||
|
`types.envVar`
|
||||||
|
|
||||||
|
: A string. Multiple definitions are concatenated with a collon `":"`.
|
||||||
|
|
||||||
|
`types.strMatching`
|
||||||
|
|
||||||
|
: A string matching a specific regular expression. Multiple
|
||||||
|
definitions cannot be merged. The regular expression is processed
|
||||||
|
using `builtins.match`.
|
||||||
|
|
||||||
|
## Value Types {#sec-option-types-value}
|
||||||
|
|
||||||
|
Value types are types that take a value parameter.
|
||||||
|
|
||||||
|
`types.enum` *`l`*
|
||||||
|
|
||||||
|
: One element of the list *`l`*, e.g. `types.enum [ "left" "right" ]`.
|
||||||
|
Multiple definitions cannot be merged.
|
||||||
|
|
||||||
|
`types.separatedString` *`sep`*
|
||||||
|
|
||||||
|
: A string with a custom separator *`sep`*, e.g.
|
||||||
|
`types.separatedString "|"`.
|
||||||
|
|
||||||
|
`types.ints.between` *`lowest highest`*
|
||||||
|
|
||||||
|
: An integer between *`lowest`* and *`highest`* (both inclusive). Useful
|
||||||
|
for creating types like `types.port`.
|
||||||
|
|
||||||
|
`types.submodule` *`o`*
|
||||||
|
|
||||||
|
: A set of sub options *`o`*. *`o`* 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
|
||||||
|
`types.submoduleWith { modules = toList o; shorthandOnlyDefinesConfig = true; }`.
|
||||||
|
Submodules are detailed in [Submodule](#section-option-types-submodule).
|
||||||
|
|
||||||
|
`types.submoduleWith` { *`modules`*, *`specialArgs`* ? {}, *`shorthandOnlyDefinesConfig`* ? false }
|
||||||
|
|
||||||
|
: Like `types.submodule`, but more flexible and with better defaults.
|
||||||
|
It has parameters
|
||||||
|
|
||||||
|
- *`modules`* 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.
|
||||||
|
|
||||||
|
::: {.note}
|
||||||
|
Only options defined with this argument are included in rendered
|
||||||
|
documentation.
|
||||||
|
:::
|
||||||
|
|
||||||
|
- *`specialArgs`* An attribute set of extra arguments to be passed
|
||||||
|
to the module functions. The option `_module.args` should be
|
||||||
|
used instead for most arguments since it allows overriding.
|
||||||
|
*`specialArgs`* 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 `lib` argument,
|
||||||
|
because `lib` itself is used to define `_module.args`, which
|
||||||
|
makes using `_module.args` to define it impossible.
|
||||||
|
|
||||||
|
- *`shorthandOnlyDefinesConfig`* Whether definitions of this type
|
||||||
|
should default to the `config` section of a module (see
|
||||||
|
[Example: Structure of NixOS Modules](#ex-module-syntax))
|
||||||
|
if it is an attribute set. Enabling this only has a benefit
|
||||||
|
when the submodule defines an option named `config` or `options`.
|
||||||
|
In such a case it would allow the option to be set with
|
||||||
|
`the-submodule.config = "value"` instead of requiring
|
||||||
|
`the-submodule.config.config = "value"`. This is because
|
||||||
|
only when modules *don\'t* set the `config` or `options`
|
||||||
|
keys, all keys are interpreted as option definitions in the
|
||||||
|
`config` section. Enabling this option implicitly puts all
|
||||||
|
attributes in the `config` section.
|
||||||
|
|
||||||
|
With this option enabled, defining a non-`config` section
|
||||||
|
requires using a function:
|
||||||
|
`the-submodule = { ... }: { options = { ... }; }`.
|
||||||
|
|
||||||
|
## Composed Types {#sec-option-types-composed}
|
||||||
|
|
||||||
|
Composed types are types that take a type as parameter. `listOf
|
||||||
|
int` and `either int str` are examples of composed types.
|
||||||
|
|
||||||
|
`types.listOf` *`t`*
|
||||||
|
|
||||||
|
: A list of *`t`* type, e.g. `types.listOf
|
||||||
|
int`. Multiple definitions are merged with list concatenation.
|
||||||
|
|
||||||
|
`types.attrsOf` *`t`*
|
||||||
|
|
||||||
|
: An attribute set of where all the values are of *`t`* type. Multiple
|
||||||
|
definitions result in the joined attribute set.
|
||||||
|
|
||||||
|
::: {.note}
|
||||||
|
This type is *strict* in its values, which in turn means attributes
|
||||||
|
cannot depend on other attributes. See `
|
||||||
|
types.lazyAttrsOf` for a lazy version.
|
||||||
|
:::
|
||||||
|
|
||||||
|
`types.lazyAttrsOf` *`t`*
|
||||||
|
|
||||||
|
: An attribute set of where all the values are of *`t`* type. Multiple
|
||||||
|
definitions result in the joined attribute set. This is the lazy
|
||||||
|
version of `types.attrsOf
|
||||||
|
`, allowing attributes to depend on each other.
|
||||||
|
|
||||||
|
::: {.warning}
|
||||||
|
This version does not fully support conditional definitions! With an
|
||||||
|
option `foo` of this type and a definition
|
||||||
|
`foo.attr = lib.mkIf false 10`, evaluating `foo ? attr` will return
|
||||||
|
`true` even though it should be false. Accessing the value will then
|
||||||
|
throw an error. For types *`t`* that have an `emptyValue` defined,
|
||||||
|
that value will be returned instead of throwing an error. So if the
|
||||||
|
type of `foo.attr` was `lazyAttrsOf (nullOr int)`, `null` would be
|
||||||
|
returned instead for the same `mkIf false` definition.
|
||||||
|
:::
|
||||||
|
|
||||||
|
`types.nullOr` *`t`*
|
||||||
|
|
||||||
|
: `null` or type *`t`*. Multiple definitions are merged according to
|
||||||
|
type *`t`*.
|
||||||
|
|
||||||
|
`types.uniq` *`t`*
|
||||||
|
|
||||||
|
: Ensures that type *`t`* cannot be merged. It is used to ensure option
|
||||||
|
definitions are declared only once.
|
||||||
|
|
||||||
|
`types.either` *`t1 t2`*
|
||||||
|
|
||||||
|
: Type *`t1`* or type *`t2`*, e.g. `with types; either int str`.
|
||||||
|
Multiple definitions cannot be merged.
|
||||||
|
|
||||||
|
`types.oneOf` \[ *`t1 t2`* \... \]
|
||||||
|
|
||||||
|
: Type *`t1`* or type *`t2`* and so forth, e.g.
|
||||||
|
`with types; oneOf [ int str bool ]`. Multiple definitions cannot be
|
||||||
|
merged.
|
||||||
|
|
||||||
|
`types.coercedTo` *`from f to`*
|
||||||
|
|
||||||
|
: Type *`to`* or type *`from`* which will be coerced to type *`to`* using
|
||||||
|
function *`f`* which takes an argument of type *`from`* and return a
|
||||||
|
value of type *`to`*. Can be used to preserve backwards compatibility
|
||||||
|
of an option if its type was changed.
|
||||||
|
|
||||||
|
## Submodule {#section-option-types-submodule}
|
||||||
|
|
||||||
|
`submodule` is a very powerful type that defines a set of sub-options
|
||||||
|
that are handled like a separate module.
|
||||||
|
|
||||||
|
It takes a parameter *`o`*, that should be a set, or a function returning
|
||||||
|
a set with an `options` key defining the sub-options. Submodule option
|
||||||
|
definitions are type-checked accordingly to the `options` declarations.
|
||||||
|
Of course, you can nest submodule option definitons for even higher
|
||||||
|
modularity.
|
||||||
|
|
||||||
|
The option set can be defined directly
|
||||||
|
([Example: Directly defined submodule](#ex-submodule-direct)) or as reference
|
||||||
|
([Example: Submodule defined as a reference](#ex-submodule-reference)).
|
||||||
|
|
||||||
|
::: {#ex-submodule-direct .example}
|
||||||
|
::: {.title}
|
||||||
|
**Example: Directly defined submodule**
|
||||||
|
:::
|
||||||
|
```nix
|
||||||
|
options.mod = mkOption {
|
||||||
|
description = "submodule example";
|
||||||
|
type = with types; submodule {
|
||||||
|
options = {
|
||||||
|
foo = mkOption {
|
||||||
|
type = int;
|
||||||
|
};
|
||||||
|
bar = mkOption {
|
||||||
|
type = str;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
|
::: {#ex-submodule-reference .example}
|
||||||
|
::: {.title}
|
||||||
|
**Example: Submodule defined as a reference**
|
||||||
|
:::
|
||||||
|
```nix
|
||||||
|
let
|
||||||
|
modOptions = {
|
||||||
|
options = {
|
||||||
|
foo = mkOption {
|
||||||
|
type = int;
|
||||||
|
};
|
||||||
|
bar = mkOption {
|
||||||
|
type = int;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in
|
||||||
|
options.mod = mkOption {
|
||||||
|
description = "submodule example";
|
||||||
|
type = with types; submodule modOptions;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
|
The `submodule` type is especially interesting when used with composed
|
||||||
|
types like `attrsOf` or `listOf`. When composed with `listOf`
|
||||||
|
([Example: Declaration of a list of submodules](#ex-submodule-listof-declaration)), `submodule` allows
|
||||||
|
multiple definitions of the submodule option set
|
||||||
|
([Example: Definition of a list of submodules](#ex-submodule-listof-definition)).
|
||||||
|
|
||||||
|
::: {#ex-submodule-listof-declaration .example}
|
||||||
|
::: {.title}
|
||||||
|
**Example: Declaration of a list of submodules**
|
||||||
|
:::
|
||||||
|
```nix
|
||||||
|
options.mod = mkOption {
|
||||||
|
description = "submodule example";
|
||||||
|
type = with types; listOf (submodule {
|
||||||
|
options = {
|
||||||
|
foo = mkOption {
|
||||||
|
type = int;
|
||||||
|
};
|
||||||
|
bar = mkOption {
|
||||||
|
type = str;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
});
|
||||||
|
};
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
|
::: {#ex-submodule-listof-definition .example}
|
||||||
|
::: {.title}
|
||||||
|
**Example: Definition of a list of submodules**
|
||||||
|
:::
|
||||||
|
```nix
|
||||||
|
config.mod = [
|
||||||
|
{ foo = 1; bar = "one"; }
|
||||||
|
{ foo = 2; bar = "two"; }
|
||||||
|
];
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
|
When composed with `attrsOf`
|
||||||
|
([Example: Declaration of attribute sets of submodules](#ex-submodule-attrsof-declaration)), `submodule` allows
|
||||||
|
multiple named definitions of the submodule option set
|
||||||
|
([Example: Definition of attribute sets of submodules](#ex-submodule-attrsof-definition)).
|
||||||
|
|
||||||
|
::: {#ex-submodule-attrsof-declaration .example}
|
||||||
|
::: {.title}
|
||||||
|
**Example: Declaration of attribute sets of submodules**
|
||||||
|
:::
|
||||||
|
```nix
|
||||||
|
options.mod = mkOption {
|
||||||
|
description = "submodule example";
|
||||||
|
type = with types; attrsOf (submodule {
|
||||||
|
options = {
|
||||||
|
foo = mkOption {
|
||||||
|
type = int;
|
||||||
|
};
|
||||||
|
bar = mkOption {
|
||||||
|
type = str;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
});
|
||||||
|
};
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
|
::: {#ex-submodule-attrsof-definition .example}
|
||||||
|
::: {.title}
|
||||||
|
**Example: Definition of attribute sets of submodules**
|
||||||
|
:::
|
||||||
|
```nix
|
||||||
|
config.mod.one = { foo = 1; bar = "one"; };
|
||||||
|
config.mod.two = { foo = 2; bar = "two"; };
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
|
## Extending types {#sec-option-types-extending}
|
||||||
|
|
||||||
|
Types are mainly characterized by their `check` and `merge` functions.
|
||||||
|
|
||||||
|
`check`
|
||||||
|
|
||||||
|
: 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
|
||||||
|
`addCheck` function ([Example: Adding a type check](#ex-extending-type-check-1)),
|
||||||
|
or to fully override the check function
|
||||||
|
([Example: Overriding a type check](#ex-extending-type-check-2)).
|
||||||
|
|
||||||
|
::: {#ex-extending-type-check-1 .example}
|
||||||
|
::: {.title}
|
||||||
|
**Example: Adding a type check**
|
||||||
|
:::
|
||||||
|
```nix
|
||||||
|
byte = mkOption {
|
||||||
|
description = "An integer between 0 and 255.";
|
||||||
|
type = types.addCheck types.int (x: x >= 0 && x <= 255);
|
||||||
|
};
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
|
::: {#ex-extending-type-check-2 .example}
|
||||||
|
::: {.title}
|
||||||
|
**Example: Overriding a type check**
|
||||||
|
:::
|
||||||
|
```nix
|
||||||
|
nixThings = mkOption {
|
||||||
|
description = "words that start with 'nix'";
|
||||||
|
type = types.str // {
|
||||||
|
check = (x: lib.hasPrefix "nix" x)
|
||||||
|
};
|
||||||
|
};
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
|
`merge`
|
||||||
|
|
||||||
|
: Function to merge the options values when multiple values are set.
|
||||||
|
The function takes two parameters, `loc` the option path as a list
|
||||||
|
of strings, and `defs` the list of defined values as a list. It is
|
||||||
|
possible to override a type merge function for custom needs.
|
||||||
|
|
||||||
|
## Custom Types {#sec-option-types-custom}
|
||||||
|
|
||||||
|
Custom types can be created with the `mkOptionType` function. As type
|
||||||
|
creation includes some more complex topics such as submodule handling,
|
||||||
|
it is recommended to get familiar with `types.nix` code before creating
|
||||||
|
a new type.
|
||||||
|
|
||||||
|
The only required parameter is `name`.
|
||||||
|
|
||||||
|
`name`
|
||||||
|
|
||||||
|
: A string representation of the type function name.
|
||||||
|
|
||||||
|
`definition`
|
||||||
|
|
||||||
|
: Description of the type used in documentation. Give information of
|
||||||
|
the type and any of its arguments.
|
||||||
|
|
||||||
|
`check`
|
||||||
|
|
||||||
|
: A function to type check the definition value. Takes the definition
|
||||||
|
value as a parameter and returns a boolean indicating the type check
|
||||||
|
result, `true` for success and `false` for failure.
|
||||||
|
|
||||||
|
`merge`
|
||||||
|
|
||||||
|
: A function to merge multiple definitions values. Takes two
|
||||||
|
parameters:
|
||||||
|
|
||||||
|
*`loc`*
|
||||||
|
|
||||||
|
: The option path as a list of strings, e.g. `["boot" "loader
|
||||||
|
"grub" "enable"]`.
|
||||||
|
|
||||||
|
*`defs`*
|
||||||
|
|
||||||
|
: The list of sets of defined `value` and `file` where the value
|
||||||
|
was defined, e.g. `[ {
|
||||||
|
file = "/foo.nix"; value = 1; } { file = "/bar.nix"; value = 2 }
|
||||||
|
]`. The `merge` function should return the merged value
|
||||||
|
or throw an error in case the values are impossible or not meant
|
||||||
|
to be merged.
|
||||||
|
|
||||||
|
`getSubOptions`
|
||||||
|
|
||||||
|
: 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.
|
||||||
|
`prefix:
|
||||||
|
elemType.getSubOptions (prefix ++
|
||||||
|
["prefix"])` where *`"prefix"`* is the newly added prefix.
|
||||||
|
|
||||||
|
`getSubModules`
|
||||||
|
|
||||||
|
: 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 `elemType`, the function should just recursively
|
||||||
|
look into submodules by returning `elemType.getSubModules;`.
|
||||||
|
|
||||||
|
`substSubModules`
|
||||||
|
|
||||||
|
: 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 `substSubModules`, e.g for a
|
||||||
|
type `composedType` that take an `elemtype` type parameter, this
|
||||||
|
function should be defined as `m:
|
||||||
|
composedType (elemType.substSubModules m)`.
|
||||||
|
|
||||||
|
`typeMerge`
|
||||||
|
|
||||||
|
: A function to merge multiple type declarations. Takes the type to
|
||||||
|
merge `functor` as parameter. A `null` return value means that type
|
||||||
|
cannot be merged.
|
||||||
|
|
||||||
|
*`f`*
|
||||||
|
|
||||||
|
: The type to merge `functor`.
|
||||||
|
|
||||||
|
Note: There is a generic `defaultTypeMerge` that work with most of
|
||||||
|
value and composed types.
|
||||||
|
|
||||||
|
`functor`
|
||||||
|
|
||||||
|
: An attribute set representing the type. It is used for type
|
||||||
|
operations and has the following keys:
|
||||||
|
|
||||||
|
`type`
|
||||||
|
|
||||||
|
: The type function.
|
||||||
|
|
||||||
|
`wrapped`
|
||||||
|
|
||||||
|
: Holds the type parameter for composed types.
|
||||||
|
|
||||||
|
`payload`
|
||||||
|
|
||||||
|
: Holds the value parameter for value types. The types that have a
|
||||||
|
`payload` are the `enum`, `separatedString` and `submodule`
|
||||||
|
types.
|
||||||
|
|
||||||
|
`binOp`
|
||||||
|
|
||||||
|
: 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.
|
|
@ -1,914 +0,0 @@
|
||||||
<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-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>
|
|
||||||
<varname>types.bool</varname>
|
|
||||||
</term>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
A boolean, its values can be <literal>true</literal> or
|
|
||||||
<literal>false</literal>.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
<varlistentry>
|
|
||||||
<term>
|
|
||||||
<varname>types.path</varname>
|
|
||||||
</term>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
A filesystem path, defined as anything that when coerced to a string
|
|
||||||
starts with a slash. Even if derivations can be considered as path, the
|
|
||||||
more specific <literal>types.package</literal> should be preferred.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
<varlistentry>
|
|
||||||
<term>
|
|
||||||
<varname>types.package</varname>
|
|
||||||
</term>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
A derivation or a store path.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
<varlistentry>
|
|
||||||
<term>
|
|
||||||
<varname>types.anything</varname>
|
|
||||||
</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.
|
|
||||||
<example xml:id="ex-types-anything">
|
|
||||||
<title><literal>types.anything</literal> Example</title>
|
|
||||||
<para>
|
|
||||||
Two definitions of this type like
|
|
||||||
<programlisting>
|
|
||||||
{
|
|
||||||
str = lib.mkDefault "foo";
|
|
||||||
pkg.hello = pkgs.hello;
|
|
||||||
fun.fun = x: x + 1;
|
|
||||||
}
|
|
||||||
</programlisting>
|
|
||||||
<programlisting>
|
|
||||||
{
|
|
||||||
str = lib.mkIf true "bar";
|
|
||||||
pkg.gcc = pkgs.gcc;
|
|
||||||
fun.fun = lib.mkForce (x: x + 2);
|
|
||||||
}
|
|
||||||
</programlisting>
|
|
||||||
will get merged to
|
|
||||||
<programlisting>
|
|
||||||
{
|
|
||||||
str = "bar";
|
|
||||||
pkg.gcc = pkgs.gcc;
|
|
||||||
pkg.hello = pkgs.hello;
|
|
||||||
fun.fun = x: x + 2;
|
|
||||||
}
|
|
||||||
</programlisting>
|
|
||||||
</para>
|
|
||||||
</example>
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
<varlistentry>
|
|
||||||
<term>
|
|
||||||
<varname>types.attrs</varname>
|
|
||||||
</term>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
A free-form attribute set.
|
|
||||||
<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>
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
</variablelist>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
Integer-related types:
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<variablelist>
|
|
||||||
<varlistentry>
|
|
||||||
<term>
|
|
||||||
<varname>types.int</varname>
|
|
||||||
</term>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
A signed integer.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
<varlistentry>
|
|
||||||
<term>
|
|
||||||
<varname>types.ints.{s8, s16, s32}</varname>
|
|
||||||
</term>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
Signed integers with a fixed length (8, 16 or 32 bits). They go from
|
|
||||||
<inlineequation><mathphrase>−2<superscript>n</superscript>/2</mathphrase>
|
|
||||||
</inlineequation> to <inlineequation>
|
|
||||||
<mathphrase>2<superscript>n</superscript>/2−1</mathphrase>
|
|
||||||
</inlineequation> respectively (e.g. <literal>−128</literal> to
|
|
||||||
<literal>127</literal> for 8 bits).
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
<varlistentry>
|
|
||||||
<term>
|
|
||||||
<varname>types.ints.unsigned</varname>
|
|
||||||
</term>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
An unsigned integer (that is >= 0).
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
<varlistentry xml:id='types.ints.ux'>
|
|
||||||
<term>
|
|
||||||
<varname>types.ints.{u8, u16, u32}</varname>
|
|
||||||
</term>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
Unsigned integers with a fixed length (8, 16 or 32 bits). They go from
|
|
||||||
<inlineequation><mathphrase>0</mathphrase></inlineequation> to
|
|
||||||
<inlineequation>
|
|
||||||
<mathphrase>2<superscript>n</superscript>−1</mathphrase>
|
|
||||||
</inlineequation> respectively (e.g. <literal>0</literal> to
|
|
||||||
<literal>255</literal> for 8 bits).
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
<varlistentry>
|
|
||||||
<term>
|
|
||||||
<varname>types.ints.positive</varname>
|
|
||||||
</term>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
A positive integer (that is > 0).
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
<varlistentry>
|
|
||||||
<term>
|
|
||||||
<varname>types.port</varname>
|
|
||||||
</term>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
A port number. This type is an alias to
|
|
||||||
<link linkend='types.ints.ux'><varname>types.ints.u16</varname></link>.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
</variablelist>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
String-related types:
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<variablelist>
|
|
||||||
<varlistentry>
|
|
||||||
<term>
|
|
||||||
<varname>types.str</varname>
|
|
||||||
</term>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
A string. Multiple definitions cannot be merged.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
<varlistentry>
|
|
||||||
<term>
|
|
||||||
<varname>types.lines</varname>
|
|
||||||
</term>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
A string. Multiple definitions are concatenated with a new line
|
|
||||||
<literal>"\n"</literal>.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
<varlistentry>
|
|
||||||
<term>
|
|
||||||
<varname>types.commas</varname>
|
|
||||||
</term>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
A string. Multiple definitions are concatenated with a comma
|
|
||||||
<literal>","</literal>.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
<varlistentry>
|
|
||||||
<term>
|
|
||||||
<varname>types.envVar</varname>
|
|
||||||
</term>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
A string. Multiple definitions are concatenated with a collon
|
|
||||||
<literal>":"</literal>.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
<varlistentry>
|
|
||||||
<term>
|
|
||||||
<varname>types.strMatching</varname>
|
|
||||||
</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>
|
|
||||||
<varname>types.enum</varname> <replaceable>l</replaceable>
|
|
||||||
</term>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
One element of the list <replaceable>l</replaceable>, e.g.
|
|
||||||
<literal>types.enum [ "left" "right" ]</literal>. Multiple definitions
|
|
||||||
cannot be merged.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
<varlistentry>
|
|
||||||
<term>
|
|
||||||
<varname>types.separatedString</varname> <replaceable>sep</replaceable>
|
|
||||||
</term>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
A string with a custom separator <replaceable>sep</replaceable>, e.g.
|
|
||||||
<literal>types.separatedString "|"</literal>.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
<varlistentry>
|
|
||||||
<term>
|
|
||||||
<varname>types.ints.between</varname> <replaceable>lowest</replaceable> <replaceable>highest</replaceable>
|
|
||||||
</term>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
An integer between <replaceable>lowest</replaceable> and
|
|
||||||
<replaceable>highest</replaceable> (both inclusive). Useful for creating
|
|
||||||
types like <literal>types.port</literal>.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
<varlistentry>
|
|
||||||
<term>
|
|
||||||
<varname>types.submodule</varname> <replaceable>o</replaceable>
|
|
||||||
</term>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
A set of sub options <replaceable>o</replaceable>.
|
|
||||||
<replaceable>o</replaceable> 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
|
|
||||||
<xref
|
|
||||||
linkend='section-option-types-submodule' />.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
<varlistentry>
|
|
||||||
<term>
|
|
||||||
<varname>types.submoduleWith</varname> {
|
|
||||||
<replaceable>modules</replaceable>,
|
|
||||||
<replaceable>specialArgs</replaceable> ? {},
|
|
||||||
<replaceable>shorthandOnlyDefinesConfig</replaceable> ? false }
|
|
||||||
</term>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
Like <varname>types.submodule</varname>, but more flexible and with better defaults.
|
|
||||||
It has parameters
|
|
||||||
<itemizedlist>
|
|
||||||
<listitem><para>
|
|
||||||
<replaceable>modules</replaceable>
|
|
||||||
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.
|
|
||||||
<note><para>
|
|
||||||
Only options defined with this argument are included in rendered documentation.
|
|
||||||
</para></note>
|
|
||||||
</para></listitem>
|
|
||||||
<listitem><para>
|
|
||||||
<replaceable>specialArgs</replaceable>
|
|
||||||
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. <replaceable>specialArgs</replaceable> 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
|
|
||||||
<varname>lib</varname> argument, because <varname>lib</varname> itself is used
|
|
||||||
to define <literal>_module.args</literal>, which makes using
|
|
||||||
<literal>_module.args</literal> to define it impossible.
|
|
||||||
</para></listitem>
|
|
||||||
<listitem><para>
|
|
||||||
<replaceable>shorthandOnlyDefinesConfig</replaceable>
|
|
||||||
Whether definitions of this type should default to the <literal>config</literal>
|
|
||||||
section of a module (see <xref linkend='ex-module-syntax'/>) 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>
|
|
||||||
</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>
|
|
||||||
<varname>types.listOf</varname> <replaceable>t</replaceable>
|
|
||||||
</term>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
A list of <replaceable>t</replaceable> type, e.g. <literal>types.listOf
|
|
||||||
int</literal>. Multiple definitions are merged with list concatenation.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
<varlistentry>
|
|
||||||
<term>
|
|
||||||
<varname>types.attrsOf</varname> <replaceable>t</replaceable>
|
|
||||||
</term>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
An attribute set of where all the values are of
|
|
||||||
<replaceable>t</replaceable> type. Multiple definitions result in the
|
|
||||||
joined attribute set.
|
|
||||||
<note><para>
|
|
||||||
This type is <emphasis>strict</emphasis> in its values, which in turn
|
|
||||||
means attributes cannot depend on other attributes. See <varname>
|
|
||||||
types.lazyAttrsOf</varname> for a lazy version.
|
|
||||||
</para></note>
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
<varlistentry>
|
|
||||||
<term>
|
|
||||||
<varname>types.lazyAttrsOf</varname> <replaceable>t</replaceable>
|
|
||||||
</term>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
An attribute set of where all the values are of
|
|
||||||
<replaceable>t</replaceable> type. Multiple definitions result in the
|
|
||||||
joined attribute set. This is the lazy version of <varname>types.attrsOf
|
|
||||||
</varname>, allowing attributes to depend on each other.
|
|
||||||
<warning><para>
|
|
||||||
This version does not fully support conditional definitions! With an
|
|
||||||
option <varname>foo</varname> 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 <replaceable>t</replaceable> 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>
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
<varlistentry>
|
|
||||||
<term>
|
|
||||||
<varname>types.nullOr</varname> <replaceable>t</replaceable>
|
|
||||||
</term>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
<literal>null</literal> or type <replaceable>t</replaceable>. Multiple
|
|
||||||
definitions are merged according to type <replaceable>t</replaceable>.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
<varlistentry>
|
|
||||||
<term>
|
|
||||||
<varname>types.uniq</varname> <replaceable>t</replaceable>
|
|
||||||
</term>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
Ensures that type <replaceable>t</replaceable> cannot be merged. It is
|
|
||||||
used to ensure option definitions are declared only once.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
<varlistentry>
|
|
||||||
<term>
|
|
||||||
<varname>types.either</varname> <replaceable>t1</replaceable> <replaceable>t2</replaceable>
|
|
||||||
</term>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
Type <replaceable>t1</replaceable> or type <replaceable>t2</replaceable>,
|
|
||||||
e.g. <literal>with types; either int str</literal>. Multiple definitions
|
|
||||||
cannot be merged.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
<varlistentry>
|
|
||||||
<term>
|
|
||||||
<varname>types.oneOf</varname> [ <replaceable>t1</replaceable> <replaceable>t2</replaceable> ... ]
|
|
||||||
</term>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
Type <replaceable>t1</replaceable> or type <replaceable>t2</replaceable> and so forth,
|
|
||||||
e.g. <literal>with types; oneOf [ int str bool ]</literal>. Multiple definitions
|
|
||||||
cannot be merged.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
<varlistentry>
|
|
||||||
<term>
|
|
||||||
<varname>types.coercedTo</varname> <replaceable>from</replaceable> <replaceable>f</replaceable> <replaceable>to</replaceable>
|
|
||||||
</term>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
Type <replaceable>to</replaceable> or type
|
|
||||||
<replaceable>from</replaceable> which will be coerced to type
|
|
||||||
<replaceable>to</replaceable> using function <replaceable>f</replaceable>
|
|
||||||
which takes an argument of type <replaceable>from</replaceable> and
|
|
||||||
return a value of type <replaceable>to</replaceable>. 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 <replaceable>o</replaceable>, 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
|
|
||||||
(<xref linkend='ex-submodule-direct' />) or as reference
|
|
||||||
(<xref linkend='ex-submodule-reference' />).
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<example xml:id='ex-submodule-direct'>
|
|
||||||
<title>Directly defined submodule</title>
|
|
||||||
<screen>
|
|
||||||
options.mod = mkOption {
|
|
||||||
description = "submodule example";
|
|
||||||
type = with types; submodule {
|
|
||||||
options = {
|
|
||||||
foo = mkOption {
|
|
||||||
type = int;
|
|
||||||
};
|
|
||||||
bar = mkOption {
|
|
||||||
type = str;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};</screen>
|
|
||||||
</example>
|
|
||||||
|
|
||||||
<example xml:id='ex-submodule-reference'>
|
|
||||||
<title>Submodule defined as a reference</title>
|
|
||||||
<screen>
|
|
||||||
let
|
|
||||||
modOptions = {
|
|
||||||
options = {
|
|
||||||
foo = mkOption {
|
|
||||||
type = int;
|
|
||||||
};
|
|
||||||
bar = mkOption {
|
|
||||||
type = int;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
in
|
|
||||||
options.mod = mkOption {
|
|
||||||
description = "submodule example";
|
|
||||||
type = with types; submodule modOptions;
|
|
||||||
};</screen>
|
|
||||||
</example>
|
|
||||||
|
|
||||||
<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>
|
|
||||||
(<xref linkend='ex-submodule-listof-declaration' />),
|
|
||||||
<literal>submodule</literal> allows multiple definitions of the submodule
|
|
||||||
option set (<xref linkend='ex-submodule-listof-definition' />).
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<example xml:id='ex-submodule-listof-declaration'>
|
|
||||||
<title>Declaration of a list of submodules</title>
|
|
||||||
<screen>
|
|
||||||
options.mod = mkOption {
|
|
||||||
description = "submodule example";
|
|
||||||
type = with types; listOf (submodule {
|
|
||||||
options = {
|
|
||||||
foo = mkOption {
|
|
||||||
type = int;
|
|
||||||
};
|
|
||||||
bar = mkOption {
|
|
||||||
type = str;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
});
|
|
||||||
};</screen>
|
|
||||||
</example>
|
|
||||||
|
|
||||||
<example xml:id='ex-submodule-listof-definition'>
|
|
||||||
<title>Definition of a list of submodules</title>
|
|
||||||
<screen>
|
|
||||||
config.mod = [
|
|
||||||
{ foo = 1; bar = "one"; }
|
|
||||||
{ foo = 2; bar = "two"; }
|
|
||||||
];</screen>
|
|
||||||
</example>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
When composed with <literal>attrsOf</literal>
|
|
||||||
(<xref linkend='ex-submodule-attrsof-declaration' />),
|
|
||||||
<literal>submodule</literal> allows multiple named definitions of the
|
|
||||||
submodule option set (<xref linkend='ex-submodule-attrsof-definition' />).
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<example xml:id='ex-submodule-attrsof-declaration'>
|
|
||||||
<title>Declaration of attribute sets of submodules</title>
|
|
||||||
<screen>
|
|
||||||
options.mod = mkOption {
|
|
||||||
description = "submodule example";
|
|
||||||
type = with types; attrsOf (submodule {
|
|
||||||
options = {
|
|
||||||
foo = mkOption {
|
|
||||||
type = int;
|
|
||||||
};
|
|
||||||
bar = mkOption {
|
|
||||||
type = str;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
});
|
|
||||||
};</screen>
|
|
||||||
</example>
|
|
||||||
|
|
||||||
<example xml:id='ex-submodule-attrsof-definition'>
|
|
||||||
<title>Declaration of attribute sets of submodules</title>
|
|
||||||
<screen>
|
|
||||||
config.mod.one = { foo = 1; bar = "one"; };
|
|
||||||
config.mod.two = { foo = 2; bar = "two"; };</screen>
|
|
||||||
</example>
|
|
||||||
</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>
|
|
||||||
<varname>check</varname>
|
|
||||||
</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
|
|
||||||
(<xref
|
|
||||||
linkend='ex-extending-type-check-1' />), or to fully
|
|
||||||
override the check function
|
|
||||||
(<xref linkend='ex-extending-type-check-2' />).
|
|
||||||
</para>
|
|
||||||
<example xml:id='ex-extending-type-check-1'>
|
|
||||||
<title>Adding a type check</title>
|
|
||||||
<screen>
|
|
||||||
byte = mkOption {
|
|
||||||
description = "An integer between 0 and 255.";
|
|
||||||
type = types.addCheck types.int (x: x >= 0 && x <= 255);
|
|
||||||
};</screen>
|
|
||||||
</example>
|
|
||||||
<example xml:id='ex-extending-type-check-2'>
|
|
||||||
<title>Overriding a type check</title>
|
|
||||||
<screen>
|
|
||||||
nixThings = mkOption {
|
|
||||||
description = "words that start with 'nix'";
|
|
||||||
type = types.str // {
|
|
||||||
check = (x: lib.hasPrefix "nix" x)
|
|
||||||
};
|
|
||||||
};</screen>
|
|
||||||
</example>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
<varlistentry>
|
|
||||||
<term>
|
|
||||||
<varname>merge</varname>
|
|
||||||
</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
|
|
||||||
<filename
|
|
||||||
xlink:href="https://github.com/NixOS/nixpkgs/blob/master/lib/types.nix">types.nix</filename>
|
|
||||||
code before creating a new type.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
The only required parameter is <literal>name</literal>.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<variablelist>
|
|
||||||
<varlistentry>
|
|
||||||
<term>
|
|
||||||
<varname>name</varname>
|
|
||||||
</term>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
A string representation of the type function name.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
<varlistentry>
|
|
||||||
<term>
|
|
||||||
<varname>definition</varname>
|
|
||||||
</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>
|
|
||||||
<varname>check</varname>
|
|
||||||
</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>
|
|
||||||
<varname>merge</varname>
|
|
||||||
</term>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
A function to merge multiple definitions values. Takes two parameters:
|
|
||||||
</para>
|
|
||||||
<variablelist>
|
|
||||||
<varlistentry>
|
|
||||||
<term>
|
|
||||||
<replaceable>loc</replaceable>
|
|
||||||
</term>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
The option path as a list of strings, e.g. <literal>["boot" "loader
|
|
||||||
"grub" "enable"]</literal>.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
<varlistentry>
|
|
||||||
<term>
|
|
||||||
<replaceable>defs</replaceable>
|
|
||||||
</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>
|
|
||||||
<varname>getSubOptions</varname>
|
|
||||||
</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 ++
|
|
||||||
[<replaceable>"prefix"</replaceable>])</literal> where
|
|
||||||
<replaceable>"prefix"</replaceable> is the newly added prefix.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
<varlistentry>
|
|
||||||
<term>
|
|
||||||
<varname>getSubModules</varname>
|
|
||||||
</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>
|
|
||||||
<varname>substSubModules</varname>
|
|
||||||
</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>
|
|
||||||
<varname>typeMerge</varname>
|
|
||||||
</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>
|
|
||||||
<replaceable>f</replaceable>
|
|
||||||
</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>
|
|
||||||
<varname>functor</varname>
|
|
||||||
</term>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
An attribute set representing the type. It is used for type operations
|
|
||||||
and has the following keys:
|
|
||||||
</para>
|
|
||||||
<variablelist>
|
|
||||||
<varlistentry>
|
|
||||||
<term>
|
|
||||||
<varname>type</varname>
|
|
||||||
</term>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
The type function.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
<varlistentry>
|
|
||||||
<term>
|
|
||||||
<varname>wrapped</varname>
|
|
||||||
</term>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
Holds the type parameter for composed types.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
<varlistentry>
|
|
||||||
<term>
|
|
||||||
<varname>payload</varname>
|
|
||||||
</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>
|
|
||||||
<varname>binOp</varname>
|
|
||||||
</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>
|
|
|
@ -180,7 +180,7 @@ in {
|
||||||
</programlisting>
|
</programlisting>
|
||||||
</example>
|
</example>
|
||||||
<xi:include href="../from_md/development/option-declarations.section.xml" />
|
<xi:include href="../from_md/development/option-declarations.section.xml" />
|
||||||
<xi:include href="option-types.xml" />
|
<xi:include href="../from_md/development/option-types.section.xml" />
|
||||||
<xi:include href="option-def.xml" />
|
<xi:include href="option-def.xml" />
|
||||||
<xi:include href="../from_md/development/assertions.section.xml" />
|
<xi:include href="../from_md/development/assertions.section.xml" />
|
||||||
<xi:include href="meta-attributes.xml" />
|
<xi:include href="meta-attributes.xml" />
|
||||||
|
|
987
nixos/doc/manual/from_md/development/option-types.section.xml
Normal file
987
nixos/doc/manual/from_md/development/option-types.section.xml
Normal file
|
@ -0,0 +1,987 @@
|
||||||
|
<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, defined as anything that when coerced to
|
||||||
|
a string starts with a slash. Even if derivations can be
|
||||||
|
considered as path, the more specific
|
||||||
|
<literal>types.package</literal> should be preferred.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term>
|
||||||
|
<literal>types.package</literal>
|
||||||
|
</term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
A derivation or a store path.
|
||||||
|
</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.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>
|
||||||
|
</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.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>
|
||||||
|
<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>
|
Loading…
Add table
Add a link
Reference in a new issue