From aec4ee4c1a3658786420a69112ad93593142173e Mon Sep 17 00:00:00 2001 From: Bert Proesmans Date: Thu, 13 Mar 2025 23:18:05 +0000 Subject: [PATCH 1/2] nixos-module: Fix potential recursion error between home-manager users and nixos users configuration Pushing users.users..packages from matching home-manager users leads to a circular dependency when one attribute set is calculated from the other. A configuration pull approach replaces the previous one to break up the circular dependency. This new approach allows more flexibility in configuring both option sets, including calculating from each other. EXAMPLE; ```nix {lib, /* custom arg */ flake, config, ...}: { home-manager.useUserPackages = true; home-manager.users = builtins.intersectAttrs (lib.filterAttrs (_: v: v.isNormalUser) config.users.users) (flake.outputs.homeModules.users); } ``` EXAMPLE; ```nix {lib, /* custom arg */ flake, config, ...}: { home-manager.useUserPackages = true; home-manager.users = { inherit (flake.outputs.homeModules.users) demo-user; }; users.users = lib.mapAttrs (_: _: { isNormalUser = true; }) (lib.filterAttrs (_: v: v.programs.git.enable) config.home-manager.users); } ``` fixes #594 --- nixos/common.nix | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/nixos/common.nix b/nixos/common.nix index 05931ad60..7da7e9463 100644 --- a/nixos/common.nix +++ b/nixos/common.nix @@ -50,6 +50,13 @@ let }; in { + options.users.users = mkOption { + type = types.attrsOf (types.submodule ({ name, config, ... }: { + config.packages = mkIf ((config.enable or true) && cfg.useUserPackages + && lib.hasAttr name cfg.users) [ cfg.users.${name}.home.path ]; + })); + }; + options.home-manager = { useUserPackages = mkEnableOption '' installation of user packages through the @@ -104,10 +111,7 @@ in { }; config = (lib.mkMerge [ - # Fix potential recursion when configuring home-manager users based on values in users.users #594 (mkIf (cfg.useUserPackages && cfg.users != { }) { - users.users = (lib.mapAttrs - (_username: usercfg: { packages = [ usercfg.home.path ]; }) cfg.users); environment.pathsToLink = [ "/etc/profile.d" ]; }) (mkIf (cfg.users != { }) { From 319b012b9dbda716c7ed3c0465aeff087cce7d94 Mon Sep 17 00:00:00 2001 From: Bert Proesmans Date: Sun, 23 Mar 2025 09:56:41 +0000 Subject: [PATCH 2/2] options-manual: Remove `users` option set from documentation The option declaration `users.users` is owned by the upstream nixos modules and should not be documented by home-manager. Home-manager declares an incomplete/partial option definition for `users.users` that cannot be documented without the full definition from the nixos modules. This partial definition is removed from the options set while generating documentation for the home-manager nixos module. --- docs/default.nix | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/docs/default.nix b/docs/default.nix index dd79c4590..63b60a16d 100644 --- a/docs/default.nix +++ b/docs/default.nix @@ -54,17 +54,17 @@ let hmPath = toString ./..; - buildOptionsDocs = args@{ modules, includeModuleSystemOptions ? true, ... }: + buildOptionsDocs = + args@{ modules, includeModuleSystemOptions ? true, isNixos ? false, ... }: let options = (lib.evalModules { inherit modules; class = "homeManager"; }).options; in pkgs.buildPackages.nixosOptionsDoc ({ - options = if includeModuleSystemOptions then - options - else - builtins.removeAttrs options [ "_module" ]; + options = builtins.removeAttrs options ([ ] + ++ (lib.optional (!includeModuleSystemOptions) "_module") + ++ (lib.optional (isNixos) "users")); transformOptions = opt: opt // { # Clean up declaration sites to not refer to the Home Manager @@ -80,7 +80,11 @@ let else decl) opt.declarations; }; - } // builtins.removeAttrs args [ "modules" "includeModuleSystemOptions" ]); + } // builtins.removeAttrs args [ + "modules" + "includeModuleSystemOptions" + "isNixos" + ]); hmOptionsDocs = buildOptionsDocs { modules = import ../modules/modules.nix { @@ -93,6 +97,7 @@ let nixosOptionsDocs = buildOptionsDocs { modules = [ ../nixos scrubbedPkgsModule dontCheckDefinitions ]; includeModuleSystemOptions = false; + isNixos = true; variablelistId = "nixos-options"; optionIdPrefix = "nixos-opt-"; }; @@ -100,6 +105,7 @@ let nixDarwinOptionsDocs = buildOptionsDocs { modules = [ ../nix-darwin scrubbedPkgsModule dontCheckDefinitions ]; includeModuleSystemOptions = false; + isNixos = true; variablelistId = "nix-darwin-options"; optionIdPrefix = "nix-darwin-opt-"; };