diff --git a/flake.nix b/flake.nix index 0987782..f53b1a4 100644 --- a/flake.nix +++ b/flake.nix @@ -144,6 +144,7 @@ ]; imports = [ + ./modules/flake/lib.nix ./modules/flake/pkgs.nix ./modules/flake/modules.nix ./modules/flake/configurations.nix diff --git a/modules/flake/configurations.nix b/modules/flake/configurations.nix index bec3eee..12d0d41 100644 --- a/modules/flake/configurations.nix +++ b/modules/flake/configurations.nix @@ -1,7 +1,7 @@ { lib, config, self, inputs, withSystem, ... }: let - inherit (import ../../nix/utils.nix { inherit lib config self; }) + inherit (config.lib) and hasFiles hasDirectories diff --git a/modules/flake/deploy.nix b/modules/flake/deploy.nix index 5a8fc0f..859a0e6 100644 --- a/modules/flake/deploy.nix +++ b/modules/flake/deploy.nix @@ -1,7 +1,7 @@ { lib, config, self, inputs, ... }: let - inherit (import ../../nix/utils.nix { inherit lib config self; }) + inherit (config.lib) accumulateHosts configuration-type-to-deploy-type; in diff --git a/modules/flake/lib.nix b/modules/flake/lib.nix new file mode 100644 index 0000000..aede7bc --- /dev/null +++ b/modules/flake/lib.nix @@ -0,0 +1,159 @@ +{ lib, config, self, ... }: + +{ + options = let + inherit (lib) types; + in { + lib = lib.mkOption { + type = types.unspecified; + }; + }; + + config.lib = rec { + # Boolean helpers + and = lib.all lib.id; + or = lib.any lib.id; + eq = x: y: x == y; + + # Directory walking helpers + recurseDir = dir: + lib.mapAttrs + (file: type: + if type == "directory" + then recurseDir "${dir}/${file}" + else type) + (builtins.readDir dir); + + allSatisfy = predicate: attrs: attrset: + lib.all + (attr: + and [ + (builtins.hasAttr attr attrset) + (predicate (builtins.getAttr attr attrset)) + ]) + attrs; + + # NOTE: Implying last argument is the output of `recurseDir` + hasFiles = allSatisfy (eq "regular"); + + # 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: adapted 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 = lib.flip lib.pipe [ + (lib.splitString "-") + (lib.concatMapStrings + (mutFirstChar lib.toUpper)) + (mutFirstChar lib.toLower) + ]; + # 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 + (mkError configuration-type)); + + # TODO: abstract away `_Hosts` and `_Modules` + + configuration-type-to-outputs-hosts = + gen-configuration-type-to + { + nixos = "nixosHosts"; + nix-on-droid = "nixOnDroidHosts"; + nix-darwin = "darwinHosts"; + home-manager = "homeManagerHosts"; + } + (configuration-type: + builtins.throw + "Invaild configuration-type \"${configuration-type}\" for flake outputs' hosts"); + + configuration-type-to-outputs-modules = + gen-configuration-type-to + { + nixos = "nixosModules"; + nix-on-droid = "nixOnDroidModules"; + nix-darwin = "darwinModules"; + home-manager = "homeManagerModules"; + flake = "flakeModules"; + } + (configuration-type: + builtins.throw + "Invaild configuration-type \"${configuration-type}\" for flake outputs' modules"); + + configuration-type-to-outputs-configurations = + gen-configuration-type-to + { + nixos = "nixosConfigurations"; + nix-on-droid = "nixOnDroidConfigurations"; + nix-darwin = "darwinConfigurations"; + home-manager = "homeConfigurations"; + } + (configuration-type: + builtins.throw + "Invaild configuration-type \"${configuration-type}\" for flake outputs' configurations"); + + configuration-type-to-deploy-type = + gen-configuration-type-to + { + nixos = "nixos"; + nix-darwin = "darwin"; + } + (configuration-type: + builtins.throw + "Invaild configuration-type \"${configuration-type}\" for deploy-rs deployment"); + + accumulateHosts = configuration-types: host-system-configuration-type-configuration-fn: + lib.flip lib.concatMapAttrs + (lib.genAttrs + configuration-types + (configuration-type: + config.flake.autoConfigurations.${configuration-type}.resultHosts)) + (configuration-type: hosts: + lib.pipe + hosts + [ + # Filter out nondirectories + (lib.filterAttrs + (system: configurations: + builtins.isAttrs configurations)) + # Convert non-template configs into `system-and-config` pairs + (lib.concatMapAttrs + (system: configurations: + (lib.concatMapAttrs + (host: configuration: + lib.optionalAttrs + (host != "__template__") + { + ${host} = { + inherit system; + configuration = + let + configurations = configuration-type-to-outputs-configurations configuration-type; + in + self.${configurations}.${host}; + }; + }) + configurations))) + # Convert each `system-and-config` pair into a *whatever* + (lib.concatMapAttrs + (host: { system, configuration }: + host-system-configuration-type-configuration-fn { inherit host system configuration-type configuration; })) + ]); + }; +} diff --git a/modules/flake/modules.nix b/modules/flake/modules.nix index 04997a6..098b792 100644 --- a/modules/flake/modules.nix +++ b/modules/flake/modules.nix @@ -1,7 +1,7 @@ { lib, config, self, inputs, ... }: let - inherit (import ../../nix/utils.nix { inherit lib config self; }) + inherit (config.lib) eq and hasFiles diff --git a/modules/flake/packages/default.nix b/modules/flake/packages/default.nix index eafcee5..6734ecd 100644 --- a/modules/flake/packages/default.nix +++ b/modules/flake/packages/default.nix @@ -1,7 +1,7 @@ { lib, config, self, inputs, ... }: let - inherit (import ../../../nix/utils.nix { inherit lib config self; }) + inherit (config.lib) eq and hasFiles; diff --git a/nix/utils.nix b/nix/utils.nix deleted file mode 100644 index 9cf5f85..0000000 --- a/nix/utils.nix +++ /dev/null @@ -1,144 +0,0 @@ -{ lib, config, self, ... }: - -rec { - # Boolean helpers - and = lib.all lib.id; - or = lib.any lib.id; - eq = x: y: x == y; - - # Directory walking helpers - recurseDir = dir: - lib.mapAttrs - (file: type: - if type == "directory" - then recurseDir "${dir}/${file}" - else type) - (builtins.readDir dir); - - allSatisfy = predicate: attrs: attrset: - lib.all - (attr: - and [ - (builtins.hasAttr attr attrset) - (predicate (builtins.getAttr attr attrset)) - ]) - attrs; - - # NOTE: Implying last argument is the output of `recurseDir` - hasFiles = allSatisfy (eq "regular"); - - # 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 - (mkError configuration-type)); - - # TODO: abstract away `_Hosts` and `_Modules` - - configuration-type-to-outputs-hosts = - gen-configuration-type-to - { - nixos = "nixosHosts"; - nix-on-droid = "nixOnDroidHosts"; - nix-darwin = "darwinHosts"; - home-manager = "homeManagerHosts"; - } - (configuration-type: - builtins.throw - "Invaild configuration-type \"${configuration-type}\" for flake outputs' hosts"); - - configuration-type-to-outputs-modules = - gen-configuration-type-to - { - nixos = "nixosModules"; - nix-on-droid = "nixOnDroidModules"; - nix-darwin = "darwinModules"; - home-manager = "homeManagerModules"; - flake = "flakeModules"; - } - (configuration-type: - builtins.throw - "Invaild configuration-type \"${configuration-type}\" for flake outputs' modules"); - - configuration-type-to-outputs-configurations = - gen-configuration-type-to - { - nixos = "nixosConfigurations"; - nix-on-droid = "nixOnDroidConfigurations"; - nix-darwin = "darwinConfigurations"; - home-manager = "homeConfigurations"; - } - (configuration-type: - builtins.throw - "Invaild configuration-type \"${configuration-type}\" for flake outputs' configurations"); - - configuration-type-to-deploy-type = - gen-configuration-type-to - { - nixos = "nixos"; - nix-darwin = "darwin"; - } - (configuration-type: - builtins.throw - "Invaild configuration-type \"${configuration-type}\" for deploy-rs deployment"); - - accumulateHosts = configuration-types: host-system-configuration-type-configuration-fn: - lib.flip lib.concatMapAttrs - (lib.genAttrs - configuration-types - (configuration-type: - config.flake.autoConfigurations.${configuration-type}.resultHosts)) - (configuration-type: hosts: - lib.pipe - hosts - [ - # Filter out nondirectories - (lib.filterAttrs - (system: configurations: - builtins.isAttrs configurations)) - # Convert non-template configs into `system-and-config` pairs - (lib.concatMapAttrs - (system: configurations: - (lib.concatMapAttrs - (host: configuration: - lib.optionalAttrs - (host != "__template__") - { - ${host} = { - inherit system; - configuration = - let - configurations = configuration-type-to-outputs-configurations configuration-type; - in - self.${configurations}.${host}; - }; - }) - configurations))) - # Convert each `system-and-config` pair into a *whatever* - (lib.concatMapAttrs - (host: { system, configuration }: - host-system-configuration-type-configuration-fn { inherit host system configuration-type configuration; })) - ]); -}