From a3b79159e6ec02eebe395fa0b2b8a6848bdfb44e Mon Sep 17 00:00:00 2001
From: Manuel Thalmann <m@nuth.ch>
Date: Mon, 14 Oct 2024 01:55:19 +0200
Subject: [PATCH] Enable software properly

---
 lib/modules/hardware.nix                      |  28 +-
 lib/modules/programs.nix                      | 145 +++----
 lib/modules/software.nix                      | 215 +++++++----
 profiles/machines/manuel/DerGeret/config.nix  |   5 +-
 profiles/machines/manuel/Generic/config.nix   |  15 +
 profiles/users/manuel/config.nix              |   8 +
 scripts/Arch/Config/SecureBoot/main.fish      |   2 +-
 scripts/Arch/Drivers/Surface/main.fish        |   2 +-
 scripts/Arch/Drivers/SurfaceBook2/main.fish   |   2 +-
 scripts/Arch/Scripts/deploy.fish              | 355 +++++++++---------
 .../Common/Drivers/Logitech G903/main.fish    |   2 +-
 scripts/Common/Drivers/SurfaceBook2/main.fish |   2 +-
 scripts/Windows/Scripts/Deployment.ps1        | 127 ++++---
 scripts/Windows/Software/chocolatey/Main.ps1  |   2 +-
 14 files changed, 512 insertions(+), 398 deletions(-)

diff --git a/lib/modules/hardware.nix b/lib/modules/hardware.nix
index c44dffa4..5e73c761 100644
--- a/lib/modules/hardware.nix
+++ b/lib/modules/hardware.nix
@@ -1,5 +1,8 @@
-{ lib, ... }:
-let inherit (lib) mkOption types;
+{ config, lib, ... }:
+let
+  inherit (lib) mkOption types;
+  optionalAttrs = lib.attrsets.optionalAttrs;
+  hw = config.valhalla.hardware;
 in {
   options = {
     valhalla = {
@@ -51,13 +54,22 @@ in {
           description = "A value indicating whether an Elgato Wave device is present.";
           default = false;
         };
-
-        logitechG = mkOption {
-          type = types.bool;
-          description = "A value indicating whether a Logitech G device is present.";
-          default = false;
-        };
       };
     };
   };
+
+  config = {
+    valhalla = {
+      linux.programs = (optionalAttrs hw.nvidiaGPU {
+        nvidia-dkms.enable = true;
+      }) // (optionalAttrs hw.xoneReceiver {
+        xone.enable = true;
+      });
+
+      windows.programs = (optionalAttrs hw.eyeX {
+        tobii-gamehub.enable = lib.mkDefault true;
+        tobii-ghost.enable = lib.mkDefault true;
+      });
+    };
+  };
 }
diff --git a/lib/modules/programs.nix b/lib/modules/programs.nix
index 3e9dd481..1c3cc67f 100644
--- a/lib/modules/programs.nix
+++ b/lib/modules/programs.nix
@@ -3,24 +3,84 @@ let
   inherit (lib) mkEnableOption mkDefault mkOption types;
   cfg = config.valhalla;
 
