query
On this page

mergeOptionDecls

lib.mergeOptionDecls

Docs pulled from | This Revision | 1 day ago


Nixpkgs manual

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 opt.options ? type && res ? type then
              if typesMergeable then
                {
                  type = mergedType;
                }
              else
                # Keep in sync with the same error below!
                throw
                  "The option `${showOption loc}' in `${opt._file}' is already declared in ${showFiles res.declarations}."
            else
              { };

          bothHave = k: opt.options ? ${k} && res ? ${k};
        in
        if bothHave "default" || bothHave "example" || bothHave "description" || bothHave "apply" then
          # Keep in sync with the same error above!
          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;