about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--hm/soispha/conf/default.nix1
-rw-r--r--hm/soispha/conf/unison/default.nix99
2 files changed, 100 insertions, 0 deletions
diff --git a/hm/soispha/conf/default.nix b/hm/soispha/conf/default.nix
index 3a267102..c7f000cb 100644
--- a/hm/soispha/conf/default.nix
+++ b/hm/soispha/conf/default.nix
@@ -37,6 +37,7 @@
     ./taskwarrior
     ./timewarrior
     ./tridactyl
+    ./unison
     ./xdg
     ./yambar
     ./ytcc
diff --git a/hm/soispha/conf/unison/default.nix b/hm/soispha/conf/unison/default.nix
new file mode 100644
index 00000000..d7603bd9
--- /dev/null
+++ b/hm/soispha/conf/unison/default.nix
@@ -0,0 +1,99 @@
+{
+  lib,
+  config,
+  nixosConfig,
+  sysLib,
+  pkgs,
+  ...
+}: let
+  unisonPath = "${config.xdg.dataHome}/unison";
+
+  # These are only used for the script
+  unisonOptions = {
+    sshcmd = "ssh";
+    ui = "text";
+    auto = "true";
+  };
+
+  paths_to_keep = [
+    "~/.local/state/mpv"
+    "~/.local/state/nvim"
+    "~/.local/share"
+    "~/.local/.Trash-1000"
+
+    "~/.mozilla/.Trash-1000"
+    "~/.mozilla/firefox"
+
+    "~/media"
+    "~/school"
+    "~/repos"
+  ];
+
+  hostName = let
+    hn = nixosConfig.networking.hostName;
+  in
+    if hn == "tiamat"
+    then "apzu"
+    else if hn == "apzu"
+    then "tiamat"
+    else builtins.throw "Host (${hn}) not yet covered in the unison host mapping.";
+
+  mkPath = path:
+    if lib.strings.hasPrefix "~" path
+    then "${builtins.elemAt (builtins.attrNames config.home.persistence)
+      0}${lib.strings.removePrefix "~" path}"
+    else
+      builtins.throw
+      "Every pathname needs to start with a '~'";
+
+  mkPair = pathname: let
+    path = mkPath pathname;
+  in {
+    name = "${pathname}";
+    value = {
+      stateDirectory = unisonPath;
+      roots = [
+        "${path}"
+        "ssh://${config.home.username}@${hostName}.fritz.box/${path}"
+      ];
+    };
+  };
+
+  serialiseArg = key: val:
+    lib.strings.concatStringsSep " "
+    (lib.forEach (lib.toList val) (x: lib.strings.escapeShellArg "-${key}=${lib.escape ["="] x}"));
+  serialiseArgs = args: lib.strings.concatStringsSep " " (lib.mapAttrsToList serialiseArg args);
+
+  esa = a: lib.strings.escapeShellArg a;
+
+  mkScriptLine = pathname: let
+    path =
+      mkPath pathname;
+  in
+    lib.strings.concatStringsSep " " [
+      "unison"
+      "${serialiseArgs unisonOptions}"
+      "${esa path}"
+      (esa "ssh://${config.home.username}@${hostName}.fritz.box/${path}")
+    ];
+
+  script = lib.strings.concatStringsSep "\n" (builtins.map mkScriptLine paths_to_keep);
+
+  pairs = builtins.listToAttrs (builtins.map mkPair paths_to_keep);
+in {
+  home.packages = [
+    (sysLib.writeShellScript {
+      name = "unison-backup";
+      src = builtins.toFile "unison-backup" (''
+          #!/usr/bin/env sh
+          export UNISON=${esa unisonPath};
+        ''
+        + script);
+      dependencies = with pkgs; [unison openssh];
+    })
+  ];
+  services.unison = {
+    enable = true;
+    inherit pairs;
+  };
+}