!wfudwzqQUiJYJnqfSY:nixos.org

NixOS Module System

205 Members
48 Servers

Load older messages


SenderMessageTime
9 Jun 2026
@hsjobeki:matrix.orghsjobekiConceptually i think you shouldn probably reconsider if you need to use foldl' with head, tail on the defs16:27:18
@hsjobeki:matrix.orghsjobeki* Conceptually i think you should probably reconsider if you need to use foldl' with head, tail on the defs16:27:23
@hsjobeki:matrix.orghsjobeki acc.type is determined by the first element? But definitions don't have a predictable/stable order 16:29:33
@hsjobeki:matrix.orghsjobeki ah no acc.type is always attrs since the bug with typeOf h 16:30:26
@aurelivia:matrix.orgaureliviaoh nice catch thanks16:38:51
@aurelivia:matrix.orgaureliviaalright unfortunately changing the calls to use mergeDefinitions did not change the outcome16:53:04
@aurelivia:matrix.orgaureliviaso I'm still doing something wrong here16:53:14
@hsjobeki:matrix.orghsjobeki mergeDefintions is definetly the right track; There might be other quirks 16:53:48
@aurelivia:matrix.orgaurelivia
  nodelike = lib.mkOptionType {
    name = "nodelike";
    description = "Something that acts like a node, with attributes, a value, and children.";
    descriptionClass = "noun";
    check = val: true;
    merge = loc: defs: if (builtins.length defs == 1)
      then (builtins.head defs).value
      else (builtins.foldl' (acc: def: let
        acc-def = { value = acc.val; file = acc.file; };
        fail = throw "The option `${lib.options.showOption loc}` has conflicting option types:${lib.options.showDefs [ acc-def def ]}";
      in if (acc.type == "list")
        then if (builtins.typeOf def.value) == "list"
          then { type = "list"; file = def.file; val = (lib.modules.mergeDefinitions loc (lib.types.listOf nodelike) [ acc-def def ]).mergedValue; }
          else if (builtins.typeOf def.value) == "set"
            then {
              type = "list"; file = def.file;
              val = (lib.modules.mergeDefinitions loc (lib.types.listOf nodelike) [
                acc-def
                { value = [ def.value ]; file = def.file; }
              ]).mergedValue;
            } else fail
        else if (acc.type == "set")
          then if (builtins.typeOf def.value) == "set"
            then { type = "set"; file = def.file; val = (lib.modules.mergeDefinitions loc (lib.types.attrsOf nodelike) [ acc-def def ]).mergedValue; }
            else if (builtins.typeOf def.value) == "list"
              then {
                type = "list"; file = def.file;
                val = (lib.modules.mergeDefinitions loc (lib.types.listOf nodelike) [
                  { value = [ acc.val ]; file = acc.file; }
                  def
                ]).mergedValue;
              } else fail
          else { type = acc.type; file = def.file; val = (lib.modules.mergeDefinitions loc lib.types.anything [ acc-def def ]).mergedValue; }
      ) (let h = builtins.head defs; in { type = builtins.typeOf h.value; file = h.file; val = h.value; }) (builtins.tail defs)).val;
  };
16:53:51
@hsjobeki:matrix.orghsjobekiCan you give an example how the type should work ? 16:55:37
@hsjobeki:matrix.orghsjobekiWhat should the produced value look like?16:55:51
@hsjobeki:matrix.orghsjobeki* What should the final value look like?16:56:01
@aurelivia:matrix.orgaurelivia It's essentially just deep-merging an attrset, except that, because this represents nodes like XML, there can be multiple instances of any key, therefore if one module defines a single instance of that key as a set, and another module defines multiple instances as a list, the result should be a list of all the definitions 16:58:49
@aurelivia:matrix.orgaureliviaor like if two modules define two single nodes, that should result in a list of both16:59:11
@hsjobeki:matrix.orghsjobeki You are aware the outcome of this is pretty unstable? h = builtins.head defs; it depends on the import order of the modules.
So switching two modules around changes your acc.type
16:59:13
@aurelivia:matrix.orgaureliviaIt shouldn't, it's set up to handle encountering a list first or a set first16:59:33
@aurelivia:matrix.orgaureliviathe order shouldn't matter16:59:48
@hsjobeki:matrix.orghsjobeki The order of the defs list itself is not stable unfortunately 17:00:03
@hsjobeki:matrix.orghsjobeki You initialize acc.type = typeOf (head defs).value
Then in the fold
if (acc.type == "list") then right ?
17:01:49
@aurelivia:matrix.orgaureliviait can handle either receiving a list or a set first17:03:15
@aurelivia:matrix.orgaureliviathe order does not matter17:03:17
@aurelivia:matrix.orgaureliviaa key is considered a node if it is either a set or a list, anything else is considered an attribute of it's parent key. If at any time a list is encountered, the result will be a list, regardless of what order it comes in. If it has a list, and gets a set, it merges it into the list, and if it has a set, and gets a list, it turns it into a list with that set and concatenates it17:06:36
@aurelivia:matrix.orgaureliviaor at least that's what it should be doing... I haven't had any issues with that bit so far17:09:04
@aurelivia:matrix.orgaurelivia Where I'm specifically encountering this issue is with two strings which should just be falling back to mergeEqualOption 17:10:35
@toonn:matrix.orgtoonn Are submodule options always optional, like when they don't have a default? 19:12:33
@aurelivia:matrix.orgaureliviaRedacted or Malformed Event19:18:11
@hsjobeki:matrix.orghsjobeki
In reply to @toonn:matrix.org
Are submodule options always optional, like when they don't have a default?
Yes. Submodules without options should be perfectly valid
19:18:45
@aurelivia:matrix.orgaurelivia Do you mean the use of lib.mkOption within a submodule's options or the options set itself? If the former, I believe it's only optional if it has a default 19:20:39
@toonn:matrix.orgtoonn The example for pixelfed.nginx doesn't contain sslCertificate, which doesn't have a default, hence my question. 19:50:18
@mattsturg:matrix.orgMatt Sturgeon
In reply to @toonn:matrix.org
Are submodule options always optional, like when they don't have a default?
If something reads the undefined option, then you'll get an error. E.g. if the submodule gets serialised to JSON or something.
20:09:47

Show newer messages


Back to Room ListRoom Version: 10