From 204f9808d3f007f2d4a4f71f96468085f0123371 Mon Sep 17 00:00:00 2001
From: Kirill Elagin <kirelagin@gmail.com>
Date: Thu, 30 Dec 2021 06:47:44 -0500
Subject: [PATCH] sagemath: add module

---
 .github/CODEOWNERS                            |  3 +
 modules/misc/news.nix                         |  7 +++
 modules/modules.nix                           |  1 +
 modules/programs/sagemath.nix                 | 63 +++++++++++++++++++
 tests/default.nix                             |  1 +
 tests/modules/programs/sagemath/default.nix   |  1 +
 .../programs/sagemath/init-expected.sage      |  1 +
 tests/modules/programs/sagemath/sagemath.nix  | 20 ++++++
 8 files changed, 97 insertions(+)
 create mode 100644 modules/programs/sagemath.nix
 create mode 100644 tests/modules/programs/sagemath/default.nix
 create mode 100644 tests/modules/programs/sagemath/init-expected.sage
 create mode 100644 tests/modules/programs/sagemath/sagemath.nix

diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index c2516f7b6..1241b106c 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -194,6 +194,9 @@
 
 /modules/programs/rtorrent.nix                        @marsam
 
+/modules/programs/sagemath.nix                        @kirelagin
+/tests/modules/programs/sagemath                      @kirelagin
+
 /modules/programs/sbt.nix                             @kubukoz
 /tests/modules/programs/sbt                           @kubukoz
 
diff --git a/modules/misc/news.nix b/modules/misc/news.nix
index 7a77fe8a1..deeac3455 100644
--- a/modules/misc/news.nix
+++ b/modules/misc/news.nix
@@ -2344,6 +2344,13 @@ in
           A new module is available: 'services.swayidle'.
         '';
       }
+
+      {
+        time = "2022-01-11T12:26:43+00:00";
+        message = ''
+          A new module is available: 'programs.sagemath'.
+        '';
+      }
     ];
   };
 }
diff --git a/modules/modules.nix b/modules/modules.nix
index b970e0def..2b2f78790 100644
--- a/modules/modules.nix
+++ b/modules/modules.nix
@@ -128,6 +128,7 @@ let
     ./programs/rofi-pass.nix
     ./programs/rofi.nix
     ./programs/rtorrent.nix
+    ./programs/sagemath.nix
     ./programs/sbt.nix
     ./programs/scmpuff.nix
     ./programs/senpai.nix
diff --git a/modules/programs/sagemath.nix b/modules/programs/sagemath.nix
new file mode 100644
index 000000000..b07cec10f
--- /dev/null
+++ b/modules/programs/sagemath.nix
@@ -0,0 +1,63 @@
+{ config, lib, pkgs, ... }:
+
+let
+
+  cfg = config.programs.sagemath;
+
+  inherit (lib) literalExpression mkEnableOption mkOption types;
+
+in {
+  meta.maintainers = [ lib.maintainers.kirelagin ];
+
+  options.programs.sagemath = {
+    enable = mkEnableOption "SageMath, a mathematics software system";
+
+    package = mkOption {
+      type = types.package;
+      default = pkgs.sage;
+      defaultText = literalExpression "pkgs.sage";
+      description = "The SageMath package to use.";
+    };
+
+    configDir = mkOption {
+      type = types.str;
+      default = "${config.xdg.configHome}/sage";
+      defaultText = literalExpression "\${config.xdg.configHome}/sage";
+      description = ''
+        Directory where the <filename>sage.init</filename> file will be stored.
+        Note that the upstream default is <filename>~/.sage</filename>,
+        but our default is to follow XDG.
+      '';
+    };
+
+    dataDir = mkOption {
+      type = types.str;
+      default = "${config.xdg.dataHome}/sage";
+      defaultText = literalExpression "\${config.xdg.dataHome}/sage";
+      description = ''
+        Location for <envar>DOT_SAGE</envar>.
+        Note that the upstream default is <filename>~/.sage</filename>,
+        but our default is to follow XDG.
+      '';
+    };
+
+    initScript = mkOption {
+      type = types.lines;
+      default = "";
+      example = "%colors linux";
+      description = ''
+        Contents of the <filename>init.sage</filename> file that is loaded on startup.
+      '';
+    };
+  };
+
+  config = lib.mkIf cfg.enable {
+    home.packages = [ cfg.package ];
+
+    home.file."${cfg.configDir}/init.sage".text = cfg.initScript;
+    home.sessionVariables = {
+      DOT_SAGE = cfg.dataDir;
+      SAGE_STARTUP_FILE = "${cfg.configDir}/init.sage";
+    };
+  };
+}
diff --git a/tests/default.nix b/tests/default.nix
index de7a2ef55..89361a29c 100644
--- a/tests/default.nix
+++ b/tests/default.nix
@@ -89,6 +89,7 @@ import nmt {
     ./modules/programs/powerline-go
     ./modules/programs/qutebrowser
     ./modules/programs/readline
+    ./modules/programs/sagemath
     ./modules/programs/sbt
     ./modules/programs/scmpuff
     ./modules/programs/sm64ex
diff --git a/tests/modules/programs/sagemath/default.nix b/tests/modules/programs/sagemath/default.nix
new file mode 100644
index 000000000..678ba0399
--- /dev/null
+++ b/tests/modules/programs/sagemath/default.nix
@@ -0,0 +1 @@
+{ sagemath = ./sagemath.nix; }
diff --git a/tests/modules/programs/sagemath/init-expected.sage b/tests/modules/programs/sagemath/init-expected.sage
new file mode 100644
index 000000000..051034177
--- /dev/null
+++ b/tests/modules/programs/sagemath/init-expected.sage
@@ -0,0 +1 @@
+%colors linux
diff --git a/tests/modules/programs/sagemath/sagemath.nix b/tests/modules/programs/sagemath/sagemath.nix
new file mode 100644
index 000000000..2f30ac502
--- /dev/null
+++ b/tests/modules/programs/sagemath/sagemath.nix
@@ -0,0 +1,20 @@
+{ config, ... }:
+
+{
+  programs.sagemath = {
+    enable = true;
+    configDir = "${config.xdg.configHome}/sage";
+    dataDir = "${config.xdg.dataHome}/sage";
+    initScript = ''
+      %colors linux
+    '';
+  };
+
+  test.stubs.sage = { };
+
+  nmt.script = ''
+    assertFileExists home-files/.config/sage/init.sage
+    assertFileContent home-files/.config/sage/init.sage \
+      ${./init-expected.sage}
+  '';
+}