lol

lib/options: Add more options to mkPackageOption

authored by

Anselm Schüler and committed by
pennae
9769e902 d6ae1560

+79 -18
+48 -15
lib/options.nix
··· 36 36 inherit (lib.types) 37 37 mkOptionType 38 38 ; 39 + inherit (lib.lists) 40 + last 41 + ; 39 42 prioritySuggestion = '' 40 43 Use `lib.mkForce value` or `lib.mkDefault value` to change the priority on any of these definitions. 41 44 ''; ··· 107 110 /* Creates an Option attribute set for an option that specifies the 108 111 package a module should use for some purpose. 109 112 110 - The package is specified as a list of strings representing its attribute path in nixpkgs. 113 + Type: mkPackageOption :: pkgs -> (string|[string]) -> 114 + { default? :: [string], example? :: null|string|[string], extraDescription? :: string } -> 115 + option 111 116 112 - Because of this, you need to pass nixpkgs itself as the first argument. 117 + The package is specified in the third argument under `default` as a list of strings 118 + representing its attribute path in nixpkgs (or another package set). 119 + Because of this, you need to pass nixpkgs itself (or a subset) as the first argument. 113 120 114 - The second argument is the name of the option, used in the description "The <name> package to use.". 121 + The second argument may be either a string or a list of strings. 122 + It provides the display name of the package in the description of the generated option 123 + (using only the last element if the passed value is a list) 124 + and serves as the fallback value for the `default` argument. 115 125 116 - You can also pass an example value, either a literal string or a package's attribute path. 126 + To include extra information in the description, pass `extraDescription` to 127 + append arbitrary text to the generated description. 128 + You can also pass an `example` value, either a literal string or an attribute path. 117 129 118 - You can omit the default path if the name of the option is also attribute path in nixpkgs. 130 + The default argument can be omitted if the provided name is 131 + an attribute of pkgs (if name is a string) or a 132 + valid attribute path in pkgs (if name is a list). 119 133 120 - Type: mkPackageOption :: pkgs -> string -> { default :: [string]; example :: null | string | [string]; } -> option 134 + If you wish to explicitly provide no default, pass `null` as `default`. 121 135 122 136 Example: 123 137 mkPackageOption pkgs "hello" { } ··· 129 143 example = "pkgs.haskell.packages.ghc92.ghc.withPackages (hkgs: [ hkgs.primes ])"; 130 144 } 131 145 => { _type = "option"; default = «derivation /nix/store/jxx55cxsjrf8kyh3fp2ya17q99w7541r-ghc-8.10.7.drv»; defaultText = { ... }; description = "The GHC package to use."; example = { ... }; type = { ... }; } 146 + 147 + Example: 148 + mkPackageOption pkgs [ "python39Packages" "pytorch" ] { 149 + extraDescription = "This is an example and doesn't actually do anything."; 150 + } 151 + => { _type = "option"; default = «derivation /nix/store/gvqgsnc4fif9whvwd9ppa568yxbkmvk8-python3.9-pytorch-1.10.2.drv»; defaultText = { ... }; description = "The pytorch package to use. This is an example and doesn't actually do anything."; type = { ... }; } 152 + 132 153 */ 133 154 mkPackageOption = 134 - # Package set (a specific version of nixpkgs) 155 + # Package set (a specific version of nixpkgs or a subset) 135 156 pkgs: 136 157 # Name for the package, shown in option description 137 158 name: 138 - { default ? [ name ], example ? null }: 139 - let default' = if !isList default then [ default ] else default; 159 + { 160 + # The attribute path where the default package is located 161 + default ? name, 162 + # A string or an attribute path to use as an example 163 + example ? null, 164 + # Additional text to include in the option description 165 + extraDescription ? "", 166 + }: 167 + let 168 + name' = if isList name then last name else name; 169 + default' = if isList default then default else [ default ]; 170 + defaultPath = concatStringsSep "." default'; 171 + defaultValue = attrByPath default' 172 + (throw "${defaultPath} cannot be found in pkgs") pkgs; 140 173 in mkOption { 174 + defaultText = literalExpression ("pkgs." + defaultPath); 141 175 type = lib.types.package; 142 - description = "The ${name} package to use."; 143 - default = attrByPath default' 144 - (throw "${concatStringsSep "." default'} cannot be found in pkgs") pkgs; 145 - defaultText = literalExpression ("pkgs." + concatStringsSep "." default'); 176 + description = "The ${name'} package to use." 177 + + (if extraDescription == "" then "" else " ") + extraDescription; 178 + ${if default != null then "default" else null} = defaultValue; 146 179 ${if example != null then "example" else null} = literalExpression 147 180 (if isList example then "pkgs." + concatStringsSep "." example else example); 148 181 }; 149 182 150 183 /* Like mkPackageOption, but emit an mdDoc description instead of DocBook. */ 151 - mkPackageOptionMD = args: name: extra: 152 - let option = mkPackageOption args name extra; 184 + mkPackageOptionMD = pkgs: name: extra: 185 + let option = mkPackageOption pkgs name extra; 153 186 in option // { description = lib.mdDoc option.description; }; 154 187 155 188 /* This option accepts anything, but it does not produce any result.
+31 -3
nixos/doc/manual/development/option-declarations.section.md
··· 101 101 102 102 **Note**: You shouldn’t necessarily make package options for all of your modules. You can always overwrite a specific package throughout nixpkgs by using [nixpkgs overlays](https://nixos.org/manual/nixpkgs/stable/#chap-overlays). 103 103 104 - The default package is specified as a list of strings representing its attribute path in nixpkgs. Because of this, you need to pass nixpkgs itself as the first argument. 104 + The package is specified in the third argument under `default` as a list of strings 105 + representing its attribute path in nixpkgs (or another package set). 106 + Because of this, you need to pass nixpkgs itself (or a subset) as the first argument. 107 + 108 + The second argument may be either a string or a list of strings. 109 + It provides the display name of the package in the description of the generated option 110 + (using only the last element if the passed value is a list) 111 + and serves as the fallback value for the `default` argument. 105 112 106 - The second argument is the name of the option, used in the description "The \<name\> package to use.". You can also pass an example value, either a literal string or a package's attribute path. 113 + To include extra information in the description, pass `extraDescription` to 114 + append arbitrary text to the generated description. 115 + You can also pass an `example` value, either a literal string or an attribute path. 107 116 108 - You can omit the default path if the name of the option is also attribute path in nixpkgs. 117 + The default argument can be omitted if the provided name is 118 + an attribute of pkgs (if name is a string) or a 119 + valid attribute path in pkgs (if name is a list). 120 + 121 + If you wish to explicitly provide no default, pass `null` as `default`. 109 122 110 123 During the transition to CommonMark documentation `mkPackageOption` creates an option with a DocBook description attribute, once the transition is completed it will create a CommonMark description instead. `mkPackageOptionMD` always creates an option with a CommonMark description attribute and will be removed some time after the transition is completed. 111 124 ··· 138 151 defaultText = lib.literalExpression "pkgs.ghc"; 139 152 example = lib.literalExpression "pkgs.haskell.packages.ghc92.ghc.withPackages (hkgs: [ hkgs.primes ])"; 140 153 description = lib.mdDoc "The GHC package to use."; 154 + } 155 + ``` 156 + ::: 157 + 158 + ::: {#ex-options-declarations-util-mkPackageOption-extraDescription .example} 159 + ```nix 160 + mkPackageOption pkgs [ "python39Packages" "pytorch" ] { 161 + extraDescription = "This is an example and doesn't actually do anything."; 162 + } 163 + # is like 164 + lib.mkOption { 165 + type = lib.types.package; 166 + default = pkgs.python39Packages.pytorch; 167 + defaultText = lib.literalExpression "pkgs.python39Packages.pytorch"; 168 + description = "The pytorch package to use. This is an example and doesn't actually do anything."; 141 169 } 142 170 ``` 143 171 :::