# Copyright Tom Hubrecht, (2023) # # Tom Hubrecht # # This software is governed by the CeCILL license under French law and # abiding by the rules of distribution of free software. You can use, # modify and/ or redistribute the software under the terms of the CeCILL # license as circulated by CEA, CNRS and INRIA at the following URL # "http://www.cecill.info". # # As a counterpart to the access to the source code and rights to copy, # modify and redistribute granted by the license, users are provided only # with a limited warranty and the software's author, the holder of the # economic rights, and the successive licensors have only limited # liability. # # In this respect, the user's attention is drawn to the risks associated # with loading, using, modifying and/or developing or reproducing the # software by the user in light of its specific status of free software, # that may mean that it is complicated to manipulate, and that also # therefore means that it is reserved for developers and experienced # professionals having in-depth computer knowledge. Users are therefore # encouraged to load and test the software's suitability as regards their # requirements in conditions enabling the security of their systems and/or # data to be ensured and, more generally, to use and operate it in the # same conditions as regards security. # # The fact that you are presently reading this means that you have had # knowledge of the CeCILL license and that you accept its terms. 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 ; /* 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" ]) ]; }