Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(114)

Side by Side Diff: third_party/WebKit/Source/bindings/scripts/print_idl_diff.py

Issue 1371573002: Get diff that made by make_diff.py and print it by color on a shell. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Modified some nits Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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
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
12 expressing a diff between two defferent Chrome versions.The structure
Yuki 2015/09/25 07:12:37 nit: a space just before "The structure"
shimadaa 2015/09/25 07:40:07 Done.
13 of the dictionary is like below.
14 order:
15 Specify how to sort. Either by using diffing tags or in alphabetical
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
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.
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 ]
Yuki 2015/09/25 07:12:37 'Name': '...' should be here, too?
shimadaa 2015/09/25 07:40:07 Done.
97 },
98 ...,
99 }
100 """
101
102
103 class Colorize(object):
104 """This class decorates text with colors and outputs it to sys.stdout.
105 TODO(shimadaa): This class doesn't work on Windows. Provides a way to
106 suppress escape sequences.
107 """
108
109 BLACK = 30
110 RED = 31
111 GREEN = 32
112 YELLOW = 33
113 COLORS = (BLACK, RED, GREEN, YELLOW)
114
115 def __init__(self, out):
116 self.out = out
117
118 def reset_color(self):
119 """Reset text's color to default.
120 """
121 self.out.write('\033[0m')
122
123 def change_color(self, color):
124 """Change text's color by specifing arguments.
125 Args:
126 color: A color to change. It should be one of |COLORS|.
127 """
128 if color in self.COLORS:
129 self.out.write('\033[' + str(color) + 'm')
130 else:
131 raise Exception('Unsupported color.')
132
133 def writeln(self, string):
134 """Print text to use for line breaks.
135 """
136 self.out.write(string + '\n')
137
138 def write(self, string):
139 """Print text not to use for line breaks.
140 """
141 self.out.write(string)
142
143
144 def sort_member_types(interface):
145 """Sort the members in the order of EXTATTRIBUTES_AND_MEMBER_TYPES.
146 Args:
147 interface: An "interface" object
148 Returns:
149 A sorted "interface" object
150 """
151 sorted_interface = OrderedDict()
152 for member_type in EXTATTRIBUTES_AND_MEMBER_TYPES:
153 sorted_interface[member_type] = interface.get(member_type)
154 sorted_interface[DIFF_TAG] = interface.get(DIFF_TAG)
155 return sorted_interface
156
157
158 def group_by_tag(interface_or_member_list):
159 """Group members of a given argument (an interface or a list of members) by
160 tags.
161 Args:
162 interface_or_member_list: Interface name's list or "members" object's
163 list.
164 Returns:
165 removed: A list that consists of removed ones.
Yuki 2015/09/25 07:12:37 I'd recommend to explicitly say that the return va
shimadaa 2015/09/25 07:40:07 Done.
166 added: A list that consists of added ones.
167 unspecified: A list that consists of neither removed ones nor added
168 ones.
169 """
170 removed = []
171 added = []
172 unspecified = []
173 for interface_or_member in interface_or_member_list:
174 if DIFF_TAG in interface_or_member:
175 if interface_or_member[DIFF_TAG] == DIFF_TAG_DELETED:
176 removed.append(interface_or_member)
177 elif interface_or_member[DIFF_TAG] == DIFF_TAG_ADDED:
178 added.append(interface_or_member)
179 else:
180 unspecified.append(interface_or_member)
181 return (removed, added, unspecified)
182
183
184 def sort_interface_names_by_tags(interfaces):
185 """Sort the order of interface names like below.
186 [a interface name of "interface" deleted whole
187 -> a interface name of "interface" added whole
188 -> a interface name of "interface" changed part]
189 Args:
190 interfaces: An "interface" objects.
191 Returns:
192 A list consists of interface names sorted
193 """
194 interface_list = interfaces.values()
195 removed, added, unspecified = group_by_tag(interface_list)
196 removed = map(lambda interface: interface['Name'], removed)
197 added = map(lambda interface: interface['Name'], added)
198 unspecified = map(lambda interface: interface['Name'], unspecified)
199 sorted_interface_name = removed + added + unspecified
200 return sorted_interface_name
201
202
203 def sort_members_by_tags(interface):
204 """Sort a "members" object by using diff_tag.
205 Args:
206 An "interface" object
207 Returns:
208 A sorted "interface" object
209 """
210 sorted_interface = OrderedDict()
211 if DIFF_TAG in interface:
212 return interface
213 for member_type in EXTATTRIBUTES_AND_MEMBER_TYPES:
214 member_list = interface[member_type]
215 removed, added, unspecified = group_by_tag(member_list)
216 sorted_interface[member_type] = removed + added + unspecified
217 return sorted_interface
218
219
220 def sort_diff_by_tags(interfaces):
221 """Sort an "interfaces" object expressing a diff by using diff_tag.
222 Args:
223 An "interfaces" object loaded by load_json_data().
224 Returns:
225 A sorted "interfaces" object
226 """
227 sorted_interfaces = OrderedDict()
228 sorted_interface_names = sort_interface_names_by_tags(interfaces)
229 for interface_name in sorted_interface_names:
230 interface = sort_members_by_tags(interfaces[interface_name])
231 sorted_interfaces[interface_name] = sort_member_types(interface)
232 return sorted_interfaces
233
234
235 def sort_members_in_alphabetical_order(interface):
236 """Sort a "members" object in alphabetical order.
237 Args:
238 An "interface" object
239 Returns:
240 A sorted "interface" object
241 """
242 sorted_interface = OrderedDict()
243 for member_type in EXTATTRIBUTES_AND_MEMBER_TYPES:
244 sorted_members = sorted(interface[member_type],
245 key=lambda member: member['Name'])
246 sorted_interface[member_type] = sorted_members
247 return sorted_interface
248
249
250 def sort_diff_in_alphabetical_order(interfaces):
251 """Sort diff in alphabetical order.
252 Args:
253 An "interfaces" object.
254 Returns:
255 A sorted "interfaces" object in alphabetical order
256 """
257 sorted_interfaces = OrderedDict()
258 for interface_name in sorted(interfaces.keys()):
259 interface = interfaces[interface_name]
260 sorted_interface = sort_members_in_alphabetical_order(interface)
261 sorted_interface[DIFF_TAG] = interface.get(DIFF_TAG)
262 sorted_interfaces[interface_name] = sorted_interface
263 return sorted_interfaces
264
265
266 def change_color_based_on_tag(member, out):
267 """Change color based on diff_tag and output prefix ('+' or '-') if |member|
268 is added/deleted.
269 Args:
270 member: A "member" object
271 """
272 if DIFF_TAG in member:
273 if member[DIFF_TAG] == DIFF_TAG_DELETED:
274 out.change_color(Colorize.RED)
275 out.write('- ')
276 elif member[DIFF_TAG] == DIFF_TAG_ADDED:
277 out.change_color(Colorize.GREEN)
278 out.write('+ ')
279 else:
280 out.change_color(Colorize.BLACK)
281 out.write(' ')
282
283
284 def print_extattributes(extattributes, out):
285 """Print extattributes in an "interface" object.
286 Args:
287 A list included as a value of "member" object named "ExtAttributes"
288 """
289 for extattribute in extattributes:
290 out.write(' ')
291 change_color_based_on_tag(extattribute, out)
292 out.writeln(extattribute['Name'])
293
294
295 def print_consts(consts, out):
296 """Print consts in an "interface" object.
297 Args:
298 A list included as a value of "member" object named "Consts"
299 """
300 for const in consts:
301 out.write(' ')
302 change_color_based_on_tag(const, out)
303 out.write(const['Type'])
304 out.write(' ')
305 out.write(const['Name'])
306 out.write(' ')
307 out.writeln(const['Value'])
308
309
310 def print_items(items, callback, out):
311 """Print ', ' in ExtAttributes or Arguments.
bashi 2015/09/25 07:52:46 How about: """Calls |callback| for each item in |i
312 Args:
313 items: extattributes or arguments
314 """
315 count = 0
316 for item in items:
317 callback(item)
318 count += 1
319 if count < len(items):
320 out.write(', ')
321
322
323 def print_extattributes_of_member(extattributes, out):
324 """Print extattributes in a "member" object.
325 Args:
326 A list included as a value of "ExtAttributes" of "member" object
327 """
328 def callback(extattribute):
329 out.write(extattribute['Name'])
330
331 out.write('[')
332 print_items(extattributes, callback, out)
333 out.write(']')
334
335
336 def print_attributes(attributes, out):
337 """Print attributes in an "interface" object.
338 Args:
339 A list included as a value of "member" object named "Attributes"
340 """
341 for attribute in attributes:
342 out.write(' ')
343 change_color_based_on_tag(attribute, out)
344 if attribute['ExtAttributes']:
345 print_extattributes_of_member(attribute['ExtAttributes'], out)
346 out.write(attribute['Type'])
347 out.write(' ')
348 out.writeln(attribute['Name'])
349
350
351 def print_arguments(arguments, out):
352 """Print arguments in a "members" object named "Operations".
353 Args: A list included as a value of "Arguments" of "member" object named
354 "Operations"
355 """
356 def callback(argument):
357 out.write(argument['Name'])
358
359 out.write('(')
360 print_items(arguments, callback, out)
361 out.writeln(')')
362
363
364 def print_operations(operations, out):
365 """Print operations in a "member" object.
366 Args:
367 A list included as a value of "member" object named "Operations"
368 """
369 for operation in operations:
370 out.write(' ')
371 change_color_based_on_tag(operation, out)
372 if operation['ExtAttributes']:
373 print_extattributes_of_member(operation['ExtAttributes'], out)
374 out.write(operation['Type'])
375 out.write(' ')
376 if operation['Arguments']:
377 out.write(operation['Name'])
378 print_arguments(operation['Arguments'], out)
379 else:
380 out.writeln(operation['Name'])
381
382
383 def print_diff(diff, out):
384 """Print the diff on a shell.
385 Args:
386 A sorted diff
387 """
388 for interface_name, interface in diff.iteritems():
389 change_color_based_on_tag(interface, out)
390 out.change_color(Colorize.YELLOW)
391 out.write('[[')
392 out.write(interface_name)
393 out.writeln(']]')
394 out.reset_color()
395 for member_name, member in interface.iteritems():
396 if member_name == 'ExtAttributes':
397 out.writeln('ExtAttributes')
398 print_extattributes(member, out)
399 elif member_name == 'Consts':
400 out.writeln(' Consts')
401 print_consts(member, out)
402 elif member_name == 'Attributes':
403 out.writeln(' Attributes')
404 print_attributes(member, out)
405 elif member_name == 'Operations':
406 out.writeln(' Operations')
407 print_operations(member, out)
408 out.reset_color()
409
410
411 def usage():
412 """Show usage."""
413 sys.stdout.write('Usage: print_diff.py <diff_file.json> <TAG>/<ALPHABET>\n')
Yuki 2015/09/25 07:12:37 <"TAG" | "ALPHABET">
shimadaa 2015/09/25 07:40:07 Done.
414
415
416 def main(argv):
417 if len(argv) != 2:
418 usage()
419 exit(1)
420 json_data = argv[0]
421 order = argv[1]
422 diff = load_json_file(json_data)
423 if order == 'TAG':
424 sort_func = sort_diff_by_tags
425 elif order == 'ALPHABET':
426 sort_func = sort_diff_in_alphabetical_order
427 else:
428 usage()
429 exit(1)
430 sorted_diff = sort_func(diff)
431 out = Colorize(sys.stdout)
432 print_diff(sorted_diff, out)
433
434
435 if __name__ == '__main__':
436 main(sys.argv[1:])
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698