From b32252ddfa530ff67e297ff6ba9e5cb0f91a767a Mon Sep 17 00:00:00 2001 From: Eric Sagnes Date: Tue, 13 Sep 2016 14:04:02 +0900 Subject: [PATCH] NixOS manual: add module option types doc (#18525) --- .../development/option-declarations.xml | 88 +--- nixos/doc/manual/development/option-types.xml | 394 ++++++++++++++++++ .../manual/development/writing-modules.xml | 1 + 3 files changed, 398 insertions(+), 85 deletions(-) create mode 100644 nixos/doc/manual/development/option-types.xml diff --git a/nixos/doc/manual/development/option-declarations.xml b/nixos/doc/manual/development/option-declarations.xml index b0689aa1d97..7be5e9d51d4 100644 --- a/nixos/doc/manual/development/option-declarations.xml +++ b/nixos/doc/manual/development/option-declarations.xml @@ -31,9 +31,9 @@ options = { type - The type of the option (see below). It may be omitted, - but that’s not advisable since it may lead to errors that are - hard to diagnose. + The type of the option (see ). + It may be omitted, but that’s not advisable since it may lead to errors + that are hard to diagnose. @@ -65,86 +65,4 @@ options = { -Here is a non-exhaustive list of option types: - - - - - types.bool - - A Boolean. - - - - - types.int - - An integer. - - - - - types.str - - A string. - - - - - types.lines - - A string. If there are multiple definitions, they are - concatenated, with newline characters in between. - - - - - types.path - - A path, defined as anything that, when coerced to a - string, starts with a slash. This includes derivations. - - - - - types.package - - A derivation (such as pkgs.hello) or a - store path (such as - /nix/store/1ifi1cfbfs5iajmvwgrbmrnrw3a147h9-hello-2.10). - - - - - types.listOf t - - A list of elements of type t - (e.g., types.listOf types.str is a list of - strings). Multiple definitions are concatenated together. - - - - - types.attrsOf t - - A set of elements of type t - (e.g., types.attrsOf types.int is a set of - name/value pairs, the values being integers). - - - - - types.nullOr t - - Either the value null or something of - type t. - - - - - -You can also create new types using the function -mkOptionType. See -lib/types.nix in Nixpkgs for details. - diff --git a/nixos/doc/manual/development/option-types.xml b/nixos/doc/manual/development/option-types.xml new file mode 100644 index 00000000000..8871b02cebf --- /dev/null +++ b/nixos/doc/manual/development/option-types.xml @@ -0,0 +1,394 @@ +
+ +Options Types + + Option types are a way to put constraints on the values a module option + can take. + Types are also responsible of how values are merged in case of multiple + value definitions. +
Basic Types + + Basic types are the simplest available types in the module system. + Basic types include multiple string types that mainly differ in how + definition merging is handled. + + + + types.bool + A boolean, its values can be true or + false. + + + types.int + An integer. + + + 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. + + + types.package + A derivation or a store path. + + + +String related types: + + + + types.str + A string. Multiple definitions cannot be + merged. + + + types.lines + A string. Multiple definitions are concatenated with a new + line "\n". + + + types.commas + A string. Multiple definitions are concatenated with a comma + ",". + + + types.envVar + A string. Multiple definitions are concatenated with a + collon ":". + + + types.separatedString + sep + A string with a custom separator + sep, e.g. types.separatedString + "|". + + + +
+ +
Composed Types + + Composed types allow to create complex types by taking another type(s) + or value(s) as parameter(s). + It is possible to compose types multiple times, e.g. with types; + nullOr (enum [ "left" "right" ]). + + + + types.listOf t + A list of t type, e.g. + types.listOf int. Multiple definitions are merged + with list concatenation. + + + types.attrsOf t + An attribute set of where all the values are of + t type. Multiple definitions result in the + joined attribute set. + + + types.loaOf t + An attribute set or a list of t + type. Multiple definitions are merged according to the + value. + + + types.loeOf t + A list or an element of t type. + Multiple definitions are merged according to the + values. + + + types.nullOr t + null or type + t. Multiple definitions are merged according + to type t. + + + types.uniq t + Ensures that type t cannot be + merged. It is used to ensure option definitions are declared only + once. + + + types.enum l + One element of the list l, e.g. + types.enum [ "left" "right" ]. Multiple definitions + cannot be merged + + + types.either t1 + t2 + Type t1 or type + t2, e.g. with types; either int + str. Multiple definitions cannot be + merged. + + + types.submodule o + A set of sub options o. + o can be an attribute set or a function + returning an attribute set. Submodules are used in composed types to + create modular options. Submodule are detailed in . + + + +
+ +
Submodule + + Submodule is a very powerful type that defines a set of sub-options that + are handled like a separate module. + It is especially interesting when used with composed types like + attrsOf or listOf. + + The submodule type take a parameter o, that + should be a set, or a function returning a set with an + options key defining the sub-options. + The option set can be defined directly () or as reference (). + + Submodule option definitions are type-checked accordingly to the options + declarations. It is possible to declare submodule options inside a submodule + sub-options for even higher modularity. + +Directly defined submodule + +options.mod = mkOption { + name = "mod"; + description = "submodule example"; + type = with types; listOf (submodule { + options = { + foo = mkOption { + type = int; + }; + bar = mkOption { + type = str; + }; + }; + }); +}; + +Submodule defined as a + reference + +let + modOptions = { + options = { + foo = mkOption { + type = int; + }; + bar = mkOption { + type = int; + }; + }; + }; +in +options.mod = mkOption { + description = "submodule example"; + type = with types; listOf (submodule modOptions); +}; + + +
Composed with <literal>listOf</literal> + + When composed with listOf, submodule allows multiple + definitions of the submodule option set. + +Declaration of a list + of submodules + +options.mod = mkOption { + description = "submodule example"; + type = with types; listOf (submodule { + options = { + foo = mkOption { + type = int; + }; + bar = mkOption { + type = str; + }; + }; + }); +}; + +Definition of a list of + submodules + +config.mod = [ + { foo = 1; bar = "one"; } + { foo = 2; bar = "two"; } +]; + +
+ + +
Composed with <literal>attrsOf</literal> + + When composed with attrsOf, submodule allows multiple + named definitions of the submodule option set. + +Declaration of + attribute sets of submodules + +options.mod = mkOption { + description = "submodule example"; + type = with types; attrsOf (submodule { + options = { + foo = mkOption { + type = int; + }; + bar = mkOption { + type = str; + }; + }; + }); +}; + +Declaration of + attribute sets of submodules + +config.mod.one = { foo = 1; bar = "one"; }; +config.mod.two = { foo = 2; bar = "two"; }; + +
+
+ +
Extending types + + Types are mainly characterized by their check and + merge functions. + + + + check + The function to type check the value. Takes a value as + parameter and return a boolean. + It is possible to extend a type check with the + addCheck function (), or to fully override the + check function (). + +Adding a type check + +byte = mkOption { + description = "An integer between 0 and 255."; + type = addCheck (x: x >= 0 && x <= 255) types.int; +}; + +Overriding a type + check + +nixThings = mkOption { + description = "words that start with 'nix'"; + type = types.str // { + check = (x: lib.hasPrefix "nix" x) + }; +}; + + + + merge + Function to merge the options values when multiple values + are set. +The function takes two parameters, loc the option path as a +list of strings, and defs the list of defined values as a +list. +It is possible to override a type merge function for custom +needs. + + + +
+ +
Custom Types + +Custom types can be created with the mkOptionType + function. +As type creation includes some more complex topics such as submodule handling, +it is recommended to get familiar with types.nix +code before creating a new type. + +The only required parameter is name. + + + + name + A string representation of the type function name, name + usually changes accordingly parameters passed to + types. + + + check + A function to type check the definition value. Takes the + definition value as a parameter and returns a boolean indicating the + type check result, true for success and + false for failure. + + + merge + A function to merge multiple definitions values. Takes two + parameters: + + + loc + The option path as a list of strings, e.g. + ["boot" "loader "grub" + "enable"]. + + + defs + The list of sets of defined value + and file where the value was defined, e.g. + [ { file = "/foo.nix"; value = 1; } { file = "/bar.nix"; + value = 2 } ]. The merge function + should return the merged value or throw an error in case the + values are impossible or not meant to be merged. + + + + + + getSubOptions + For composed types that can take a submodule as type + parameter, this function generate sub-options documentation. It takes + the current option prefix as a list and return the set of sub-options. + Usually defined in a recursive manner by adding a term to the prefix, + e.g. prefix: elemType.getSubOptions (prefix ++ + ["prefix"]) where + "prefix" is the newly added + prefix. + + + getSubModules + For composed types that can take a submodule as type + parameter, this function should return the type parameters submodules. + If the type parameter is called elemType, the + function should just recursively look into submodules by returning + elemType.getSubModules;. + + + substSubModules + For composed types that can take a submodule as type + parameter, this function can be used to substitute the parameter of a + submodule type. It takes a module as parameter and return the type with + the submodule options substituted. It is usally defined as a type + function call with a recursive call to + substSubModules, e.g for a type + composedType that take an elemtype + type parameter, this function should be defined as m: + composedType (elemType.substSubModules m). + + + +
+
diff --git a/nixos/doc/manual/development/writing-modules.xml b/nixos/doc/manual/development/writing-modules.xml index a68b122ce02..ef6920160e6 100644 --- a/nixos/doc/manual/development/writing-modules.xml +++ b/nixos/doc/manual/development/writing-modules.xml @@ -176,6 +176,7 @@ in { +