- 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 ../..)
82 lines
2.2 KiB
Nix
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}')";
|
|
}
|
|
];
|
|
};
|
|
}
|