query
On this page

evalOptionValue

lib.evalOptionValue

Docs pulled from | This Revision | about 2 hours ago


Merge all the definitions of an option to produce the final config value.

Inputs

loc

1. Function argument

opt

2. Function argument

defs

3. Function argument


Noogle detected

Aliases

Implementation

The following is the current implementation of this function.

evalOptionValue = loc: opt: defs:
    let
      # Add in the default value for this option, if any.
      defs' =
          (optional (opt ? default)
            { file = head opt.declarations; value = mkOptionDefault opt.default; }) ++ defs;

      # Handle properties, check types, and merge everything together.
      res =
        if opt.readOnly or false && length defs' > 1 then
          let
            # For a better error message, evaluate all readOnly definitions as
            # if they were the only definition.
            separateDefs = map (def: def // {
              value = (mergeDefinitions loc opt.type [ def ]).mergedValue;
            }) defs';
          in throw "The option `${showOption loc}' is read-only, but it's set multiple times. Definition values:${showDefs separateDefs}"
        else
          mergeDefinitions loc opt.type defs';

      # Apply the 'apply' function to the merged value. This allows options to
      # yield a value computed from the definitions
      value = if opt ? apply then opt.apply res.mergedValue else res.mergedValue;

      warnDeprecation =
        warnIf (opt.type.deprecationMessage != null)
          "The type `types.${opt.type.name}' of option `${showOption loc}' defined in ${showFiles opt.declarations} is deprecated. ${opt.type.deprecationMessage}";

    in warnDeprecation opt //
      { value = addErrorContext "while evaluating the option `${showOption loc}':" value;
        inherit (res.defsFinal') highestPrio;
        definitions = map (def: def.value) res.defsFinal;
        files = map (def: def.file) res.defsFinal;
        definitionsWithLocations = res.defsFinal;
        inherit (res) isDefined;
        # This allows options to be correctly displayed using `${options.path.to.it}`
        __toString = _: showOption loc;
      };