From c6432c7dab164693cb990cb1a7f4374bc8416747 Mon Sep 17 00:00:00 2001 From: reo101 Date: Thu, 25 Jul 2024 00:45:23 +0300 Subject: [PATCH] feat(modules)!: modularize over `machines` dir --- flake.nix | 2 ++ nix/modules.nix | 91 ++++++++++++++++++++++++++++++++++++++++++++----- nix/utils.nix | 20 +++++++++++ 3 files changed, 104 insertions(+), 9 deletions(-) diff --git a/flake.nix b/flake.nix index b7ef2fb..ece4207 100644 --- a/flake.nix +++ b/flake.nix @@ -172,6 +172,8 @@ flake = { inherit self; + autoModules.enableAll = true; + # Templates templates = import ./templates { inherit inputs; diff --git a/nix/modules.nix b/nix/modules.nix index 334e5e9..993a097 100644 --- a/nix/modules.nix +++ b/nix/modules.nix @@ -5,10 +5,12 @@ let inherit (import ./utils.nix { inherit lib self; }) eq and - hasFiles; + hasFiles + camelToKebab; in let # Modules helpers + moduleTypes = ["nixos" "nixOnDroid" "nixDarwin" "homeManager" "flake"]; createModules = baseDir: { passthru ? { inherit inputs outputs; }, ... }: lib.pipe baseDir [ # Read given directory @@ -17,7 +19,9 @@ let (lib.mapAttrs' (name: type: let - moduleDir = lib.path.append baseDir "${name}"; + # BUG: cannot use `append` because of `${self}` (not a path) + # moduleDir = lib.path.append baseDir "${name}"; + moduleDir = "${baseDir}/${name}"; in if and [ (type == "directory") @@ -59,12 +63,81 @@ let ]; in { - flake = { - # Modules - nixosModules = createModules ../modules/nixos { }; - nixOnDroidModules = createModules ../modules/nix-on-droid { }; - nixDarwinModules = createModules ../modules/nix-darwin { }; - homeManagerModules = createModules ../modules/home-manager { }; - flakeModules = createModules ../modules/flake { }; + options = let + inherit (lib) types; + in { + flake.autoModules = lib.mkOption { + description = '' + Automagivally generate modules from walking directories with Nix files + ''; + type = types.submodule (submodule: { + options = { + enableAll = lib.mkEnableOption "Automatic ${builtins.toString moduleTypes} modules extraction"; + baseDir = lib.mkOption { + description = '' + Base directory of the contained modules, used as a base for the rest of the options + ''; + type = types.path; + default = "${self}/modules"; + defaultText = ''''${self}/modules''; + }; + } // ( + lib.pipe + moduleTypes + [ + (builtins.map + # NOTE: create small submodule for every `moduleType` + (moduleType: + lib.nameValuePair + "${moduleType}" + (lib.mkOption { + type = types.submodule { + options = { + # NOTE: each can be enabled (default global `enableAll`) + enable = lib.mkEnableOption "Automatic ${moduleType} modules extraction" // { + default = submodule.config.enableAll; + }; + # NOTE: each can be read from a different directory + # (default global `baseDir` + `camelToKebab`-ed `moduleType`) + dir = lib.mkOption { + type = types.path; + default = "${submodule.config.baseDir}/${camelToKebab moduleType}"; + }; + }; + }; + default = {}; + }))) + builtins.listToAttrs + ]); + }); + default = {}; + }; + }; + + config = { + flake = let + autoModules = + lib.pipe + moduleTypes + [ + (builtins.map + (moduleType: + lib.nameValuePair + "${moduleType}Modules" + (if config.flake.autoModules.${moduleType}.enable + then createModules config.flake.autoModules.${moduleType}.dir { } + else { }))) + builtins.listToAttrs + ]; + in { + # NOTE: manually inheriting generated modules to avoid recursion + # (`autoModules` depends on `config.flake` itself) + inherit (autoModules) + nixosModules + nixOnDroidModules + nixDarwinModules + homeManagerModules + flakeModules; + }; }; } diff --git a/nix/utils.nix b/nix/utils.nix index b7ccf92..10b32c5 100644 --- a/nix/utils.nix +++ b/nix/utils.nix @@ -30,6 +30,26 @@ rec { # NOTE: Implying last argument is the output of `recurseDir` hasDirectories = allSatisfy lib.isAttrs; + camelToKebab = + lib.stringAsChars + (c: if c == lib.toUpper c then "-${lib.toLower c}" else c); + + # NOTE: from Tweag's Nix Hour 76 - + mutFirstChar = + f: s: + let + firstChar = f (lib.substring 0 1 s); + rest = lib.substring 1 (-1) s; + in firstChar + rest; + + kebabToCamel = + s: + mutFirstChar lib.toLower ( + lib.concatMapStrings (mutFirstChar lib.toUpper) ( + lib.splitString "-" s + ) + ); + gen-configuration-type-to = mappings: mkError: configuration-type: mappings.${configuration-type} or (builtins.throw