-  mkUsersOption = osConfig: mkOption {
+  mkUsersOption = programs: osConfig: mkOption {
     type = types.attrsOf (types.submodule (
       { ... }: {
-      config = {
-        programs = builtins.mapAttrs (
-          name: config: {
-            enable = mkDefault config.enable;
-          }) osConfig.programs;
+        options = {
+          inherit programs;
+        };
+
+        config = {
+          programs = builtins.mapAttrs (
+            name: config: {
+              enable = mkDefault config.enable;
+            }) osConfig.programs;
       };
     }));
   };
 
-  mkPrograms = infos: builtins.foldl' (info: programs:
+  mkPrograms = infos: builtins.foldl' (programs: info:
     programs // {
-      "${info.0}" = {
-        enable = mkEnableOption info.1;
+      ${builtins.elemAt info 0} = {
+        enable = mkEnableOption (builtins.elemAt info 1);
       };
     }) { } infos;
+
+  programs = mkPrograms [
+    ["aliae" "aliae"]
+    ["brave" "Brave Browser"]
+    ["discord" "Discord"]
+    ["docker" "docker"]
+    ["firefox" "Firefox Web Browser"]
+    ["openssh" "OpenSSH"]
+    ["osu!lazer" "osu!lazer"]
+    ["pennywise" "Pennywise"]
+    ["powershell" "PowerShell Core"]
+    ["retroarch" "RetroArch"]
+    ["steam" "Steam"]
+    ["thunderbird" "Thunderbird"]
+    ["vscode" "Visual Studio Code"]
+    ["zoxide" "zoxide"]
+  ];
+
+  linuxPrograms = mkPrograms [
+    ["bash" "Bash"]
+    ["fish" "fish"]
+    ["icedtea" "IcedTea"]
+    ["grub" "GRUB"]
+    ["logo-ls" "logo-ls"]
+    ["lutris" "Lutris"]
+    ["minegrub-theme" "Minegrub Theme"]
+    ["nodejs-n" "n"]
+    ["nuke-usb" "nuke-usb"]
+    ["nvidia-dkms" "Nvidia Drivers"]
+    ["plasma" "Plasma"]
+    ["pyenv" "pyenv"]
+    ["sddm" "SDDM"]
+    ["vim" "Vim"]
+    ["virt-manager" "Virtual Machine Manager"]
+    ["waydroid" "Waydroid"]
+    ["xone" "xone"]
+  ];
+
+  windowsPrograms = mkPrograms [
+    ["lghub" "Logitech G Hub"]
+    ["maniaplanet" "ManiaPlanet"]
+    ["msedge-redirect" "MSEdgeRedirect"]
+    ["nvs" "Node Version Switcher"]
+    ["osu!" "Osu!"]
+    ["posh-git" "posh-git"]
+    ["putty" "PuTTY"]
+    ["rewasd" "reWASD"]
+    ["terminal-icons" "Terminal Icons"]
+    ["tm-nations-forever" "TrackMania Nations Forever"]
+    ["tm-united-forever" "TrackMania United Forever"]
+    ["tobii-gamehub" "Tobii Game Hub"]
+    ["tobii-ghost" "Tobii Ghost"]
+    ["ubiquiti-unifi-controller" "Ubiquiti UniFi Controller"]
+    ["visualstudio" "Visual Studio"]
+    ["winscp" "WinSCP"]
+  ];
 in {
   imports = [
     ./programs/git.nix
@@ -31,68 +91,13 @@ in {
 
   options = {
     valhalla = {
-      users = mkUsersOption cfg;
-      linux.users = mkUsersOption cfg.linux;
-      windows.users = mkUsersOption cfg.windows;
+      users = mkUsersOption programs cfg;
+      linux.users = mkUsersOption linuxPrograms cfg.linux;
+      windows.users = mkUsersOption windowsPrograms cfg.windows;
 
-      programs = mkPrograms [
-        ["aliae" "aliae"]
-        ["brave" "Brave Browser"]
-        ["discord" "Discord"]
-        ["docker" "docker"]
-        ["firefox" "Firefox Web Browser"]
-        ["git" "git"]
-        ["nextcloud" "Nextcloud Client"]
-        ["oh-my-posh" "Oh My Posh"]
-        ["openssh" "OpenSSH"]
-        ["osu!lazer" "osu!lazer"]
-        ["pennywise" "Pennywise"]
-        ["powershell" "PowerShell Core"]
-        ["retroarch" "RetroArch"]
-        ["steam" "Steam"]
-        ["thunderbird" "Thunderbird"]
-        ["vscode" "Visual Studio Code"]
-        ["zoxide" "zoxide"]
-      ];
-
-      linux.programs = mkPrograms [
-        ["bash" "Bash"]
-        ["fish" "fish"]
-        ["icedtea" "IcedTea"]
-        ["grub" "GRUB"]
-        ["lghub" "Logitech G Hub"]
-        ["logo-ls" "logo-ls"]
-        ["lutris" "Lutris"]
-        ["minegrub-theme" "Minegrub Theme"]
-        ["nodejs-n" "n"]
-        ["nuke-usb" "nuke-usb"]
-        ["nvidia-dkms" "Nvidia Drivers"]
-        ["plasma" "Plasma"]
-        ["pyenv" "pyenv"]
-        ["rclone" "rclone"]
-        ["sddm" "SDDM"]
-        ["vim" "Vim"]
-        ["virt-manager" "Virtual Machine Manager"]
-        ["waydroid" "Waydroid"]
-        ["xone" "xone"]
-      ];
-
-      windows.programs = mkPrograms [
-        ["maniaplanet" "ManiaPlanet"]
-        ["msedge-redirect" "MSEdgeRedirect"]
-        ["nvs" "Node Version Switcher"]
-        ["osu!" "Osu!"]
-        ["putty" "PuTTY"]
-        ["rewasd" "reWASD"]
-        ["terminal-icons" "Terminal Icons"]
-        ["tm-nations-forever" "TrackMania Nations Forever"]
-        ["tm-united-forever" "TrackMania United Forever"]
-        ["tobii-gamehub" "Tobii Game Hub"]
-        ["tobii-ghost" "Tobii Ghost"]
-        ["ubiquiti-unifi-controller" "Ubiquiti UniFi Controller"]
-        ["visualstudio" "Visual Studio"]
-        ["winscp" "WinSCP"]
-      ];
+      inherit programs;
+      linux.programs = linuxPrograms;
+      windows.programs = windowsPrograms;
     };
   };
 }
diff --git a/lib/modules/software.nix b/lib/modules/software.nix
index e3d23416..6553daf7 100644
--- a/lib/modules/software.nix
+++ b/lib/modules/software.nix
@@ -1,89 +1,154 @@
-{ lib, config, ... }:
-let
-  inherit (lib) mkOption types;
-  cfg = config.valhalla;
-in {
-  imports = [
-    ./programs.nix
-  ];
+{ lib, ... }:
+  let inherit (lib) mkOption types;
+  in {
+    imports = [
+      ./programs.nix
+    ];
 
-  options = {
-    valhalla = {
-      software = let
-        inherit (cfg.software) coding common desktopExperience school server;
-      in {
-        essential = mkOption {
-          type = types.bool;
-          description = "A value indicating whether essentials should be installed.";
-          default = true;
-        };
+    options = {
+      valhalla = mkOption {
+        type = types.submodule (
+          { config, ... }:
+            let
+              optionalAttrs = lib.attrsets.optionalAttrs;
+              cfg = config;
+              inherit (cfg.software) coding desktopExperience essential gaming socialMedia;
 
-        common = mkOption {
-          type = types.bool;
-          description = "A value indicating whether common software should be installed.";
-          default = true;
-        };
+              mkPrograms = programs: builtins.foldl' (
+                programs: name: programs // {
+                  ${name}.enable = true;
+                }) {} programs;
+            in {
+              options = {
+                software = {
+                  essential = mkOption {
+                    type = types.bool;
+                    description = "A value indicating whether essentials should be installed.";
+                    default = false;
+                  };
 
-        server = mkOption {
-          type = types.bool;
-          description = "A value indicating whether server applications should be installed.";
-          default = false;
-        };
+                  common = mkOption {
+                    type = types.bool;
+                    description = "A value indicating whether common software should be installed.";
+                    default = false;
+                  };
 
-        desktopExperience = mkOption {
-          type = types.bool;
-          description = "A value indicating whether GUI apps should be installed.";
-          default = common && !server;
-        };
+                  server = mkOption {
+                    type = types.bool;
+                    description = "A value indicating whether server applications should be installed.";
+                    default = false;
+                  };
 
-        fileSync = mkOption {
-          type = types.bool;
-          description = "A value indicating whether file syncs should be installed.";
-          default = common && !server;
-        };
+                  desktopExperience = mkOption {
+                    type = types.bool;
+                    description = "A value indicating whether GUI apps should be installed.";
+                    default = false;
+                  };
 
-        school = mkOption {
-          type = types.bool;
-          description = "A value indicating whether software for studies should be installed.";
-          default = false;
-        };
+                  school = mkOption {
+                    type = types.bool;
+                    description = "A value indicating whether software for studies should be installed.";
+                    default = false;
+                  };
 
-        productivity = mkOption {
-          type = types.bool;
-          description = "A value indicating whether productivity apps should be installed.";
-          default = common || school;
-        };
+                  productivity = mkOption {
+                    type = types.bool;
+                    description = "A value indicating whether productivity apps should be installed.";
+                    default = false;
+                  };
 
-        socialMedia = mkOption {
-          type = types.bool;
-          description = "A value indicating whether social media apps should be installed.";
-          default = common && desktopExperience;
-        };
+                  socialMedia = mkOption {
+                    type = types.bool;
+                    description = "A value indicating whether social media apps should be installed.";
+                    default = false;
+                  };
 
-        media = mkOption {
-          type = types.bool;
-          description = "A value indicating whether media apps should be installed.";
-          default = common && desktopExperience;
-        };
+                  media = mkOption {
+                    type = types.bool;
+                    description = "A value indicating whether media apps should be installed.";
+                    default = false;
+                  };
 
-        gaming = mkOption {
-          type = types.bool;
-          description = "A value indicating whether gaming apps should be installed.";
-          default = common && desktopExperience;
-        };
+                  gaming = mkOption {
+                    type = types.bool;
+                    description = "A value indicating whether gaming apps should be installed.";
+                    default = false;
+                  };
 
-        coding = mkOption {
-          type = types.bool;
-          description = "A value indicating whether development apps should be installed.";
-          default = common;
-        };
+                  coding = mkOption {
+                    type = types.bool;
+                    description = "A value indicating whether development apps should be installed.";
+                    default = false;
+                  };
+                };
+              };
 
-        python = mkOption {
-          type = types.bool;
-          description = "A value indicating whether apps for coding python should be installed.";
-          default = coding;
-        };
+              config = {
+                programs = (optionalAttrs essential (mkPrograms [
+                  "aliae"
+                  "git"
+                  "oh-my-posh"
+                  "openssh"
+                  "powershell"
+                  "zoxide"
+                ])) // (optionalAttrs desktopExperience (mkPrograms [
+                  "brave"
+                  "firefox"
+                  "pennywise"
+                  "thunderbird"
+                ])) // (optionalAttrs socialMedia (mkPrograms [
+                  "discord"
+                ])) // (optionalAttrs coding (mkPrograms [
+                  "docker"
+                  "vscode"
+                ])) // (optionalAttrs gaming (mkPrograms [
+                  "osu!lazer"
+                  "retroarch"
+                  "steam"
+                ]));
+
+                linux.programs = (optionalAttrs essential (mkPrograms [
+                  "bash"
+                  "logo-ls"
+                  "minegrub-theme"
+                  "nuke-usb"
+                  "vim"
+                ])) // (optionalAttrs desktopExperience (mkPrograms [
+                  "icedtea"
+                  "plasma"
+                  "sddm"
+                  "waydroid"
+                  "virt-manager"
+                ])) // (optionalAttrs coding (mkPrograms [
+                  "nodejs-n"
+                  "pyenv"
+                ])) // (optionalAttrs gaming (mkPrograms [
+                  "lutris"
+                ]));
+
+                # Essentials
+                windows.programs = (optionalAttrs essential (mkPrograms [
+                  "posh-git"
+                  "terminal-icons"
+                # Desktop Experience
+                ])) // (optionalAttrs desktopExperience (mkPrograms [
+                  "msedge-redirect"
+                  "putty"
+                  "winscp"
+                # Development
+                ])) // (optionalAttrs coding (mkPrograms [
+                  "nvs"
+                  "visualstudio"
+                # Gaming
+                ])) // (optionalAttrs gaming (mkPrograms [
+                  "maniaplanet"
+                  "osu!"
+                  "rewasd"
+                  "tm-nations-forever"
+                  "tm-united-forever"
+                ]));
+              };
+            });
       };
     };
