| 
									
										
										
										
											2009-02-09 16:51:03 +00:00
										 |  |  |  | # Nixpkgs/NixOS option handling. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | let lib = import ./default.nix; in | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-28 18:21:25 +00:00
										 |  |  |  | with import ./trivial.nix; | 
					
						
							| 
									
										
										
										
											2009-02-09 16:51:03 +00:00
										 |  |  |  | with import ./lists.nix; | 
					
						
							|  |  |  |  | with import ./attrsets.nix; | 
					
						
							| 
									
										
										
										
											2013-10-28 01:14:16 +01:00
										 |  |  |  | with import ./strings.nix; | 
					
						
							| 
									
										
										
										
											2009-02-09 16:51:03 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | rec { | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-23 18:20:39 +02:00
										 |  |  |  |   isOption = lib.isType "option"; | 
					
						
							| 
									
										
										
										
											2013-10-30 15:33:20 +01:00
										 |  |  |  |   mkOption = | 
					
						
							|  |  |  |  |     { default ? null # Default value used when no definition is given in the configuration. | 
					
						
							|  |  |  |  |     , defaultText ? null # Textual representation of the default, for in the manual. | 
					
						
							|  |  |  |  |     , example ? null # Example value used in the manual. | 
					
						
							|  |  |  |  |     , description ? null # String describing the option. | 
					
						
							|  |  |  |  |     , type ? null # Option type, providing type-checking and value merging. | 
					
						
							|  |  |  |  |     , apply ? null # Function that converts the option value to something else. | 
					
						
							|  |  |  |  |     , internal ? null # Whether the option is for NixOS developers only. | 
					
						
							|  |  |  |  |     , visible ? null # Whether the option shows up in the manual. | 
					
						
							| 
									
										
										
										
											2015-07-30 13:36:57 +02:00
										 |  |  |  |     , readOnly ? null # Whether the option can be set only once | 
					
						
							| 
									
										
										
										
											2013-10-30 15:33:20 +01:00
										 |  |  |  |     , options ? null # Obsolete, used by types.optionSet. | 
					
						
							|  |  |  |  |     } @ attrs: | 
					
						
							|  |  |  |  |     attrs // { _type = "option"; }; | 
					
						
							| 
									
										
										
										
											2009-05-27 20:25:17 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-18 15:13:42 -04:00
										 |  |  |  |   mkEnableOption = name: mkOption { | 
					
						
							|  |  |  |  |     default = false; | 
					
						
							|  |  |  |  |     example = true; | 
					
						
							| 
									
										
										
										
											2013-10-17 14:29:51 +02:00
										 |  |  |  |     description = "Whether to enable ${name}."; | 
					
						
							| 
									
										
										
										
											2013-07-18 15:13:42 -04:00
										 |  |  |  |     type = lib.types.bool; | 
					
						
							|  |  |  |  |   }; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-21 14:50:46 +01:00
										 |  |  |  |   # This option accept anything, but it does not produce any result.  This | 
					
						
							|  |  |  |  |   # is useful for sharing a module across different module sets without | 
					
						
							|  |  |  |  |   # having to implement similar features as long as the value of the options | 
					
						
							|  |  |  |  |   # are not expected. | 
					
						
							|  |  |  |  |   mkSinkUndeclaredOptions = attrs: mkOption ({ | 
					
						
							|  |  |  |  |     internal = true; | 
					
						
							|  |  |  |  |     visible = false; | 
					
						
							|  |  |  |  |     default = false; | 
					
						
							|  |  |  |  |     description = "Sink for option definitions."; | 
					
						
							|  |  |  |  |     type = mkOptionType { | 
					
						
							|  |  |  |  |       name = "sink"; | 
					
						
							|  |  |  |  |       check = x: true; | 
					
						
							|  |  |  |  |       merge = loc: defs: false; | 
					
						
							|  |  |  |  |     }; | 
					
						
							|  |  |  |  |     apply = x: throw "Option value is not readable because the option is not declared."; | 
					
						
							|  |  |  |  |   } // attrs); | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-30 14:21:41 +01:00
										 |  |  |  |   mergeDefaultOption = loc: defs: | 
					
						
							|  |  |  |  |     let list = getValues defs; in | 
					
						
							| 
									
										
										
										
											2012-08-13 14:19:31 -04:00
										 |  |  |  |     if length list == 1 then head list | 
					
						
							| 
									
										
										
										
											2013-11-12 13:48:19 +01:00
										 |  |  |  |     else if all isFunction list then x: mergeDefaultOption loc (map (f: f x) list) | 
					
						
							| 
									
										
										
										
											2009-05-19 14:54:41 +00:00
										 |  |  |  |     else if all isList list then concatLists list | 
					
						
							| 
									
										
										
										
											2015-07-23 17:19:21 +02:00
										 |  |  |  |     else if all isAttrs list then foldl' lib.mergeAttrs {} list | 
					
						
							|  |  |  |  |     else if all isBool list then foldl' lib.or false list | 
					
						
							| 
									
										
										
										
											2013-11-12 13:48:19 +01:00
										 |  |  |  |     else if all isString list then lib.concatStrings list | 
					
						
							|  |  |  |  |     else if all isInt list && all (x: x == head list) list then head list | 
					
						
							| 
									
										
										
										
											2013-10-30 14:21:41 +01:00
										 |  |  |  |     else throw "Cannot merge definitions of `${showOption loc}' given in ${showFiles (getFiles defs)}."; | 
					
						
							| 
									
										
										
										
											2009-02-09 16:51:03 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-30 14:21:41 +01:00
										 |  |  |  |   mergeOneOption = loc: defs: | 
					
						
							|  |  |  |  |     if defs == [] then abort "This case should never happen." | 
					
						
							|  |  |  |  |     else if length defs != 1 then | 
					
						
							|  |  |  |  |       throw "The unique option `${showOption loc}' is defined multiple times, in ${showFiles (getFiles defs)}." | 
					
						
							|  |  |  |  |     else (head defs).value; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-15 18:04:27 +02:00
										 |  |  |  |   /* "Merge" option definitions by checking that they all have the same value. */ | 
					
						
							|  |  |  |  |   mergeEqualOption = loc: defs: | 
					
						
							|  |  |  |  |     if defs == [] then abort "This case should never happen." | 
					
						
							| 
									
										
										
										
											2015-07-23 17:19:21 +02:00
										 |  |  |  |     else foldl' (val: def: | 
					
						
							| 
									
										
										
										
											2015-06-15 18:04:27 +02:00
										 |  |  |  |       if def.value != val then | 
					
						
							|  |  |  |  |         throw "The option `${showOption loc}' has conflicting definitions, in ${showFiles (getFiles defs)}." | 
					
						
							|  |  |  |  |       else | 
					
						
							|  |  |  |  |         val) (head defs).value defs; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-30 14:21:41 +01:00
										 |  |  |  |   getValues = map (x: x.value); | 
					
						
							|  |  |  |  |   getFiles = map (x: x.file); | 
					
						
							| 
									
										
										
										
											2009-02-09 16:51:03 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-11 16:03:38 +00:00
										 |  |  |  |   # Generate documentation template from the list of option declaration like | 
					
						
							|  |  |  |  |   # the set generated with filterOptionSets. | 
					
						
							| 
									
										
										
										
											2013-10-28 14:25:58 +01:00
										 |  |  |  |   optionAttrSetToDocList = optionAttrSetToDocList' []; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   optionAttrSetToDocList' = prefix: options: | 
					
						
							| 
									
										
										
										
											2015-07-23 16:32:52 +02:00
										 |  |  |  |     concatMap (opt: | 
					
						
							| 
									
										
										
										
											2013-10-28 14:25:58 +01:00
										 |  |  |  |       let | 
					
						
							|  |  |  |  |         docOption = rec { | 
					
						
							|  |  |  |  |           name = showOption opt.loc; | 
					
						
							|  |  |  |  |           description = opt.description or (throw "Option `${name}' has no description."); | 
					
						
							|  |  |  |  |           declarations = filter (x: x != unknownModule) opt.declarations; | 
					
						
							|  |  |  |  |           internal = opt.internal or false; | 
					
						
							|  |  |  |  |           visible = opt.visible or true; | 
					
						
							| 
									
										
										
										
											2015-07-30 13:36:57 +02:00
										 |  |  |  |           readOnly = opt.readOnly or false; | 
					
						
							| 
									
										
										
										
											2015-01-04 15:40:59 +01:00
										 |  |  |  |           type = opt.type.name or null; | 
					
						
							| 
									
										
										
										
											2013-10-28 14:25:58 +01:00
										 |  |  |  |         } | 
					
						
							| 
									
										
										
										
											2014-10-05 01:54:34 +02:00
										 |  |  |  |         // (if opt ? example then { example = scrubOptionValue opt.example; } else {}) | 
					
						
							|  |  |  |  |         // (if opt ? default then { default = scrubOptionValue opt.default; } else {}) | 
					
						
							|  |  |  |  |         // (if opt ? defaultText then { default = opt.defaultText; } else {}); | 
					
						
							| 
									
										
										
										
											2013-10-28 14:25:58 +01:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |         subOptions = | 
					
						
							|  |  |  |  |           let ss = opt.type.getSubOptions opt.loc; | 
					
						
							|  |  |  |  |           in if ss != {} then optionAttrSetToDocList' opt.loc ss else []; | 
					
						
							|  |  |  |  |       in | 
					
						
							| 
									
										
										
										
											2015-07-23 16:32:52 +02:00
										 |  |  |  |         [ docOption ] ++ subOptions) (collect isOption options); | 
					
						
							| 
									
										
										
										
											2009-06-11 16:03:38 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-09 16:51:03 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-12 11:07:49 +00:00
										 |  |  |  |   /* This function recursively removes all derivation attributes from
 | 
					
						
							|  |  |  |  |      `x' except for the `name' attribute.  This is to make the | 
					
						
							|  |  |  |  |      generation of `options.xml' much more efficient: the XML | 
					
						
							|  |  |  |  |      representation of derivations is very large (on the order of | 
					
						
							|  |  |  |  |      megabytes) and is not actually used by the manual generator. */ | 
					
						
							| 
									
										
										
										
											2013-10-17 14:29:51 +02:00
										 |  |  |  |   scrubOptionValue = x: | 
					
						
							| 
									
										
										
										
											2013-10-30 16:19:07 +01:00
										 |  |  |  |     if isDerivation x then | 
					
						
							|  |  |  |  |       { type = "derivation"; drvPath = x.name; outPath = x.name; name = x.name; } | 
					
						
							| 
									
										
										
										
											2010-05-12 11:07:49 +00:00
										 |  |  |  |     else if isList x then map scrubOptionValue x | 
					
						
							| 
									
										
										
										
											2010-06-01 14:24:16 +00:00
										 |  |  |  |     else if isAttrs x then mapAttrs (n: v: scrubOptionValue v) (removeAttrs x ["_args"]) | 
					
						
							| 
									
										
										
										
											2010-05-12 11:07:49 +00:00
										 |  |  |  |     else x; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-05 10:14:24 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |   /* For use in the ‘example’ option attribute.  It causes the given
 | 
					
						
							|  |  |  |  |      text to be included verbatim in documentation.  This is necessary | 
					
						
							|  |  |  |  |      for example values that are not simple values, e.g., | 
					
						
							|  |  |  |  |      functions. */ | 
					
						
							|  |  |  |  |   literalExample = text: { _type = "literalExample"; inherit text; }; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-28 00:56:22 +01:00
										 |  |  |  |   /* Helper functions. */ | 
					
						
							|  |  |  |  |   showOption = concatStringsSep "."; | 
					
						
							| 
									
										
										
										
											2013-10-28 19:48:30 +01:00
										 |  |  |  |   showFiles = files: concatStringsSep " and " (map (f: "`${f}'") files); | 
					
						
							| 
									
										
										
										
											2013-10-28 14:25:58 +01:00
										 |  |  |  |   unknownModule = "<unknown-file>"; | 
					
						
							| 
									
										
										
										
											2013-10-28 00:56:22 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-24 10:57:41 +00:00
										 |  |  |  | } |