From a8c244097ab5b3098fff8ece85b7a28049efd709 Mon Sep 17 00:00:00 2001 From: PseudoFractal Date: Sun, 14 Jun 2026 23:45:25 +0530 Subject: [PATCH 1/2] add nix flake with home manager module Adds a Nix flake that builds rmcl from source via rustPlatform.buildRustPackage and a Home Manager module for configuring programs.rmcl. The HM module generates config.toml and theme.toml from Nix options. The package option defaults to the flake's own build so users don't need rmcl in their nixpkgs. Also adds Nix install instructions and a HM usage example to the README, and updates .gitignore for Nix build artifacts. --- .gitignore | 3 + README.md | 25 ++++++ flake.lock | 61 ++++++++++++++ flake.nix | 238 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 327 insertions(+) create mode 100644 flake.lock create mode 100644 flake.nix diff --git a/.gitignore b/.gitignore index 1a4595e..d1bc5ee 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,5 @@ /target *.log +result +result-* +.direnv diff --git a/README.md b/README.md index 8a8c86b..2f936cd 100644 --- a/README.md +++ b/README.md @@ -84,6 +84,30 @@ paru -S rmcl-bin paru -S rmcl-git ``` +### Nix + +```sh +nix run github:objz/rmcl +nix profile install github:objz/rmcl +``` + +a home manager module is also available. add the flake as an input and enable it: + +```nix +{ + inputs = { + nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable"; + rmcl.url = "github:objz/rmcl"; + }; + + outputs = { rmcl, ... }: { + homeManagerModules.default = rmcl.homeManagerModules.default; + }; +} +``` + +see `flake.nix` for available options (`programs.rmcl.*`). + ### Cargo ```sh @@ -102,6 +126,7 @@ package managers: [![Homebrew tap](https://img.shields.io/badge/homebrew-objz%2Ftap-FBB040?style=for-the-badge&logo=homebrew)](https://github.com/objz/homebrew-tap) [![WinGet](https://img.shields.io/badge/winget-Objz.Rmcl-0078D4?style=for-the-badge&logo=windows11)](https://winstall.app/apps/Objz.Rmcl) [![Chocolatey](https://img.shields.io/chocolatey/v/rmcl?style=for-the-badge&logo=chocolatey)](https://community.chocolatey.org/packages/rmcl) +[![Nix](https://img.shields.io/badge/nix-5277C4?style=for-the-badge&logo=nixos)](https://github.com/objz/rmcl) aur: diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..f6166f0 --- /dev/null +++ b/flake.lock @@ -0,0 +1,61 @@ +{ + "nodes": { + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1781359544, + "narHash": "sha256-iUuzKQcyXvopYDDzFpMK5eQKP3WIJExYny2kJtbgUcE=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "9f11f828c213641c2369a9f1fa31fe31557e3156", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..216dc66 --- /dev/null +++ b/flake.nix @@ -0,0 +1,238 @@ +{ + description = "rmcl: A fully featured Minecraft TUI launcher"; + + inputs = { + nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable"; + flake-utils.url = "github:numtide/flake-utils"; + }; + + outputs = { + self, + nixpkgs, + flake-utils, + ... + }: + flake-utils.lib.eachDefaultSystem (system: let + pkgs = nixpkgs.legacyPackages.${system}; + in { + packages.default = pkgs.rustPlatform.buildRustPackage { + pname = "rmcl"; + version = (builtins.fromTOML (builtins.readFile ./Cargo.toml)).package.version; + src = pkgs.lib.cleanSource ./.; + cargoLock.lockFile = ./Cargo.lock; + nativeBuildInputs = [pkgs.jdk]; + + meta = with pkgs.lib; { + description = "A fully featured Minecraft TUI launcher"; + homepage = "https://github.com/objz/rmcl"; + license = licenses.gpl3Only; + mainProgram = "rmcl"; + }; + }; + }) + // { + homeManagerModules.default = { + config, + lib, + pkgs, + ... + }: + with lib; let + cfg = config.programs.rmcl; + tomlFormat = pkgs.formats.toml {}; + filterNulls = filterAttrs (_: v: v != null); + nullStr = types.nullOr types.str; + nullUint = types.nullOr types.ints.unsigned; + pathsCfg = { + instances_dir = cfg.instancesDir; + meta_dir = cfg.metaDir; + java_path = cfg.javaPath; + }; + defaultsCfg = { + memory_min = cfg.memoryMin; + memory_max = cfg.memoryMax; + }; + uiCfg = { + error_auto_dismiss_ms = cfg.errorAutoDismissMs; + error_slide_start_ms = cfg.errorSlideStartMs; + error_fly_out_ms = cfg.errorFlyOutMs; + max_error_events = cfg.maxErrorEvents; + }; + in { + options.programs.rmcl = { + enable = mkEnableOption "rmcl: A fully featured Minecraft TUI launcher"; + + package = mkOption { + type = types.package; + default = self.packages.${pkgs.stdenv.hostPlatform.system}.default; + defaultText = literalExpression "self.packages.\${pkgs.stdenv.hostPlatform.system}.default"; + description = "The rmcl package to use."; + }; + + # -- config.toml: paths -- + instancesDir = mkOption { + type = nullStr; + default = null; + example = "~/games/minecraft/instances"; + description = '' + Where Minecraft instances are stored. + Default: ~/.local/share/rmcl/instances. + ''; + }; + + metaDir = mkOption { + type = nullStr; + default = null; + example = "~/games/minecraft/meta"; + description = '' + Metadata and cache directory. + Default: ~/.local/share/rmcl/meta. + ''; + }; + + javaPath = mkOption { + type = nullStr; + default = null; + example = "${pkgs.jdk}/bin/java"; + description = '' + Path to Java executable for launching Minecraft. + Default: falls back to JAVA_HOME. + ''; + }; + + # -- config.toml: defaults -- + memoryMin = mkOption { + type = nullStr; + default = null; + example = "512M"; + description = '' + Minimum Java heap size (Xms) for Minecraft instances. + Default: "512M". + ''; + }; + + memoryMax = mkOption { + type = nullStr; + default = null; + example = "4G"; + description = '' + Maximum Java heap size (Xmx) for Minecraft instances. + Default: "2G". + ''; + }; + + # -- config.toml: ui -- + errorAutoDismissMs = mkOption { + type = nullUint; + default = null; + example = 5000; + description = '' + How long (ms) an error toast stays visible before auto-dismissing. + Default: 5000. + ''; + }; + + errorSlideStartMs = mkOption { + type = nullUint; + default = null; + example = 3500; + description = '' + When (ms) the error toast begins sliding off screen. + Default: 3500. + ''; + }; + + errorFlyOutMs = mkOption { + type = nullUint; + default = null; + example = 300; + description = '' + Duration (ms) of the error toast fly-out animation. + Default: 300. + ''; + }; + + maxErrorEvents = mkOption { + type = nullUint; + default = null; + example = 50; + description = '' + Maximum number of error events retained in the log buffer. + Default: 50. + ''; + }; + + # -- theme.toml -- + theme = mkOption { + type = types.str; + default = "catppuccin"; + example = "dracula"; + description = '' + Base theme name (one of: catppuccin, dracula, nord, gruvbox, + one-dark, solarized, tailwind, tokyo-night, rose-pine, terminal) + or an absolute path to a custom theme file. + ''; + }; + + borderStyle = mkOption { + type = types.enum ["rounded" "plain" "double" "thick"]; + default = "rounded"; + description = "Widget border style."; + }; + + customTheme = mkOption { + type = types.attrs; + default = {}; + example = literalExpression '' + { + accent = "Red"; + text = "White"; + surface = { Rgb = [36 36 36]; }; + background = { Rgb = [30 30 30]; }; + } + ''; + description = '' + Color overrides applied on top of the base theme. + Each key is a color slot (accent, accent_dim, text, text_dim, + text_bright, success, error, warning, info, diff_added, + diff_removed, diff_context, border, surface, background). + Values are either a named color string ("Red", "White", etc.) + or an RGB inline table ({ Rgb = [R G B]; }). + ''; + }; + + # -- extra config.toml fields -- + extraConfig = mkOption { + type = tomlFormat.type; + default = {}; + example = literalExpression '' + { + general.debug = true; + } + ''; + description = '' + Additional config.toml settings merged into the generated file. + ''; + }; + }; + + config = mkIf cfg.enable { + home.packages = [cfg.package]; + + xdg.configFile."rmcl/config.toml".source = tomlFormat.generate "rmcl-config.toml" (recursiveUpdate { + paths = filterNulls pathsCfg; + defaults = filterNulls defaultsCfg; + ui = filterNulls uiCfg; + } cfg.extraConfig); + + xdg.configFile."rmcl/theme.toml".source = tomlFormat.generate "rmcl-theme.toml" ({ + inherit (cfg) theme; + border_style = cfg.borderStyle; + } + // optionalAttrs (cfg.customTheme != {}) { + custom = cfg.customTheme; + }); + }; + }; + }; +} From 027510ea34b07a81e8e0f63199a300a899b68957 Mon Sep 17 00:00:00 2001 From: PseudoFractal Date: Mon, 15 Jun 2026 22:41:58 +0530 Subject: [PATCH 2/2] fix(nix): disable tests in nix build sandbox --- flake.nix | 2 ++ 1 file changed, 2 insertions(+) diff --git a/flake.nix b/flake.nix index 216dc66..0395ad6 100644 --- a/flake.nix +++ b/flake.nix @@ -22,6 +22,8 @@ cargoLock.lockFile = ./Cargo.lock; nativeBuildInputs = [pkgs.jdk]; + doCheck = false; + meta = with pkgs.lib; { description = "A fully featured Minecraft TUI launcher"; homepage = "https://github.com/objz/rmcl";