diff --git a/README.md b/README.md index fd355d2..a6e4cee 100644 --- a/README.md +++ b/README.md @@ -52,6 +52,7 @@ Parts of this flake were inspired by the likes of: - [isabelroses](https://github.com/isabelroses) - [uncenter](https://github.com/uncenter) +- [xaiyadev](https://github.com/xaiyadev) and documentations such as: diff --git a/flake.nix b/flake.nix index 27d4c2e..82baf98 100644 --- a/flake.nix +++ b/flake.nix @@ -7,6 +7,7 @@ "nix-command" ]; extra-substituters = [ + "https://cache.nixos.org" "https://nix-community.cachix.org" ]; extra-trusted-public-keys = [ diff --git a/homes/nixos/jo/default.nix b/homes/nixos/jo/default.nix new file mode 100644 index 0000000..18cc357 --- /dev/null +++ b/homes/nixos/jo/default.nix @@ -0,0 +1,3 @@ +{ ... }: { + home.stateVersion = "25.05"; +} diff --git a/lib/module/default.nix b/lib/module/default.nix index d3efe74..3d52e9d 100644 --- a/lib/module/default.nix +++ b/lib/module/default.nix @@ -1,4 +1,4 @@ -{lib, ...}: { +{ lib, self, ... }: { # Create a NixOS module option on a single line. mkOpt = type: default: description: lib.mkOption {inherit type default description;}; @@ -9,5 +9,21 @@ type = lib.types.bool; }; - # Todo: add mkIfElse function + # Create a module compliant with the NixOS module system. + mkModule = + { + name ? "puzzlevision", + class, + modules, + }: { + _class = class; + + # Template: "[path-to-flake]/flake.nix#[class-name]Modules.[module-name]" + # Example: "[path-to-flake]/flake.nix#nixosModules.system.audio" + _file = "${self.outPath}/flake.nix#${class}Modules.${name}"; + + imports = modules; + }; + + # TODO: add mkIfElse function } diff --git a/modules/flake/arguments.nix b/modules/flake/arguments.nix deleted file mode 100644 index 048ef80..0000000 --- a/modules/flake/arguments.nix +++ /dev/null @@ -1,6 +0,0 @@ -{config, ...}: { - # Apply some useful module arguments. - _module.args = { - namespace = config.flake.namespace; - }; -} diff --git a/modules/flake/default.nix b/modules/flake/default.nix index bf5047b..fb9d01d 100644 --- a/modules/flake/default.nix +++ b/modules/flake/default.nix @@ -1,18 +1,18 @@ { imports = [ - # Applies some useful arguments, like namespace, to all flake modules. - ./arguments.nix + # Exposes nixosModules and homeModules on flake outputs. + ./modules.nix - # Automagically imports libs from "/lib/lib-name" and applies them to the `lib.${namespace}` or `puzzlevision.lib` module argument. + # Automagically imports libs from "/lib/lib-name" and exposes them to the `flake.lib` output. ./lib.nix - # Recursively imports overlays from "/overlays/overlay-name" and applies them to the `pkgs` or `puzzlevision.pkgs` module argument. - # ./overlays.nix + # Recursively imports overlays from "/overlays/overlay-name" and exposes them to the `flake.overlays` output. + #./overlays.nix # Automagically imports systems from "/systems/arch-classname/system-name". ./systems.nix # Automagically imports homes from "/homes/user-name". - ./homes.nix + #./homes.nix ]; } diff --git a/modules/flake/homes.nix b/modules/flake/homes.nix deleted file mode 100644 index 20cfc34..0000000 --- a/modules/flake/homes.nix +++ /dev/null @@ -1,22 +0,0 @@ -{ - lib, - inputs, - puzzlelib, - ... -}: let - HomeConfiguration = args: let - nixpkgs = inputs.nixpkgs; - in - inputs.home-manager.lib.homeManagerConfiguration { - modules = (puzzlelib.dirToModuleList ../home) ++ args.modules; - extraSpecialArgs = - { - inherit (args) nixpkgs; - } - // args.extraSpecialArgs; - }; -in { - perSystem = { - # TODO Dynamically export homeConfigurations by consuming contents of /homes/user-name - }; -} diff --git a/modules/flake/lib.nix b/modules/flake/lib.nix index d034d57..88c442a 100644 --- a/modules/flake/lib.nix +++ b/modules/flake/lib.nix @@ -1,6 +1,6 @@ { lib, - puzzlelib, + self, ... }: let # Utility function to read a directory and return its contents. @@ -41,10 +41,9 @@ # Files return attribute sets with their resulting expressions, directories return the result of multiple file handling operations. acc // (filesystemEntityToAttrSet directory importArgs name (builtins.getAttr name readDir)) ) {} (builtins.attrNames readDir); + + puzzlelib = dirToAttrSet ../../lib {inherit lib self;} // {inherit dirToAttrSet dirToModuleList filesystemEntityToList filesystemEntityToAttrSet;}; in { - # Add lib.${namespace} attribute to module arguments, for easy access. - # Additionally, pass on dirToAttrSet method on lib.${namespace} for reusability in other modules. - _module.args = { - puzzlelib = dirToAttrSet ../../lib {inherit lib puzzlelib;} // {inherit dirToAttrSet dirToModuleList filesystemEntityToList filesystemEntityToAttrSet;}; - }; + # Expose custom library on flake "lib" output + flake.lib = puzzlelib; } diff --git a/modules/flake/modules.nix b/modules/flake/modules.nix new file mode 100644 index 0000000..9c3c01b --- /dev/null +++ b/modules/flake/modules.nix @@ -0,0 +1,14 @@ +{ self, ... }: +{ + flake = { + nixosModules.puzzlevision = self.lib.mkModule { + class = "nixos"; + modules = self.lib.dirToModuleList ../nixos; + }; + + homeModules.puzzlevision = self.lib.mkModule { + class = "home"; + modules = self.lib.dirToModuleList ../home; + }; + }; +} diff --git a/modules/flake/systems.nix b/modules/flake/systems.nix index 208a4b1..b0198bb 100644 --- a/modules/flake/systems.nix +++ b/modules/flake/systems.nix @@ -1,28 +1,21 @@ { lib, inputs, - namespace, - puzzlelib, + self, ... }: { - imports = [inputs.easy-hosts.flakeModule]; + imports = [ inputs.easy-hosts.flakeModule ]; easyHosts = { autoConstruct = true; path = ../../systems; - shared = { - specialArgs = { - inherit namespace puzzlelib; - }; - }; - perClass = class: { modules = (lib.optionals (class == "nixos") [ inputs.home-manager.nixosModules.default ]) - ++ (puzzlelib.dirToModuleList ../${class}); # Import modules based on current classname. + ++ (self.lib.dirToModuleList ../${class}); # Import modules based on current classname. }; }; } diff --git a/modules/home/desktop/gnome.nix b/modules/home/desktop/gnome.nix deleted file mode 100644 index ca6176e..0000000 --- a/modules/home/desktop/gnome.nix +++ /dev/null @@ -1,2 +0,0 @@ -{}: { -} diff --git a/modules/home/desktop/gnome/default.nix b/modules/home/desktop/gnome/default.nix new file mode 100644 index 0000000..5d29baf --- /dev/null +++ b/modules/home/desktop/gnome/default.nix @@ -0,0 +1,33 @@ +{ + lib, + pkgs, + self, + config, + osConfig, + ... +}: let + inherit (lib) mkIf mkOption; + inherit (self) namespace; + + cfg = config.${namespace}.desktop.gnome; +in { + options.${namespace}.desktop.gnome = with lib.types; { + enabled-extensions = mkOption { + type = listOf package; + default = with pkgs.gnomeExtensions; [dash-to-dock user-themes blur-my-shell appindicator unite color-picker clipboard-history]; + example = [dash-to-dock blur-my-shell]; + description = "Specify gnome extensions to install."; + }; + }; + + config = mkIf osConfig.${namespace}.desktop.gnome.enable { + home.packages = cfg.enabled-extensions; + + dconf.settings = { + "org/gnome/shell" = { + enabled-extensions = lib.forEach cfg.enabled-extensions (x: x.extensionUuid); + disabled-extensions = []; # Make sure none of our extensions are disabled on system rebuild + }; + }; + }; +} diff --git a/modules/nixos/desktop/gnome/default.nix b/modules/nixos/desktop/gnome/default.nix index a9e88f0..d2432b5 100644 --- a/modules/nixos/desktop/gnome/default.nix +++ b/modules/nixos/desktop/gnome/default.nix @@ -1,10 +1,12 @@ { lib, config, - namespace, + self, ... }: let inherit (lib) mkEnableOption mkIf; + inherit (self) namespace; + cfg = config.${namespace}.desktop.gnome; in { options.${namespace}.desktop.gnome = {enable = mkEnableOption "Enable the gnome desktop environment ${namespace}";}; diff --git a/modules/nixos/users/default.nix b/modules/nixos/users/default.nix new file mode 100644 index 0000000..71988ce --- /dev/null +++ b/modules/nixos/users/default.nix @@ -0,0 +1,86 @@ +{ + lib, + config, + self, + ... +}: let + inherit (lib) mkEnableOption mkIf mkOption types; + inherit (self) namespace; + inherit (self.lib) mkOpt dirToModuleList; + + cfg = config.${namespace}.users; + + system = builtins.currentSystem; + systemClass = + if builtins.match ".*-linux" system != null then "nixos" + else if builtins.match ".*-darwin" system != null then "darwin" + else "nixos"; # Default fallback + + # Type for a user configuration + userType = types.submodule { + options = { + enable = mkEnableOption "Enable this user"; + initialPassword = mkOpt (types.nullOr types.str) null "Initial password for the user"; + hashedPassword = mkOpt (types.nullOr types.str) null "Hashed password for the user"; + isNormalUser = mkOpt types.bool true "Whether this user is a normal user"; + extraGroups = mkOpt (types.listOf types.str) [] "Extra groups for the user"; + }; + }; + + # Function to get home configuration path for a username + getHomeConfigPath = username: "${self.outPath}/homes/${systemClass}/${username}"; + + # Function to check if a home configuration exists for a username + homeConfigExists = username: + let path = getHomeConfigPath username; + in builtins.pathExists "${path}/default.nix"; + + # Import all home-manager modules + homeModules = dirToModuleList "${self.outPath}/modules/home"; +in { + imports = [ + # Import home-manager NixOS module + # This assumes home-manager is available as a flake input + self.inputs.home-manager.nixosModules.home-manager + ]; + + options.${namespace}.users = mkOption { + type = types.attrsOf userType; + default = {}; + description = "User configurations with auto-imported home-manager setup"; + }; + + config = { + # Create the actual users + users.users = lib.mapAttrs (username: userConfig: + mkIf userConfig.enable { + name = username; + isNormalUser = userConfig.isNormalUser; + inherit (userConfig) extraGroups; + initialPassword = userConfig.initialPassword; + hashedPassword = userConfig.hashedPassword; + } + ) cfg; + + # Configure home-manager with auto-imported configs + home-manager = { + useGlobalPkgs = true; + useUserPackages = true; + + extraSpecialArgs = { + inherit self; + namespace = self.namespace; + }; + + users = lib.mapAttrs (username: userConfig: + mkIf (userConfig.enable && homeConfigExists username) ( + { ... }: { + imports = [ + (getHomeConfigPath username) # Import the user's specific home configuration + ] ++ homeModules; # Include all home modules from /modules/home + } + ) + ) cfg; + }; + }; +} diff --git a/modules/nixos/utils/vm/default.nix b/modules/nixos/utils/vm/default.nix index f0e88fa..5a72bbb 100644 --- a/modules/nixos/utils/vm/default.nix +++ b/modules/nixos/utils/vm/default.nix @@ -1,44 +1,26 @@ { lib, config, - namespace, - puzzlelib, + self, ... }: let - inherit (lib) mkIf mkMerge; - inherit (puzzlelib) mkOpt mkBool; + inherit (lib) mkIf; + inherit (self) namespace; cfg = config.${namespace}.utils.vm; in { options.${namespace}.utils.vm = { - enable = mkBool true "Whether to enable custom vm presets"; - preset = mkOpt lib.types.str "performance" "Specify the prefered vm settings preset: performance, balance or powersave"; + enable = self.lib.mkBool true "Whether to enable custom vm presets"; + preset = self.lib.mkOpt lib.types.str "performance" "Specify the prefered vm settings preset: performance, balance or powersave"; }; config = mkIf cfg.enable { - virtualisation.vmVariant = mkMerge [ - (mkIf cfg.preset - == "performance" { - virtualisation = { - cores = 6; - memorySize = 4096; - graphics = true; - }; - }) - (mkIf cfg.preset - == "balance" { - virtualisation = { - cores = 4; - memorySize = 2048; - }; - }) - (mkIf cfg.preset - == "powersave" { - virtualisation = { - cores = 2; - memorySize = 1024; - }; - }) - ]; + virtualisation.vmVariant = { + virtualisation = { + cores = 6; + memorySize = 4096; + graphics = true; + }; + }; }; } diff --git a/systems/x86_64-nixos/puzzlevision/default.nix b/systems/x86_64-nixos/puzzlevision/default.nix index 00e7d3e..79ef0c0 100644 --- a/systems/x86_64-nixos/puzzlevision/default.nix +++ b/systems/x86_64-nixos/puzzlevision/default.nix @@ -9,8 +9,13 @@ # System configuration puzzlevision = { - # Todo: pass a set of users to enable from within easy-hosts and automatically map the corresponding home-manager configurations - # users = [ "jo" ]; + # TODO: improve home-manager configuration loading as development continues and make sure everything works correctly. + users = { + jo = { + enable = true; + initialPassword = "balls"; + }; + }; desktop.gnome.enable = true; };