Unverified Commit e8927c46 authored by Naïm Favier's avatar Naïm Favier
Browse files

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`.
parent 3dc19ce8
Loading
Loading
Loading
Loading
+10 −9
Original line number Diff line number Diff line
@@ -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 }:
+22 −4
Original line number Diff line number Diff line
@@ -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}

+34 −6
Original line number Diff line number Diff line
@@ -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">
+1 −1
Original line number Diff line number Diff line
@@ -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.