-  };
-}
+  }
diff --git a/profiles/machines/manuel/DerGeret/config.nix b/profiles/machines/manuel/DerGeret/config.nix
index 6186ab95..ab80c4b3 100644
--- a/profiles/machines/manuel/DerGeret/config.nix
+++ b/profiles/machines/manuel/DerGeret/config.nix
@@ -18,6 +18,10 @@
           microsoftAccount = true;
           groups = [ "Administrators" ];
         };
+
+        programs = {
+          lghub.enable = true;
+        };
       };
 
       partition.os.partitions = {
@@ -45,7 +49,6 @@
         eyeX = true;
         amdCPU = true;
         nvidiaGPU = true;
-        logitechG = true;
         corsairDevice = true;
         elgatoWave = true;
       };
diff --git a/profiles/machines/manuel/Generic/config.nix b/profiles/machines/manuel/Generic/config.nix
index b67a6b07..581f1e8d 100644
--- a/profiles/machines/manuel/Generic/config.nix
+++ b/profiles/machines/manuel/Generic/config.nix
@@ -45,6 +45,19 @@ in {
         };
       };
 
+      software = {
+        essential = true;
+        common = true;
+        desktopExperience = true;
+        productivity = true;
+        socialMedia = true;
+        media = true;
+        gaming = true;
+        coding = true;
+      };
+
+      linux.programs.grub.enable = true;
+
       programs = {
         git = let defaultBranch = "main";
         in {
@@ -86,6 +99,8 @@ in {
           };
         };
       };
