blueprint icon indicating copy to clipboard operation
blueprint copied to clipboard

Nested modules

Open IogaMaster opened this issue 1 year ago • 5 comments

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

IogaMaster avatar Dec 31 '24 19:12 IogaMaster

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

JumpIn-Git avatar Jan 20 '25 11:01 JumpIn-Git

@zimbatm what do you think of this?

JumpIn-Git avatar Feb 07 '25 19:02 JumpIn-Git

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

JumpIn-Git avatar Mar 15 '25 20:03 JumpIn-Git

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.

PhilipWhiteside avatar May 10 '25 09:05 PhilipWhiteside

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.

PhilipWhiteside avatar May 10 '25 09:05 PhilipWhiteside