1 Feb 2024 |
guangtao | * is it possible to solve your problem through the apply option? I mean you can set the defualt to be {}, use apply instead
apply = cfg: lib.recursiveUpdate {<default>} cfg;
| 20:12:42 |
guangtao | Yeah, if I understand your problem correctly. | 20:13:50 |
infinisil | Oh don't use apply , that's generally an anti-pattern | 20:14:12 |
infinisil | I'll take a closer look at the code | 20:14:22 |
@djacu:matrix.org | apply also generally wouldn't work because this module wouldn't necessarily be at the top level. I mean it could work but would be messy. Also, it breaks out of the module ecosystem and isn't very user friendly. | 20:16:08 |
infinisil | Oh so it doesn't work because to the module system, all definitions have the same priority | 20:16:57 |
infinisil | You set them both with out = <attrset> , no mkDefault or so | 20:17:16 |
infinisil | But out = mkDefault config.default wouldn't work because then the entire attribute set gets overridden by the users one, therefore not using any defaults | 20:18:00 |
infinisil | What you need is out = mapAttrs (name: mkDefault) config.default | 20:18:26 |
@djacu:matrix.org | I'm a little lost. Which line would I inject this:
out = mapAttrs (name: mkDefault) config.default
Also doesn't mapAttrs a function of 2 variables?
| 20:21:09 |
infinisil | The line out = config.default; | 20:21:48 |
@djacu:matrix.org | * I'm a little lost. Which line would I inject this:
out = mapAttrs (name: mkDefault) config.default
Also isn't mapAttrs a function of 2 variables?
| 20:22:09 |
infinisil | Currying function arguments :) | 20:22:12 |
guangtao | that makes sense; set all attrts of default to having order. | 20:23:54 |
@djacu:matrix.org | What is this deep magic!? It works | 20:26:24 |
@djacu:matrix.org | Oh did you just apply mkDefault to all the values set in default ?? | 20:27:02 |
infinisil | Indeed :) | 20:27:18 |
@djacu:matrix.org | Cool man. Thanks!
What is really nice is that I can use ({...}: {user = {b = 3;};}) and it overrides. Which provides a nice API for end users (i.e. not having to use mkForce).
So this partially makes sense. But why didn't having a user config with ({...}: {user = {b = lib.mkForce 3;};}) work before? It should have a really high priority.
Without your fix, does the config.default have... no priority? What was the failure mechanism before the fix?
| 20:31:17 |
infinisil | Before, config.user and config.default had the same priority. The conflict happened one level above | 20:32:25 |
infinisil | You could've fixed this with { user = lib.mkForce { b = 3; }; } | 20:32:49 |
infinisil | So putting the mkForce also on the same level where the conflict happened | 20:33:01 |
@djacu:matrix.org | In reply to @infinisil:matrix.org Before, config.user and config.default had the same priority. The conflict happened one level above I tried that! You can see it is the last thing under the # NONE OF THESE WORK; conflicting definitions section. line 56 | 20:34:06 |
infinisil | Oh um.... | 20:34:36 |
infinisil | Ahh! The problem is that config.user doesn't contain any mkForce anymore. It's an evaluated option, so all of those modifiers are gone | 20:39:01 |
infinisil | So the input to user is lib.mkForce { b = 3; } , but it outputs just { b = 3; } , no conflict there, since there's just one definition | 20:39:48 |
infinisil | Similarly the input to defaults is just that one default = { a = 1; b = 2; } (which is actually defaults = lib.mkOptionDefault { ... } but that's not relevant here), it outputs { a = 1; b = 2; } | 20:40:38 |
infinisil | Finally, you have effectively
{
out = lib.mkMerge [
config.default
config.user
];
}
| 20:41:10 |
infinisil | * Finally, you have effectively
{
out = lib.mkMerge [
{ a = 1; b = 2; }
{ b = 3; }
];
}
Both of which are without priority, so it recurses into the attrs and conflicts because two b s
| 20:41:59 |
infinisil | Instead if you want to actually copy the definitions from one option to another, the mkAlias function suite is what you need: https://github.com/NixOS/nixpkgs/blob/master/lib/modules.nix#L1039-L1073 | 20:43:19 |
infinisil | * Instead if you want to actually copy the definitions from one option to another, the mkAlias function suite is what you need: https://github.com/NixOS/nixpkgs/blob/a0d3f10c751b6b2642b44d327470f68ad6bc7952/lib/modules.nix#L1039-L1073 | 20:43:32 |