From 665344f14839ea286a7aeb329fbf4f44da268ce4 Mon Sep 17 00:00:00 2001 From: Silvan Mosberger Date: Mon, 2 Aug 2021 21:42:45 +0200 Subject: lib/types: Introduce types.raw for unprocessed values --- .../from_md/development/option-types.section.xml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'nixos/doc/manual/from_md/development/option-types.section.xml') diff --git a/nixos/doc/manual/from_md/development/option-types.section.xml b/nixos/doc/manual/from_md/development/option-types.section.xml index 76ffb6f837c..90ef05a24e7 100644 --- a/nixos/doc/manual/from_md/development/option-types.section.xml +++ b/nixos/doc/manual/from_md/development/option-types.section.xml @@ -92,6 +92,25 @@ + + + types.raw + + + + A type which doesn’t do any checking, merging or nested + evaluation. It accepts a single arbitrary value that is not + recursed into, making it useful for values coming from + outside the module system, such as package sets or arbitrary + data. Options of this type are still evaluated according to + priorities and conditionals, so mkForce, + mkIf and co. still work on the option + value itself, but not for any value nested within it. This + type should only be used when checking, merging and nested + evaluation are not desirable. + + + types.attrs -- cgit 1.4.1 From 5cbeddfde486ca5524baeaf3da6e8944075cf463 Mon Sep 17 00:00:00 2001 From: Silvan Mosberger Date: Wed, 8 Dec 2021 19:02:29 +0100 Subject: lib.types: Introduce `types.optionType` This type correctly merges multiple option types together while also annotating them with file information. In a future commit this will be used for `_module.freeformType` --- lib/tests/modules.sh | 7 +++++ lib/tests/modules/optionTypeFile.nix | 28 +++++++++++++++++++ lib/tests/modules/optionTypeMerging.nix | 27 +++++++++++++++++++ lib/types.nix | 31 +++++++++++++++++++++- .../doc/manual/development/option-types.section.md | 7 +++++ .../from_md/development/option-types.section.xml | 14 ++++++++++ 6 files changed, 113 insertions(+), 1 deletion(-) create mode 100644 lib/tests/modules/optionTypeFile.nix create mode 100644 lib/tests/modules/optionTypeMerging.nix (limited to 'nixos/doc/manual/from_md/development/option-types.section.xml') diff --git a/lib/tests/modules.sh b/lib/tests/modules.sh index a1c592cf4ef..d11f32e5996 100755 --- a/lib/tests/modules.sh +++ b/lib/tests/modules.sh @@ -299,6 +299,13 @@ checkConfigOutput "10" config.processedToplevel ./raw.nix checkConfigError "The option .multiple. is defined multiple times" config.multiple ./raw.nix checkConfigOutput "bar" config.priorities ./raw.nix +# Test that types.optionType merges types correctly +checkConfigOutput '^10$' config.theOption.int ./optionTypeMerging.nix +checkConfigOutput '^"hello"$' config.theOption.str ./optionTypeMerging.nix + +# Test that types.optionType correctly annotates option locations +checkConfigError 'The option .theOption.nested. in .other.nix. is already declared in .optionTypeFile.nix.' config.theOption.nested ./optionTypeFile.nix + cat < + + + types.optionType + + + + The type of an option’s type. Its merging operation ensures + that nested options have the correct file location + annotated, and that if possible, multiple option definitions + are correctly merged together. The main use case is as the + type of the _module.freeformType option. + + + types.attrs -- cgit 1.4.1 From f386c42a48397d232869e03f123e2bb5f8bfd3d8 Mon Sep 17 00:00:00 2001 From: Alexandru Scvortov Date: Fri, 4 Mar 2022 20:08:09 +0000 Subject: nixos/doc: improve wording in "Options Types" and "Option Declarations" --- .../development/option-declarations.section.md | 26 +++++++++---------- .../doc/manual/development/option-types.section.md | 6 ++--- .../development/option-declarations.section.xml | 29 +++++++++++----------- .../from_md/development/option-types.section.xml | 8 +++--- 4 files changed, 35 insertions(+), 34 deletions(-) (limited to 'nixos/doc/manual/from_md/development/option-types.section.xml') diff --git a/nixos/doc/manual/development/option-declarations.section.md b/nixos/doc/manual/development/option-declarations.section.md index fff06e1ea5b..819fc6d891f 100644 --- a/nixos/doc/manual/development/option-declarations.section.md +++ b/nixos/doc/manual/development/option-declarations.section.md @@ -145,26 +145,26 @@ As an example, we will take the case of display managers. There is a central display manager module for generic display manager options and a module file per display manager backend (sddm, gdm \...). -There are two approach to this module structure: +There are two approaches we could take with this module structure: -- Managing the display managers independently by adding an enable +- Configuring the display managers independently by adding an enable option to every display manager module backend. (NixOS) -- Managing the display managers in the central module by adding an - option to select which display manager backend to use. +- Configuring the display managers in the central module by adding + an option to select which display manager backend to use. Both approaches have problems. Making backends independent can quickly become hard to manage. For -display managers, there can be only one enabled at a time, but the type -system can not enforce this restriction as there is no relation between -each backend `enable` option. As a result, this restriction has to be -done explicitely by adding assertions in each display manager backend -module. +display managers, there can only be one enabled at a time, but the +type system cannot enforce this restriction as there is no relation +between each backend's `enable` option. As a result, this restriction +has to be done explicitly by adding assertions in each display manager +backend module. -On the other hand, managing the display managers backends in the central -module will require to change the central module option every time a new -backend is added or removed. +On the other hand, managing the display manager backends in the +central module will require changing the central module option every +time a new backend is added or removed. By using extensible option types, it is possible to create a placeholder option in the central module @@ -175,7 +175,7 @@ and to extend it in each backend module As a result, `displayManager.enable` option values can be added without changing the main service module file and the type system automatically -enforce that there can only be a single display manager enabled. +enforces that there can only be a single display manager enabled. ::: {#ex-option-declaration-eot-service .example} ::: {.title} diff --git a/nixos/doc/manual/development/option-types.section.md b/nixos/doc/manual/development/option-types.section.md index 071e7751eb6..c34ac0367c4 100644 --- a/nixos/doc/manual/development/option-types.section.md +++ b/nixos/doc/manual/development/option-types.section.md @@ -16,9 +16,9 @@ merging is handled. `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. +: A filesystem path is anything that starts with a slash when + coerced to a string. Even if derivations can be considered as + paths, the more specific `types.package` should be preferred. `types.package` diff --git a/nixos/doc/manual/from_md/development/option-declarations.section.xml b/nixos/doc/manual/from_md/development/option-declarations.section.xml index 0eeffae628e..554705e2e42 100644 --- a/nixos/doc/manual/from_md/development/option-declarations.section.xml +++ b/nixos/doc/manual/from_md/development/option-declarations.section.xml @@ -215,21 +215,22 @@ lib.mkOption { manager backend (sddm, gdm ...). - There are two approach to this module structure: + There are two approaches we could take with this module + structure: - Managing the display managers independently by adding an - enable option to every display manager module backend. - (NixOS) + Configuring the display managers independently by adding + an enable option to every display manager module + backend. (NixOS) - Managing the display managers in the central module by - adding an option to select which display manager backend - to use. + Configuring the display managers in the central module + by adding an option to select which display manager + backend to use. @@ -238,16 +239,16 @@ lib.mkOption { Making backends independent can quickly become hard to - manage. For display managers, there can be only one enabled - at a time, but the type system can not enforce this - restriction as there is no relation between each backend + manage. For display managers, there can only be one enabled + at a time, but the type system cannot enforce this + restriction as there is no relation between each backend’s enable option. As a result, this - restriction has to be done explicitely by adding assertions + restriction has to be done explicitly by adding assertions in each display manager backend module. - On the other hand, managing the display managers backends in - the central module will require to change the central module + On the other hand, managing the display manager backends in + the central module will require changing the central module option every time a new backend is added or removed. @@ -268,7 +269,7 @@ lib.mkOption { As a result, displayManager.enable option values can be added without changing the main service module - file and the type system automatically enforce that there + file and the type system automatically enforces that there can only be a single display manager enabled. diff --git a/nixos/doc/manual/from_md/development/option-types.section.xml b/nixos/doc/manual/from_md/development/option-types.section.xml index 50a3da0ef5b..e16453df51e 100644 --- a/nixos/doc/manual/from_md/development/option-types.section.xml +++ b/nixos/doc/manual/from_md/development/option-types.section.xml @@ -30,10 +30,10 @@ - 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. + A filesystem path is anything that starts with a slash when + coerced to a string. Even if derivations can be considered + as paths, the more specific types.package + should be preferred. -- cgit 1.4.1 From 9c2266c03171dcf492b6accdb0cde0cb28e156b5 Mon Sep 17 00:00:00 2001 From: Naïm Favier Date: Wed, 9 Mar 2022 13:14:22 +0100 Subject: lib.types.package: only call toDerivation when necessary The current logic assumes that everything that isn't a derivation is a store path, but it can also be something that's *coercible* to a store path, like a flake input. Unnecessary uses of `lib.toDerivation` result in errors in pure evaluation mode when `builtins.storePath` is disabled. Also document what a `package` is. --- lib/types.nix | 12 ++++++++++-- nixos/doc/manual/development/option-types.section.md | 3 ++- .../doc/manual/from_md/development/option-types.section.xml | 4 +++- 3 files changed, 15 insertions(+), 4 deletions(-) (limited to 'nixos/doc/manual/from_md/development/option-types.section.xml') diff --git a/lib/types.nix b/lib/types.nix index 3fcac9c31b3..bf18866e55e 100644 --- a/lib/types.nix +++ b/lib/types.nix @@ -368,13 +368,21 @@ rec { emptyValue = { value = {}; }; }; - # derivation is a reserved keyword. + # A package is a top-level store path (/nix/store/hash-name). This includes: + # - derivations + # - more generally, attribute sets with an `outPath` or `__toString` attribute + # pointing to a store path, e.g. flake inputs + # - strings with context, e.g. "${pkgs.foo}" or (toString pkgs.foo) + # - hardcoded store path literals (/nix/store/hash-foo) or strings without context + # ("/nix/store/hash-foo"). These get a context added to them using builtins.storePath. package = mkOptionType { name = "package"; check = x: isDerivation x || isStorePath x; merge = loc: defs: let res = mergeOneOption loc defs; - in if isDerivation res then res else toDerivation res; + in if builtins.isPath res || (builtins.isString res && ! builtins.hasContext res) + then toDerivation res + else res; }; shellPackage = package // { diff --git a/nixos/doc/manual/development/option-types.section.md b/nixos/doc/manual/development/option-types.section.md index c34ac0367c4..00f1d85bdb6 100644 --- a/nixos/doc/manual/development/option-types.section.md +++ b/nixos/doc/manual/development/option-types.section.md @@ -22,7 +22,8 @@ merging is handled. `types.package` -: A derivation or a store path. +: A top-level store path. This can be an attribute set pointing + to a store path, like a derivation or a flake input. `types.anything` diff --git a/nixos/doc/manual/from_md/development/option-types.section.xml b/nixos/doc/manual/from_md/development/option-types.section.xml index e16453df51e..44472929270 100644 --- a/nixos/doc/manual/from_md/development/option-types.section.xml +++ b/nixos/doc/manual/from_md/development/option-types.section.xml @@ -43,7 +43,9 @@ - A derivation or a store path. + A top-level store path. This can be an attribute set + pointing to a store path, like a derivation or a flake + input. -- cgit 1.4.1