From bb14224f51ae4caed12a7b26f245d042c8cf8553 Mon Sep 17 00:00:00 2001
From: Nova Leary <coder.nova99@mailbox.org>
Date: Tue, 21 Jan 2025 06:14:48 -0600
Subject: [PATCH] mu: allow option to set muhome

Allows for the database path for mu to be configured. Useful for keeping
the maildir and mu xapian cache together without having to modify
XDG_CACHE_HOME. Add test to check for custom home setting.

Fixes #5534
---
 modules/programs/mu.nix                       | 19 +++++++++++---
 .../programs/mu/basic-configuration.nix       |  2 +-
 .../programs/mu/custom-configuration.nix      | 25 +++++++++++++++++++
 tests/modules/programs/mu/default.nix         |  5 +++-
 4 files changed, 46 insertions(+), 5 deletions(-)
 create mode 100644 tests/modules/programs/mu/custom-configuration.nix

diff --git a/modules/programs/mu.nix b/modules/programs/mu.nix
index d1543f000..f5ef51b0a 100644
--- a/modules/programs/mu.nix
+++ b/modules/programs/mu.nix
@@ -36,6 +36,16 @@ in {
 
       package = mkPackageOption pkgs "mu" { };
 
+      home = mkOption {
+        type = types.path;
+        default = config.xdg.cacheHome + "/mu";
+        defaultText = literalExpression ''config.xdg.cacheHome + "/mu"'';
+        example = "\${config.home.homeDirectory}/Maildir/.mu";
+        description = ''
+          Directory to store Mu's database.
+        '';
+      };
+
       # No options/config file present for mu, and program author will not be
       # adding one soon. See https://github.com/djcb/mu/issues/882 for more
       # information about this.
@@ -51,9 +61,10 @@ in {
   config = mkIf cfg.enable {
     home.packages = [ cfg.package ];
 
+    home.sessionVariables.MUHOME = cfg.home;
+
     home.activation.runMuInit = let
       maildirOption = genCmdMaildir config.accounts.email.maildirBasePath;
-      dbLocation = config.xdg.cacheHome + "/mu";
       muExe = getExe cfg.package;
       gawkExe = getExe pkgs.gawk;
     in hm.dag.entryAfter [ "writeBoundary" ] ''
@@ -62,10 +73,12 @@ in {
       # In theory, mu is the only thing that creates that directory, and it is
       # only created during the initial index.
       MU_SORTED_ADDRS=$((${muExe} info store | ${gawkExe} '/personal-address/{print $4}' | LC_ALL=C sort | paste -sd ' ') || exit 0)
-      if [[ ! -d "${dbLocation}" || ! "$MU_SORTED_ADDRS" = "${
+      if [[ ! -d "${cfg.home}" || ! "$MU_SORTED_ADDRS" = "${
         concatStringsSep " " sortedAddresses
       }" ]]; then
-        run ${muExe} init ${maildirOption} ${myAddresses} $VERBOSE_ARG;
+        run ${muExe} init ${maildirOption} --muhome "${
+          escapeShellArg cfg.home
+        }" ${myAddresses} $VERBOSE_ARG;
       fi
     '';
   };
diff --git a/tests/modules/programs/mu/basic-configuration.nix b/tests/modules/programs/mu/basic-configuration.nix
index edca63a70..60c14697a 100644
--- a/tests/modules/programs/mu/basic-configuration.nix
+++ b/tests/modules/programs/mu/basic-configuration.nix
@@ -19,6 +19,6 @@
       'if [[ ! -d "/home/hm-user/.cache/mu" || ! "$MU_SORTED_ADDRS" = "foo@example.com hm@example.com" ]]; then'
 
     assertFileContains activate \
-      'run @mu@/bin/mu init --maildir=/home/hm-user/Mail --my-address=foo@example.com --my-address=hm@example.com $VERBOSE_ARG;'
+      'run @mu@/bin/mu init --maildir=/home/hm-user/Mail --muhome "/home/hm-user/.cache/mu" --my-address=foo@example.com --my-address=hm@example.com $VERBOSE_ARG;'
   '';
 }
diff --git a/tests/modules/programs/mu/custom-configuration.nix b/tests/modules/programs/mu/custom-configuration.nix
new file mode 100644
index 000000000..41f9b84ce
--- /dev/null
+++ b/tests/modules/programs/mu/custom-configuration.nix
@@ -0,0 +1,25 @@
+{ config, ... }: {
+  imports = [ ../../accounts/email-test-accounts.nix ];
+
+  accounts.email.accounts = {
+    "hm@example.com" = {
+      mu.enable = true;
+      aliases = [ "foo@example.com" ];
+    };
+  };
+
+  programs.mu = {
+    enable = true;
+    home = config.xdg.dataHome + "/mu";
+  };
+
+  test.stubs.mu = { name = "mu"; };
+
+  nmt.script = ''
+    assertFileContains activate \
+      'if [[ ! -d "/home/hm-user/.local/share/mu" || ! "$MU_SORTED_ADDRS" = "foo@example.com hm@example.com" ]]; then'
+
+    assertFileContains activate \
+      'run @mu@/bin/mu init --maildir=/home/hm-user/Mail --muhome "/home/hm-user/.local/share/mu" --my-address=foo@example.com --my-address=hm@example.com $VERBOSE_ARG;'
+  '';
+}
diff --git a/tests/modules/programs/mu/default.nix b/tests/modules/programs/mu/default.nix
index bdd8b1560..8d150aef3 100644
--- a/tests/modules/programs/mu/default.nix
+++ b/tests/modules/programs/mu/default.nix
@@ -1 +1,4 @@
-{ mu-basic-configuration = ./basic-configuration.nix; }
+{
+  mu-basic-configuration = ./basic-configuration.nix;
+  mu-custom-configuration = ./custom-configuration.nix;
+}