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

Side by Side Diff: tools/compare_build_artifacts/compare_build_artifacts.py

Issue 2232723002: Import compare_build_artifacts.py from isolate recipe module. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 4 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 | tools/compare_build_artifacts/deterministic_build_blacklist.json » ('j') | 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 2014 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 """Compare the artifacts from two builds."""
7
8 import difflib
9 import json
10 import optparse
11 import os
12 import struct
13 import sys
14 import time
15
16 BASE_DIR = os.path.dirname(os.path.abspath(__file__))
17
18
19 # List of files that are known to be non deterministic. This is a "temporary"
20 # workaround to find regression on the deterministic builders.
21 #
22 # PNaCl general bug: https://crbug.com/429358
23 #
24 # TODO(sebmarchand): Remove this once all the files are deterministic.
25 WHITELIST = {
26 # https://crbug.com/383340
27 'android': {
28 'd8',
M-A Ruel 2016/08/10 13:15:08 Mike, is it true?
Yoshisato Yanagisawa 2016/08/17 09:30:21 FYI. As far as I checked with recent Android Deter
M-A Ruel 2016/08/17 12:46:09 Ok please update accordingly then commit.
29 'mksnapshot',
30 },
31
32 # https://crbug.com/330263
33 'linux': {
34 # Completed.
35 },
36
37 # https://crbug.com/330262
38 'mac': {
39 'accessibility_unittests',
40 'accessibility_unittests.isolated',
41 'angle_end2end_tests',
42 'angle_unittests',
43 'app_list_demo',
44 'app_list_unittests',
45 'app_list_unittests.isolated',
46 'app_shell_unittests',
47 'app_shell_unittests.isolated',
48 'ar_sample_test_driver',
49 'audio_unittests',
50 'audio_unittests.isolated',
51 'base_i18n_perftests',
52 'base_perftests',
53 'base_unittests',
54 'base_unittests.isolated',
55 'battor_agent',
56 'bitmaptools',
57 'blink_heap_unittests',
58 'blink_heap_unittests.isolated',
59 'blink_platform_unittests',
60 'blink_platform_unittests.isolated',
61 'boringssl_aead_test',
62 'boringssl_aes_test',
63 'boringssl_base64_test',
64 'boringssl_bio_test',
65 'boringssl_bn_test',
66 'boringssl_bytestring_test',
67 'boringssl_cipher_test',
68 'boringssl_cmac_test',
69 'boringssl_constant_time_test',
70 'boringssl_dh_test',
71 'boringssl_digest_test',
72 'boringssl_dsa_test',
73 'boringssl_ec_test',
74 'boringssl_ecdsa_test',
75 'boringssl_err_test',
76 'boringssl_evp_extra_test',
77 'boringssl_evp_test',
78 'boringssl_example_mul',
79 'boringssl_gcm_test',
80 'boringssl_hkdf_test',
81 'boringssl_hmac_test',
82 'boringssl_lhash_test',
83 'boringssl_pbkdf_test',
84 'boringssl_pkcs12_test',
85 'boringssl_pkcs7_test',
86 'boringssl_pkcs8_test',
87 'boringssl_poly1305_test',
88 'boringssl_pqueue_test',
89 'boringssl_refcount_test',
90 'boringssl_rsa_test',
91 'boringssl_ssl_test',
92 'boringssl_tab_test',
93 'boringssl_thread_test',
94 'boringssl_unittests',
95 'boringssl_v3name_test',
96 'browser_tests',
97 'browser_tests.isolated',
98 'build_utf8_validator_tables',
99 'cacheinvalidation_unittests',
100 'cacheinvalidation_unittests.isolated',
101 'cast_benchmarks',
102 'cast_h264_vt_encoder_unittests',
103 'cast_receiver_app',
104 'cast_sender_app',
105 'cast_simulator',
106 'cast_unittests',
107 'cast_unittests.isolated',
108 'cc_blink_unittests',
109 'cc_perftests',
110 'cc_unittests',
111 'cc_unittests.isolated',
112 'check_example',
113 'chrome.isolated',
114 'chrome_app_unittests',
115 'chromedriver',
116 'chromedriver_tests',
117 'chromedriver_unittests',
118 'chromedriver_unittests.isolated',
119 'chromoting_test_driver',
120 'clear_system_cache',
121 'cloud_print_unittests',
122 'codesighs',
123 'components_browsertests',
124 'components_browsertests.isolated',
125 'components_perftests',
126 'components_unittests',
127 'components_unittests.isolated',
128 'compositor_unittests',
129 'compositor_unittests.isolated',
130 'content_browsertests',
131 'content_browsertests.isolated',
132 'content_gl_benchmark',
133 'content_gl_tests',
134 'content_perftests',
135 'content_unittests',
136 'content_unittests.isolated',
137 'courgette',
138 'courgette_fuzz',
139 'courgette_minimal_tool',
140 'courgette_unittests',
141 'courgette_unittests.isolated',
142 'crash_cache',
143 'crash_inspector',
144 'crashpad_handler',
145 'crl_set_dump',
146 'crypto_unittests',
147 'crypto_unittests.isolated',
148 'd8',
149 'device_unittests',
150 'device_unittests.isolated',
151 'display_unittests',
152 'dns_fuzz_stub',
153 'dump_cache',
154 'dump_syms',
155 'env_chromium_unittests',
156 'events_unittests',
157 'events_unittests.isolated',
158 'exif.so',
159 'extensions_browsertests',
160 'extensions_browsertests.isolated',
161 'extensions_unittests',
162 'extensions_unittests.isolated',
163 'ffmpeg_regression_tests',
164 'ffmpegsumo.so',
165 'filter_fuzz_stub',
166 'frame_analyzer',
167 'gcapi_example',
168 'gcm_unit_tests',
169 'gcm_unit_tests.isolated',
170 'gdig',
171 'generate_barcode_video',
172 'generate_test_gn_data',
173 'generate_timecode_audio',
174 'genmacro',
175 'genmodule',
176 'genperf',
177 'genstring',
178 'genversion',
179 'get_server_time',
180 'gfx_unittests',
181 'gin_shell',
182 'gin_unittests',
183 'gl_tests',
184 'gl_unittests',
185 'gl_unittests.isolated',
186 'gles2_conform_support',
187 'gles2_conform_test',
188 'gn',
189 'gn_unittests',
190 'gn_unittests.isolated',
191 'goobsdiff',
192 'goobspatch',
193 'google_apis_unittests',
194 'google_apis_unittests.isolated',
195 'gpu_perftests',
196 'gpu_unittests',
197 'gpu_unittests.isolated',
198 'hpack_example_generator',
199 'hpack_fuzz_mutator',
200 'hpack_fuzz_wrapper',
201 'image_diff',
202 'image_operations_bench',
203 'infoplist_strings_tool',
204 'interactive_ui_tests',
205 'interactive_ui_tests.isolated',
206 'ipc_mojo_perftests',
207 'ipc_mojo_unittests',
208 'ipc_perftests',
209 'ipc_tests',
210 'ipc_tests.isolated',
211 'jingle_unittests',
212 'jingle_unittests.isolated',
213 'jtl_compiler',
214 'khronos_glcts_test',
215 'layout_test_helper',
216 'libEGL.dylib',
217 'libGLESv2.dylib',
218 'libaddressinput_unittests',
219 'libclearkeycdm.dylib',
220 'libcommand_buffer_gles2.dylib',
221 'liblzma_decompress.dylib',
222 'libmojo_public_test_support.dylib',
223 'libphonenumber_unittests',
224 'load_library_perf_tests',
225 'macviews_interactive_ui_tests',
226 'maptsvdifftool',
227 'mcs_probe',
228 'media_blink_unittests',
229 'media_blink_unittests.isolated',
230 'media_perftests',
231 'media_unittests',
232 'media_unittests.isolated',
233 'message_center_unittests',
234 'message_center_unittests.isolated',
235 'midi_unittests',
236 'midi_unittests.isolated',
237 'minidump_stackwalk',
238 'mksnapshot',
239 'mojo_common_unittests',
240 'mojo_common_unittests.isolated',
241 'mojo_js_integration_tests',
242 'mojo_js_unittests',
243 'mojo_message_pipe_perftests',
244 'mojo_public_application_unittests',
245 'mojo_public_bindings_perftests',
246 'mojo_public_bindings_unittests',
247 'mojo_public_bindings_unittests.isolated',
248 'mojo_public_system_perftests',
249 'mojo_public_system_unittests',
250 'mojo_public_system_unittests.isolated',
251 'mojo_system_unittests',
252 'nacl_loader_unittests',
253 'nacl_loader_unittests.isolated',
254 'net_perftests',
255 'net_unittests',
256 'net_unittests.isolated',
257 'net_watcher',
258 'nm2tsv',
259 'openh264_unittests',
260 'osmesa.so',
261 'pdfium_diff',
262 'pdfium_test',
263 'pdfsqueeze',
264 'peerconnection_server',
265 'pepper_hash_for_uma',
266 'performance_browser_tests',
267 'ppapi_perftests',
268 'ppapi_unittests',
269 'printing_unittests',
270 'printing_unittests.isolated',
271 'protoc',
272 'qcms_test',
273 'qcms_tests',
274 'quic_client',
275 'quic_server',
276 're2c',
277 'remoting_perftests',
278 'remoting_start_host',
279 'remoting_unittests',
280 'remoting_unittests.isolated',
281 'rgba_to_i420_converter',
282 'rlz_id',
283 'rlz_unittests',
284 'run_sync_testserver',
285 'run_testserver',
286 'sandbox_mac_unittests',
287 'sandbox_mac_unittests.isolated',
288 'skia_runner',
289 'skia_unittests',
290 'skia_unittests.isolated',
291 'snapshot_unittests',
292 'sql_unittests',
293 'sql_unittests.isolated',
294 'stress_cache',
295 'symupload',
296 'sync_client',
297 'sync_integration_tests',
298 'sync_integration_tests.isolated',
299 'sync_listen_notifications',
300 'sync_performance_tests',
301 'telemetry_gpu_unittests.isolated',
302 'tld_cleanup',
303 'tls_edit',
304 'udp_proxy',
305 'ui_base_unittests',
306 'ui_touch_selection_unittests',
307 'ui_touch_selection_unittests.isolated',
308 'unit_tests',
309 'unit_tests.isolated',
310 'url_unittests',
311 'url_unittests.isolated',
312 'views_examples_with_content_exe',
313 'views_unittests',
314 'webkit_unit_tests',
315 'webkit_unit_tests.isolated',
316 'wifi_test',
317 'wtf_unittests',
318 'wtf_unittests.isolated',
319 'xz',
320 'xzdec',
321 'yasm',
322 },
323
324 # https://crbug.com/330260
325 'win': {
326 'accessibility_unittests.exe',
M-A Ruel 2016/08/10 13:15:08 Expect the list to have to be updated.
Yoshisato Yanagisawa 2016/08/12 09:21:02 I am not confident but I have updated the whitelis
327 'accessibility_unittests.isolated',
328 'angle_end2end_tests.exe',
329 'angle_unittests.exe',
330 'angle_perftests.exe',
331 'app_list_demo.exe',
332 'app_list_unittests.exe',
333 'app_list_unittests.isolated',
334 'app_shell.exe',
335 'app_shell_unittests.exe',
336 'app_shell_unittests.isolated',
337 'ar_sample_test_driver.exe',
338 'ash_shell.exe',
339 'ash_unittests.exe',
340 'ash_unittests.isolated',
341 'audio_unittests.exe',
342 'audio_unittests.isolated',
343 'base_i18n_perftests.exe',
344 'base_perftests.exe',
345 'base_unittests.exe',
346 'base_unittests.isolated',
347 'blink_heap_unittests.exe',
348 'blink_platform_unittests.exe',
349 'browser_tests.exe',
350 'browser_tests.isolated',
351 'cast_unittests.exe',
352 'cast_unittests.isolated',
353 'cc_blink_unittests.exe',
354 'cc_perftests.exe',
355 'cc_unittests.exe',
356 'cc_unittests.isolated',
357 'chrome.dll',
358 'chrome.exe',
359 'chrome.isolated',
360 'chrome_app_unittests.exe',
361 'chrome_child.dll',
362 'chrome_elf_unittests.exe',
363 'chrome_watcher.dll',
364 'chromedriver.exe',
365 'chromedriver_tests.exe',
366 'chromoting_test_driver.exe',
367 'clearkeycdm.dll',
368 'cloud_print_service.exe',
369 'cloud_print_service_config.exe',
370 'cloud_print_unittests.exe',
371 'components_browsertests.exe',
372 'components_browsertests.isolated',
373 'components_unittests.exe',
374 'components_unittests.isolated',
375 'compositor_unittests.exe',
376 'compositor_unittests.isolated',
377 'content_browsertests.exe',
378 'content_browsertests.isolated',
379 'content_gl_benchmark.exe',
380 'content_gl_tests.exe',
381 'content_perftests.exe',
382 'content_shell.exe',
383 'content_unittests.exe',
384 'content_unittests.isolated',
385 'courgette64.exe',
386 'crash_service64.exe',
387 'crypto_unittests.exe',
388 'crypto_unittests.isolated',
389 'd8.exe',
390 'delegate_execute.exe',
391 'delegate_execute_unittests.exe',
392 'device_unittests.exe',
393 'device_unittests.isolated',
394 'events_unittests.exe',
395 'events_unittests.isolated',
396 'extensions_browsertests.exe',
397 'extensions_browsertests.isolated',
398 'extensions_unittests.exe',
399 'extensions_unittests.isolated',
400 'gcapi_test.exe',
401 'gcm_unit_tests.exe',
402 'gcm_unit_tests.isolated',
403 'gcp20_device.exe',
404 'gcp20_device_unittests.exe',
405 'gcp_portmon64.dll',
406 'get_server_time.exe',
407 'gfx_unittests.exe',
408 'gin_shell.exe',
409 'gin_unittests.exe',
410 'gl_unittests.exe',
411 'gl_unittests.isolated',
412 'google_apis_unittests.exe',
413 'google_apis_unittests.isolated',
414 'gpu_perftests.exe',
415 'gpu_unittests.exe',
416 'gpu_unittests.isolated',
417 'interactive_ui_tests.exe',
418 'interactive_ui_tests.isolated',
419 'ipc_mojo_perftests.exe',
420 'ipc_mojo_unittests.exe',
421 'ipc_perftests.exe',
422 'ipc_tests.exe',
423 'ipc_tests.isolated',
424 'jingle_unittests.exe',
425 'jingle_unittests.isolated',
426 'keyboard_unittests.exe',
427 'libaddressinput_unittests.exe',
428 'media_unittests.exe',
429 'media_unittests.isolated',
430 'metro_driver.dll',
431 'midi_unittests.exe',
432 'midi_unittests.isolated',
433 'mini_installer.exe',
434 'mksnapshot.exe',
435 'mock_nacl_gdb.exe',
436 'mojo_js_integration_tests.exe',
437 'mojo_js_unittests.exe',
438 'mojo_message_pipe_perftests.exe',
439 'mojo_public_bindings_perftests.exe',
440 'mojo_public_bindings_unittests.exe',
441 'mojo_public_bindings_unittests.isolated',
442 'mojo_public_system_perftests.exe',
443 'mojo_public_system_unittests.exe',
444 'mojo_public_system_unittests.isolated',
445 'mojo_system_unittests.exe',
446 'nacl_loader_unittests.exe',
447 'nacl_loader_unittests.isolated',
448 'net_perftests.exe',
449 'net_unittests.exe',
450 'net_unittests.isolated',
451 'np_test_netscape_plugin.dll',
452 'npapi_test_plugin.dll',
453 'pdfium_test.exe',
454 'peerconnection_server.exe',
455 'performance_browser_tests.exe',
456 'ppapi_perftests.exe',
457 'ppapi_unittests.exe',
458 'printing_unittests.exe',
459 'printing_unittests.isolated',
460 'remoting_core.dll',
461 'remoting_start_host.exe',
462 'remoting_unittests.exe',
463 'remoting_unittests.isolated',
464 'sbox_integration_tests.isolated',
465 'sbox_unittests.exe',
466 'sbox_unittests.isolated',
467 'sbox_validation_tests.isolated',
468 'setup_unittests.exe',
469 'setup_unittests.isolated',
470 'skia_unittests.exe',
471 'skia_unittests.isolated',
472 'sql_unittests.exe',
473 'sql_unittests.isolated',
474 'sync_client.exe',
475 'sync_integration_tests.exe',
476 'sync_integration_tests.isolated',
477 'sync_performance_tests.exe',
478 'test_registrar.exe',
479 'ui_base_unittests.exe',
480 'unit_tests.exe',
481 'unit_tests.isolated',
482 'url_unittests.exe',
483 'url_unittests.isolated',
484 'video_decode_accelerator_unittest.exe',
485 'views_examples_with_content_exe.exe',
486 'views_unittests.exe',
487 'webkit_unit_tests.exe',
488 'wtf_unittests.exe',
489 },
490 }
491
492 def get_files_to_compare(build_dir, recursive=False):
493 """Get the list of files to compare."""
494 allowed = frozenset(
495 ('', '.apk', '.app', '.dll', '.dylib', '.exe', '.nexe', '.so'))
M-A Ruel 2016/08/10 13:15:08 Add: # TODO(maruel): Add '.pdb'. In practice, wh
Yoshisato Yanagisawa 2016/08/12 09:21:02 Done.
496 non_x_ok_exts = frozenset(('.apk', '.isolated'))
497 def check(f):
498 if not os.path.isfile(f):
499 return False
500 if os.path.basename(f).startswith('.'):
501 return False
502 ext = os.path.splitext(f)[1]
503 if ext in non_x_ok_exts:
504 return True
505 return ext in allowed and os.access(f, os.X_OK)
506
507 ret_files = set()
508 for root, dirs, files in os.walk(build_dir):
509 if not recursive:
510 dirs[:] = [d for d in dirs if d.endswith('_apk')]
511 for f in (f for f in files if check(os.path.join(root, f))):
512 ret_files.add(os.path.relpath(os.path.join(root, f), build_dir))
513 return ret_files
514
515
516 def diff_dict(a, b):
517 """Returns a yaml-like textural diff of two dict.
518
519 It is currently optimized for the .isolated format.
520 """
521 out = ''
522 for key in set(a) | set(b):
523 va = a.get(key)
524 vb = b.get(key)
525 if va.__class__ != vb.__class__:
526 out += '- %s: %r != %r\n' % (key, va, vb)
527 elif isinstance(va, dict):
528 c = diff_dict(va, vb)
529 if c:
530 out += '- %s:\n%s\n' % (
531 key, '\n'.join(' ' + l for l in c.splitlines()))
532 elif va != vb:
533 out += '- %s: %s != %s\n' % (key, va, vb)
534 return out.rstrip()
535
536
537 def diff_binary(first_filepath, second_filepath, file_len):
538 """Returns a compact binary diff if the diff is small enough."""
539 CHUNK_SIZE = 32
540 MAX_STREAMS = 10
541 diffs = 0
542 streams = []
543 offset = 0
544 with open(first_filepath, 'rb') as lhs:
545 with open(second_filepath, 'rb') as rhs:
546 while True:
547 lhs_data = lhs.read(CHUNK_SIZE)
548 rhs_data = rhs.read(CHUNK_SIZE)
549 if not lhs_data:
550 break
551 if lhs_data != rhs_data:
552 diffs += sum(l != r for l, r in zip(lhs_data, rhs_data))
553 if streams is not None:
554 if len(streams) < MAX_STREAMS:
555 streams.append((offset, lhs_data, rhs_data))
556 else:
557 streams = None
558 offset += len(lhs_data)
559 del lhs_data
560 del rhs_data
561 if not diffs:
562 return None
563 result = '%d out of %d bytes are different (%.2f%%)' % (
564 diffs, file_len, 100.0 * diffs / file_len)
565 if streams:
566 encode = lambda text: ''.join(i if 31 < ord(i) < 128 else '.' for i in text)
567 for offset, lhs_data, rhs_data in streams:
568 lhs_line = '%s \'%s\'' % (lhs_data.encode('hex'), encode(lhs_data))
569 rhs_line = '%s \'%s\'' % (rhs_data.encode('hex'), encode(rhs_data))
570 diff = list(difflib.Differ().compare([lhs_line], [rhs_line]))[-1][2:-1]
571 result += '\n 0x%-8x: %s\n %s\n %s' % (
572 offset, lhs_line, rhs_line, diff)
573 return result
574
575
576 def compare_files(first_filepath, second_filepath):
577 """Compares two binaries and return the number of differences between them.
578
579 Returns None if the files are equal, a string otherwise.
580 """
581 if first_filepath.endswith('.isolated'):
582 with open(first_filepath, 'rb') as f:
583 lhs = json.load(f)
584 with open(second_filepath, 'rb') as f:
585 rhs = json.load(f)
586 diff = diff_dict(lhs, rhs)
587 if diff:
588 return '\n' + '\n'.join(' ' + line for line in diff.splitlines())
589 # else, falls through binary comparison, it must be binary equal too.
590
591 file_len = os.stat(first_filepath).st_size
592 if file_len != os.stat(second_filepath).st_size:
593 return 'different size: %d != %d' % (
594 file_len, os.stat(second_filepath).st_size)
595
596 return diff_binary(first_filepath, second_filepath, file_len)
597
598
599 def compare_build_artifacts(first_dir, second_dir, target_platform,
600 recursive=False):
601 """Compares the artifacts from two distinct builds."""
602 if not os.path.isdir(first_dir):
603 print >> sys.stderr, '%s isn\'t a valid directory.' % first_dir
604 return 1
605 if not os.path.isdir(second_dir):
606 print >> sys.stderr, '%s isn\'t a valid directory.' % second_dir
607 return 1
608
609 epoch_hex = struct.pack('<I', int(time.time())).encode('hex')
610 print('Epoch: %s' %
611 ' '.join(epoch_hex[i:i+2] for i in xrange(0, len(epoch_hex), 2)))
612
613 with open(os.path.join(BASE_DIR, 'deterministic_build_blacklist.json')) as f:
614 blacklist = frozenset(json.load(f))
615 whitelist = WHITELIST[target_platform]
616
617 # The two directories.
618 first_list = get_files_to_compare(first_dir, recursive) - blacklist
619 second_list = get_files_to_compare(second_dir, recursive) - blacklist
620
621 equals = []
622 expected_diffs = []
623 unexpected_diffs = []
624 unexpected_equals = []
625 all_files = sorted(first_list & second_list)
626 missing_files = sorted(first_list.symmetric_difference(second_list))
627 if missing_files:
628 print >> sys.stderr, 'Different list of files in both directories:'
629 print >> sys.stderr, '\n'.join(' ' + i for i in missing_files)
630 unexpected_diffs.extend(missing_files)
631
632 max_filepath_len = max(len(n) for n in all_files)
633 for f in all_files:
634 first_file = os.path.join(first_dir, f)
635 second_file = os.path.join(second_dir, f)
636 result = compare_files(first_file, second_file)
637 if not result:
638 tag = 'equal'
639 equals.append(f)
640 if f in whitelist:
641 unexpected_equals.append(f)
642 else:
643 if f in whitelist:
644 expected_diffs.append(f)
645 tag = 'expected'
646 else:
647 unexpected_diffs.append(f)
648 tag = 'unexpected'
649 result = 'DIFFERENT (%s): %s' % (tag, result)
650 print('%-*s: %s' % (max_filepath_len, f, result))
651 unexpected_diffs.sort()
652
653 print('Equals: %d' % len(equals))
654 print('Expected diffs: %d' % len(expected_diffs))
655 print('Unexpected diffs: %d' % len(unexpected_diffs))
656 if unexpected_diffs:
657 print('Unexpected files with diffs:\n')
658 for u in unexpected_diffs:
659 print(' %s' % u)
660 if unexpected_equals:
661 print('Unexpected files with no diffs:\n')
662 for u in unexpected_equals:
663 print(' %s' % u)
664
665 return int(bool(unexpected_diffs))
666
667
668 def main():
669 parser = optparse.OptionParser(usage='%prog [options]')
670 parser.add_option(
671 '-f', '--first-build-dir', help='The first build directory.')
672 parser.add_option(
673 '-s', '--second-build-dir', help='The second build directory.')
674 parser.add_option('-r', '--recursive', action='store_true', default=False,
675 help='Indicates if the comparison should be recursive.')
676 parser.add_option('-t', '--target-platform', help='The target platform.')
M-A Ruel 2016/08/10 13:15:09 Small addition while at it: target = { 'darwin'
Yoshisato Yanagisawa 2016/08/12 09:21:02 Done.
677 options, _ = parser.parse_args()
678
679 if not options.first_build_dir:
680 parser.error('--first-build-dir is required')
681 if not options.second_build_dir:
682 parser.error('--second-build-dir is required')
683 if not options.target_platform:
684 parser.error('--target-platform is required')
685
686 return compare_build_artifacts(os.path.abspath(options.first_build_dir),
687 os.path.abspath(options.second_build_dir),
688 options.target_platform,
689 options.recursive)
690
691
692 if __name__ == '__main__':
693 sys.exit(main())
OLDNEW
« no previous file with comments | « no previous file | tools/compare_build_artifacts/deterministic_build_blacklist.json » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698