parent
bfd21cd2c1
commit
d48cfce2bf
@ -0,0 +1,91 @@ |
||||
# Option Definitions {#sec-option-definitions} |
||||
|
||||
Option definitions are generally straight-forward bindings of values to |
||||
option names, like |
||||
|
||||
```nix |
||||
config = { |
||||
services.httpd.enable = true; |
||||
}; |
||||
``` |
||||
|
||||
However, sometimes you need to wrap an option definition or set of |
||||
option definitions in a *property* to achieve certain effects: |
||||
|
||||
## Delaying Conditionals {#sec-option-definitions-delaying-conditionals .unnumbered} |
||||
|
||||
If a set of option definitions is conditional on the value of another |
||||
option, you may need to use `mkIf`. Consider, for instance: |
||||
|
||||
```nix |
||||
config = if config.services.httpd.enable then { |
||||
environment.systemPackages = [ ... ]; |
||||
... |
||||
} else {}; |
||||
``` |
||||
|
||||
This definition will cause Nix to fail with an "infinite recursion" |
||||
error. Why? Because the value of `config.services.httpd.enable` depends |
||||
on the value being constructed here. After all, you could also write the |
||||
clearly circular and contradictory: |
||||
|
||||
```nix |
||||
config = if config.services.httpd.enable then { |
||||
services.httpd.enable = false; |
||||
} else { |
||||
services.httpd.enable = true; |
||||
}; |
||||
``` |
||||
|
||||
The solution is to write: |
||||
|
||||
```nix |
||||
config = mkIf config.services.httpd.enable { |
||||
environment.systemPackages = [ ... ]; |
||||
... |
||||
}; |
||||
``` |
||||
|
||||
The special function `mkIf` causes the evaluation of the conditional to |
||||
be "pushed down" into the individual definitions, as if you had written: |
||||
|
||||
```nix |
||||
config = { |
||||
environment.systemPackages = if config.services.httpd.enable then [ ... ] else []; |
||||
... |
||||
}; |
||||
``` |
||||
|
||||
## Setting Priorities {#sec-option-definitions-setting-priorities .unnumbered} |
||||
|
||||
A module can override the definitions of an option in other modules by |
||||
setting a *priority*. All option definitions that do not have the lowest |
||||
priority value are discarded. By default, option definitions have |
||||
priority 1000. You can specify an explicit priority by using |
||||
`mkOverride`, e.g. |
||||
|
||||
```nix |
||||
services.openssh.enable = mkOverride 10 false; |
||||
``` |
||||
|
||||
This definition causes all other definitions with priorities above 10 to |
||||
be discarded. The function `mkForce` is equal to `mkOverride 50`. |
||||
|
||||
## Merging Configurations {#sec-option-definitions-merging .unnumbered} |
||||
|
||||
In conjunction with `mkIf`, it is sometimes useful for a module to |
||||
return multiple sets of option definitions, to be merged together as if |
||||
they were declared in separate modules. This can be done using |
||||
`mkMerge`: |
||||
|
||||
```nix |
||||
config = mkMerge |
||||
[ # Unconditional stuff. |
||||
{ environment.systemPackages = [ ... ]; |
||||
} |
||||
# Conditional stuff. |
||||
(mkIf config.services.bla.enable { |
||||
environment.systemPackages = [ ... ]; |
||||
}) |
||||
]; |
||||
``` |
@ -1,99 +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-definitions"> |
||||
<title>Option Definitions</title> |
||||
|
||||
<para> |
||||
Option definitions are generally straight-forward bindings of values to |
||||
option names, like |
||||
<programlisting> |
||||
config = { |
||||
services.httpd.enable = true; |
||||
}; |
||||
</programlisting> |
||||
However, sometimes you need to wrap an option definition or set of option |
||||
definitions in a <emphasis>property</emphasis> to achieve certain effects: |
||||
</para> |
||||
|
||||
<simplesect xml:id="sec-option-definitions-delaying-conditionals"> |
||||
<title>Delaying Conditionals</title> |
||||
<para> |
||||
If a set of option definitions is conditional on the value of another |
||||
option, you may need to use <varname>mkIf</varname>. Consider, for instance: |
||||
<programlisting> |
||||
config = if config.services.httpd.enable then { |
||||
environment.systemPackages = [ <replaceable>...</replaceable> ]; |
||||
<replaceable>...</replaceable> |
||||
} else {}; |
||||
</programlisting> |
||||
This definition will cause Nix to fail with an “infinite recursion” |
||||
error. Why? Because the value of |
||||
<option>config.services.httpd.enable</option> depends on the value being |
||||
constructed here. After all, you could also write the clearly circular and |
||||
contradictory: |
||||
<programlisting> |
||||
config = if config.services.httpd.enable then { |
||||
services.httpd.enable = false; |
||||
} else { |
||||
services.httpd.enable = true; |
||||
}; |
||||
</programlisting> |
||||
The solution is to write: |
||||
<programlisting> |
||||
config = mkIf config.services.httpd.enable { |
||||
environment.systemPackages = [ <replaceable>...</replaceable> ]; |
||||
<replaceable>...</replaceable> |
||||
}; |
||||
</programlisting> |
||||
The special function <varname>mkIf</varname> causes the evaluation of the |
||||
conditional to be “pushed down” into the individual definitions, as if |
||||
you had written: |
||||
<programlisting> |
||||
config = { |
||||
environment.systemPackages = if config.services.httpd.enable then [ <replaceable>...</replaceable> ] else []; |
||||
<replaceable>...</replaceable> |
||||
}; |
||||
</programlisting> |
||||
</para> |
||||
</simplesect> |
||||
|
||||
<simplesect xml:id="sec-option-definitions-setting-priorities"> |
||||
<title>Setting Priorities</title> |
||||
<para> |
||||
A module can override the definitions of an option in other modules by |
||||
setting a <emphasis>priority</emphasis>. All option definitions that do not |
||||
have the lowest priority value are discarded. By default, option definitions |
||||
have priority 1000. You can specify an explicit priority by using |
||||
<varname>mkOverride</varname>, e.g. |
||||
<programlisting> |
||||
services.openssh.enable = mkOverride 10 false; |
||||
</programlisting> |
||||
This definition causes all other definitions with priorities above 10 to be |
||||
discarded. The function <varname>mkForce</varname> is equal to |
||||
<varname>mkOverride 50</varname>. |
||||
</para> |
||||
</simplesect> |
||||
|
||||
<simplesect xml:id="sec-option-definitions-merging"> |
||||
<title>Merging Configurations</title> |
||||
<para> |
||||
In conjunction with <literal>mkIf</literal>, it is sometimes useful for a |
||||
module to return multiple sets of option definitions, to be merged together |
||||
as if they were declared in separate modules. This can be done using |
||||
<varname>mkMerge</varname>: |
||||
<programlisting> |
||||
config = mkMerge |
||||
[ # Unconditional stuff. |
||||
{ environment.systemPackages = [ <replaceable>...</replaceable> ]; |
||||
} |
||||
# Conditional stuff. |
||||
(mkIf config.services.bla.enable { |
||||
environment.systemPackages = [ <replaceable>...</replaceable> ]; |
||||
}) |
||||
]; |
||||
</programlisting> |
||||
</para> |
||||
</simplesect> |
||||
</section> |
@ -0,0 +1,104 @@ |
||||
<section xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="sec-option-definitions"> |
||||
<title>Option Definitions</title> |
||||
<para> |
||||
Option definitions are generally straight-forward bindings of values |
||||
to option names, like |
||||
</para> |
||||
<programlisting language="bash"> |
||||
config = { |
||||
services.httpd.enable = true; |
||||
}; |
||||
</programlisting> |
||||
<para> |
||||
However, sometimes you need to wrap an option definition or set of |
||||
option definitions in a <emphasis>property</emphasis> to achieve |
||||
certain effects: |
||||
</para> |
||||
<section xml:id="sec-option-definitions-delaying-conditionals"> |
||||
<title>Delaying Conditionals</title> |
||||
<para> |
||||
If a set of option definitions is conditional on the value of |
||||
another option, you may need to use <literal>mkIf</literal>. |
||||
Consider, for instance: |
||||
</para> |
||||
<programlisting language="bash"> |
||||
config = if config.services.httpd.enable then { |
||||
environment.systemPackages = [ ... ]; |
||||
... |
||||
} else {}; |
||||
</programlisting> |
||||
<para> |
||||
This definition will cause Nix to fail with an <quote>infinite |
||||
recursion</quote> error. Why? Because the value of |
||||
<literal>config.services.httpd.enable</literal> depends on the |
||||
value being constructed here. After all, you could also write the |
||||
clearly circular and contradictory: |
||||
</para> |
||||
<programlisting language="bash"> |
||||
config = if config.services.httpd.enable then { |
||||
services.httpd.enable = false; |
||||
} else { |
||||
services.httpd.enable = true; |
||||
}; |
||||
</programlisting> |
||||
<para> |
||||
The solution is to write: |
||||
</para> |
||||
<programlisting language="bash"> |
||||
config = mkIf config.services.httpd.enable { |
||||
environment.systemPackages = [ ... ]; |
||||
... |
||||
}; |
||||
</programlisting> |
||||
<para> |
||||
The special function <literal>mkIf</literal> causes the evaluation |
||||
of the conditional to be <quote>pushed down</quote> into the |
||||
individual definitions, as if you had written: |
||||
</para> |
||||
<programlisting language="bash"> |
||||
config = { |
||||
environment.systemPackages = if config.services.httpd.enable then [ ... ] else []; |
||||
... |
||||
}; |
||||
</programlisting> |
||||
</section> |
||||
<section xml:id="sec-option-definitions-setting-priorities"> |
||||
<title>Setting Priorities</title> |
||||
<para> |
||||
A module can override the definitions of an option in other |
||||
modules by setting a <emphasis>priority</emphasis>. All option |
||||
definitions that do not have the lowest priority value are |
||||
discarded. By default, option definitions have priority 1000. You |
||||
can specify an explicit priority by using |
||||
<literal>mkOverride</literal>, e.g. |
||||
</para> |
||||
<programlisting language="bash"> |
||||
services.openssh.enable = mkOverride 10 false; |
||||
</programlisting> |
||||
<para> |
||||
This definition causes all other definitions with priorities above |
||||
10 to be discarded. The function <literal>mkForce</literal> is |
||||
equal to <literal>mkOverride 50</literal>. |
||||
</para> |
||||
</section> |
||||
<section xml:id="sec-option-definitions-merging"> |
||||
<title>Merging Configurations</title> |
||||
<para> |
||||
In conjunction with <literal>mkIf</literal>, it is sometimes |
||||
useful for a module to return multiple sets of option definitions, |
||||
to be merged together as if they were declared in separate |
||||
modules. This can be done using <literal>mkMerge</literal>: |
||||
</para> |
||||
<programlisting language="bash"> |
||||
config = mkMerge |
||||
[ # Unconditional stuff. |
||||
{ environment.systemPackages = [ ... ]; |
||||
} |
||||
# Conditional stuff. |
||||
(mkIf config.services.bla.enable { |
||||
environment.systemPackages = [ ... ]; |
||||
}) |
||||
]; |
||||
</programlisting> |
||||
</section> |
||||
</section> |
Loading…
Reference in new issue