-
Notifications
You must be signed in to change notification settings - Fork 0
/
dbd_diff.py
151 lines (120 loc) · 3.99 KB
/
dbd_diff.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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
import sys
import os
import dbd
import argparse
import re
#
# dbd_diff.py
# tool for displaying differences between client definitions.
#
parser = argparse.ArgumentParser(
prog="dbd_diff",
description="Diff tool for dbd versions"
)
parser.add_argument('src',
help="Directory containing .dbd files, or filename of .dbd")
parser.add_argument("target_version",
help="Target client version")
parser.add_argument("compare_version",
help="Client version to compare against")
parser.add_argument('-v', '--verbose',
action="store_true")
args = parser.parse_args()
# validate args
is_src_file = os.path.isfile(args.src)
is_src_dir = os.path.isdir(args.src)
if not is_src_file and not is_src_dir:
print("src is not valud.")
sys.exit(1)
version_pattern = r"^(\d+)\.(\d+)\.(\d+)\.(\d+)$"
target_version = None
compare_version = None
if match := re.match(version_pattern, args.target_version):
target_version = dbd.build_version_raw(
int(match.group(1)),
int(match.group(2)),
int(match.group(3)),
int(match.group(4))
)
else:
print("Target version doesnt match pattern.")
sys.exit(1)
if match := re.match(version_pattern, args.compare_version):
compare_version = dbd.build_version_raw(
int(match.group(1)),
int(match.group(2)),
int(match.group(3)),
int(match.group(4))
)
else:
print("Compare version doesnt match pattern.")
sys.exit(1)
defintion_files = []
root_path = ""
if is_src_file:
root_path = os.path.dirname(args.src)
defintion_files = [os.path.basename(args.src)]
else:
root_path = args.src
defintion_files = os.listdir(args.src)
defintion_files = [file for file in defintion_files if file.endswith('.dbd')]
if(args.verbose):
print("Found {} .dbd files.".format(len(defintion_files)))
summary = {
"checked": 0,
"changed": 0
}
checked_definitions = 0
changed_definitions = 0
multi_defs = len(defintion_files) > 1
shown_def_name = False
def msg_print(msg):
global shown_def_name
if (not shown_def_name):
print("---- " + defintion_file + " ----")
shown_def_name = True
print(msg)
for defintion_file in defintion_files:
shown_def_name = False
parsed = dbd.parse_dbd_file(os.path.join(root_path, defintion_file))
target_def = None
compare_def = None
for definition in parsed.definitions:
for build in definition.builds:
if build == target_version:
target_def = definition
if build == compare_version:
compare_def = definition
if not target_def and not compare_def:
continue
summary["checked"] += 1
if not target_def:
msg_print("Unable to find target version definition.")
if not compare_def:
msg_print("Unable to find compare version definition.")
if not target_def or not compare_def:
summary["changed"] += 1
continue
target_entries_len = len(target_def.entries)
compare_entries_len = len(compare_def.entries)
if args.verbose:
if target_entries_len != compare_entries_len:
msg_print("Entry count different.")
largest_entries = max(target_entries_len, compare_entries_len)
has_changes = False
for i in range(0, largest_entries - 1):
target_entry = target_def.entries[i] or None
compare_entry = compare_def.entries[i] or None
if target_entry.__str__() != compare_entry.__str__():
msg_print("- Change at row {} - ".format(i))
msg_print(target_entry)
msg_print(compare_entry)
has_changes = True
if not has_changes:
if (not multi_defs):
msg_print("No changes")
else:
summary["changed"] += 1
if(args.verbose):
print("{checked} definitions checked, {changed} changes.".format(**summary))
sys.exit(0)