# Copyright Tom Hubrecht, (2023) # SPDX-FileCopyrightText: 2024 Tom Hubrecht # # SPDX-License-Identifier: EUPL-1.2 let # Reimplement optional functions _optional = default: b: value: if b then value else default; in rec { inherit (import ./nixpkgs.nix) flip hasPrefix recursiveUpdate splitString unique warn ; /* Fuses a list of attribute sets into a single attribute set. Type: [attrs] -> attrs Example: x = [ { a = 1; } { b = 2; } ] fuseAttrs x => { a = 1; b = 2; } */ fuseAttrs = builtins.foldl' (attrs: x: attrs // x) { }; fuseValueAttrs = attrs: fuseAttrs (builtins.attrValues attrs); /* Applies a function to `attrsList` before fusing the resulting list of attribute sets. Type: ('a -> attrs) -> ['a] -> attrs Example: x = [ "to" "ta" "ti" ] f = s: { ${s} = s + s; } mapFuse f x => { to = "toto"; ta = "tata"; ti = "titi"; } */ mapFuse = # 'a -> attrs f: # ['a] attrsList: fuseAttrs (builtins.map f attrsList); /* Equivalent of lib.singleton but for an attribute set. Type: str -> 'a -> attrs Example: singleAttr "a" 1 => { a = 1; } */ singleAttr = name: value: { ${name} = value; }; # Enables a list of modules. enableAttrs' = enable: mapFuse (m: { ${m}.${enable} = true; }); enableModules = enableAttrs' "enable"; /* Create an attribute set from a list of values, mapping those values through the function `f`. Example: mapSingleFuse (x: "val-${x}") [ "a" "b" ] => { a = "val-a"; b = "val-b" } */ mapSingleFuse = f: mapFuse (x: singleAttr x (f x)); /* Creates a relative path as a string Type: path -> str -> path Example: mkRel /home/test/ "file.txt" => "/home/test/file.txt" */ mkRel = path: file: path + "/${file}"; setDefault = default: mapFuse (name: { ${name} = default; }); mkBaseSecrets = root: mapFuse (secret: { ${secret}.file = mkRel root secret; }); getSecrets = dir: builtins.attrNames (import (mkRel dir "secrets.nix")); subAttr = attrs: name: attrs.${name}; subAttrs = attrs: builtins.map (subAttr attrs); optionalList = _optional [ ]; optionalAttrs = _optional { }; optionalString = _optional ""; /* Same as fuseAttrs but using `lib.recursiveUpdate` to merge attribute sets together. Type: [attrs] -> attrs */ recursiveFuse = builtins.foldl' recursiveUpdate { }; mkImport = root: file: let path = mkRel root file; in path + (optionalString (!(builtins.pathExists path)) ".nix"); mkImports = root: builtins.map (mkImport root); /* Creates a confugiration by merging enabled modules, services and extraConfig. Example: mkConfig { enabledModules = [ "ht-defaults" ]; enabledServices = [ "toto" ]; extraConfig = { services.nginx.enable = true; }; root = ./.; } => { imports = [ ./toto ]; ht-defaults.enable = true; services.nginx.enable = true; } */ mkConfig = { # List of modules to enable with `enableModules` enabledModules, # List of services to import enabledServices, # Extra configuration, defaults to `{ }` extraConfig ? { }, # Path relative to which the enabled services will be imported root, }: recursiveFuse [ (enableModules enabledModules) { imports = (extraConfig.imports or [ ]) ++ (mkImports root ([ "_hardware-configuration" ] ++ enabledServices)); } (removeAttrs extraConfig [ "imports" ]) ]; }