Files
nixos-config/home/lib/default.nix
m3tm3re f3749c5679 feat: implement profile system with mkHomeConfig and context constraints
- Add home/lib/default.nix with mkHomeConfig utility
  - Loads base + common modules always
  - Maps profiles (coding, gaming, media) to module imports
  - Enforces desktop/server mutual exclusion via assertion
  - Context must be 'desktop', 'server', or null

- Migrate all per-host home configs to new profile system
  - m3-ares: context=desktop, profiles=[coding, gaming, media]
  - m3-kratos: context=desktop, profiles=[coding, gaming, media]
  - m3-atlas: context=server, profiles=[coding]
  - m3-helios: context=server, profiles=[]
  - m3-hermes: context=server, profiles=[]
  - m3-aether: context=server, profiles=[]
  - m3-daedalus: context=desktop, profiles=[coding, media]

- Replace features.* options with new namespaces:
  - features.cli.* -> base.shell.* / base.cliTools.* / base.secrets
  - features.desktop.* -> desktop.wm.* / desktop.apps.* / desktop.theme.*
  - gaming/media moved to profiles.gaming.* / profiles.media.*

- Fix home/coding/editor/neovim.nix: remove duplicate option declaration
  (coding.editors.neovim.enable already declared by m3ta-nixpkgs)

- Fix home/coding/lsp/servers.nix: replace removed nodePackages.typescript-language-server
  with typescript-language-server

- Fix home/desktop/theme/wallpapers.nix: correct relative path
  (was ../../.. which resolved to project root, should be ../..)
2026-04-26 11:03:43 +02:00

82 lines
2.2 KiB
Nix

# home/lib/default.nix
# Profile loading utilities for home-manager configurations.
#
# Usage:
# let homeLib = import ../lib { inherit lib; };
# in {
# imports = [
# (homeLib.mkHomeConfig { profiles = ["coding" "gaming"]; context = "desktop"; })
# ];
# }
{ lib }:
let
inherit (lib) optional;
# Infrastructure layer — nixpkgs overlays, nix-colors, m3ta-nixpkgs modules.
# Always loaded on every host.
commonModule = ../common;
# Base user environment — shell (nushell, starship), CLI tools, secrets.
# Always loaded on every host.
baseModule = ../base;
# Context-specific modules — desktop and server are mutually exclusive.
contextModuleMap = {
desktop = ../desktop;
server = ../server;
};
# Profile modules — freely combinable additions on top of base + context.
profileModuleMap = {
coding = ../coding;
gaming = ../profiles/gaming;
media = ../profiles/media;
};
in {
# Generate a home-manager module with imports based on profiles and context.
#
# Args:
# profiles: list of profile names (e.g. ["coding" "gaming" "media"])
# context: host context, one of "desktop" | "server" | null
#
# Returns: a home-manager module attrset with imports and assertions.
# Desktop and server contexts are mutually exclusive by design — passing
# any value other than "desktop", "server", or null causes an assertion
# failure at evaluation time.
mkHomeConfig = {
profiles ? [],
context ? null,
}:
let
contextImport =
if context == "desktop" then [ contextModuleMap.desktop ]
else if context == "server" then [ contextModuleMap.server ]
else [];
activeProfiles = builtins.filter
(profileName: builtins.hasAttr profileName profileModuleMap)
profiles;
profileImports = map (profileName: profileModuleMap.${profileName}) activeProfiles;
contextStr = if context == null then "null" else context;
in {
imports =
[ commonModule baseModule ]
++ contextImport
++ profileImports;
assertions = [
{
assertion = builtins.elem context [ "desktop" "server" null ];
message =
"m3ta home: context must be 'desktop', 'server', or null"
+ " (got: '${contextStr}')";
}
];
};
}