marienz / nix-doom-emacs-unstraightened

Builds Doom Emacs using Nix
Apache License 2.0
47 stars 3 forks source link

Infinite recursion on home-manager #15

Closed akaihola closed 3 months ago

akaihola commented 3 months ago

I just did a stand-alone home-manager install on NixOS 24.05. If I add this to my home-manager configuration:

imports = [ inputs.nix-doom-emacs-unstraightened.hmModule ];

and run

home-manager switch

I get

error:
       … while evaluating the attribute 'activationPackage'

         at /home/akaihola/.nix-defexpr/channels/home-manager/modules/default.nix:49:7:

           48|
           49|       activationPackage = module.config.home.activationPackage;
             |       ^
           50|

       … while evaluating a branch condition

         at /nix/var/nix/profiles/per-user/root/channels/nixos/lib/lists.nix:125:9:

          124|       fold' = n:
          125|         if n == len
             |         ^
          126|         then nul

       (stack trace truncated; use '--show-trace' to show the full trace)

       error: infinite recursion encountered

       at /nix/var/nix/profiles/per-user/root/channels/nixos/lib/modules.nix:508:28:

          507|         builtins.addErrorContext (context name)
          508|           (args.${name} or config._module.args.${name})
             |                            ^
          509|       ) (lib.functionArgs f);
