forked from amandasaurus/podiff
-
Notifications
You must be signed in to change notification settings - Fork 0
/
podiff.py
executable file
·127 lines (94 loc) · 4.66 KB
/
podiff.py
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#! /usr/bin/env python2
import polib, os, sys, argparse
def podiff(old_pofile, new_pofile):
# TODO support context
old_msgs = dict(((entry.msgid, entry.msgctxt, entry.msgid_plural), entry) for entry in old_pofile)
new_msgs = dict(((entry.msgid, entry.msgctxt, entry.msgid_plural), entry) for entry in new_pofile)
added_msgs = set(new_msgs.keys()) - set(old_msgs.keys())
deleted_msgs = set(old_msgs.keys()) - set(new_msgs.keys())
common_msgs = set(old_msgs.keys()) & set(new_msgs.keys())
changed = []
for common in common_msgs:
old_msg = old_msgs[common]
new_msg = new_msgs[common]
identical = True
for attr in ['msgid', 'msgid_plural', 'msgstr']:
if getattr(old_msg, attr) != getattr(new_msg, attr):
identical = False
if set(old_msg.flags) != set(new_msg.flags):
identical = False
if not identical:
changed.append({'old':old_msg, 'new':new_msg})
# metadata
added_metadata_keys = set(new_pofile.metadata) - set(old_pofile.metadata)
deleted_metadata_keys = set(old_pofile.metadata) - set(new_pofile.metadata)
common_metadata_keys = set(old_pofile.metadata) & set(new_pofile.metadata)
changed_metadata = []
for common in common_metadata_keys:
old_metadata = old_pofile.metadata[common]
new_metadata = new_pofile.metadata[common]
if old_metadata != new_metadata:
changed_metadata.append({'key': common, 'old':old_metadata, 'new':new_metadata})
return {
'added':[new_msgs[x] for x in added_msgs], 'deleted':[old_msgs[x] for x in deleted_msgs], 'changed':changed,
'added_metadata_keys': [x for x in new_pofile.metadata.items() if x[0] in added_metadata_keys],
'deleted_metadata_keys': [x for x in old_pofile.metadata.items() if x[0] in deleted_metadata_keys],
'changed_metadata': changed_metadata,
}
def _repr_msg(msg):
if msg.msgid_plural == '':
return '%r' % msg.msgid
else:
return '%r/%r' % (msg.msgid, msg.msgid_plural)
def pprint_diff(diff):
if len(diff['added']) > 0:
for msg in diff['added']:
if msg.msgid_plural == '':
print "New msg: msgid=%r msgstr=%r msgctxt=%r" % (msg.msgid, msg.msgstr, msg.msgctxt)
else:
print "New msg: msgid=%r/%r msgstr=%r msgctxt=%r" % (msg.msgid, msg.msgid_plural, msg.msgstr, msg.msgctxt)
if len(diff['deleted']) > 0:
for msg in diff['deleted']:
if msg.msgid_plural == '':
print "Deleted msg: msgid=%r msgstr=%r msgctxt=%r" % (msg.msgid, msg.msgstr, msg.msgctxt)
else:
print "Deleted msg: msgid=%r/%r msgstr=%r msgctxt=%r" % (msg.msgid, msg.msgid_plural, msg.msgstr, msg.msgctxt)
for msg in diff['changed']:
old, new = msg['old'], msg['new']
change = ""
print "Changed msg: %s" % _repr_msg(old)
if old.msgstr != new.msgstr:
print "\tmsgstr old: %r\n\t new: %r" % (old.msgstr, new.msgstr)
if old.msgstr_plural != new.msgstr_plural:
print "\tmsgstr_plural old: %r\n\tnew: %r" % (old.msgstr_plural, new.msgstr_plural)
added_flags = set(new.flags) - set(old.flags)
deleted_flags = set(old.flags) - set(new.flags)
if len(added_flags) > 0:
print "\tAdded flags: %s" % (",".join(sorted(added_flags)))
if len(deleted_flags) > 0:
print "\tDelete flags: %s" % (",".join(sorted(deleted_flags)))
for key, value in diff['added_metadata_keys']:
print "New metadata: %r: %r" % (key, value)
for key, value in diff['deleted_metadata_keys']:
print "Deleted metadata: %r: %r" % (key, value)
for key in diff['changed_metadata']:
print "Changed metadata: %r" % key['key']
print "\told: %r" % key['old']
print "\tnew: %r" % key['new']
diff_keys = ['added', 'deleted', 'changed', 'added_metadata_keys', 'deleted_metadata_keys', 'changed_metadata']
if all(len(diff[key]) == 0 for key in diff_keys):
print "pofiles are semantically identical"
def exit_code(diff):
diff_keys = ['added', 'deleted', 'changed', 'added_metadata_keys', 'deleted_metadata_keys', 'changed_metadata']
return 0 if all(len(diff[key]) == 0 for key in diff_keys) else 1
def main():
parser = argparse.ArgumentParser()
#parser.add_argument('--no-ignore-comments')
parser.add_argument('old_file')
parser.add_argument('new_file')
args = parser.parse_args()
diffs = podiff(polib.pofile(args.old_file), polib.pofile(args.new_file))
pprint_diff(diffs)
return exit_code(diffs)
if __name__ == '__main__':
sys.exit(main())