From c906064af1b36ad2e1478c917da300ac12e115ae Mon Sep 17 00:00:00 2001 From: Johannes Kirschbauer Date: Tue, 18 Mar 2025 14:32:30 +0000 Subject: [PATCH] lib.modules: document mkDefinition section --- .../manual/development/option-def.section.md | 44 +++++++++++++++++++ nixos/doc/manual/redirects.json | 3 ++ 2 files changed, 47 insertions(+) diff --git a/nixos/doc/manual/development/option-def.section.md b/nixos/doc/manual/development/option-def.section.md index 227f41d812ff..6ab5b7dc96de 100644 --- a/nixos/doc/manual/development/option-def.section.md +++ b/nixos/doc/manual/development/option-def.section.md @@ -123,3 +123,47 @@ they were declared in separate modules. This can be done using ]; } ``` + +## Free-floating definitions {#sec-option-definitions-definitions} + +:::{.note} +The module system internally transforms module syntax into definitions. This always happens internally. +::: + +It is possible to create first class definitions which are not transformed _again_ into definitions by the module system. + +Usually the file location of a definition is implicit and equal to the file it came from. +However, when manipulating definitions, it may be useful for them to be completely self-contained (or "free-floating"). + +A free-floating definition is created with `mkDefinition { file = ...; value = ...; }`. + +Preserving the file location creates better error messages, for example when copying definitions from one option to another. + +Other properties like `mkOverride` `mkMerge` `mkAfter` can be used in the `value` attribute but not the other way around. + +The following shows an example configuration that yields an error with the custom position information: + +```nix +{ + _file = "file.nix"; + options.foo = mkOption { + default = 13; + }; + config.foo = lib.mkDefinition { + file = "custom place"; + # mkOptionDefault creates a conflict with the option foo's `default = 1` on purpose + # So we see the error message below contains the conflicting values and different positions + value = lib.mkOptionDefault 42; + }; +} +``` + +evaluating the module yields the following error: + +``` +error: Cannot merge definitions of `foo'. Definition values: +- In `file.nix': 13 +- In `custom place': 42 +``` + +To set the file location for all definitions in a module, you may add the `_file` module syntax attribute, which has a similar effect to using `mkDefinition` on all definitions in the module, without the hassle. diff --git a/nixos/doc/manual/redirects.json b/nixos/doc/manual/redirects.json index 65520e2afb7d..ab86ee58dda7 100644 --- a/nixos/doc/manual/redirects.json +++ b/nixos/doc/manual/redirects.json @@ -1664,6 +1664,9 @@ "sec-option-definitions-merging": [ "index.html#sec-option-definitions-merging" ], + "sec-option-definitions-definitions": [ + "index.html#sec-option-definitions-definitions" + ], "sec-assertions": [ "index.html#sec-assertions" ],