diff --git a/modules/aspects/dependencies.nix b/modules/aspects/dependencies.nix index 873f199..358d5ef 100644 --- a/modules/aspects/dependencies.nix +++ b/modules/aspects/dependencies.nix @@ -6,15 +6,11 @@ let inherit (den.lib) owned statics - parametric + take ; - inherit (den.lib.take) exactly; - dependencies = [ - (exactly osDependencies) - (exactly hmUserDependencies) - (exactly hmStandaloneDependencies) + (take.exactly osDependencies) ]; osDependencies = @@ -50,45 +46,6 @@ let ]; }; - # from OS home-managed integration. - hmUserDependencies = - { - OS-HM, - host, - user, - }: - let - inherit (OS-HM) OS HM; - context = { - inherit - OS - HM - user - host - ; - }; - in - { - includes = [ - (owned den.default) - (statics den.default) - (owned HM) - (statics HM) - (parametric.fixedTo context OS) - ]; - }; - - hmStandaloneDependencies = - { HM, home }: - den.lib.take.unused home { - includes = [ - (owned den.default) - (statics den.default) - (owned HM) - (statics HM) - ]; - }; - in { den.default.includes = dependencies; diff --git a/modules/aspects/provides/home-manager/hm-dependencies.nix b/modules/aspects/provides/home-manager/hm-dependencies.nix new file mode 100644 index 0000000..253c9dd --- /dev/null +++ b/modules/aspects/provides/home-manager/hm-dependencies.nix @@ -0,0 +1,45 @@ +{ + den, + ... +}: +let + inherit (den.lib) + owned + statics + parametric + take + ; + + dependencies = [ + (take.exactly hmUserDependencies) + (take.exactly hmStandaloneDependencies) + ]; + + # from OS home-managed integration. + hmUserDependencies = + { HM-OS-USER }: + { + includes = [ + (owned den.default) + (statics den.default) + (owned HM-OS-USER.HM) + (statics HM-OS-USER.HM) + (parametric.fixedTo HM-OS-USER HM-OS-USER.OS) + ]; + }; + + hmStandaloneDependencies = + { HM, home }: + take.unused home { + includes = [ + (owned den.default) + (statics den.default) + (owned HM) + (statics HM) + ]; + }; + +in +{ + den.default.includes = dependencies; +} diff --git a/modules/aspects/provides/home-manager.nix b/modules/aspects/provides/home-manager/hm-integration.nix similarity index 70% rename from modules/aspects/provides/home-manager.nix rename to modules/aspects/provides/home-manager/hm-integration.nix index bc68cca..5bef379 100644 --- a/modules/aspects/provides/home-manager.nix +++ b/modules/aspects/provides/home-manager/hm-integration.nix @@ -26,25 +26,28 @@ let ''; homeManager = - { OS, host }: - { class, aspect-chain }: + { HM-OS-HOST }: let + inherit (HM-OS-HOST) OS host; + hmClass = "homeManager"; hmUsers = builtins.filter (u: u.class == hmClass) (lib.attrValues host.users); hmUserModule = user: let - ctx = { - inherit aspect-chain; - class = hmClass; - }; HM = den.aspects.${user.aspect}; aspect = HM { - inherit host user; - OS-HM = { inherit OS HM; }; + HM-OS-USER = { + inherit + OS + HM + host + user + ; + }; }; - module = aspect.resolve ctx; + module = aspect.resolve { class = hmClass; }; in module; @@ -53,19 +56,14 @@ let value.imports = [ (hmUserModule user) ]; }) hmUsers; - hmModule = host.hm-module or inputs.home-manager."${class}Modules".home-manager; - aspect.${class} = { + hmModule = host.hm-module or inputs.home-manager."${host.class}Modules".home-manager; + aspect.${host.class} = { imports = [ hmModule ]; home-manager.users = lib.listToAttrs users; }; - supportedOS = builtins.elem class [ - "nixos" - "darwin" - ]; - enabled = supportedOS && builtins.length hmUsers > 0; in - if enabled then aspect else { }; + aspect; in { diff --git a/modules/aspects/provides/home-manager/hm-os-host.nix b/modules/aspects/provides/home-manager/hm-os-host.nix new file mode 100644 index 0000000..8ed56c3 --- /dev/null +++ b/modules/aspects/provides/home-manager/hm-os-host.nix @@ -0,0 +1,43 @@ +{ den, lib, ... }: +let + description = '' + This is a private aspect always included in den.default. + + This aspect detects hosts that have an HM supported OS and + that have at least one user with ${hm-class} class. + + When this occurs it produces a context `HM-OS-HOST` + that other host aspects can use. + + When the `den._.home-manager` aspect is enabled by the user, + it reacts to this context and configures HM on the host. + + This same context can be used by other aspects to configure + OS settings ONLY for hosts having HM enabled. + ''; + + hm-class = "homeManager"; + hm-os-classes = [ + "nixos" + "darwin" + ]; + + hm-detect = + { OS, host }: + let + is-os-supported = builtins.elem host.class hm-os-classes; + hm-users = builtins.filter (u: u.class == hm-class) (lib.attrValues host.users); + has-hm-users = builtins.length hm-users > 0; + is-hm-host = is-os-supported && has-hm-users; + ctx.HM-OS-HOST = { inherit OS host; }; + in + if is-hm-host then OS ctx else { }; + + aspect = { + inherit description; + __functor = _: den.lib.take.exactly hm-detect; + }; +in +{ + den.default.includes = [ aspect ]; +} diff --git a/templates/examples/modules/_example/ci/hm-enabled-host.nix b/templates/examples/modules/_example/ci/hm-enabled-host.nix new file mode 100644 index 0000000..7911c4c --- /dev/null +++ b/templates/examples/modules/_example/ci/hm-enabled-host.nix @@ -0,0 +1,29 @@ +{ den, inputs, ... }: +{ + # The `{ HM-OS-HOST }` context is activated ONLY for hosts that have + # a HM supported OS and at least one user with homeManager class. + den.aspects.hm-global-pkgs = + { HM-OS-HOST }: + den.lib.take.unused [ HM-OS-HOST.host ] # access host from context if needed + { + nixos.home-manager.useGlobalPkgs = true; + }; + + den.default.includes = [ den.aspects.hm-global-pkgs ]; + + den.hosts.x86_64-linux.no-homes = { }; + + perSystem = + { checkCond, rockhopper, ... }: + { + checks.rockhopper-hm-global-pkgs = checkCond "rockhopper-hm-global-pkgs" ( + rockhopper.config.home-manager.useGlobalPkgs + ); + + checks.no-homes-hm-global-pkgs = checkCond "no-homes-hm-global-pkgs" ( + # no home-manager enabled nor useGlobalPkgs + !inputs.self.nixosConfigurations.no-homes.config ? home-manager.useGlobalPkgs + ); + }; + +} diff --git a/templates/examples/modules/_example/ci/top-level-parametric.nix b/templates/examples/modules/_example/ci/top-level-parametric.nix index a4c2bf4..1bd0555 100644 --- a/templates/examples/modules/_example/ci/top-level-parametric.nix +++ b/templates/examples/modules/_example/ci/top-level-parametric.nix @@ -22,8 +22,11 @@ in homeManager.imports = [ (topLevel host.name) ]; }; - den.aspects.alice.includes = [ + den.aspects.rockhopper.includes = [ den.aspects.toplevel-host + ]; + + den.aspects.alice.includes = [ den.aspects.toplevel-user ];