From acf6b46011d044d1e99fedf111a8e7c4ef6c93cd Mon Sep 17 00:00:00 2001 From: Robert Hensing Date: Fri, 23 May 2025 12:00:51 +0200 Subject: [PATCH] system.build: Treat as variables, make lazy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes an unnecessary evaluation dependency that prevented the custom and much appreciated primaryUser error from popping up. Specifically: … while evaluating the option `system.build': … while evaluating definitions from `/nix/store/lc6n4bhxj9255kzfn9pnpx65583a8cgc-source/modules/environment': … while evaluating definitions from `/nix/store/lc6n4bhxj9255kzfn9pnpx65583a8cgc-source/modules/nix': … while evaluating the option `environment.darwinConfig': … while evaluating the option `system.primaryUserHome': error: expected a string but found null: null at /nix/store/lc6n4bhxj9255kzfn9pnpx65583a8cgc-source/modules/system/primary-user.nix:26:30: 25| default = 26| config.users.users.${config.system.primaryUser}.home or "/Users/${config.system.primaryUser}"; | ^ 27| }; While it did have some indication as to the cause, it lets the good error message go to waste. **Context** `lazyAttrsOf` is the better choice when you use an attrset as individual variables instead of in aggregate (e.g. `attrNames`, `toJSON`). The reason is that an expression like `a.b` is strict in `a`, which entails the evaluating the _whole_ set of attribute _names_ in `a`. In the `attrsOf` this means evaluating all `mkIf` conditions, which in turn also means evaluating all the regular definitions to the smallest degree (WHNF) to determine that they're not `mkIf`s. `lazyAttrsOf` simply assumes that all attributes aren't `mkIf false`, and throws an error in the attribute value if necessary. This would be a problem with `toJSON` and such, but is completely fine when the attributes are treated as variables of a lazy program, as is the case here. **NixOS** NixOS made `system.build` a submodule with a `freeformType`, allowing the things inside of it to be declared, and for them to have niceties like documentation and merging behavior. nix-darwin could probably adopt this. --- modules/system/default.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/system/default.nix b/modules/system/default.nix index 3144695..733a73a 100644 --- a/modules/system/default.nix +++ b/modules/system/default.nix @@ -20,7 +20,7 @@ in system.build = mkOption { internal = true; - type = types.attrsOf types.unspecified; + type = types.lazyAttrsOf types.unspecified; default = {}; description = '' Attribute set of derivation used to setup the system.