From be4a9233dd3f6104c9b0fdd3d56f953eb519a4c7 Mon Sep 17 00:00:00 2001 From: jtrrll Date: Sat, 8 Nov 2025 21:01:58 +0000 Subject: [PATCH] retroarch: add module add a module for configuring retroarch through home-manager --- .../misc/news/2025/11/2025-11-08_20-50-07.nix | 12 +++ modules/programs/retroarch.nix | 91 +++++++++++++++++++ tests/modules/programs/retroarch/cores.nix | 34 +++++++ tests/modules/programs/retroarch/default.nix | 5 + tests/modules/programs/retroarch/settings.nix | 28 ++++++ tests/modules/programs/retroarch/stubs.nix | 32 +++++++ 6 files changed, 202 insertions(+) create mode 100644 modules/misc/news/2025/11/2025-11-08_20-50-07.nix create mode 100644 modules/programs/retroarch.nix create mode 100644 tests/modules/programs/retroarch/cores.nix create mode 100644 tests/modules/programs/retroarch/default.nix create mode 100644 tests/modules/programs/retroarch/settings.nix create mode 100644 tests/modules/programs/retroarch/stubs.nix diff --git a/modules/misc/news/2025/11/2025-11-08_20-50-07.nix b/modules/misc/news/2025/11/2025-11-08_20-50-07.nix new file mode 100644 index 000000000..2c9917a86 --- /dev/null +++ b/modules/misc/news/2025/11/2025-11-08_20-50-07.nix @@ -0,0 +1,12 @@ +{ pkgs, ... }: +{ + time = "2025-11-08T20:50:07+00:00"; + condition = pkgs.stdenv.hostPlatform.isLinux; + message = '' + A new module is available: 'programs.retroarch'. + + RetroArch is a frontend for emulators, game engines, and media players. + Among other things, it enables you to run classic games on a wide + range of computers and consoles through its slick graphical interface. + ''; +} diff --git a/modules/programs/retroarch.nix b/modules/programs/retroarch.nix new file mode 100644 index 000000000..3e817c236 --- /dev/null +++ b/modules/programs/retroarch.nix @@ -0,0 +1,91 @@ +{ + config, + lib, + pkgs, + ... +}: +let + cfg = config.programs.retroarch; + + enabledCores = lib.filterAttrs (_: core: core.enable) cfg.cores; +in +{ + meta.maintainers = [ + lib.hm.maintainers.jtrrll + ]; + + options.programs.retroarch = { + enable = lib.mkEnableOption "RetroArch"; + + package = lib.mkPackageOption pkgs "retroarch" { + default = "retroarch-bare"; + }; + + finalPackage = lib.mkOption { + type = lib.types.package; + readOnly = true; + description = '' + Resulting RetroArch package. + ''; + }; + + cores = lib.mkOption { + type = lib.types.attrsOf ( + lib.types.submodule ( + { name, ... }: + { + options = { + enable = lib.mkEnableOption "RetroArch core"; + package = lib.mkPackageOption pkgs [ "libretro" name ] { }; + }; + } + ) + ); + default = { }; + example = lib.literalExpression '' + { + mgba.enable = true; # Uses pkgs.libretro.mgba + snes9x = { + enable = true; + package = pkgs.libretro.snes9x2010; + }; + custom-core = { + enable = true; + package = pkgs.callPackage ./custom-core.nix { }; + }; + } + ''; + description = '' + RetroArch cores to enable. You can provide custom core packages. + ''; + }; + + settings = lib.mkOption { + type = lib.types.attrsOf lib.types.str; + default = { }; + example = { + input_max_users = "4"; + menu_scale_factor = "0.950000"; + netplay_nickname = "username"; + video_driver = "vulkan"; + video_fullscreen = "true"; + }; + description = '' + RetroArch configuration settings. + + See + for available configuration options. + ''; + }; + }; + + config = lib.mkIf cfg.enable { + programs.retroarch.finalPackage = ( + cfg.package.wrapper { + inherit (cfg) settings; + cores = lib.mapAttrsToList (_: core: core.package) enabledCores; + } + ); + home.packages = [ cfg.finalPackage ]; + }; +} diff --git a/tests/modules/programs/retroarch/cores.nix b/tests/modules/programs/retroarch/cores.nix new file mode 100644 index 000000000..228763ac4 --- /dev/null +++ b/tests/modules/programs/retroarch/cores.nix @@ -0,0 +1,34 @@ +{ config, pkgs, ... }: +{ + imports = [ ./stubs.nix ]; + + programs.retroarch = { + enable = true; + cores = { + mgba.enable = true; + snes9x = { + enable = true; + package = pkgs.libretro.snes9x2010; + }; + custom = { + enable = true; + package = config.lib.test.mkStubPackage { + buildScript = '' + mkdir -p $out/lib/retroarch/cores + touch $out/lib/retroarch/cores/custom_libretro.so + ''; + extraAttrs.libretroCore = "/lib/retroarch/cores"; + }; + }; + }; + }; + + nmt.script = '' + assertFileExists home-path/bin/retroarch + assertFileRegex home-path/bin/retroarch 'L.*lib/retroarch/cores' + + assertFileExists home-path/lib/retroarch/cores/mgba_libretro.so + assertFileExists home-path/lib/retroarch/cores/snes9x2010_libretro.so + assertFileExists home-path/lib/retroarch/cores/custom_libretro.so + ''; +} diff --git a/tests/modules/programs/retroarch/default.nix b/tests/modules/programs/retroarch/default.nix new file mode 100644 index 000000000..e80e72c9c --- /dev/null +++ b/tests/modules/programs/retroarch/default.nix @@ -0,0 +1,5 @@ +{ lib, pkgs, ... }: +lib.optionalAttrs pkgs.stdenv.hostPlatform.isLinux { + retroarch-cores = ./cores.nix; + retroarch-settings = ./settings.nix; +} diff --git a/tests/modules/programs/retroarch/settings.nix b/tests/modules/programs/retroarch/settings.nix new file mode 100644 index 000000000..03d1c9815 --- /dev/null +++ b/tests/modules/programs/retroarch/settings.nix @@ -0,0 +1,28 @@ +{ pkgs, ... }: +{ + imports = [ ./stubs.nix ]; + + programs.retroarch = { + enable = true; + settings = { + input_max_users = "4"; + menu_scale_factor = "0.950000"; + netplay_nickname = "username"; + video_driver = "vulkan"; + video_fullscreen = "true"; + }; + }; + + nmt.script = '' + assertFileExists home-path/bin/retroarch + assertFileRegex home-path/bin/retroarch 'appendconfig.*declarative-retroarch\.cfg' + + configFile=$(grep -aoP '/nix/store/[a-z0-9]+-declarative-retroarch\.cfg' $TESTED/home-path/bin/retroarch | head -1) + assertFileExists "$configFile" + assertFileContains "$configFile" 'input_max_users = "4"' + assertFileContains "$configFile" 'menu_scale_factor = "0.950000"' + assertFileContains "$configFile" 'netplay_nickname = "username"' + assertFileContains "$configFile" 'video_driver = "vulkan"' + assertFileContains "$configFile" 'video_fullscreen = "true"' + ''; +} diff --git a/tests/modules/programs/retroarch/stubs.nix b/tests/modules/programs/retroarch/stubs.nix new file mode 100644 index 000000000..0e4cb307f --- /dev/null +++ b/tests/modules/programs/retroarch/stubs.nix @@ -0,0 +1,32 @@ +{ + config, + pkgs, + realPkgs, + ... +}: +let + mkLibretroCore = + name: + config.lib.test.mkStubPackage { + buildScript = '' + mkdir -p $out/lib/retroarch/cores + touch $out/lib/retroarch/cores/${name}_libretro.so + ''; + extraAttrs.libretroCore = "/lib/retroarch/cores"; + }; +in +{ + test.stubs = { + libretro = { + extraAttrs = { + mgba = mkLibretroCore "mgba"; + snes9x2010 = mkLibretroCore "snes9x2010"; + }; + }; + retroarch-bare = { + extraAttrs = { + inherit (realPkgs.retroarch-bare) wrapper; + }; + }; + }; +}