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
|
|
|
# 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
|
|
|
|
|
# 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 [];
|
|
|
|
|
|
2026-04-26 11:17:03 +02:00
|
|
|
# Partition profiles into known and unknown for assertion + safe import.
|
|
|
|
|
unknownProfiles = builtins.filter
|
|
|
|
|
(profileName: ! builtins.hasAttr profileName profileModuleMap)
|
|
|
|
|
profiles;
|
|
|
|
|
|
|
|
|
|
# Only import known profiles; the assertion below catches unknowns.
|
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
|
|
|
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}')";
|
|
|
|
|
}
|
2026-04-26 11:17:03 +02:00
|
|
|
{
|
|
|
|
|
assertion = unknownProfiles == [];
|
|
|
|
|
message =
|
|
|
|
|
"m3ta home: unknown profiles requested:"
|
|
|
|
|
+ " [ ${builtins.concatStringsSep " " unknownProfiles} ]."
|
|
|
|
|
+ " Valid profiles are:"
|
|
|
|
|
+ " [ ${builtins.concatStringsSep " " (builtins.attrNames profileModuleMap)} ]";
|
|
|
|
|
}
|
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
|
|
|
];
|
|
|
|
|
};
|
|
|
|
|
}
|