Using mkIf with nested if

I’m currently trying to make a module compatible with NixOS configuration.nix and with home-manager’s home.nix.

The only difference I have is when adding the package. With NixOS I use environment.systemPackages = [my_pkg] while with home-manager I use home.packages = [my_pkg].

I came up with this :

  config = mkIf cfg.enable (if home-manager then {
    home.packages = [ my_pkg ];
  } else {
    environment.systemPackages = [ my_pkg ];
  });

But I have an infinite recursion encountered error. I do not know where the recursion is, and I’m kind of stuck. Any idea ?

config = mkIf cfg.enable (mkMerge [
   (mkIf condition1 {
      ...
   })
   (mkIf condition2 {
      ...
   })
   ....
]);
1 Like

Thank you ! It indeed solved the infinite recursion encountered (I still do not really understand why it behaved this way ?).

I now have the following issue :

The option `environment' defined in `/home/ely/test.nix' does not exist.

I have the feeling that the mkIf expression is still evaluated even if the flag is set, right ? If it does, is there a way to get around this limitation ?

I still do not really understand why it behaved this way ?

I tried to explain why it works like this in Best resources for learning about the NixOS module system?

I have the feeling that the mkIf expression is still evaluated even if the flag is set, right

right.

So what can be done:

  • you may set _module.check = false;, then it won’t complain about this kind of problems. It is bad, because when you do typos in option names, it won’t detect those typos
  • you may add an explicit variable load. For example, add to each module:
    let home-manager = builtins.getEnv "IS_HOME_MANAGER_EVAL" == "yes"; in
    This way resolving home-manager doesn’t require module system eval, so it won’t cause infinite recursion. Now all you have to do is export IS_HOME_MANAGER_EVAL=yes before home-manager rebuilds.
  • best is to split system config and home configs and don’t try to mix that
  • or mix those correctly. I’ve seen that @Infinisil had merged those nicely in https://github.com/Infinisil/system. For example, here is how system service and home.packages are intermixed. Check this file for how to add home-manager module.

Thank you for your help ! I’ve split them.