blob: 831993c15ee4aa21fd92203bc898b6c0522ae695 (
plain) (
tree)
|
|
{
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";
# This is useless, with hm links
links = "false";
};
paths_to_keep = [
"~/.local/state/mpv"
"~/.local/state/nvim"
"~/.local/share"
"~/.local/.Trash-1000"
"~/.mozilla/.Trash-1000"
"~/.mozilla/firefox"
"~/media"
"~/school"
"~/repos"
];
paths_to_ignore = [
# already synchronized by the taskserver
"~/.local/share/task"
# Should not be synchronized
"~/.local/share/unison"
];
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.";
unitName = name: builtins.replaceStrings ["/"] ["-"] name;
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 = unitName "${pathname}";
value = {
stateDirectory = unisonPath;
roots = [
"${path}"
"ssh://${config.home.username}@${hostName}.fritz.box/${path}"
];
};
};
getIgnoredSingle = path: path_to_ignore: let
clean_path_to_ignore = mkPath path_to_ignore;
commonPath = builtins.substring 0 (builtins.stringLength path) clean_path_to_ignore;
in
if commonPath == path
then let
preFinalPath =
builtins.substring (builtins.stringLength commonPath)
(builtins.stringLength clean_path_to_ignore)
clean_path_to_ignore;
finalPath =
if lib.strings.hasPrefix "/" preFinalPath
then lib.strings.removePrefix "/" preFinalPath
else preFinalPath;
in "BelowPath ${finalPath}"
else null;
getIgnored = paths_to_ignore: path:
serialiseArgs {
ignore =
builtins.filter (x: x != null) (builtins.map (getIgnoredSingle path) paths_to_ignore);
};
serialiseArg = key: val:
if builtins.typeOf val == "string"
then lib.strings.escapeShellArg "-${key}=${lib.strings.escape ["="] val}"
else if builtins.typeOf val == "list"
then lib.strings.concatStringsSep " " (builtins.map (serialiseArg key) val)
else builtins.throw "Unsupported type: ${builtins.typeOf val}";
serialiseArgs = args:
lib.strings.concatStringsSep " " (
lib.attrsets.mapAttrsToList
serialiseArg
args
);
esa = a: lib.strings.escapeShellArg a;
mkScriptLine = pathname: let
path =
mkPath pathname;
in
lib.strings.concatStringsSep " " [
"unison"
"${serialiseArgs unisonOptions}"
"${getIgnored paths_to_ignore path}"
"${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.sessionVariables = {
UNISON = unisonPath;
};
home.packages = [
pkgs.unison
(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 = false;
inherit pairs;
};
}
|