prismlauncher: add module

This commit is contained in:
mikaeladev 2026-01-30 22:48:22 +00:00 committed by Austin Horstman
parent 6f64dee491
commit 04e5203db6
4 changed files with 192 additions and 0 deletions

View file

@ -0,0 +1,10 @@
{
time = "2026-01-27T20:02:41+00:00";
condition = true;
message = ''
A new module is available: 'programs.prismlauncher'.
An open-source Minecraft launcher that can manage multiple instances,
accounts, and mods. Focused on user freedom and free redistributability.
'';
}

View file

@ -0,0 +1,114 @@
{
config,
lib,
pkgs,
...
}:
let
inherit (pkgs.stdenv.hostPlatform) isDarwin;
inherit (lib)
escapeShellArg
getExe
listToAttrs
literalExpression
mkEnableOption
mkIf
mkMerge
mkOption
mkPackageOption
types
;
cfg = config.programs.prismlauncher;
dataDir =
if (isDarwin && !config.xdg.enable) then
"Library/Application Support/PrismLauncher"
else
"${config.xdg.dataHome}/PrismLauncher";
iniFormat = pkgs.formats.ini { };
impureConfigMerger = filePath: staticSettingsFile: emptySettingsFile: ''
mkdir -p $(dirname '${escapeShellArg filePath}')
if [ ! -e '${escapeShellArg filePath}' ]; then
cat '${escapeShellArg emptySettingsFile}' > '${escapeShellArg filePath}'
fi
${getExe pkgs.crudini} --merge --ini-options=nospace \
'${escapeShellArg filePath}' < '${escapeShellArg staticSettingsFile}'
'';
in
{
meta.maintainers = with lib.hm.maintainers; [
mikaeladev
];
options.programs.prismlauncher = {
enable = mkEnableOption "Prism Launcher";
package = mkPackageOption pkgs "prismlauncher" { nullable = true; };
extraPackages = mkOption {
type = types.listOf types.package;
default = [ ];
description = ''
Additional theme packages to install to the user environment.
Themes can be sourced from <https://github.com/PrismLauncher/Themes> and should
install to `$out/share/PrismLauncher/{themes,iconthemes,catpacks}`.
'';
};
icons = mkOption {
type = types.listOf types.path;
default = [ ];
example = literalExpression "[ ./java.png ]";
description = ''
List of paths to instance icons.
These will be linked in {file}`$XDG_DATA_HOME/PrismLauncher/icons` on Linux and
{file}`~/Library/Application Support/PrismLauncher/icons` on macOS.
'';
};
settings = mkOption {
type = types.attrsOf iniFormat.lib.types.atom;
default = { };
example = {
ShowConsole = true;
ConsoleMaxLines = 100000;
};
description = ''
Configuration written to {file}`prismlauncher.cfg`.
'';
};
};
config = mkIf cfg.enable {
home.packages = mkMerge ([ (mkIf (cfg.package != null) [ cfg.package ]) ] ++ cfg.extraPackages);
home.activation = {
prismlauncherConfigActivation = (
lib.hm.dag.entryAfter [ "linkGeneration" ] (
impureConfigMerger "${dataDir}/prismlauncher.cfg" (iniFormat.generate "prismlauncher-static.cfg" {
General = cfg.settings;
}) (iniFormat.generate "prismlauncher-empty.cfg" { General = { }; })
)
);
};
home.file = mkIf (cfg.icons != [ ]) (
listToAttrs (
map (source: {
name = "${dataDir}/icons/${baseNameOf source}";
value = { inherit source; };
}) cfg.icons
)
);
};
}

View file

@ -0,0 +1,3 @@
{
prismlauncher-settings = ./settings.nix;
}

View file

@ -0,0 +1,65 @@
{
config,
lib,
pkgs,
...
}:
let
configPath = ".local/share/PrismLauncher/prismlauncher.cfg";
preexistingConfig = pkgs.writeText "preexisting.cfg" ''
[General]
ApplicationTheme=system
MaxMemAlloc=8192
MinMemAlloc=512
'';
expectedConfig = pkgs.writeText "expected.cfg" ''
[General]
ApplicationTheme=dark
MaxMemAlloc=8192
MinMemAlloc=512
ConsoleMaxLines=100000
ShowConsole=true
'';
activationScript = pkgs.writeScript "activation" config.home.activation.prismlauncherConfigActivation.data;
in
{
programs.prismlauncher = {
enable = true;
package = config.lib.test.mkStubPackage { };
settings = {
ApplicationTheme = "dark";
ShowConsole = true;
ConsoleMaxLines = 100000;
};
};
home.homeDirectory = lib.mkForce "/@TMPDIR@/hm-user";
nmt.script = ''
export HOME=$TMPDIR/hm-user
# write preexisting config
mkdir -p $HOME/.local/share/PrismLauncher
cat ${preexistingConfig} > $HOME/${configPath}
# run the activation script
substitute ${activationScript} $TMPDIR/activate --subst-var TMPDIR
chmod +x $TMPDIR/activate
$TMPDIR/activate
# validate the merged config
assertFileExists "$HOME/${configPath}"
assertFileContent "$HOME/${configPath}" "${expectedConfig}"
# test idempotence
$TMPDIR/activate
assertFileExists "$HOME/${configPath}"
assertFileContent "$HOME/${configPath}" "${expectedConfig}"
'';
}