blob: 4618ae8e47aa26ec579aa57a62c085e75d4afe38 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
|
{
sysLib,
lib,
pkgs,
cfg,
}: let
esa = lib.strings.escapeShellArg;
expandHomePath = path:
if lib.strings.hasPrefix "~" path
then "${cfg.userSourceDir}${lib.strings.removePrefix "~" path}"
else
builtins.throw
''
BUG: Every pathname needs to start with a '~'.
This should have been checked by the NixOS module system?
'';
getIgnored = paths_to_ignore: path:
serialiseArgs {
ignore =
builtins.filter (x: x != null) (builtins.map (getIgnoredSingle path) paths_to_ignore);
};
getIgnoredSingle = path: pathToIgnore: let
clean_path_to_ignore = expandHomePath pathToIgnore;
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;
serialiseArg = key: val:
if builtins.typeOf val == "string"
then esa "-${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
);
mkScriptLine = pathname: let
path =
expandHomePath pathname;
in
lib.strings.concatStringsSep " " [
"unison"
"${serialiseArgs cfg.unisonOptions}"
"$EXTRA_OPTIONS"
"${getIgnored cfg.pathsToIgnore path}"
"${esa path}"
(esa "ssh://${cfg.foreign.userName}@${cfg.foreign.address}/${path}")
];
script = lib.strings.concatStringsSep "\n" (builtins.map mkScriptLine cfg.pathsToSync);
in
sysLib.writeShellScript {
name = "unison-sync";
src = builtins.toFile "unison-backup" (''
#!/usr/bin/env dash
# shellcheck source=/dev/null
SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
export UNISON=${esa cfg.dataDir};
EXTRA_OPTIONS="$UNISON_EXTRA_OPTIONS $*"
''
+ script);
dependencies = with pkgs; [
unison
openssh # needed to connect to the other server
less # needed to show diffs
diffutils # needed to compute diffs
];
}
|