akaihola commented 3 months ago
Here's the same with `--show-trace` ```nix error: … while evaluating the attribute 'activationPackage' at /home/akaihola/.nix-defexpr/channels/home-manager/modules/default.nix:49:7: 48| 49| activationPackage = module.config.home.activationPackage; | ^ 50| … from call site at /home/akaihola/.nix-defexpr/channels/home-manager/modules/default.nix:45:18: 44| withExtraAttrs = rawModule: 45| let module = moduleChecks rawModule; | ^ 46| in { … while calling 'moduleChecks' at /home/akaihola/.nix-defexpr/channels/home-manager/modules/default.nix:32:18: 31| 32| moduleChecks = raw: | ^ 33| showWarnings (let … from call site at /home/akaihola/.nix-defexpr/channels/home-manager/modules/default.nix:33:5: 32| moduleChecks = raw: 33| showWarnings (let | ^ 34| failed = collectFailed raw.config; … while calling 'showWarnings' at /home/akaihola/.nix-defexpr/channels/home-manager/modules/default.nix:15:18: 14| 15| showWarnings = res: | ^ 16| let f = w: x: builtins.trace "warning: ${w}" x; … from call site at /home/akaihola/.nix-defexpr/channels/home-manager/modules/default.nix:17:8: 16| let f = w: x: builtins.trace "warning: ${w}" x; 17| in fold f res res.config.warnings; | ^ 18| … while calling 'foldr' at /nix/var/nix/profiles/per-user/root/channels/nixos/lib/lists.nix:121:20: 120| */ 121| foldr = op: nul: list: | ^ 122| let … from call site at /nix/var/nix/profiles/per-user/root/channels/nixos/lib/lists.nix:128:8: 127| else op (elemAt list n) (fold' (n + 1)); 128| in fold' 0; | ^ 129| … while calling 'fold'' at /nix/var/nix/profiles/per-user/root/channels/nixos/lib/lists.nix:124:15: 123| len = length list; 124| fold' = n: | ^ 125| if n == len … from call site at /home/akaihola/.nix-defexpr/channels/home-manager/modules/default.nix:34:16: 33| showWarnings (let 34| failed = collectFailed raw.config; | ^ 35| failedStr = concatStringsSep "\n" (map (x: "- ${x}") failed); … while calling 'collectFailed' at /home/akaihola/.nix-defexpr/channels/home-manager/modules/default.nix:12:19: 11| 12| collectFailed = cfg: | ^ 13| map (x: x.message) (filter (x: !x.assertion) cfg.assertions); … from call site at /nix/var/nix/profiles/per-user/root/channels/nixos/lib/modules.nix:242:28: 241| # For definitions that have an associated option 242| declaredConfig = mapAttrsRecursiveCond (v: ! isOption v) (_: v: v.value) options; | ^ 243| … while calling 'mapAttrsRecursiveCond' at /nix/var/nix/profiles/per-user/root/channels/nixos/lib/attrsets.nix:1201:5: 1200| f: 1201| set: | ^ 1202| let … from call site at /nix/var/nix/profiles/per-user/root/channels/nixos/lib/modules.nix:234:33: 233| ({ inherit lib options config specialArgs; } // specialArgs); 234| in mergeModules prefix (reverseList collected); | ^ 235| … while calling 'reverseList' at /nix/var/nix/profiles/per-user/root/channels/nixos/lib/lists.nix:1116:17: 1115| */ 1116| reverseList = xs: | ^ 1117| let l = length xs; in genList (n: elemAt xs (l - n - 1)) l; … from call site at /nix/var/nix/profiles/per-user/root/channels/nixos/lib/modules.nix:229:25: 228| merged = 229| let collected = collectModules | ^ 230| class … while calling anonymous lambda at /nix/var/nix/profiles/per-user/root/channels/nixos/lib/modules.nix:445:37: 444| 445| in modulesPath: initialModules: args: | ^ 446| filterModules modulesPath (collectStructuredModules unknownModule "" initialModules args); … from call site at /nix/var/nix/profiles/per-user/root/channels/nixos/lib/modules.nix:446:7: 445| in modulesPath: initialModules: args: 446| filterModules modulesPath (collectStructuredModules unknownModule "" initialModules args); | ^ 447| … while calling 'filterModules' at /nix/var/nix/profiles/per-user/root/channels/nixos/lib/modules.nix:413:36: 412| # modules recursively. It returns the final list of unique-by-key modules 413| filterModules = modulesPath: { disabled, modules }: | ^ 414| let … while calling anonymous lambda at /nix/var/nix/profiles/per-user/root/channels/nixos/lib/modules.nix:439:31: 438| disabledKeys = concatMap ({ file, disabled }: map (moduleKey file) disabled) disabled; 439| keyFilter = filter (attrs: ! elem attrs.key disabledKeys); | ^ 440| in map (attrs: attrs.module) (builtins.genericClosure { … from call site at /nix/var/nix/profiles/per-user/root/channels/nixos/lib/modules.nix:400:22: 399| let 400| module = checkModule (loadModule args parentFile "${parentKey}:anon-${toString n}" x); | ^ 401| collectedImports = collectStructuredModules module._file module.key module.imports args; … while calling anonymous lambda at /nix/var/nix/profiles/per-user/root/channels/nixos/lib/modules.nix:359:11: 358| then 359| m: | ^ 360| if m._class != null -> m._class == class … from call site at /nix/var/nix/profiles/per-user/root/channels/nixos/lib/modules.nix:400:35: 399| let 400| module = checkModule (loadModule args parentFile "${parentKey}:anon-${toString n}" x); | ^ 401| collectedImports = collectStructuredModules module._file module.key module.imports args; … while calling 'loadModule' at /nix/var/nix/profiles/per-user/root/channels/nixos/lib/modules.nix:336:53: 335| # Like unifyModuleSyntax, but also imports paths and calls functions if necessary 336| loadModule = args: fallbackFile: fallbackKey: m: | ^ 337| if isFunction m then … from call site at /nix/var/nix/profiles/per-user/root/channels/nixos/lib/modules.nix:337:12: 336| loadModule = args: fallbackFile: fallbackKey: m: 337| if isFunction m then | ^ 338| unifyModuleSyntax fallbackFile fallbackKey (applyModuleArgs fallbackKey m args) … while calling 'isFunction' at /nix/var/nix/profiles/per-user/root/channels/nixos/lib/trivial.nix:929:16: 928| */ 929| isFunction = f: builtins.isFunction f || | ^ 930| (f ? __functor && isFunction (f.__functor f)); … while calling anonymous lambda at /nix/var/nix/profiles/per-user/root/channels/nixos/lib/modules.nix:506:44: 505| context = name: ''while evaluating the module argument `${name}' in "${key}":''; 506| extraArgs = builtins.mapAttrs (name: _: | ^ 507| builtins.addErrorContext (context name) … while evaluating the module argument `inputs' in "/home/akaihola/repos/nixos-config/home-manager/emacs.nix": error: infinite recursion encountered at /nix/var/nix/profiles/per-user/root/channels/nixos/lib/modules.nix:508:28: 507| builtins.addErrorContext (context name) 508| (args.${name} or config._module.args.${name}) | ^ 509| ) (lib.functionArgs f); ```
marienz commented 3 months ago

… while evaluating the module argument `inputs' in "/home/akaihola/repos/nixos-config/home-manager/emacs.nix

I think you're either not providing inputs or providing it in a way not available while resolving imports (in particular, setting _module.args.inputs will not work / could result in infinite recursion like this, see https://nixos.org/manual/nixpkgs/stable/#module-system-lib-evalModules-param-specialArgs).

For home-manager, that probably means adding home-manager.extraSpecialArgs = { inherit inputs; } somewhere (I'd need to see more of your config to be more precise, sorry...)

akaihola commented 3 months ago

I believe I solved the infinite recursion problem by adding in the outputs = block of flake.nix:

For other newbies, it might be useful if your README mentioned those.

However, now programs.doom-emacs can't be found.

Once I've solved this completely, I'll be happy to submit a PR to extend the README example for home-manager.

flake.nix ```nix { inputs = { nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; home-manager = { url = "github:nix-community/home-manager"; inputs.nixpkgs.follows = "nixpkgs"; }; nix-doom-emacs-unstraightened.url = "github:marienz/nix-doom-emacs-unstraightened"; }; outputs = inputs @ { nixpkgs, home-manager, ... }: let system = "x86_64-linux"; pkgs = nixpkgs.legacyPackages.${system}; in { imports = [ inputs.nix-doom-emacs-unstraightened.hmModule ]; homeConfigurations."akaihola" = home-manager.lib.homeManagerConfiguration { inherit pkgs; modules = [ ./home.nix ]; extraSpecialArgs = { inherit inputs; }; }; }; } ```
home.nix ```nix { config, pkgs, ... }: { programs.doom-emacs.enable = true; # ... } ```
output of `home-manager switch` ```nix error: … while evaluating a branch condition at /nix/store/bi5zxc0v5g6ylygdwyqzh280sccg3ykb-source/lib/lists.nix:125:9: 124| fold' = n: 125| if n == len | ^ 126| then nul … while calling the 'length' builtin at /nix/store/bi5zxc0v5g6ylygdwyqzh280sccg3ykb-source/lib/lists.nix:123:13: 122| let 123| len = length list; | ^ 124| fold' = n: (stack trace truncated; use '--show-trace' to show the full trace) error: The option `programs.doom-emacs' does not exist. Definition values: - In `/nix/store/wbss4yr2ixl3i8ipqrsnhchbwc1rnqkn-source/home-manager/home.nix': { enable = true; } ```
akaihola commented 3 months ago

Actually, seems that in flake.nix I need to add unstraightened into modules =[ instead of imports = [!

flake.nix ```nix { inputs = { # Specify the source of Home Manager and Nixpkgs. nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; home-manager = { url = "github:nix-community/home-manager"; inputs.nixpkgs.follows = "nixpkgs"; }; nix-doom-emacs-unstraightened.url = "github:marienz/nix-doom-emacs-unstraightened"; }; outputs = inputs @ { nixpkgs, home-manager, ... }: let system = "x86_64-linux"; pkgs = nixpkgs.legacyPackages.${system}; in { homeConfigurations."akaihola" = home-manager.lib.homeManagerConfiguration { inherit pkgs; modules = [ inputs.nix-doom-emacs-unstraightened.hmModule ./home.nix ]; extraSpecialArgs = { inherit inputs; }; }; }; } ```
marienz commented 3 months ago

Ah, right, that was more confusing than it needed to be...

imports = [ inputs.nix-doom-emacs-unstraightened.hmModule ] should have worked in home.nix. But unless you've broken up your config into a bunch of smaller modules, just adding it to modules like you have makes more sense. And if you have split things up, you can probably figure out how to adapt your example, and the reverse is a lot harder.

Hopefully your PR #18 (thanks!) will make this a little easier for others in the future.

(Closing, please feel free to reopen if anything's still unclear or does not work)