Files
nix-meow/lib.nix
2025-10-15 19:27:05 +00:00

205 lines
5.6 KiB
Nix

{
nixpkgs,
home-manager,
hostsFolder,
hardwaresFolder,
modulesFolder,
inputs,
globalConfig ? { },
globalOverlays ? [ ],
defaultUser ? "meow",
}:
let
inherit (nixpkgs) lib;
self = rec {
inherit
hostsFolder
hardwaresFolder
modulesFolder
globalConfig
globalOverlays
;
moduleList = builtins.attrNames (builtins.readDir modulesFolder);
mergedModules = mergeModules ((map (fn: (import "${modulesFolder}/${fn}" { })) moduleList));
generateHostname =
{
hostName,
hardwareName,
system,
}:
"${hardwareName}-${hostName}-${system}";
mkHost =
{
host,
hardware,
system,
stateVersion,
overlays ? [ ],
nixpkgsConfig ? { },
nixpkgsHostPlatform ? null,
user ? defaultUser,
}:
let
hostSystemConfig = "${hostsFolder}/${host}/nixos.nix";
hardwareSystemConfig = "${hardwaresFolder}/${hardware}/nixos.nix";
hostHomeConfig = "${hostsFolder}/${host}/home.nix";
hardwareHomeConfig = "${hardwaresFolder}/${hardware}/home.nix";
hostSystemExists = builtins.pathExists hostSystemConfig;
hardwareSystemExists = builtins.pathExists hardwareSystemConfig;
hostHomeExists = builtins.pathExists hostHomeConfig;
hardwareHomeExists = builtins.pathExists hardwareHomeConfig;
hasNixos = hostSystemExists || hardwareSystemExists;
hasHome = hostHomeExists || hardwareHomeExists;
importIfExists = path: if builtins.pathExists path then [ (import path) ] else [ ];
nixosModules =
(importIfExists hostSystemConfig) ++ (importIfExists hardwareSystemConfig) ++ mergedModules.nixos;
homeModules =
(importIfExists hostHomeConfig) ++ (importIfExists hardwareHomeConfig) ++ mergedModules.home;
hostname = generateHostname {
hostName = host;
hardwareName = hardware;
inherit system;
};
extraArgs = {
inherit inputs;
hostname = "${hardware}-${host}";
nix-meow = self;
};
mergedNixpkgsConfig = deepMerge [
globalConfig
nixpkgsConfig
];
mergedOverlays = overlays ++ globalOverlays;
nixosConfigurations = lib.optionalAttrs hasNixos {
${hostname} = nixpkgs.lib.nixosSystem {
specialArgs = extraArgs // {
inherit user system;
installer = false;
};
inherit system;
modules = [
{
nixpkgs.config = mergedNixpkgsConfig;
nixpkgs.overlays = mergedOverlays;
}
]
++ nixosModules;
};
};
homeConfigurations = lib.optionalAttrs hasHome {
${hostname} = home-manager.lib.homeManagerConfiguration {
pkgs = import nixpkgs {
inherit system;
config = mergedNixpkgsConfig;
overlays = mergedOverlays;
};
extraSpecialArgs = extraArgs // {
inherit system user;
};
modules = homeModules;
};
};
in
{
debug.${hostname} = {
inherit
host
hardware
system
stateVersion
hostSystemConfig
hardwareSystemConfig
hostHomeConfig
hardwareHomeConfig
hostSystemExists
hardwareSystemExists
hostHomeExists
hardwareHomeExists
hasNixos
hasHome
hostname
;
};
inherit nixosConfigurations homeConfigurations;
};
mergeHosts =
{ hosts, hardwares }:
let
inherit (builtins)
attrNames
map
filter
concatMap
removeAttrs
elem
;
hostNames = attrNames hosts;
hardwareNames = attrNames hardwares;
in
concatMap (
hostName:
let
hostAttrs = hosts.${hostName};
hostNoSystems = removeAttrs hostAttrs [ "systems" ];
hostSystems = hostAttrs.systems;
in
concatMap (
system:
let
matchingHardwares = filter (
hardwareName: elem system hardwares.${hardwareName}.systems
) hardwareNames;
in
map (hardwareName: {
hardware = removeAttrs hardwares.${hardwareName} [ "systems" ];
host = hostNoSystems;
inherit system hardwareName hostName;
}) matchingHardwares
) hostSystems
) hostNames;
deepMergeInner =
a: b:
builtins.foldl' (
merged: key:
merged
// {
${key} =
if (a ? ${key}) && (b ? ${key}) && (builtins.isAttrs a.${key}) && (builtins.isAttrs b.${key}) then
deepMergeInner a.${key} b.${key}
else if
(a ? ${key}) && (b ? ${key}) && (builtins.isList a.${key}) && (builtins.isList b.${key})
then
a.${key} ++ b.${key}
else
b.${key} or a.${key};
}
) { } (builtins.attrNames (a // b));
deepMerge = sets: builtins.foldl' deepMergeInner { } sets;
mergeModules =
modules:
let
mergedModules = builtins.mapAttrs (name: module: {
nixos = if builtins.hasAttr "nixos" module then [ module.nixos ] else [ ];
home = if builtins.hasAttr "home" module then [ module.home ] else [ ];
}) modules;
in
deepMerge mergedModules;
};
in
self