From 3363059b651fef3d315863a36f6bd8f1dffc3f76 Mon Sep 17 00:00:00 2001 From: technofab Date: Sun, 5 Oct 2025 15:14:16 +0200 Subject: [PATCH] feat: add utility functions for disko and module discovery/loading --- lib/default.nix | 85 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 84 insertions(+), 1 deletion(-) diff --git a/lib/default.nix b/lib/default.nix index 59ed19c..2f48264 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -1,5 +1,88 @@ -args: { +{lib, ...} @ args: let + inherit + (lib) + pipe + mapAttrs + flatten + hasSuffix + removeSuffix + removePrefix + splitString + setAttrByPath + fold + recursiveUpdate + ; +in rec { mkSystem = import ./mkSystem.nix args; mkHome = import ./mkHome.nix args; mkDisk = import ./mkDisk.nix args; + + # collects all disks from the cell, can be passed to disko.devices: + # + # disko.devices = utils.collectDisks cell.disks; + collectDisks = disks: + fold (acc: item: recursiveUpdate acc item) {} + (map (dev: builtins.removeAttrs dev.userConfig ["ren"]) + (builtins.attrValues disks)); + + # find modules/files in directory, return them all as a list of paths to import + findModules = { + dir, + currentFile ? "default.nix", + relative ? false, + }: let + processDir = subDir: first: + pipe "${dir}${subDir}" [ + builtins.readDir + (mapAttrs ( + n: v: let + p = + if relative + then "${subDir}/${n}" + else "${dir}${subDir}/${n}"; + in + if v == "directory" + then (processDir "${subDir}/${n}" false) + else + # filter out the current file to prevent recursive import + if first && n == currentFile + then [] + else p + )) + builtins.attrValues + flatten + (builtins.filter (path: hasSuffix ".nix" path)) + ]; + in + processDir "" true; + + # find, then import, then merge all modules in a dir + importModules = { + dir, + args ? {}, + currentFile ? "default.nix", + usePathAsKeys ? false, + }: let + allNixFiles = findModules { + inherit dir currentFile; + relative = true; + }; + + filePathToAttrPath = filePath: let + relativePath = removeSuffix ".nix" (removePrefix "/" filePath); + in + splitString "/" relativePath; + + importAndProcessFile = file: let + importedData = import "${dir}/${file}" args; + attrPath = filePathToAttrPath file; + in + if usePathAsKeys + then setAttrByPath attrPath importedData + else importedData; + + importedContents = map importAndProcessFile allNixFiles; + mergedFiles = fold (acc: item: recursiveUpdate acc item) {} importedContents; + in + mergedFiles; }