-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdifftree-touch
executable file
·63 lines (55 loc) · 1.96 KB
/
difftree-touch
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
#! /usr/bin/env python3
# Reads an output logfile produced by difftree and touches each file
# mentioned in it, that is, sets access and modification times to the
# current time. This seems to trigger Time Machine to "notice" that
# the files need to be backed up. (For good measure, for each file
# touched, the parent directory is also touched.) Thus, if there are
# persistent differences between a filesystem and its Time Machine
# backups, running this script causes those differences to be
# eliminated in the next backup.
#
# Usage: difftree-touch label=tree logfile
#
# `tree` should be the (non-backup) directory tree difftree was
# originally run against. For example, if difftree was run against
# the home directory with label "current", then this script would be
# invoked as:
#
# difftree-touch current=$HOME logfile
#
# Greg Janee <[email protected]>
import errno
import os
import re
import sys
def format_exception(exception):
return f"{type(exception).__name__}: {exception!s}"
def error(exception_type, exception, traceback):
print("difftree-touch: " + format_exception(exception), file=sys.stderr)
sys.exit(1)
sys.excepthook = error
if len(sys.argv) != 3 or not re.match("(\w+)=(.*)", sys.argv[1]):
print("Usage: difftree-touch label=tree logfile", file=sys.stderr)
sys.exit(1)
label, tree = re.match("(\w+)=(.*)", sys.argv[1]).groups()
logfile = sys.argv[2]
def touch(file):
try:
os.utime(file, follow_symlinks=False)
except OSError as e:
if e.errno == errno.ENOENT:
print(
f"difftree-touch: warning: {format_exception(e)}: {file}",
file=sys.stderr
)
else:
raise
for line in open(logfile):
m = (
re.match("(file|directory) (.*) differs$", line[:-1])
or re.match(f"only in {label}: (file|directory) (.*)", line[:-1])
)
if m:
file = os.path.join(tree, m.group(2))
touch(file)
touch(os.path.dirname(file))