Files
m3ta-home/lib/mkHome.nix

109 lines
3.3 KiB
Nix

# lib/mkHome.nix — Compose a complete home-manager configuration.
#
# This is the central function that replaces the old mkHomeConfig from nixos-config.
# It assembles imports based on three dimensions:
#
# WHO you are → user + identity (preferences + git/ssh/jj config)
# WHAT you do → context (desktop|server) + sets (coding, gaming, media)
# WHERE you are → host (handled by nixos-config, only overrides here)
#
# Usage:
# imports = [ (m3ta-lib.mkHome {
# user = "m3tam3re";
# identity = "private"; # or "work"
# context = "desktop"; # or "server"
# sets = [ "coding" "gaming" "media" ];
# }) ];
#
# Then override host-specific settings in the consuming module:
# m3ta.home.sets.coding.languages.python.extra = true;
# wayland.windowManager.hyprland.settings.monitor = [ ... ];
#
{inputs, selfPath}: let
lib = inputs.nixpkgs.lib;
in {
mkHome = {
user ? "m3tam3re",
identity ? "private",
context ? null,
sets ? [],
}: let
# --- Module path helpers ---
profilePath = ../profiles;
userPath = ../users;
# Always loaded — CLI tools, shell, secrets, overlays
baseModule = "${profilePath}/base";
# Context modules — mutually exclusive (desktop or server)
contextModuleMap = {
desktop = "${profilePath}/contexts/desktop";
server = "${profilePath}/contexts/server";
};
# Feature sets — freely combinable, some have context guards
setModuleMap = {
coding = "${profilePath}/sets/coding";
gaming = "${profilePath}/sets/gaming";
media = "${profilePath}/sets/media";
};
# Sets that require desktop context
desktopOnlySets = ["gaming" "media"];
# User preferences — always loaded (shell style, editor config, etc.)
preferencesPath = "${userPath}/${user}/preferences";
# Identity — git name/email, SSH match blocks, jj config
identityPath = "${userPath}/${user}/identities/${identity}.nix";
# Resolve context module
contextImport =
if context == null
then []
else if builtins.hasAttr context contextModuleMap
then [contextModuleMap.${context}]
else throw "m3ta-home: unknown context '${context}'. Valid: desktop, server";
# Resolve set modules
setImports =
map
(s:
if builtins.hasAttr s setModuleMap
then setModuleMap.${s}
else throw "m3ta-home: unknown set '${s}'. Valid: ${lib.concatStringsSep ", " (builtins.attrNames setModuleMap)}")
sets;
# Validation: desktop-only sets
usedDesktopOnlySets =
builtins.filter (s: builtins.elem s desktopOnlySets) sets;
in {
imports =
[
# Paths module — must be first, provides m3taHome.paths.srcRoot
../modules/paths.nix
baseModule
preferencesPath
identityPath
]
++ contextImport
++ setImports;
# Set the flake source root for asset path resolution
"m3ta-home".paths.srcRoot = selfPath;
assertions =
[
{
assertion = builtins.elem context ["desktop" "server" null];
message = "m3ta-home: context must be 'desktop', 'server', or null (got: '${toString context}')";
}
]
++ map (s: {
assertion = context == "desktop";
message = "m3ta-home: set '${s}' requires context = 'desktop'";
})
usedDesktopOnlySets;
};
}