!wfudwzqQUiJYJnqfSY:nixos.org

NixOS Module System

127 Members
26 Servers

Load older messages


SenderMessageTime
16 May 2025
@ss:someonex.netSomeoneSerge (Bruxelles) *

I suspect this works and then gets rejected by some kind of a final type check: error: The option `marker_a' was accessed but has no value defined. Try setting the option

(my attempt: https://gist.github.com/SomeoneSerge/29a9e6e10cdcd3596f865c41c7042610)

22:05:59
@mattsturg:matrix.orgMatt Sturgeon

That's not a type check, that's an "empty value" stub. When an option has no definitions, its value is set to a stub that throws that error.

You're probably reading the value somewhere, e.g. using config.marker_a instead of options.marker_a, or not using removeAttrs when creating __result?

22:06:40
@mattsturg:matrix.orgMatt Sturgeon On line 11 you assign freeformType to a submodule, but freeformType must be an attrsOf type. 22:12:06
@mattsturg:matrix.orgMatt Sturgeon

On line 45 you're defining apply which is meaningless in a module, it's a feature of options.

If you're evaluating these directly with lib.evalModules instead of using a submodule option, you can do the apply manually:

(lib.evalModules { /* ... */ }).config.__result
22:14:08
@ss:someonex.netSomeoneSerge (Bruxelles)

On line 45 you're defining apply which is meaningless in a module, it's a feature of options.

Yeah I was wondering if I misunderstood the "freeformType is an option"

22:15:13
@ss:someonex.netSomeoneSerge (Bruxelles)Whoops, the snippet is screwed then I guess22:15:50
@mattsturg:matrix.orgMatt Sturgeon

Here's what I meant by freeformType is an option: https://github.com/NixOS/nixpkgs/blob/ec56f7ae8cdc39eebb8a3b4aa7a3a6365c214fb5/lib/modules.nix#L213-L227

You can set it explicitly in a submodule by defining e.g. config._module.freeformType = attrsOf str, but the module system allows a "shorthand" syntax where freeformType can be defined as a top-level attr in a module and it'll do the conversion to assigning the option for you.

22:17:34
@ss:someonex.netSomeoneSerge (Bruxelles)

Here's what I meant by freeformType is an option:

Was my second guess. Thanks for walking me through these!

22:19:58
@ss:someonex.netSomeoneSerge (Bruxelles) Does work with mkOption indeed: https://gist.github.com/SomeoneSerge/b278317b83e5090fbfa9472c78701703 22:51:20
@mattsturg:matrix.orgMatt Sturgeon

Awesome!

I'd highly recommend checking the marker_a.isDefined && marker_b.isDefined case too, which I assume should be an error?

The else case where neither are defined may need some special handling too: is it an error? Is it still an error if cfg is empty?

22:56:09
@ss:someonex.netSomeoneSerge (Bruxelles) Yes, an error. Still struggling a bit conceptually though, seems like there are three different kinds of entities in evalModules: "types" are things that have checks, "modules" are things that produce options and configs, but options are confusing 23:17:40
@ss:someonex.netSomeoneSerge (Bruxelles) It's not possible to extend options._module.freeformType with an apply from outside? 23:18:12
@ss:someonex.netSomeoneSerge (Bruxelles) * It's not possible to extend options._module.freeformType with an apply from outside is it? 23:18:15
@ss:someonex.netSomeoneSerge (Bruxelles) * Yes, an error. Still struggling a bit conceptually though, seems like there are three different kinds of entities in evalModules: "types" are things that have checks, "modules" are things that produce options and configs, but "options" are confusing 23:18:43
@mattsturg:matrix.orgMatt Sturgeon

Yes, there's a few "types" of thing in the module system:

  1. configuration is the final evaluated module eval, returned by evalModules. It contains _type, options, config, type` (a submodule option-type), etc
  2. module these are the "modules" the module system evaluates. Can be a long-form or short-hand attrset, a function returning one, or a file containing one.
  3. options these describe the attrs that can be defined in the configuration. Declared using options.foo = mkOption {}, defined using config.foo = "value" (or the short-hand syntax foo = "value").
  4. option-types these are types that options can declare they have. This is where type checking and definition merging is done.

Submodules are an option-type representing another configuration. The submodule type expects the option definitions to be modules, and it merges those modules using evalModules and uses the configuration's config as its final value.

23:24:13
@mattsturg:matrix.orgMatt Sturgeon

I'm not sure. Usually merging things relates to having multiple definitions for an option, but the module system does also support merging multiple declarations for an option too, in some scenarios.

You may be able to declare options._module.freeformType = mkOption { apply = x: x; }, but IDK why you would want to do that... ?

23:26:47
@ss:someonex.netSomeoneSerge (Bruxelles) Ah right, I was trying ...freeformType.apply = instead, but I actually knew this bit.
But I realized I don't actually need apply in freeformType: I was trying to reproduce the same trick at the top-level instead of at foo.
23:35:26
17 May 2025
@oddlama:matrix.orgoddlama changed their display name from oddlama to Malte.20:12:20
20 May 2025
@kongrooparadox:matrix.orgkongrooparadox joined the room.21:44:52
21 May 2025
@oddlama:matrix.orgoddlama changed their display name from Malte to oddlama.17:42:04
@ss:someonex.netSomeoneSerge (Bruxelles) I see that nixos/lib and nixos/modules use normal path values in _file (except for modulesPath = toString ./eval-config.nix), but somehow in man configuration.nix we get relative paths without hashes? How does that happen 17:48:12
@mattsturg:matrix.orgMatt Sturgeon

path values only get copied to the store when used with string interpolation (e.g. "${./some/path}"). If you instead stringify them with toString, then they are not copied.

E.g.

"${./foo}"
=> "/nix/store/r1l6z113nnzx44iiqp728f50lpczp577-foo"

toString ./foo
=> "/home/matt/foo"

./foo
=> /home/matt/foo
17:53:58
@ss:someonex.netSomeoneSerge (Bruxelles) Ohhh so nixos/modules actually does pass strings around and not paths? 18:00:37
@ss:someonex.netSomeoneSerge (Bruxelles)
nixos/lib/eval-config.nix
71-  pkgsModule = rec {
72:    _file = ./eval-config.nix;
73:    key = _file;
18:02:08
@ss:someonex.netSomeoneSerge (Bruxelles)This is 100% a "path"18:02:19
@ss:someonex.netSomeoneSerge (Bruxelles)
$ man configuration.nix
...
       nixpkgs.pkgs
...
           Declared by:
               <nixpkgs/nixos/modules/misc/nixpkgs.nix>
18:03:29
@ss:someonex.netSomeoneSerge (Bruxelles) So there is some magic happening that makes this ./eval-config.nix into a string that is relative to.... hmmm parent of the checkout 18:03:57
@mattsturg:matrix.orgMatt Sturgeon IIRC specialArgs.modulesPath is removed if it is a prefix of the stringified _file. 18:05:42
@mattsturg:matrix.orgMatt Sturgeon

actually does pass strings around

No, but when rendering files in errors, docs, etc they are stringified using toString

18:06:40
@spaenny:tchncs.dePhilipp joined the room.18:21:49

Show newer messages


Back to Room ListRoom Version: 10