Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 #!/usr/bin/env python | |
| 2 # Copyright 2015 The Chromium Authors. All rights reserved. | |
| 3 # Use of this source code is governed by a BSD-style license that can be | |
| 4 # found in the LICENSE file. | |
| 5 | |
| 6 """Print a diff generated by generate_idl_diff.py. | |
| 7 Before printing, sort the idl data of the diff in alphabetical order or by | |
|
haraken
2015/09/25 10:30:19
sort the diff in the alphabetical order or the ord
shimadaa
2015/09/25 11:31:27
Done.
| |
| 8 diffing tags. | |
| 9 Usage: print_idl_diff.py diff_file.json order | |
| 10 diff.json: | |
| 11 Output of generate_idl_diff.py. A json file consists of a dictionary | |
|
haraken
2015/09/25 10:30:19
The json file contains a dictionary that represent
shimadaa
2015/09/25 11:31:27
Done.
| |
| 12 expressing a diff between two defferent Chrome versions. The structure | |
|
haraken
2015/09/25 10:30:18
different Chromium versions
shimadaa
2015/09/25 11:31:28
Done.
| |
| 13 of the dictionary is like below. | |
| 14 order: | |
| 15 Specify how to sort. Either by using diffing tags or in alphabetical | |
|
haraken
2015/09/25 10:30:18
"ALPHABET" or "TAG"
shimadaa
2015/09/25 11:31:27
Done.
| |
| 16 order. | |
| 17 """ | |
| 18 | |
| 19 from collections import OrderedDict | |
| 20 import json | |
| 21 import sys | |
| 22 | |
| 23 from generate_idl_diff import load_json_file | |
| 24 from generate_idl_diff import EXTATTRIBUTES_AND_MEMBER_TYPES | |
| 25 from generate_idl_diff import DIFF_TAG | |
| 26 from generate_idl_diff import DIFF_TAG_ADDED | |
| 27 from generate_idl_diff import DIFF_TAG_DELETED | |
| 28 | |
| 29 | |
| 30 """Refer to the explanation of generate_idl_diff.py's input files. | |
| 31 The deffference between input structure of generate_idl_diff.py and | |
|
haraken
2015/09/25 10:30:19
The difference between the input structure...
shimadaa
2015/09/25 11:31:27
Done.
| |
| 32 that of print_diff.py is whether diffing tags are included or not. | |
| 33 The diffing tags are included in a parts that have a diff. | |
|
haraken
2015/09/25 10:30:18
I'd remove this sentence.
shimadaa
2015/09/25 11:31:27
Done.
| |
| 34 {'Interface': { | |
| 35 'diff_tag': 'deleted' | |
| 36 'ExtAttributes': [{'Name': '...' | |
| 37 'diff_tag': 'deleted'}, | |
| 38 ..., | |
| 39 ], | |
| 40 'Consts': [{'Type': '...', | |
| 41 'Name': '...', | |
| 42 'Value': '...' | |
| 43 'diff_tag': 'deleted'}, | |
| 44 ..., | |
| 45 ], | |
| 46 'Attributes': [{'Type': '...', | |
| 47 'Name': '...', | |
| 48 'ExtAttributes':[{'Name': '...'}, | |
| 49 ..., | |
| 50 ] | |
| 51 'diff_tag': 'deleted'}, | |
| 52 ..., | |
| 53 ], | |
| 54 'Operations': [{'Type': '...', | |
| 55 'Name': '...', | |
| 56 'ExtAttributes':[{'Name': '...'}, | |
| 57 ..., | |
| 58 ], | |
| 59 'Arguments': [{'Type': '...', | |
| 60 'Name': '...'}, | |
| 61 ..., | |
| 62 ] | |
| 63 'diff_tag': 'deleted'}, | |
| 64 ..., | |
| 65 ], | |
| 66 'Name': '...' | |
| 67 }, | |
| 68 { | |
| 69 'ExtAttributes': [{'Name': '...'}, | |
| 70 ..., | |
| 71 ], | |
| 72 'Consts': [{'Type': '...', | |
| 73 'Name': '...', | |
| 74 'Value': '...' | |
| 75 'diff_tag': 'added'}, | |
| 76 ..., | |
| 77 ], | |
| 78 'Attributes': [{'Type': '...', | |
| 79 'Name': '...', | |
| 80 'ExtAttributes':[{'Name': '...'}, | |
| 81 ..., | |
| 82 ]}, | |
| 83 ..., | |
| 84 ], | |
| 85 'Operations': [{'Type': '...', | |
| 86 'Name': '...', | |
| 87 'ExtAttributes':[{'Name': '...'}, | |
| 88 ..., | |
| 89 ], | |
| 90 'Arguments': [{'Type': '...', | |
| 91 'Name': '...'}, | |
| 92 ..., | |
| 93 ] | |
| 94 'diff_tag': 'deleted'}, | |
| 95 ..., | |
| 96 ], | |
| 97 'Name': '...' | |
| 98 }, | |
| 99 ..., | |
| 100 } | |
| 101 """ | |
| 102 | |
| 103 | |
| 104 class Colorize(object): | |
| 105 """This class decorates text with colors and outputs it to sys.stdout. | |
|
haraken
2015/09/25 10:30:19
This class outputs a colored text to sys.stdout.
shimadaa
2015/09/25 11:31:27
Done.
| |
| 106 TODO(shimadaa): This class doesn't work on Windows. Provides a way to | |
|
haraken
2015/09/25 10:30:19
TODO(bashi)
haraken
2015/09/25 10:30:19
Provide
shimadaa
2015/09/25 11:31:27
Done.
shimadaa
2015/09/25 11:31:28
Done.
| |
| 107 suppress escape sequences. | |
| 108 """ | |
| 109 | |
| 110 BLACK = 30 | |
| 111 RED = 31 | |
| 112 GREEN = 32 | |
| 113 YELLOW = 33 | |
| 114 COLORS = (BLACK, RED, GREEN, YELLOW) | |
| 115 | |
| 116 def __init__(self, out): | |
| 117 self.out = out | |
| 118 | |
| 119 def reset_color(self): | |
| 120 """Reset text's color to default. | |
| 121 """ | |
| 122 self.out.write('\033[0m') | |
| 123 | |
| 124 def change_color(self, color): | |
| 125 """Change text's color by specifing arguments. | |
| 126 Args: | |
| 127 color: A color to change. It should be one of |COLORS|. | |
|
haraken
2015/09/25 10:30:19
A new color.
shimadaa
2015/09/25 11:31:27
Done.
| |
| 128 """ | |
| 129 if color in self.COLORS: | |
| 130 self.out.write('\033[' + str(color) + 'm') | |
| 131 else: | |
| 132 raise Exception('Unsupported color.') | |
| 133 | |
| 134 def writeln(self, string): | |
| 135 """Print text to use for line breaks. | |
|
haraken
2015/09/25 10:30:19
Print text with a line-break.
shimadaa
2015/09/25 11:31:27
Done.
| |
| 136 """ | |
| 137 self.out.write(string + '\n') | |
| 138 | |
| 139 def write(self, string): | |
| 140 """Print text not to use for line breaks. | |
|
haraken
2015/09/25 10:30:18
Print text without a line-break.
shimadaa
2015/09/25 11:31:26
Done.
| |
| 141 """ | |
| 142 self.out.write(string) | |
| 143 | |
| 144 | |
| 145 def sort_member_types(interface): | |
| 146 """Sort the members in the order of EXTATTRIBUTES_AND_MEMBER_TYPES. | |
| 147 Args: | |
| 148 interface: An "interface" object | |
| 149 Returns: | |
| 150 A sorted "interface" object | |
| 151 """ | |
| 152 sorted_interface = OrderedDict() | |
| 153 for member_type in EXTATTRIBUTES_AND_MEMBER_TYPES: | |
| 154 sorted_interface[member_type] = interface.get(member_type) | |
| 155 sorted_interface[DIFF_TAG] = interface.get(DIFF_TAG) | |
| 156 return sorted_interface | |
| 157 | |
| 158 | |
| 159 def group_by_tag(interface_or_member_list): | |
| 160 """Group members of a given argument (an interface or a list of members) by | |
|
haraken
2015/09/25 10:30:20
Group members of |interface_or_member_list| by tag
shimadaa
2015/09/25 11:31:27
Done.
| |
| 161 tags. | |
| 162 Args: | |
| 163 interface_or_member_list: Interface name's list or "members" object's | |
|
haraken
2015/09/25 10:30:20
A list of interface names or a list of "members"
shimadaa
2015/09/25 11:31:28
Done.
| |
| 164 list. | |
| 165 Returns: | |
| 166 A tuple of (removed, added, unchanged) where | |
| 167 removed: A list that consists of removed ones. | |
|
haraken
2015/09/25 10:30:18
A list of removed members
shimadaa
2015/09/25 11:31:27
Done.
| |
| 168 added: A list that consists of added ones. | |
|
haraken
2015/09/25 10:30:19
A list of added members
shimadaa
2015/09/25 11:31:28
Done.
| |
| 169 unspecified: A list that consists of neither removed ones nor added | |
|
haraken
2015/09/25 10:30:19
A list of other members
shimadaa
2015/09/25 11:31:28
Done.
| |
| 170 ones. | |
| 171 """ | |
| 172 removed = [] | |
| 173 added = [] | |
| 174 unspecified = [] | |
| 175 for interface_or_member in interface_or_member_list: | |
| 176 if DIFF_TAG in interface_or_member: | |
| 177 if interface_or_member[DIFF_TAG] == DIFF_TAG_DELETED: | |
| 178 removed.append(interface_or_member) | |
| 179 elif interface_or_member[DIFF_TAG] == DIFF_TAG_ADDED: | |
| 180 added.append(interface_or_member) | |
| 181 else: | |
| 182 unspecified.append(interface_or_member) | |
| 183 return (removed, added, unspecified) | |
| 184 | |
| 185 | |
| 186 def sort_interface_names_by_tags(interfaces): | |
| 187 """Sort the order of interface names like below. | |
|
haraken
2015/09/25 10:30:19
Sort interface names as follows.
shimadaa
2015/09/25 11:31:27
Done.
| |
| 188 [a interface name of "interface" deleted whole | |
|
haraken
2015/09/25 10:30:19
names of deleted "interface"s
shimadaa
2015/09/25 11:31:28
Done.
| |
| 189 -> a interface name of "interface" added whole | |
|
haraken
2015/09/25 10:30:20
names of added "interface"s
shimadaa
2015/09/25 11:31:27
Done.
| |
| 190 -> a interface name of "interface" changed part] | |
|
haraken
2015/09/25 10:30:19
names of other "interface"s
shimadaa
2015/09/25 11:31:27
Done.
| |
| 191 Args: | |
| 192 interfaces: An "interface" objects. | |
|
haraken
2015/09/25 10:30:19
"interface" objects
shimadaa
2015/09/25 11:31:27
Done.
| |
| 193 Returns: | |
| 194 A list consists of interface names sorted | |
|
haraken
2015/09/25 10:30:19
A list of sorted interface names
shimadaa
2015/09/25 11:31:26
Done.
| |
| 195 """ | |
| 196 interface_list = interfaces.values() | |
| 197 removed, added, unspecified = group_by_tag(interface_list) | |
| 198 removed = map(lambda interface: interface['Name'], removed) | |
| 199 added = map(lambda interface: interface['Name'], added) | |
| 200 unspecified = map(lambda interface: interface['Name'], unspecified) | |
| 201 sorted_interface_name = removed + added + unspecified | |
|
haraken
2015/09/25 10:30:20
sorted_interface_names
shimadaa
2015/09/25 11:31:28
Done.
| |
| 202 return sorted_interface_name | |
| 203 | |
| 204 | |
| 205 def sort_members_by_tags(interface): | |
| 206 """Sort a "members" object by using diff_tag. | |
|
haraken
2015/09/25 10:30:19
Sort members of a given interface in the order of
shimadaa
2015/09/25 11:31:27
Done.
| |
| 207 Args: | |
| 208 An "interface" object | |
| 209 Returns: | |
| 210 A sorted "interface" object | |
| 211 """ | |
| 212 sorted_interface = OrderedDict() | |
| 213 if DIFF_TAG in interface: | |
| 214 return interface | |
| 215 for member_type in EXTATTRIBUTES_AND_MEMBER_TYPES: | |
| 216 member_list = interface[member_type] | |
| 217 removed, added, unspecified = group_by_tag(member_list) | |
| 218 sorted_interface[member_type] = removed + added + unspecified | |
| 219 return sorted_interface | |
| 220 | |
| 221 | |
| 222 def sort_diff_by_tags(interfaces): | |
| 223 """Sort an "interfaces" object expressing a diff by using diff_tag. | |
|
haraken
2015/09/25 10:30:19
Sort an "interfaces" object in the order of diffin
shimadaa
2015/09/25 11:31:27
Done.
| |
| 224 Args: | |
| 225 An "interfaces" object loaded by load_json_data(). | |
| 226 Returns: | |
| 227 A sorted "interfaces" object | |
| 228 """ | |
| 229 sorted_interfaces = OrderedDict() | |
| 230 sorted_interface_names = sort_interface_names_by_tags(interfaces) | |
| 231 for interface_name in sorted_interface_names: | |
| 232 interface = sort_members_by_tags(interfaces[interface_name]) | |
| 233 sorted_interfaces[interface_name] = sort_member_types(interface) | |
| 234 return sorted_interfaces | |
| 235 | |
| 236 | |
| 237 def sort_members_in_alphabetical_order(interface): | |
| 238 """Sort a "members" object in alphabetical order. | |
|
haraken
2015/09/25 10:30:19
in the alphabetical order
shimadaa
2015/09/25 11:31:28
Done.
| |
| 239 Args: | |
| 240 An "interface" object | |
| 241 Returns: | |
| 242 A sorted "interface" object | |
| 243 """ | |
| 244 sorted_interface = OrderedDict() | |
| 245 for member_type in EXTATTRIBUTES_AND_MEMBER_TYPES: | |
| 246 sorted_members = sorted(interface[member_type], | |
| 247 key=lambda member: member['Name']) | |
| 248 sorted_interface[member_type] = sorted_members | |
| 249 return sorted_interface | |
| 250 | |
| 251 | |
| 252 def sort_diff_in_alphabetical_order(interfaces): | |
| 253 """Sort diff in alphabetical order. | |
|
haraken
2015/09/25 10:30:18
Sort an "interfaces" object in the alphabetical or
shimadaa
2015/09/25 11:31:28
Done.
| |
| 254 Args: | |
| 255 An "interfaces" object. | |
| 256 Returns: | |
| 257 A sorted "interfaces" object in alphabetical order | |
|
haraken
2015/09/25 10:30:20
A sorted "interfaces" object
shimadaa
2015/09/25 11:31:28
Done.
| |
| 258 """ | |
| 259 sorted_interfaces = OrderedDict() | |
| 260 for interface_name in sorted(interfaces.keys()): | |
| 261 interface = interfaces[interface_name] | |
| 262 sorted_interface = sort_members_in_alphabetical_order(interface) | |
| 263 sorted_interface[DIFF_TAG] = interface.get(DIFF_TAG) | |
| 264 sorted_interfaces[interface_name] = sorted_interface | |
| 265 return sorted_interfaces | |
| 266 | |
| 267 | |
| 268 def change_color_based_on_tag(member, out): | |
|
haraken
2015/09/25 10:30:18
change_color_based_on_tag => print_member_with_col
shimadaa
2015/09/25 11:31:27
Done.
| |
| 269 """Change color based on diff_tag and output prefix ('+' or '-') if |member| | |
|
haraken
2015/09/25 10:30:19
Print the "member" with a colored text. '+' is add
shimadaa
2015/09/25 11:31:27
Done.
| |
| 270 is added/deleted. | |
| 271 Args: | |
| 272 member: A "member" object | |
| 273 """ | |
| 274 if DIFF_TAG in member: | |
| 275 if member[DIFF_TAG] == DIFF_TAG_DELETED: | |
| 276 out.change_color(Colorize.RED) | |
| 277 out.write('- ') | |
| 278 elif member[DIFF_TAG] == DIFF_TAG_ADDED: | |
| 279 out.change_color(Colorize.GREEN) | |
| 280 out.write('+ ') | |
| 281 else: | |
| 282 out.change_color(Colorize.BLACK) | |
| 283 out.write(' ') | |
| 284 | |
| 285 | |
| 286 def print_extattributes(extattributes, out): | |
| 287 """Print extattributes in an "interface" object. | |
| 288 Args: | |
| 289 A list included as a value of "member" object named "ExtAttributes" | |
|
haraken
2015/09/25 10:30:19
A list of "ExtAttributes" in the "interface" objec
shimadaa
2015/09/25 11:31:27
Done.
| |
| 290 """ | |
| 291 for extattribute in extattributes: | |
| 292 out.write(' ') | |
| 293 change_color_based_on_tag(extattribute, out) | |
| 294 out.writeln(extattribute['Name']) | |
| 295 | |
| 296 | |
| 297 def print_consts(consts, out): | |
| 298 """Print consts in an "interface" object. | |
| 299 Args: | |
| 300 A list included as a value of "member" object named "Consts" | |
|
haraken
2015/09/25 10:30:19
A list of "Consts" of the "interface" object
shimadaa
2015/09/25 11:31:28
Done.
| |
| 301 """ | |
| 302 for const in consts: | |
| 303 out.write(' ') | |
| 304 change_color_based_on_tag(const, out) | |
| 305 out.write(const['Type']) | |
| 306 out.write(' ') | |
| 307 out.write(const['Name']) | |
| 308 out.write(' ') | |
| 309 out.writeln(const['Value']) | |
| 310 | |
| 311 | |
| 312 def print_items(items, callback, out): | |
| 313 """Calls |callback| for each item in |items|, printing commas between | |
| 314 |callback| calls. | |
| 315 Args: | |
| 316 items: extattributes or arguments | |
| 317 """ | |
| 318 count = 0 | |
| 319 for item in items: | |
| 320 callback(item) | |
| 321 count += 1 | |
| 322 if count < len(items): | |
| 323 out.write(', ') | |
| 324 | |
| 325 | |
| 326 def print_extattributes_of_member(extattributes, out): | |
|
haraken
2015/09/25 10:30:19
Why do we need to distinguish print_extattributes_
haraken
2015/09/25 10:30:19
print_extattributes_in_member
shimadaa
2015/09/25 11:31:27
Done.
shimadaa
2015/09/25 11:31:27
Sorry I don't have time to modify...
| |
| 327 """Print extattributes in a "member" object. | |
| 328 Args: | |
| 329 A list included as a value of "ExtAttributes" of "member" object | |
|
haraken
2015/09/25 10:30:19
A list of "ExtAttributes" in the "member" object
shimadaa
2015/09/25 11:31:28
Done.
| |
| 330 """ | |
| 331 def callback(extattribute): | |
| 332 out.write(extattribute['Name']) | |
| 333 | |
| 334 out.write('[') | |
| 335 print_items(extattributes, callback, out) | |
| 336 out.write(']') | |
| 337 | |
| 338 | |
| 339 def print_attributes(attributes, out): | |
| 340 """Print attributes in an "interface" object. | |
| 341 Args: | |
| 342 A list included as a value of "member" object named "Attributes" | |
|
haraken
2015/09/25 10:30:19
A list of "Attributes" in the "interface" object
shimadaa
2015/09/25 11:31:28
Done.
| |
| 343 """ | |
| 344 for attribute in attributes: | |
| 345 out.write(' ') | |
| 346 change_color_based_on_tag(attribute, out) | |
| 347 if attribute['ExtAttributes']: | |
| 348 print_extattributes_of_member(attribute['ExtAttributes'], out) | |
| 349 out.write(attribute['Type']) | |
| 350 out.write(' ') | |
| 351 out.writeln(attribute['Name']) | |
| 352 | |
| 353 | |
| 354 def print_arguments(arguments, out): | |
| 355 """Print arguments in a "members" object named "Operations". | |
| 356 Args: A list included as a value of "Arguments" of "member" object named | |
|
haraken
2015/09/25 10:30:19
A list of "Arguments".
shimadaa
2015/09/25 11:31:27
Done.
| |
| 357 "Operations" | |
| 358 """ | |
| 359 def callback(argument): | |
| 360 out.write(argument['Name']) | |
| 361 | |
| 362 out.write('(') | |
| 363 print_items(arguments, callback, out) | |
| 364 out.writeln(')') | |
| 365 | |
| 366 | |
| 367 def print_operations(operations, out): | |
| 368 """Print operations in a "member" object. | |
| 369 Args: | |
| 370 A list included as a value of "member" object named "Operations" | |
|
haraken
2015/09/25 10:30:20
A list of "Operations"
shimadaa
2015/09/25 11:31:28
Done.
| |
| 371 """ | |
| 372 for operation in operations: | |
| 373 out.write(' ') | |
| 374 change_color_based_on_tag(operation, out) | |
| 375 if operation['ExtAttributes']: | |
| 376 print_extattributes_of_member(operation['ExtAttributes'], out) | |
| 377 out.write(operation['Type']) | |
| 378 out.write(' ') | |
| 379 if operation['Arguments']: | |
| 380 out.write(operation['Name']) | |
| 381 print_arguments(operation['Arguments'], out) | |
| 382 else: | |
| 383 out.writeln(operation['Name']) | |
| 384 | |
| 385 | |
| 386 def print_diff(diff, out): | |
| 387 """Print the diff on a shell. | |
| 388 Args: | |
| 389 A sorted diff | |
| 390 """ | |
| 391 for interface_name, interface in diff.iteritems(): | |
| 392 change_color_based_on_tag(interface, out) | |
| 393 out.change_color(Colorize.YELLOW) | |
| 394 out.write('[[') | |
| 395 out.write(interface_name) | |
| 396 out.writeln(']]') | |
| 397 out.reset_color() | |
| 398 for member_name, member in interface.iteritems(): | |
| 399 if member_name == 'ExtAttributes': | |
| 400 out.writeln('ExtAttributes') | |
| 401 print_extattributes(member, out) | |
| 402 elif member_name == 'Consts': | |
| 403 out.writeln(' Consts') | |
| 404 print_consts(member, out) | |
| 405 elif member_name == 'Attributes': | |
| 406 out.writeln(' Attributes') | |
| 407 print_attributes(member, out) | |
| 408 elif member_name == 'Operations': | |
| 409 out.writeln(' Operations') | |
| 410 print_operations(member, out) | |
| 411 out.reset_color() | |
| 412 | |
| 413 | |
| 414 def usage(): | |
|
haraken
2015/09/25 10:30:18
print_usage
| |
| 415 """Show usage.""" | |
| 416 sys.stdout.write('Usage: print_diff.py <diff_file.json> <"TAG"|"ALPHABET">\n ') | |
| 417 | |
| 418 | |
| 419 def main(argv): | |
| 420 if len(argv) != 2: | |
| 421 usage() | |
| 422 exit(1) | |
| 423 json_data = argv[0] | |
| 424 order = argv[1] | |
| 425 diff = load_json_file(json_data) | |
| 426 if order == 'TAG': | |
| 427 sort_func = sort_diff_by_tags | |
| 428 elif order == 'ALPHABET': | |
| 429 sort_func = sort_diff_in_alphabetical_order | |
| 430 else: | |
| 431 usage() | |
| 432 exit(1) | |
| 433 sorted_diff = sort_func(diff) | |
| 434 out = Colorize(sys.stdout) | |
| 435 print_diff(sorted_diff, out) | |
| 436 | |
| 437 | |
| 438 if __name__ == '__main__': | |
| 439 main(sys.argv[1:]) | |
| OLD | NEW |