From bb944b4dc80e7b2a22ac8e76355e7bf80aec6636 Mon Sep 17 00:00:00 2001 From: Nicolas Pierron Date: Fri, 29 Aug 2014 14:38:19 +0200 Subject: [PATCH] Annotate option-set options with the file in which they are declared. This modification improves NixOS manual by listing in which file, each submodule option is declared. This solve the issue that files are not reported when looking at options such as fileSystems..neededForBoot --- lib/modules.nix | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/lib/modules.nix b/lib/modules.nix index 9fe26083cfd4..31134c66276b 100644 --- a/lib/modules.nix +++ b/lib/modules.nix @@ -132,7 +132,12 @@ rec { The exception is the ‘options’ attribute, which specifies sub-options. These can be specified multiple times to allow one module to add sub-options to an option declared somewhere else - (e.g. multiple modules define sub-options for ‘fileSystems’). */ + (e.g. multiple modules define sub-options for ‘fileSystems’). + + 'loc' is the list of attribute names where the option is located. + + 'opts' is a list of modules. Each module has an options attribute which + correspond to the definition of 'loc' in 'opt.file'. */ mergeOptionDecls = loc: opts: fold (opt: res: if opt.options ? default && res ? default || @@ -143,9 +148,23 @@ rec { then throw "The option `${showOption loc}' in `${opt.file}' is already declared in ${showFiles res.declarations}." else - opt.options // res // + let + /* Add the modules of the current option to the list of modules + already collected. The options attribute except either a list of + submodules or a submodule. For each submodule, we add the file of the + current option declaration as the file use for the submodule. If the + submodule defines any filename, then we ignore the enclosing option file. */ + options' = toList opt.options.options; + coerceOption = file: opt: + if isFunction opt then args: { _file = file; } // (opt args) + else args: { _file = file; options = opt; }; + submodules = + if opt.options ? options + then map (coerceOption opt.file) options' ++ res.options + else res.options; + in opt.options // res // { declarations = [opt.file] ++ res.declarations; - options = if opt.options ? options then [(toList opt.options.options ++ res.options)] else []; + options = submodules; } ) { inherit loc; declarations = []; options = []; } opts; @@ -276,12 +295,8 @@ rec { optionSet to configOf. FIXME: remove eventually. */ fixupOptionType = loc: opt: let - options' = opt.options or + options = opt.options or (throw "Option `${showOption loc'}' has type optionSet but has no option attribute, in ${showFiles opt.declarations}."); - coerce = x: - if isFunction x then x - else { config, ... }: { options = x; }; - options = map coerce (flatten options'); f = tp: if tp.name == "option set" || tp.name == "submodule" then throw "The option ${showOption loc} uses submodules without a wrapping type, in ${showFiles opt.declarations}."