nixos/doc: document mkOrder and friends

Add a section on ordering option definitions.

Also mention `mkDefault` in the section on `mkOverride`.

Clarify the code a bit by renaming `defaultPriority` to
`defaultOverridePriority` and introducing `defaultOrderPriority`.
This commit is contained in:
Naïm Favier 2022-12-02 13:39:47 +01:00
parent 3dc19ce82d
commit e8927c46b8
No known key found for this signature in database
GPG Key ID: 95AFCE8211908325
4 changed files with 67 additions and 20 deletions

View File

@ -833,7 +833,7 @@ rec {
filterOverrides' = defs:
let
getPrio = def: if def.value._type or "" == "override" then def.value.priority else defaultPriority;
getPrio = def: if def.value._type or "" == "override" then def.value.priority else defaultOverridePriority;
highestPrio = foldl' (prio: def: min (getPrio def) prio) 9999 defs;
strip = def: if def.value._type or "" == "override" then def // { value = def.value.content; } else def;
in {
@ -842,7 +842,7 @@ rec {
};
/* Sort a list of properties. The sort priority of a property is
1000 by default, but can be overridden by wrapping the property
defaultOrderPriority by default, but can be overridden by wrapping the property
using mkOrder. */
sortProperties = defs:
let
@ -851,7 +851,7 @@ rec {
then def // { value = def.value.content; inherit (def.value) priority; }
else def;
defs' = map strip defs;
compare = a: b: (a.priority or 1000) < (b.priority or 1000);
compare = a: b: (a.priority or defaultOrderPriority) < (b.priority or defaultOrderPriority);
in sort compare defs';
# This calls substSubModules, whose entire purpose is only to ensure that
@ -887,10 +887,13 @@ rec {
mkOptionDefault = mkOverride 1500; # priority of option defaults
mkDefault = mkOverride 1000; # used in config sections of non-user modules to set a default
defaultOverridePriority = 100;
mkImageMediaOverride = mkOverride 60; # image media profiles can be derived by inclusion into host config, hence needing to override host config, but do allow user to mkForce
mkForce = mkOverride 50;
mkVMOverride = mkOverride 10; # used by nixos-rebuild build-vm
defaultPriority = lib.warnIf (lib.isInOldestRelease 2305) "lib.modules.defaultPriority is deprecated, please use lib.modules.defaultOverridePriority instead." defaultOverridePriority;
mkFixStrictness = lib.warn "lib.mkFixStrictness has no effect and will be removed. It returns its argument unmodified, so you can just remove any calls." id;
mkOrder = priority: content:
@ -899,11 +902,9 @@ rec {
};
mkBefore = mkOrder 500;
defaultOrderPriority = 1000;
mkAfter = mkOrder 1500;
# The default priority for things that don't have a priority specified.
defaultPriority = 100;
# Convenient property used to transfer all definitions and their
# properties from one option to another. This property is useful for
# renaming options, and also for including properties from another module
@ -930,10 +931,10 @@ rec {
# Similar to mkAliasAndWrapDefinitions but copies over the priority from the
# option as well.
#
# If a priority is not set, it assumes a priority of defaultPriority.
# If a priority is not set, it assumes a priority of defaultOverridePriority.
mkAliasAndWrapDefsWithPriority = wrap: option:
let
prio = option.highestPrio or defaultPriority;
prio = option.highestPrio or defaultOverridePriority;
defsWithPrio = map (mkOverride prio) option.definitions;
in mkAliasIfDef option (wrap (mkMerge defsWithPrio));
@ -1115,7 +1116,7 @@ rec {
# to definitions.
mkDerivedConfig = opt: f:
mkOverride
(opt.highestPrio or defaultPriority)
(opt.highestPrio or defaultOverridePriority)
(f opt.value);
doRename = { from, to, visible, warn, use, withPriority ? true }:

View File

@ -59,17 +59,35 @@ config = {
## 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
setting an *override 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.
priority 100 and option defaults have priority 1500.
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`.
be discarded. The function `mkForce` is equal to `mkOverride 50`, and
`mkDefault` is equal to `mkOverride 1000`.
## Ordering Definitions {#sec-option-definitions-ordering .unnumbered}
It is also possible to influence the order in which the definitions for an option are
merged by setting an *order priority* with `mkOrder`. The default order priority is 1000.
The functions `mkBefore` and `mkAfter` are equal to `mkOrder 500` and `mkOrder 1500`, respectively.
As an example,
```nix
hardware.firmware = mkBefore [ myFirmware ];
```
This definition ensures that `myFirmware` comes before other unordered
definitions in the final list value of `hardware.firmware`.
Note that this is different from [override priorities](#sec-option-definitions-setting-priorities):
setting an order does not affect whether the definition is included or not.
## Merging Configurations {#sec-option-definitions-merging .unnumbered}

View File

@ -66,11 +66,11 @@ config = {
<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.
modules by setting an <emphasis>override priority</emphasis>. All
option definitions that do not have the lowest priority value are
discarded. By default, option definitions have priority 100 and
option defaults have priority 1500. You can specify an explicit
priority by using <literal>mkOverride</literal>, e.g.
</para>
<programlisting language="bash">
services.openssh.enable = mkOverride 10 false;
@ -78,7 +78,35 @@ services.openssh.enable = mkOverride 10 false;
<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>.
equal to <literal>mkOverride 50</literal>, and
<literal>mkDefault</literal> is equal to
<literal>mkOverride 1000</literal>.
</para>
</section>
<section xml:id="sec-option-definitions-ordering">
<title>Ordering Definitions</title>
<para>
It is also possible to influence the order in which the
definitions for an option are merged by setting an <emphasis>order
priority</emphasis> with <literal>mkOrder</literal>. The default
order priority is 1000. The functions <literal>mkBefore</literal>
and <literal>mkAfter</literal> are equal to
<literal>mkOrder 500</literal> and
<literal>mkOrder 1500</literal>, respectively. As an example,
</para>
<programlisting language="bash">
hardware.firmware = mkBefore [ myFirmware ];
</programlisting>
<para>
This definition ensures that <literal>myFirmware</literal> comes
before other unordered definitions in the final list value of
<literal>hardware.firmware</literal>.
</para>
<para>
Note that this is different from
<link linkend="sec-option-definitions-setting-priorities">override
priorities</link>: setting an order does not affect whether the
definition is included or not.
</para>
</section>
<section xml:id="sec-option-definitions-merging">

View File

@ -806,7 +806,7 @@ in
optional (
cfg.writableStore &&
cfg.useNixStoreImage &&
opt.writableStore.highestPrio > lib.modules.defaultPriority)
opt.writableStore.highestPrio > lib.modules.defaultOverridePriority)
''
You have enabled ${opt.useNixStoreImage} = true,
without setting ${opt.writableStore} = false.