+
+      windows.programs.ubiquiti-unifi-controller.enable = true;
     };
   };
 }
diff --git a/profiles/users/manuel/config.nix b/profiles/users/manuel/config.nix
index 3a3d2276..0e649fdb 100644
--- a/profiles/users/manuel/config.nix
+++ b/profiles/users/manuel/config.nix
@@ -3,6 +3,14 @@
 
   config = {
     valhalla = {
+      programs = {
+        nextcloud.enable = true;
+      };
+
+      linux.programs = {
+        rclone.enable = true;
+      };
+
       users.manuel = {
         displayName = "Manuel Thalmann";
         mailAddress = "m@nuth.ch";
diff --git a/scripts/Arch/Config/SecureBoot/main.fish b/scripts/Arch/Config/SecureBoot/main.fish
index 6a076974..ed5c5692 100755
--- a/scripts/Arch/Config/SecureBoot/main.fish
+++ b/scripts/Arch/Config/SecureBoot/main.fish
@@ -31,5 +31,5 @@ begin
         sudo secure-grub-install
     end
 
-    runInstaller $argv
+    runInstaller --force $argv
 end
diff --git a/scripts/Arch/Drivers/Surface/main.fish b/scripts/Arch/Drivers/Surface/main.fish
index 93e7e355..86518934 100755
--- a/scripts/Arch/Drivers/Surface/main.fish
+++ b/scripts/Arch/Drivers/Surface/main.fish
@@ -40,5 +40,5 @@ begin
         fish "$dir/../../Software/grub/main.fish" configure
     end
 
-    runInstaller $argv
+    runInstaller --force $argv
 end
diff --git a/scripts/Arch/Drivers/SurfaceBook2/main.fish b/scripts/Arch/Drivers/SurfaceBook2/main.fish
index 64edee8d..28fe415e 100755
--- a/scripts/Arch/Drivers/SurfaceBook2/main.fish
+++ b/scripts/Arch/Drivers/SurfaceBook2/main.fish
@@ -21,6 +21,6 @@ begin
         sudo systemctl enable --global surface-dtx-userd.service
     end
 
-    runInstaller $argv
+    runInstaller --force $argv
     fish "$dir/../Surface/main.fish" $argv
 end
diff --git a/scripts/Arch/Scripts/deploy.fish b/scripts/Arch/Scripts/deploy.fish
index ec47f4fd..c4e3ecdc 100644
--- a/scripts/Arch/Scripts/deploy.fish
+++ b/scripts/Arch/Scripts/deploy.fish
@@ -45,142 +45,130 @@ function deploySoftware -d "Deploys a the specified software action" -a action
         yayinst bt-dualboot
     end
 
-    and if collectionActive essential
-        if $isInstall
-            yayinst \
-                mkinitcpio-firmware \
-                neofetch \
-                bash-completion \
-                wget \
-                screen \
-                tmux \
-                htop \
-                lsof \
-                zsh \
-                fish \
-                pkgfile \
-                sl \
-                rar
+    and if collectionActive essential && $isInstall
+        yayinst \
+            mkinitcpio-firmware \
+            neofetch \
+            bash-completion \
+            wget \
+            screen \
+            tmux \
+            htop \
+            lsof \
+            zsh \
+            fish \
+            pkgfile \
+            sl \
+            rar
 
-            and sudo pkgfile --update
-        end
+        and sudo pkgfile --update
 
-        and source "$dir/../../Common/Software/bash/main.fish" $argv
-        and source "$dir/../../Common/Software/nuke-usb/main.fish" $argv
-        and source "$dir/../Software/sudo/main.fish" $argv
-        and source "$dir/../Software/aliae/main.fish" $argv
-        and source "$dir/../Software/oh-my-posh/main.fish" $argv
-        and source "$dir/../Software/openssh/main.fish" $argv
-        and source "$dir/../Software/vim/main.fish" $argv
-        and source "$dir/../Software/git/main.fish" $argv
-        and source "$dir/../Software/zoxide/main.fish" $argv
-        and source "$dir/../Software/logo-ls/main.fish" $argv
-
-        # GRUB Shenanigans - if that's not essential I don't know what is!
-        and source "$dir/../Software/minegrub-theme/main.fish" $argv
+        yayinst \
+            tldr \
+            btop \
+            terminal-parrot
     end
 
-    and if collectionActive common
-        if $isInstall
-            yayinst \
-                tldr \
-                btop \
-                terminal-parrot
-        end
-    end
+    and source "$dir/../../Common/Software/bash/main.fish" $argv
+    and source "$dir/../../Common/Software/nuke-usb/main.fish" $argv
+    and source "$dir/../Software/sudo/main.fish" $argv
+    and source "$dir/../Software/aliae/main.fish" $argv
+    and source "$dir/../Software/oh-my-posh/main.fish" $argv
+    and source "$dir/../Software/openssh/main.fish" $argv
+    and source "$dir/../Software/vim/main.fish" $argv
+    and source "$dir/../Software/git/main.fish" $argv
+    and source "$dir/../Software/zoxide/main.fish" $argv
+    and source "$dir/../Software/logo-ls/main.fish" $argv
 
-    and if collectionActive desktopExperience
-        source "$dir/../Software/plasma/main.fish" $argv
-        and source "$dir/../Software/sddm/main.fish" $argv
+    # GRUB Shenanigans - if that's not essential I don't know what is!
+    and source "$dir/../Software/minegrub-theme/main.fish" $argv
 
-        and if $isInstall
-            yayinst \
-                maliit-keyboard \
-                dconf-editor \
-                flatpak (
-                    # Fixes: https://www.reddit.com/r/flatpak/comments/168tav2/how_to_fix_blurry_flatpaks_on_high_resolution/
-                ) xdg-desktop-portal-gtk
+    # Desktop Experience
+    source "$dir/../Software/plasma/main.fish" $argv
+    and source "$dir/../Software/sddm/main.fish" $argv
+    and source "$dir/../Software/icedtea/main.fish" $argv
 
-            # Fonts
-            and yayinst \
-                ttf-cascadia-code-nerd \
-                ttf-ms-win11-auto \
-                otf-cascadia-code \
-                ttf-droid
+    and if collectionActive desktopExperience && $isInstall
+        yayinst \
+            maliit-keyboard \
+            dconf-editor \
+            flatpak (
+                # Fixes: https://www.reddit.com/r/flatpak/comments/168tav2/how_to_fix_blurry_flatpaks_on_high_resolution/
+            ) xdg-desktop-portal-gtk
 
-            # Password Management
-            and yayinst \
-                bitwarden \
-                keepass \
-                keepassxc
+        # Fonts
+        and yayinst \
+            ttf-cascadia-code-nerd \
+            ttf-ms-win11-auto \
+            otf-cascadia-code \
+            ttf-droid
 
-            # Tools
-            and yayinst \
-                android-tools \
-                blackbox-terminal \
-                cpu-x \
-                gnome-calculator \
-                yubikey-manager-qt \
-                wireshark-qt \
-                linux-wifi-hotspot
+        # Password Management
+        and yayinst \
+            bitwarden \
+            keepass \
+            keepassxc
 
-            # Remote Access
-            and yayinst \
-                remmina (
-                    # RDP support for Remmina
-                ) freerdp
+        # Tools
+        and yayinst \
+            android-tools \
+            blackbox-terminal \
+            cpu-x \
+            gnome-calculator \
+            yubikey-manager-qt \
+            wireshark-qt \
+            linux-wifi-hotspot
 
-            # Creativity
-            and yayinst \
-                gimp \
-                inkscape
+        # Remote Access
+        and yayinst \
+            remmina (
+                # RDP support for Remmina
+            ) freerdp
 
-            # Office stuff
-            and yayinst \
-                libreoffice-fresh \
-                naps2-bin \
-                pdfarranger \
-                protonmail-bridge \
-                thunderbird
+        # Creativity
+        and yayinst \
+            gimp \
+            inkscape
 
-            and yayinst \
-                texlive \
-                texlive-langgerman
+        # Office stuff
+        and yayinst \
+            libreoffice-fresh \
+            naps2-bin \
+            pdfarranger \
+            protonmail-bridge
 
-            # Virtualization
-            and yayinst propertree-git # mac .plist config file editor
-
-            and if collectionActive school
-                yayinst \
-                    teams-for-linux \
-                    xournalpp-git \
-                    rnote
-            end
-        end
-
-        # Internet Access
-        and source "$dir/../Software/firefox/main.fish" $argv
-        and source "$dir/../Software/brave/main.fish" $argv
-        and source "$dir/../Software/pennywise/main.fish" $argv
+        and yayinst \
+            texlive \
+            texlive-langgerman
 
         # Virtualization
-        and source "$dir/../Software/waydroid/main.fish" $argv
-        and source "$dir/../Software/virt-manager/main.fish" $argv
-
-        and if collectionActive coding
-            if $isInstall
-                yayinst \
-                    devdocs-desktop \
-                    godot-mono
-            end
-
-            and source "$dir/../Software/vscode/main.fish" $argv
-        end
+        and yayinst propertree-git # mac .plist config file editor
     end
 
-    and if collectionActive server
-    else
-        if $isInstall
+    and if isProgramEnabled "thunderbird" && $isInstall
+        yayinst thunderbird
+    end
+
+    # School & Studies
+    and if collectionActive school && $isInstall
+        yayinst \
+            teams-for-linux \
+            xournalpp-git \
+            rnote
+    end
+
+    # Internet Access
+    and source "$dir/../Software/firefox/main.fish" $argv
+    and source "$dir/../Software/brave/main.fish" $argv
+    and source "$dir/../Software/pennywise/main.fish" $argv
+
+    # Virtualization
+    and source "$dir/../Software/waydroid/main.fish" $argv
+    and source "$dir/../Software/virt-manager/main.fish" $argv
+
+    and if $isInstall
+        if collectionActive server
+        else
             # Energy Saving
             yayinst power-profiles-daemon
             and sudo systemctl enable --now power-profiles-daemon
@@ -191,70 +179,71 @@ function deploySoftware -d "Deploys a the specified software action" -a action
                 networkmanager-openconnect \
                 proton-vpn-gtk-app \
                 protonvpn-cli-community
-        end
 
-        and if collectionActive common
-            if $isInstall
-                and yayinst \
+            and if collectionActive common
+                yayinst \
                     img2pdf \
                     numbat-bin \
                     nvtop \
                     pdf2svg \
                     tnef
             end
-
-            and source "$dir/../Software/icedtea/main.fish" $argv
         end
-    end
 
-    and if collectionActive media && $isInstall
-        yayinst \
-            ytmdesktop-bin \
-            netflix \
-            spotube-bin \
-            stremio \
-            tidal-dl-ng \
-            tidal-hifi-bin \
-            nuclear-player-bin \
-            audius-client-bin
-    end
+        and if collectionActive media
+            yayinst \
+                ytmdesktop-bin \
+                netflix \
+                spotube-bin \
+                stremio \
+                tidal-dl-ng \
+                tidal-hifi-bin \
+                nuclear-player-bin \
+                audius-client-bin
+        end
 
-    and if collectionActive fileSync
-        if $isInstall
+        and if isProgramEnabled "nextcloud"
             yayinst nextcloud-client
         end
-
-        and source "$dir/../Software/rclone/main.fish" $argv
     end
 
-    and if collectionActive socialMedia && $isInstall
-        yayinst \
-            signal-desktop \
-            vesktop-bin
+    and source "$dir/../Software/rclone/main.fish" $argv
 
-        and begin
-            yes y | runYay threema-desktop
+    if $isInstall
+        if collectionActive socialMedia
+            yayinst signal-desktop
+    
+            and begin
+                yes y | runYay threema-desktop
+            end
+    
+            and begin
+                yes y | runYay nodejs
+            end
         end
 
-        and begin
-            yes y | runYay nodejs
+        and if isProgramEnabled discord
+            yayinst vesktop-bin
+        end
+
+        and if collectionActive productivity
+            yayinst \
+                anki-bin
         end
     end
 
-    and if collectionActive productivity && $isInstall
-        yayinst \
-            anki-bin
-    end
-
-    and if collectionActive school && $isInstall
-        yayinst \
-            jdk17-temurin \
-            gradle \
-            jetbrains-toolbox
+    and if collectionActive school
+        if $isInstall
+            yayinst \
+                jdk17-temurin \
+                gradle \
+                jetbrains-toolbox
+        end
 
         and source "$dir/../../Common/Software/udev/ct-board.fish"
     end
 
+    # Development
     and if collectionActive coding
         if $isInstall
             yayinst \
@@ -267,40 +256,44 @@ function deploySoftware -d "Deploys a the specified software action" -a action
                     # AsciiDocs
                 ) python-docutils (
                     # reStructuredText
-                ) esbonio
-        end
-
-        and source "$dir/../Software/nodejs-n/main.fish" $argv
-        and source "$dir/../Software/docker/main.fish" $argv
-    end
-
-    and if collectionActive python
-        if $isInstall
-            yayinst \
+                ) esbonio \
+                devdocs-desktop \
+                godot-mono \
                 python \
                 python-pip \
                 python-pipenv
         end
-
-        and source "$dir/../Software/pyenv/main.fish" $argv
     end
 
-    and if collectionActive gaming
-        if $isInstall
-            yayinst \
-                chiaki-ng \
-                osu-lazer-bin \
-                libretro \
-                supertux \
-                gamepad-tool-bin
+    and source "$dir/../Software/pyenv/main.fish" $argv
+    and source "$dir/../Software/nodejs-n/main.fish" $argv
+    and source "$dir/../Software/docker/main.fish" $argv
+    and source "$dir/../Software/vscode/main.fish" $argv
 
-            and sudo flatpak install -y flathub com.usebottles.bottles
+    if $isInstall
+        if collectionActive gaming
+            if $isInstall
+                yayinst \
+                    chiaki-ng \
+                    supertux \
+                    gamepad-tool-bin
+                    
+                and sudo flatpak install -y flathub com.usebottles.bottles
+            end
+        end
+                    
+        and if isProgramEnabled "osu!lazer"
+            yayinst osu-lazer-bin
         end
 
-        and source "$dir/../Software/lutris/main.fish" $argv
-        and source "$dir/../Software/steam/main.fish" $argv
+        and if isProgramEnabled "retroarch"
+            yayinst libretro
+        end
     end
 
+    and source "$dir/../Software/lutris/main.fish" $argv
+    and source "$dir/../Software/steam/main.fish" $argv
+
     and if collectionActive essential && $isInstall
         yayinst bb
     end
diff --git a/scripts/Common/Drivers/Logitech G903/main.fish b/scripts/Common/Drivers/Logitech G903/main.fish
index 813f996e..5f874847 100644
--- a/scripts/Common/Drivers/Logitech G903/main.fish	
+++ b/scripts/Common/Drivers/Logitech G903/main.fish	
@@ -8,5 +8,5 @@ begin
         addInputConfig 1133 16519 "Logitech G903 LS" "PointerAccelerationProfile=1"
     end
 
-    runInstaller $argv
+    runInstaller --force $argv
 end
diff --git a/scripts/Common/Drivers/SurfaceBook2/main.fish b/scripts/Common/Drivers/SurfaceBook2/main.fish
index 7d74c6eb..8d2757a7 100644
--- a/scripts/Common/Drivers/SurfaceBook2/main.fish
+++ b/scripts/Common/Drivers/SurfaceBook2/main.fish
@@ -8,5 +8,5 @@ begin
         addInputConfig 1118 2338 "Microsoft Surface Keyboard Touchpad" "NaturalScroll=true"
     end
 
-    runInstaller $argv
+    runInstaller --force $argv
 end
diff --git a/scripts/Windows/Scripts/Deployment.ps1 b/scripts/Windows/Scripts/Deployment.ps1
index c8fb3599..5849e97d 100644
--- a/scripts/Windows/Scripts/Deployment.ps1
+++ b/scripts/Windows/Scripts/Deployment.ps1
@@ -1,5 +1,6 @@
 . "$PSScriptRoot/PowerManagement.ps1";
 . "$PSScriptRoot/SoftwareManagement.ps1";
+. "$PSScriptRoot/../../Common/Scripts/Config.ps1";
 . "$PSScriptRoot/../../Common/Scripts/SoftwareManagement.ps1";
 . "$PSScriptRoot/../../Common/Types/InstallerAction.ps1";
 
@@ -93,26 +94,24 @@ function Deploy-SoftwareAction {
         # Windows Config
         & "$softwarePath/windows/Main.ps1" @arguments;
 
-        if ($hardware.logitechG) {
-            & "$softwarePath/lghub/Main.ps1" @arguments;
+        # Driver Programs
+        & "$softwarePath/lghub/Main.ps1" @arguments;
+        & "$softwarePath/aliae/Main.ps1" @arguments;
+        & "$softwarePath/git/Main.ps1" @arguments;
+        & "$softwarePath/openssh/Main.ps1" @arguments;
+        & "$softwarePath/powershell/Main.ps1" @arguments;
+        & "$softwarePath/chocolatey/Main.ps1" @arguments;
+        & "$softwarePath/zoxide/Main.ps1" @arguments;
+        & "$commonSoftware/posh-git/Main.ps1" @arguments;
+        & "$commonSoftware/terminal-icons/Main.ps1" @arguments;
+        & "$softwarePath/oh-my-posh/Main.ps1" @arguments;
+
+        if (Get-OSConfig "dualboot") {
+            & "$softwarePath/ext4fsd/Main.ps1" @arguments;
         }
 
         # Essentials
         if ($collections.essential) {
-            & "$softwarePath/aliae/Main.ps1" @arguments;
-            & "$softwarePath/git/Main.ps1" @arguments;
-            & "$softwarePath/openssh/Main.ps1" @arguments;
-            & "$softwarePath/powershell/Main.ps1" @arguments;
-            & "$softwarePath/chocolatey/Main.ps1" @arguments;
-            & "$softwarePath/zoxide/Main.ps1" @arguments;
-            & "$commonSoftware/posh-git/Main.ps1" @arguments;
-            & "$commonSoftware/terminal-icons/Main.ps1" @arguments;
-            & "$softwarePath/oh-my-posh/Main.ps1" @arguments;
-
-            if (Get-OSConfig "dualboot") {
-                & "$softwarePath/ext4fsd/Main.ps1" @arguments;
-            }
-
             if ($install) {
                 Install-ChocoPackage `
                     procexp `
@@ -126,11 +125,11 @@ function Deploy-SoftwareAction {
         }
 
         # Common Software
-        if ($collections.common) {
-            & "$softwarePath/winscp/Main.ps1" @arguments;
-            & "$softwarePath/thunderbird/Main.ps1" @arguments;
-            & "$softwarePath/putty/Main.ps1" @arguments;
+        & "$softwarePath/winscp/Main.ps1" @arguments;
+        & "$softwarePath/thunderbird/Main.ps1" @arguments;
+        & "$softwarePath/putty/Main.ps1" @arguments;
 
+        if ($collections.common) {
             if ($install) {
                 Install-ChocoPackage `
                     7zip `
@@ -149,17 +148,28 @@ function Deploy-SoftwareAction {
             }
         }
 
+        # Internet Access
+        if ($install) {
+            if (Test-Program "brave") {
+                Install-WingetPackage Brave.Brave;
+                Remove-DesktopIcon "*Brave*";
+                Remove-TaskbarItem "*Brave*";
+            }
+
+            if (Test-Program "pennywise") {
+                Install-WingetPackage kamranahmedse.pennywise;
+                Remove-DesktopIcon "Pennywise*";
+            }
+        }
+
+        & "$softwarePath/firefox/Main.ps1" @arguments;
+        & "$softwarePath/msedge-redirect/Main.ps1" @arguments;
+
         if ($collections.desktopExperience) {
             if ($install) {
                 # Fonts
                 Install-ChocoPackage nerd-fonts-CascadiaCode;
 
-                # Internet Access
-                Install-WingetPackage Brave.Brave kamranahmedse.pennywise;
-                Remove-DesktopIcon "*Brave*";
-                Remove-TaskbarItem "*Brave*";
-                Remove-DesktopIcon "Pennywise*";
-
                 # Tools
                 Install-SetupPackage -Source "https://github.com/mRemoteNG/mRemoteNG/releases/download/2023.03.03-v1.77.3-nb/mRemoteNG-Installer-1.77.3.nb-1784.msi" -ArgumentList "/Quiet";
                 Remove-DesktopIcon "mRemoteNG*";
@@ -196,19 +206,12 @@ function Deploy-SoftwareAction {
 
                 Remove-DesktopIcon "JDownloader*";
             }
-
-            # ToDo: Consider hiding behind own config?
-            & "$softwarePath/ubiquiti-unifi-controller/Main.ps1" @arguments;
-
-            # Internet Access
-            & "$softwarePath/firefox/Main.ps1" @arguments;
-            & "$softwarePath/msedge-redirect/Main.ps1" @arguments;
-
-            if ($collections.fileSync) {
-                & "$softwarePath/nextcloud/Main.ps1" @arguments;
-            }
         }
 
+        # ToDo: Consider hiding behind own config?
+        & "$softwarePath/ubiquiti-unifi-controller/Main.ps1" @arguments;
+        & "$softwarePath/nextcloud/Main.ps1" @arguments;
+
         if ($collections.socialMedia) {
             if ($install) {
                 Install-ChocoPackage `
@@ -221,10 +224,10 @@ function Deploy-SoftwareAction {
                 Remove-DesktopIcon "*Element*";
                 Remove-DesktopIcon "*TeamSpeak*";
             }
-
-            . "$softwarePath/discord/Main.ps1" @arguments;
         }
 
+        . "$softwarePath/discord/Main.ps1" @arguments;
+
         if ($collections.media) {
             if ($install) {
                 Install-ChocoPackage `
@@ -249,24 +252,36 @@ function Deploy-SoftwareAction {
                     github-desktop `
                     ida-free `
                     HxD `
-                    docker-desktop `
                     imhex `
                     dotpeek `
                     ;
 
                 Remove-DesktopIcon "IDA *";
                 Remove-DesktopIcon "GitHub*";
-                Remove-DesktopIcon "Docker*";
+
+                if (Test-Program "docker") {
+                    Install-ChocoPackage docker-desktop;
+                    Remove-DesktopIcon "Docker*";
+                }
             }
-
-            & "$softwarePath/vscode/Main.ps1" @arguments;
-            & "$softwarePath/visualstudio/Main.ps1" @arguments;
-
-            # Node.js
-            & "$softwarePath/nvs/Main.ps1" @arguments;
         }
 
+        & "$softwarePath/vscode/Main.ps1" @arguments;
+        & "$softwarePath/visualstudio/Main.ps1" @arguments;
+
+        # Node.js
+        & "$softwarePath/nvs/Main.ps1" @arguments;
+
         # Gaming
+        if (Test-Program "steam") {
+            Install-ChocoPackage `
+                steam `
+                -ArgumentList "--ignore-checksums" `
+                ;
+
+            Remove-DesktopIcon "*Steam*";
+        }
+
         if ($collections.gaming) {
             if ($install) {
                 Install-ChocoPackage `
@@ -280,25 +295,23 @@ function Deploy-SoftwareAction {
                 Remove-DesktopIcon "*PPSSPP *-Bit*";
 
                 Install-ChocoPackage `
-                    steam `
                     ubisoft-connect `
                     -ArgumentList "--ignore-checksums" `
                     ;
 
-                Remove-DesktopIcon "*Steam*";
                 Remove-DesktopIcon "*Ubisoft Connect*";
 
                 Install-WingetPackage ElectronicArts.EADesktop;
                 Remove-DesktopIcon "EA.*";
             }
-
-            & "$softwarePath/tm-nations-forever/Main.ps1" @arguments;
-            & "$softwarePath/tm-united-forever/Main.ps1" @arguments;
-            & "$softwarePath/maniaplanet/Main.ps1" @arguments;
-            & "$softwarePath/osu!/Main.ps1" @arguments;
-            & "$softwarePath/osu!lazer/Main.ps1" @arguments;
-            & "$softwarePath/retroarch/Main.ps1" @arguments;
-            & "$softwarePath/rewasd/Main.ps1" @arguments;
         }
+
+        & "$softwarePath/tm-nations-forever/Main.ps1" @arguments;
+        & "$softwarePath/tm-united-forever/Main.ps1" @arguments;
+        & "$softwarePath/maniaplanet/Main.ps1" @arguments;
+        & "$softwarePath/osu!/Main.ps1" @arguments;
+        & "$softwarePath/osu!lazer/Main.ps1" @arguments;
+        & "$softwarePath/retroarch/Main.ps1" @arguments;
+        & "$softwarePath/rewasd/Main.ps1" @arguments;
     };
 }
diff --git a/scripts/Windows/Software/chocolatey/Main.ps1 b/scripts/Windows/Software/chocolatey/Main.ps1
index a1d12388..df74b2b2 100644
--- a/scripts/Windows/Software/chocolatey/Main.ps1
+++ b/scripts/Windows/Software/chocolatey/Main.ps1
@@ -3,7 +3,7 @@ using namespace Microsoft.Win32;
 . "$PSScriptRoot/../../../Common/Scripts/Software.ps1";
 . "$PSScriptRoot/../../../Common/Software/powershell/Profile.ps1";
 
-Start-SoftwareInstaller @args `
+Start-SoftwareInstaller -Force @args `
     -Configurator {
         param([string] $Name)
         [string] $backup = $null;