diff options
author | Bobby Rong <rjl931189261@126.com> | 2021-07-03 22:14:03 +0800 |
---|---|---|
committer | Bobby Rong <rjl931189261@126.com> | 2021-07-03 22:20:55 +0800 |
commit | 6877012179ebfbbf47451d2bc8d61212981c7940 (patch) | |
tree | 4cfbd95acef0bfef978f20b08db3df1fc3501699 /nixos/doc/manual/development | |
parent | 401578ed7e4d577c9717ce2c342d9bdab42208ec (diff) | |
download | nixpkgs-6877012179ebfbbf47451d2bc8d61212981c7940.tar nixpkgs-6877012179ebfbbf47451d2bc8d61212981c7940.tar.gz nixpkgs-6877012179ebfbbf47451d2bc8d61212981c7940.tar.bz2 nixpkgs-6877012179ebfbbf47451d2bc8d61212981c7940.tar.lz nixpkgs-6877012179ebfbbf47451d2bc8d61212981c7940.tar.xz nixpkgs-6877012179ebfbbf47451d2bc8d61212981c7940.tar.zst nixpkgs-6877012179ebfbbf47451d2bc8d61212981c7940.zip |
nixos: nixos/doc/manual/development/option-declarations.xml to CommonMark
Diffstat (limited to 'nixos/doc/manual/development')
-rw-r--r-- | nixos/doc/manual/development/option-declarations.section.md | 136 | ||||
-rw-r--r-- | nixos/doc/manual/development/option-declarations.xml | 199 | ||||
-rw-r--r-- | nixos/doc/manual/development/writing-modules.xml | 2 |
3 files changed, 137 insertions, 200 deletions
diff --git a/nixos/doc/manual/development/option-declarations.section.md b/nixos/doc/manual/development/option-declarations.section.md new file mode 100644 index 00000000000..819c23684cd --- /dev/null +++ b/nixos/doc/manual/development/option-declarations.section.md @@ -0,0 +1,136 @@ +# Option Declarations {#sec-option-declarations} + +An option declaration specifies the name, type and description of a +NixOS configuration option. It is invalid to define an option that +hasn't been declared in any module. An option declaration generally +looks like this: + +```nix +options = { + name = mkOption { + type = type specification; + default = default value; + example = example value; + description = "Description for use in the NixOS manual."; + }; +}; +``` + +The attribute names within the `name` attribute path must be camel +cased in general but should, as an exception, match the [ package +attribute name](https://nixos.org/nixpkgs/manual/#sec-package-naming) +when referencing a Nixpkgs package. For example, the option +`services.nix-serve.bindAddress` references the `nix-serve` Nixpkgs +package. + +The function `mkOption` accepts the following arguments. + +`type` + +: The type of the option (see [](#sec-option-types)). It may be + omitted, but that's not advisable since it may lead to errors that + are hard to diagnose. + +`default` + +: The default value used if no value is defined by any module. A + default is not required; but if a default is not given, then users + of the module will have to define the value of the option, otherwise + an error will be thrown. + +`example` + +: An example value that will be shown in the NixOS manual. + +`description` + +: A textual description of the option, in DocBook format, that will be + included in the NixOS manual. + +## Extensible Option Types {#sec-option-declarations-eot} + +Extensible option types is a feature that allow to extend certain types +declaration through multiple module files. This feature only work with a +restricted set of types, namely `enum` and `submodules` and any composed +forms of them. + +Extensible option types can be used for `enum` options that affects +multiple modules, or as an alternative to related `enable` options. + +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: + +- Managing 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. + +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. + +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. + +By using extensible option types, it is possible to create a placeholder +option in the central module +([Example: Extensible type placeholder in the service module](#ex-option-declaration-eot-service)), +and to extend it in each backend module +([Example: Extending `services.xserver.displayManager.enable` in the `gdm` module](#ex-option-declaration-eot-backend-gdm), +[Example: Extending `services.xserver.displayManager.enable` in the `sddm` module](#ex-option-declaration-eot-backend-sddm)). + +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. + +::: {#ex-option-declaration-eot-service .example} +::: {.title} +**Example: Extensible type placeholder in the service module** +::: +```nix +services.xserver.displayManager.enable = mkOption { + description = "Display manager to use"; + type = with types; nullOr (enum [ ]); +}; +``` +::: + +::: {#ex-option-declaration-eot-backend-gdm .example} +::: {.title} +**Example: Extending `services.xserver.displayManager.enable` in the `gdm` module** +::: +```nix +services.xserver.displayManager.enable = mkOption { + type = with types; nullOr (enum [ "gdm" ]); +}; +``` +::: + +::: {#ex-option-declaration-eot-backend-sddm .example} +::: {.title} +**Example: Extending `services.xserver.displayManager.enable` in the `sddm` module** +::: +```nix +services.xserver.displayManager.enable = mkOption { + type = with types; nullOr (enum [ "sddm" ]); +}; +``` +::: + +The placeholder declaration is a standard `mkOption` declaration, but it +is important that extensible option declarations only use the `type` +argument. + +Extensible option types work with any of the composed variants of `enum` +such as `with types; nullOr (enum [ "foo" "bar" ])` or `with types; +listOf (enum [ "foo" "bar" ])`. diff --git a/nixos/doc/manual/development/option-declarations.xml b/nixos/doc/manual/development/option-declarations.xml deleted file mode 100644 index 56ebf481630..00000000000 --- a/nixos/doc/manual/development/option-declarations.xml +++ /dev/null @@ -1,199 +0,0 @@ -<section xmlns="http://docbook.org/ns/docbook" - xmlns:xlink="http://www.w3.org/1999/xlink" - xmlns:xi="http://www.w3.org/2001/XInclude" - version="5.0" - xml:id="sec-option-declarations"> - <title>Option Declarations</title> - - <para> - An option declaration specifies the name, type and description of a NixOS - configuration option. It is invalid to define an option that hasn’t been - declared in any module. An option declaration generally looks like this: -<programlisting> -options = { - <replaceable>name</replaceable> = mkOption { - type = <replaceable>type specification</replaceable>; - default = <replaceable>default value</replaceable>; - example = <replaceable>example value</replaceable>; - description = "<replaceable>Description for use in the NixOS manual.</replaceable>"; - }; -}; -</programlisting> - The attribute names within the <replaceable>name</replaceable> attribute path - must be camel cased in general but should, as an exception, match the - <link -xlink:href="https://nixos.org/nixpkgs/manual/#sec-package-naming"> - package attribute name</link> when referencing a Nixpkgs package. For - example, the option <varname>services.nix-serve.bindAddress</varname> - references the <varname>nix-serve</varname> Nixpkgs package. - </para> - - <para> - The function <varname>mkOption</varname> accepts the following arguments. - <variablelist> - <varlistentry> - <term> - <varname>type</varname> - </term> - <listitem> - <para> - The type of the option (see <xref linkend='sec-option-types' />). It may - be omitted, but that’s not advisable since it may lead to errors that - are hard to diagnose. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <varname>default</varname> - </term> - <listitem> - <para> - The default value used if no value is defined by any module. A default is - not required; but if a default is not given, then users of the module - will have to define the value of the option, otherwise an error will be - thrown. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <varname>example</varname> - </term> - <listitem> - <para> - An example value that will be shown in the NixOS manual. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <varname>description</varname> - </term> - <listitem> - <para> - A textual description of the option, in DocBook format, that will be - included in the NixOS manual. - </para> - </listitem> - </varlistentry> - </variablelist> - </para> - - <section xml:id="sec-option-declarations-eot"> - <title>Extensible Option Types</title> - - <para> - Extensible option types is a feature that allow to extend certain types - declaration through multiple module files. This feature only work with a - restricted set of types, namely <literal>enum</literal> and - <literal>submodules</literal> and any composed forms of them. - </para> - - <para> - Extensible option types can be used for <literal>enum</literal> options that - affects multiple modules, or as an alternative to related - <literal>enable</literal> options. - </para> - - <para> - 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 ...). - </para> - - <para> - There are two approach to this module structure: - <itemizedlist> - <listitem> - <para> - Managing the display managers independently by adding an enable option to - every display manager module backend. (NixOS) - </para> - </listitem> - <listitem> - <para> - Managing the display managers in the central module by adding an option - to select which display manager backend to use. - </para> - </listitem> - </itemizedlist> - </para> - - <para> - Both approaches have problems. - </para> - - <para> - 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 - <literal>enable</literal> option. As a result, this restriction has to be - done explicitely by adding assertions in each display manager backend - module. - </para> - - <para> - 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. - </para> - - <para> - By using extensible option types, it is possible to create a placeholder - option in the central module - (<xref linkend='ex-option-declaration-eot-service' - />), and to extend - it in each backend module - (<xref - linkend='ex-option-declaration-eot-backend-gdm' />, - <xref - linkend='ex-option-declaration-eot-backend-sddm' />). - </para> - - <para> - As a result, <literal>displayManager.enable</literal> 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. - </para> - - <example xml:id='ex-option-declaration-eot-service'> - <title>Extensible type placeholder in the service module</title> -<screen> -services.xserver.displayManager.enable = mkOption { - description = "Display manager to use"; - type = with types; nullOr (enum [ ]); -};</screen> - </example> - - <example xml:id='ex-option-declaration-eot-backend-gdm'> - <title>Extending <literal>services.xserver.displayManager.enable</literal> in the <literal>gdm</literal> module</title> -<screen> -services.xserver.displayManager.enable = mkOption { - type = with types; nullOr (enum [ "gdm" ]); -};</screen> - </example> - - <example xml:id='ex-option-declaration-eot-backend-sddm'> - <title>Extending <literal>services.xserver.displayManager.enable</literal> in the <literal>sddm</literal> module</title> -<screen> -services.xserver.displayManager.enable = mkOption { - type = with types; nullOr (enum [ "sddm" ]); -};</screen> - </example> - - <para> - The placeholder declaration is a standard <literal>mkOption</literal> - declaration, but it is important that extensible option declarations only - use the <literal>type</literal> argument. - </para> - - <para> - Extensible option types work with any of the composed variants of - <literal>enum</literal> such as <literal>with types; nullOr (enum [ "foo" - "bar" ])</literal> or <literal>with types; listOf (enum [ "foo" "bar" - ])</literal>. - </para> - </section> -</section> diff --git a/nixos/doc/manual/development/writing-modules.xml b/nixos/doc/manual/development/writing-modules.xml index 04497db77b8..a1efbeac723 100644 --- a/nixos/doc/manual/development/writing-modules.xml +++ b/nixos/doc/manual/development/writing-modules.xml @@ -179,7 +179,7 @@ in { } </programlisting> </example> - <xi:include href="option-declarations.xml" /> + <xi:include href="../from_md/development/option-declarations.section.xml" /> <xi:include href="option-types.xml" /> <xi:include href="option-def.xml" /> <xi:include href="../from_md/development/assertions.section.xml" /> |