2024-07-19 00:06:58 +02:00
|
|
|
{ lib, config, self, inputs, ... }:
|
|
|
|
|
|
|
|
let
|
2024-07-29 01:11:32 +02:00
|
|
|
inherit (config.lib)
|
2024-07-19 00:06:58 +02:00
|
|
|
eq
|
|
|
|
and
|
2024-07-24 23:45:23 +02:00
|
|
|
hasFiles
|
2024-07-25 00:25:21 +02:00
|
|
|
configuration-type-to-outputs-modules;
|
2024-07-19 00:06:58 +02:00
|
|
|
in
|
|
|
|
let
|
|
|
|
# Modules helpers
|
2024-07-25 00:25:21 +02:00
|
|
|
moduleTypes = ["nixos" "nix-on-droid" "nix-darwin" "home-manager" "flake"];
|
|
|
|
|
2024-07-29 00:35:14 +02:00
|
|
|
createModules = baseDir: { passthru ? { inherit inputs; }, ... }:
|
2024-07-19 00:06:58 +02:00
|
|
|
lib.pipe baseDir [
|
|
|
|
# Read given directory
|
|
|
|
builtins.readDir
|
|
|
|
# Map each entry to a module
|
|
|
|
(lib.mapAttrs'
|
|
|
|
(name: type:
|
|
|
|
let
|
2024-07-24 23:45:23 +02:00
|
|
|
# BUG: cannot use `append` because of `${self}` (not a path)
|
|
|
|
# moduleDir = lib.path.append baseDir "${name}";
|
|
|
|
moduleDir = "${baseDir}/${name}";
|
2024-07-19 00:06:58 +02:00
|
|
|
in
|
|
|
|
if and [
|
|
|
|
(type == "directory")
|
|
|
|
(hasFiles [ "default.nix" ] (builtins.readDir moduleDir))
|
|
|
|
] then
|
|
|
|
# Classic module in a directory
|
|
|
|
lib.nameValuePair
|
|
|
|
name
|
|
|
|
(import moduleDir)
|
|
|
|
else if and [
|
|
|
|
(type == "regular")
|
|
|
|
(lib.hasSuffix ".nix" name)
|
|
|
|
] then
|
|
|
|
# Classic module in a file
|
|
|
|
lib.nameValuePair
|
|
|
|
(lib.removeSuffix ".nix" name)
|
|
|
|
(import moduleDir)
|
|
|
|
else
|
|
|
|
# Invalid module
|
|
|
|
lib.nameValuePair
|
|
|
|
name
|
|
|
|
null))
|
|
|
|
# Filter invalid modules
|
|
|
|
(lib.filterAttrs
|
|
|
|
(moduleName: module:
|
|
|
|
module != null))
|
|
|
|
# Passthru if needed
|
|
|
|
(lib.mapAttrs
|
|
|
|
(moduleName: module:
|
|
|
|
if and [
|
|
|
|
(builtins.isFunction
|
|
|
|
module)
|
2024-07-29 00:35:14 +02:00
|
|
|
# FIXME: check for subset, not `eq`
|
2024-07-19 00:06:58 +02:00
|
|
|
(eq
|
|
|
|
(lib.pipe module [ builtins.functionArgs builtins.attrNames ])
|
|
|
|
(lib.pipe passthru [ builtins.attrNames ]))
|
|
|
|
]
|
|
|
|
then module passthru
|
|
|
|
else module))
|
|
|
|
];
|
|
|
|
in
|
|
|
|
{
|
2024-07-24 23:45:23 +02:00
|
|
|
options = let
|
|
|
|
inherit (lib) types;
|
|
|
|
in {
|
|
|
|
flake.autoModules = lib.mkOption {
|
|
|
|
description = ''
|
2024-07-25 00:25:21 +02:00
|
|
|
Automagically generate modules from walking directories with Nix files
|
2024-07-24 23:45:23 +02:00
|
|
|
'';
|
|
|
|
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;
|
2024-07-25 00:25:21 +02:00
|
|
|
default = "${submodule.config.baseDir}/${moduleType}";
|
2024-07-24 23:45:23 +02:00
|
|
|
};
|
2024-07-29 00:35:14 +02:00
|
|
|
result = lib.mkOption {
|
|
|
|
description = ''
|
|
|
|
The resulting automatic packages
|
|
|
|
'';
|
|
|
|
# TODO: specify
|
|
|
|
type = types.unspecified;
|
|
|
|
readOnly = true;
|
|
|
|
internal = true;
|
|
|
|
default =
|
|
|
|
lib.optionalAttrs
|
|
|
|
config.flake.autoModules.${moduleType}.enable
|
|
|
|
(createModules config.flake.autoModules.${moduleType}.dir { });
|
|
|
|
};
|
2024-07-24 23:45:23 +02:00
|
|
|
};
|
|
|
|
};
|
|
|
|
default = {};
|
|
|
|
})))
|
|
|
|
builtins.listToAttrs
|
|
|
|
]);
|
|
|
|
});
|
|
|
|
default = {};
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
config = {
|
|
|
|
flake = let
|
|
|
|
autoModules =
|
|
|
|
lib.pipe
|
|
|
|
moduleTypes
|
|
|
|
[
|
|
|
|
(builtins.map
|
|
|
|
(moduleType:
|
2024-07-29 00:35:14 +02:00
|
|
|
let
|
|
|
|
name = "${configuration-type-to-outputs-modules moduleType}";
|
|
|
|
value = config.flake.autoModules.${moduleType}.result;
|
|
|
|
in
|
|
|
|
lib.nameValuePair name value))
|
2024-07-24 23:45:23 +02:00
|
|
|
builtins.listToAttrs
|
|
|
|
];
|
2024-07-29 00:35:14 +02:00
|
|
|
in autoModules;
|
2024-07-19 00:06:58 +02:00
|
|
|
};
|
|
|
|
}
|