!wfudwzqQUiJYJnqfSY:nixos.org

NixOS Module System

202 Members
47 Servers

Load older messages


SenderMessageTime
9 Jun 2026
@toonn:matrix.orgtoonnSo in this case there's no way to tell whether the options are required or not? Since it depends on the use in the module?20:22:08
@hsjobeki:matrix.orghsjobekiAn option is always "required" at the time it's value is accessed20:24:52
@mattsturg:matrix.orgMatt Sturgeon Essentially, yes. Generally, well designed module with "optional" options will gate usage behind option.isDefined. Hopefully such cases document clearly whether the option is truly optional or just missing a default definition. 20:26:09
@hsjobeki:matrix.orghsjobekiI guess you are thinking about translating options -> json schema?20:26:40
@mattsturg:matrix.orgMatt Sturgeon
In reply to @hsjobeki:matrix.org
I guess you are thinking about translating options -> json schema?
If so, this kinda optional field is one of the use-cases for the long-stalled types.record PR
20:27:43
@toonn:matrix.orgtoonnYeah, trying to make the schemas as accurate as possible.20:29:52
@mattsturg:matrix.orgMatt Sturgeon

If this is an option you're designing today, then you can work-around the limitations with a combination of option-level apply and reading valueMeta to access the actual submodule configuration's evaluated options.

It'd be ugly, but you could in theory filter out attributes whose corresponding option isDefined→false. If you have nested options you may end up with some empty attrsets, though, which would be hard to distinguish from option-remnants and empty freeform definitions.

20:33:43
@hsjobeki:matrix.orghsjobekiThere is a distinction between the input and the output of the module system. I guess you are trying to find the type constraints of the inputs of eval-modules. And that means if option.isDefined then it is not required (to be set from outside)20:35:33
@mattsturg:matrix.orgMatt Sturgeon
In reply to @toonn:matrix.org
Yeah, trying to make the schemas as accurate as possible.

As an aside, I've found that in rfc42 style settings-options, the more explicit sub-options you declare the more maintenance debt you're signing up for.

Every declared option has to be kept in sync with changes to upstream's docs and schema.

IMO it's better to lean on freeformType and allow users to define anything they like, without you having to maintain a nix-representation of the schema.

20:40:00
@nbp:mozilla.orgnbpI will suggest also that if you lean on freeformType, then you should also rely on a verification process to see whether the config is valid or not, whether the program can load the generated configuration or not. Such that we fail early, and now 5 days later when the service does not start as expected.20:42:14
@nbp:mozilla.orgnbp* I will suggest also that if you lean on freeformType, then you should also rely on a verification process to see whether the config is valid or not, whether the program can load the generated configuration or not. Such that we fail early, and not 5 days later when the service does not start as expected.20:42:20
@toonn:matrix.orgtoonnI wish I was the one writing the modules, would take away all the problems : )20:44:02
@toonn:matrix.orgtoonnI'll look into isDefined though, thanks for the help!20:44:17
@hsjobeki:matrix.orghsjobekiClan has a converter for both input and output to json-schema for module system options. I built a large portion of the first iterations and co-authored the current version. https://git.clan.lol/clan/clan-core/src/branch/main/lib/jsonschema/default.nix The question whether an option is required is also a question whether it has children that are required if i remember this correctly. If you want we can move this into a different repo and make it work for more use-cases. Have you tried it? 20:45:11
@mattsturg:matrix.orgMatt Sturgeon
In reply to @toonn:matrix.org
I'll look into isDefined though, thanks for the help!
One footgun I ran into is getSubOptions vs valueMeta. The former will not have accurate isDefined data, as it's intended only for docs generation, while the latter will be accurate, but is only accessible from v2 checkAndMerge types.
20:48:05
@toonn:matrix.orgtoonn Darn, so that's gonna already bite me in the behind. 20:51:18
@toonn:matrix.orgtoonn Clan's jsonschema didn't work out for me. 20:51:28
@mattsturg:matrix.orgMatt Sturgeon
In reply to @toonn:matrix.org
Darn, so that's gonna already bite me in the behind.

It shouldn't bite you. submodule supports v2, as do most composite types. One exception is nullOr is still stuck on v1.

To be clear, we're talking about the submodule option, not its sub-options; sub-options don't need valueMeta or v2 checkAndMerge unless you want to be recursively walking into submodules within submodules.

20:55:52
@hsjobeki:matrix.orghsjobekiI also want working jsonschema. Ideally at some point upstream in nixpkgs. If you have concrete examples that didn't work to convert i'd also be interested to take a look at21:11:56
@hsjobeki:matrix.orghsjobeki* I also want working jsonschema. Ideally at some point upstream in nixpkgs. If you have concrete examples that didn't work to convert i'd be happy to take a look at21:12:41
@toonn:matrix.orgtoonn Yeah the idea *is* to recursively walk the entire options for a module. 21:51:24
@toonn:matrix.orgtoonn Well, one example is pixelfed.nginx, sslCertificate for example doesn't have a default but the example for pixelfed.nginx leads me to believe it's not a required option. 21:52:45
10 Jun 2026
@mattsturg:matrix.orgMatt SturgeonThe only reason I made the distinction, is because it is possible to walk an option-tree without recursing also into submodule option-trees. In some scenarios, you know that none of your sub-options will themselves be submodules, so it'd be ok in those scenarios.00:12:36
@toonn:matrix.orgtoonn You can avoid recursing but that wouldn't give a complete view of available options. 07:46:53
@toonn:matrix.orgtoonn OK, so pixelfed.nginx's type is nullOr submodule, the nullOr means I can't get at the options through valueMeta and going through getSubOptions sslCertificate.isDefined = false. So for all intents and purposes it looks like a required option. I think they don't give the option a default/defaultText because it is overridden (not default) if ACME is used but otherwise required, https://github.com/NixOS/nixpkgs/blob/nixos-unstable/nixos/modules/services/web-servers/nginx/default.nix#L28 12:17:19
@hsjobeki:matrix.orghsjobeki

Here is a workaround i used for that:

modules = (opt.definitions ++ opt.type.getSubModules);
submoduleEval = lib.evalModules {
    inherit modules;
};
12:26:40
@hsjobeki:matrix.orghsjobekiit's not pretty but it worked :D12:27:39
@toonn:matrix.orgtoonnTo get through a nullOr? Because the result of that for pixelfed.nginx is full of errors, only type and extendModules aren't errors.12:35:21
@mattsturg:matrix.orgMatt Sturgeon Could the original submodule be using specialArgs, such that re-evaluating its modules alone isn't enough? types.submodule doesn't provide access to extendModules anywhere, does it? 12:39:09
@hsjobeki:matrix.orghsjobekii guess the best solution is to move on with nullOr merge.v2 12:41:31

Show newer messages


Back to Room ListRoom Version: 10