Nested modules
Is your feature request related to a problem? Please describe.
I would like to have modules nested like so:
modules/foo/bar/baz/
and
modules/foo/qux/baz/
and allow both to work
Describe the solution you'd like
Snowfall lib exports the modules under a string
outputs.nixosModules."modules/foo/bar/baz/"
outputs.nixosModules."modules/foo/qux/baz/"
This allows the simple use like:
myproject.foo.bar.baz.enable =true;
myproject.foo.qux.baz.enable =true;
Describe alternatives you've considered
Additional context
I have a proposal for this:
modules/nixos/module.nix maps to flake.nixosModules.module.nix, while modules/nixos/desktops/gnome.nix maps to flake.nixosModules.desktop.gnome and if a subdirectory exists with only default.nix, for example modules/nixos/gnome/default.nix it will just map to flake.nixosModules.gnome
@zimbatm what do you think of this?
Any update on this... i really miss this feature, if i fore example would want to modularize a neovim/hyprland config i want to make a sub directory for it
I too would like folder nesting simply for organisation. Currently I'm using prefixes
modules/home/profile-philip-cli.nix
modules/home/profile-philip-gui.nix
modules/home/unit-zsh.nix
modules/home/unit-tmux.nix
I then import the profile to my system config. That profile has all the imports grouped together. E.g. zsh & tmux imported into philip-cli. Then philip-cli imported into the user.
Snowfalls enable = true; does not come from the nesting. Each module can have an option definition to allow this. I don't think this differs with blueprint. Blueprint is enable by import not enable by enable. So you would have to create the option, import the module by its name, then enable it with the enable flag.
An example of snowfall-lib with enable option. This uses a namespace defined for the custom config options. Then each module specifies the option which enables it. The config is not enabled as it's behind an if statement to check the config option. This is how the enable = true is achieved with snowfall-lib.
{
lib,
config,
pkgs,
namespace,
...
}: let
inherit (lib) mkEnableOption mkIf;
cfg = config.${namespace}.cli-apps.zsh;
# user = config.${namespace}.user; # Depends on modules/home/user & mypkgs.user = enabled;
in {
options.${namespace}.cli-apps.zsh = {
enable = mkEnableOption "zsh";
};
config =
mkIf cfg.enable {
programs = {
zsh = {
enable = true;
# shellAliases = shellAliases;
oh-my-zsh = {
enable = true;
plugins = ["git" "sudo" "docker"];
theme = "robbyrussell";
};
initExtra = ''PS1="$(hostname) $PS1"'';
};
};
};
}
This approach, although looks cool, does add complexity. This caused me many issues of having to keep my cfg/options correct for each file that I made. It was difficult to trace from my host config to a particular module as the module is not specifically the same name as the option. This was quite powerful in letting me use custom options into modules just like you would with nixpkgs.
Blueprint is simpler and I like that. I don't have extra namespace/cfg/option code to manage in each and every module. I'm choosing to group modules with profile- and stack- prefixes so that I'm not doing 100s of imports per system/user.