diff --git a/flake-module.nix b/flake-module.nix index 21c3d5a..708b3fa 100644 --- a/flake-module.nix +++ b/flake-module.nix @@ -6,7 +6,9 @@ }: let cfg = config.nix-machine; - configurations = map (x: x.value) (lib.attrsets.attrsToList cfg.configurations); + parseConfig = import ./lib/parse-config.nix {inherit lib;}; + + configurations = map (x: x.value) (lib.attrsets.attrsToList (parseConfig cfg.configurations)); sharedOptions = lib.catAttrs "options" configurations; nixDarwinConfigurations = lib.catAttrs "nixDarwin" configurations; @@ -30,6 +32,14 @@ type = lib.types.deferredModule; default = {}; }; + path = lib.mkOption { + type = lib.types.nullOr lib.types.path; + default = null; + }; + scheme = lib.mkOption { + type = lib.types.nullOr lib.types.str; + default = null; + }; }; in { options.nix-machine.configurations = lib.mkOption { diff --git a/lib/parse-config.nix b/lib/parse-config.nix new file mode 100644 index 0000000..8b26020 --- /dev/null +++ b/lib/parse-config.nix @@ -0,0 +1,35 @@ +{lib, ...}: let + enumerateModules = basePath: fileName: let + inherit (builtins) readDir; + inherit (lib) attrNames filter filterAttrs pathExists foldl'; + inherit (lib.trivial) pipe; + + packagePaths = path: attrNames (filterAttrs (_: type: type == "directory") (readDir path)); + modulesInPackage = package: [package "${fileName}.nix"]; + renderPath = foldl' (path: elem: path + "/${elem}"); + + modules = pipe (packagePaths basePath) [ + (map modulesInPackage) + (map (renderPath basePath)) + (filter pathExists) + ]; + in + {...}: { + imports = modules; + }; + + importConfig = path: let + createModule = enumerateModules path; + in { + options = createModule "options"; + nixDarwin = createModule "darwin-module"; + homeManager = createModule "hm-module"; + }; + + # If a path is specified, + main = configuration: + if configuration.path != null && configuration.scheme == "flat" + then importConfig configuration.path + else configuration; +in + configurations: builtins.mapAttrs (c: v: main v) configurations