-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathplist_diff.py
More file actions
101 lines (73 loc) · 2.01 KB
/
plist_diff.py
File metadata and controls
101 lines (73 loc) · 2.01 KB
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
92
93
94
95
96
97
98
99
100
101
__author__ = 'namezys'
import plistlib
import pprint
from argparse import ArgumentParser
DESCR = "Compare 2 plist files"
class Append(object):
def __init__(self, v):
self.v = v
def __repr__(self):
return "+%r" % self.v
class Remove(object):
def __init__(self, v):
self.v = v
def __repr__(self):
return "-%r" % self.v
class Replace(object):
def __init__(self, v, v1):
self.v = v
self.v1 = v1
def __repr__(self):
return "%r>%r" % (self.v, self.v1)
def diff_non_dict(v1, v2):
if v1 == v2:
return None
if v1 is None:
return Append(v2)
if v2 is None:
return Remove(v1)
return Replace(v1, v2)
def diff_list(l1, l2):
if len(l1) != len(l2):
return Replace(l1, l2)
res = []
for i in range(len(l1)):
t1 = l1[i]
t2 = l2[i]
r = diff_value(t1, t2)
res.append(r)
if any(l for l in res):
return res
return None
def diff_value(v1, v2):
if isinstance(v1, list) and isinstance(v2, list):
return diff_list(v1, v2)
if not isinstance(v1, dict) or not isinstance(v2, dict):
return diff_non_dict(v1, v2)
keys = set(v1) | set(v2)
res = {}
for k in keys:
t1 = v1.get(k, None)
t2 = v2.get(k, None)
r = diff_value(t1, t2)
if r is not None:
res[k] = r
return res or None
def test():
a = {"a": "a", "b": "b", "d": 1}
b = {"a": "a", "c": "c", "d": "2"}
v1 = {"a": {"a": a}, "b": "bb", "c": 1, "d": [1, 2, 3]}
v2 = {"a": {"a": b}, "b": "cc", "c": 1, "d": [1, 2]}
r = diff_value(v1, v2)
pprint.pprint(r)
def main():
parser = ArgumentParser(description=DESCR)
parser.add_argument("file_a", help="First file")
parser.add_argument("file_b", help="Second file")
args = parser.parse_args()
a = plistlib.readPlist(args.file_a)
b = plistlib.readPlist(args.file_b)
r = diff_value(a, b)
pprint.pprint(r)
if __name__ == "__main__":
main()