query
On this page

mergeOptionDecls

lib.modules.mergeOptionDecls

Docs pulled from | This Revision | 21 minutes ago


Merge multiple option declarations into a single declaration. In general, there should be only one declaration of each option. 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’).

'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'.

Inputs

loc

1. Function argument

opts

2. Function argument


Noogle detected

Aliases

Implementation

The following is the current implementation of this function.

mergeOptionDecls =
   loc: opts:
    foldl' (res: opt:
      let t  = res.type;
          t' = opt.options.type;
          mergedType = t.typeMerge t'.functor;
          typesMergeable = mergedType != null;
          typeSet = if (bothHave "type") && typesMergeable
                       then { type = mergedType; }
                       else {};
          bothHave = k: opt.options ? ${k} && res ? ${k};
      in
      if bothHave "default" ||
         bothHave "example" ||
         bothHave "description" ||
         bothHave "apply" ||
         (bothHave "type" && (! typesMergeable))
      then
        throw "The option `${showOption loc}' in `${opt._file}' is already declared in ${showFiles res.declarations}."
      else
        let
          getSubModules = opt.options.type.getSubModules or null;
          submodules =
            if getSubModules != null then map (setDefaultModuleLocation opt._file) getSubModules ++ res.options
            else res.options;
        in opt.options // res //
          { declarations = res.declarations ++ [opt._file];
            # In the case of modules that are generated dynamically, we won't
            # have exact declaration lines; fall back to just the file being
            # evaluated.
            declarationPositions = res.declarationPositions
              ++ (if opt.pos != null
                then [opt.pos]
                else [{ file = opt._file; line = null; column = null; }]);
            options = submodules;
          } // typeSet
    ) { inherit loc; declarations = []; declarationPositions = []; options = []; } opts;