1
0
Fork 0
mirror of https://github.com/nix-community/home-manager.git synced 2025-11-08 19:46:05 +01:00

nixos-module: Fix potential recursion between users.users and home-manager.users (#6622)

Pushing users.users.<name>.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

* 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.
This commit is contained in:
Proesmans Bert 2025-03-31 16:19:52 +02:00 committed by GitHub
parent b6fd653ef8
commit 216690777e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 19 additions and 9 deletions

View file

@ -54,17 +54,17 @@ let
hmPath = toString ./..; hmPath = toString ./..;
buildOptionsDocs = args@{ modules, includeModuleSystemOptions ? true, ... }: buildOptionsDocs =
args@{ modules, includeModuleSystemOptions ? true, isNixos ? false, ... }:
let let
options = (lib.evalModules { options = (lib.evalModules {
inherit modules; inherit modules;
class = "homeManager"; class = "homeManager";
}).options; }).options;
in pkgs.buildPackages.nixosOptionsDoc ({ in pkgs.buildPackages.nixosOptionsDoc ({
options = if includeModuleSystemOptions then options = builtins.removeAttrs options ([ ]
options ++ (lib.optional (!includeModuleSystemOptions) "_module")
else ++ (lib.optional (isNixos) "users"));
builtins.removeAttrs options [ "_module" ];
transformOptions = opt: transformOptions = opt:
opt // { opt // {
# Clean up declaration sites to not refer to the Home Manager # Clean up declaration sites to not refer to the Home Manager
@ -80,7 +80,11 @@ let
else else
decl) opt.declarations; decl) opt.declarations;
}; };
} // builtins.removeAttrs args [ "modules" "includeModuleSystemOptions" ]); } // builtins.removeAttrs args [
"modules"
"includeModuleSystemOptions"
"isNixos"
]);
hmOptionsDocs = buildOptionsDocs { hmOptionsDocs = buildOptionsDocs {
modules = import ../modules/modules.nix { modules = import ../modules/modules.nix {
@ -93,6 +97,7 @@ let
nixosOptionsDocs = buildOptionsDocs { nixosOptionsDocs = buildOptionsDocs {
modules = [ ../nixos scrubbedPkgsModule dontCheckDefinitions ]; modules = [ ../nixos scrubbedPkgsModule dontCheckDefinitions ];
includeModuleSystemOptions = false; includeModuleSystemOptions = false;
isNixos = true;
variablelistId = "nixos-options"; variablelistId = "nixos-options";
optionIdPrefix = "nixos-opt-"; optionIdPrefix = "nixos-opt-";
}; };
@ -100,6 +105,7 @@ let
nixDarwinOptionsDocs = buildOptionsDocs { nixDarwinOptionsDocs = buildOptionsDocs {
modules = [ ../nix-darwin scrubbedPkgsModule dontCheckDefinitions ]; modules = [ ../nix-darwin scrubbedPkgsModule dontCheckDefinitions ];
includeModuleSystemOptions = false; includeModuleSystemOptions = false;
isNixos = true;
variablelistId = "nix-darwin-options"; variablelistId = "nix-darwin-options";
optionIdPrefix = "nix-darwin-opt-"; optionIdPrefix = "nix-darwin-opt-";
}; };

View file

@ -50,6 +50,13 @@ let
}; };
in { 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 = { options.home-manager = {
useUserPackages = mkEnableOption '' useUserPackages = mkEnableOption ''
installation of user packages through the installation of user packages through the
@ -104,10 +111,7 @@ in {
}; };
config = (lib.mkMerge [ config = (lib.mkMerge [
# Fix potential recursion when configuring home-manager users based on values in users.users #594
(mkIf (cfg.useUserPackages && cfg.users != { }) { (mkIf (cfg.useUserPackages && cfg.users != { }) {
users.users = (lib.mapAttrs
(_username: usercfg: { packages = [ usercfg.home.path ]; }) cfg.users);
environment.pathsToLink = [ "/etc/profile.d" ]; environment.pathsToLink = [ "/etc/profile.d" ];
}) })
(mkIf (cfg.users != { }) { (mkIf (cfg.users != { }) {