| OLD | NEW |
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
| 5 | 5 |
| 6 """Compare the artifacts from two builds.""" | 6 """Compare the artifacts from two builds.""" |
| 7 | 7 |
| 8 import difflib | 8 import difflib |
| 9 import json | 9 import json |
| 10 import optparse | 10 import optparse |
| (...skipping 427 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 438 | 438 |
| 439 def diff_binary(first_filepath, second_filepath, file_len): | 439 def diff_binary(first_filepath, second_filepath, file_len): |
| 440 """Returns a compact binary diff if the diff is small enough.""" | 440 """Returns a compact binary diff if the diff is small enough.""" |
| 441 CHUNK_SIZE = 32 | 441 CHUNK_SIZE = 32 |
| 442 MAX_STREAMS = 10 | 442 MAX_STREAMS = 10 |
| 443 diffs = 0 | 443 diffs = 0 |
| 444 streams = [] | 444 streams = [] |
| 445 offset = 0 | 445 offset = 0 |
| 446 with open(first_filepath, 'rb') as lhs: | 446 with open(first_filepath, 'rb') as lhs: |
| 447 with open(second_filepath, 'rb') as rhs: | 447 with open(second_filepath, 'rb') as rhs: |
| 448 # Skip part of Win32 COFF header if timestamps are different. |
| 449 # |
| 450 # COFF header: |
| 451 # 0 - 1: magic. |
| 452 # 2 - 3: # sections. |
| 453 # 4 - 7: timestamp. |
| 454 # .... |
| 455 COFF_HEADER_TO_COMPARE_SIZE = 8 |
| 456 if (sys.platform == 'win32' and first_filepath.endswith('.obj') |
| 457 and file_len > COFF_HEADER_TO_COMPARE_SIZE): |
| 458 rhs_data = rhs.read(COFF_HEADER_TO_COMPARE_SIZE) |
| 459 lhs_data = lhs.read(COFF_HEADER_TO_COMPARE_SIZE) |
| 460 if lhs_data[0:4] == rhs_data[0:4] and lhs_data[4:8] != rhs_data[4:8]: |
| 461 offset += COFF_HEADER_TO_COMPARE_SIZE |
| 462 else: |
| 463 lhs.seek(0) |
| 464 rhs.seek(0) |
| 465 |
| 448 while True: | 466 while True: |
| 449 lhs_data = lhs.read(CHUNK_SIZE) | 467 lhs_data = lhs.read(CHUNK_SIZE) |
| 450 rhs_data = rhs.read(CHUNK_SIZE) | 468 rhs_data = rhs.read(CHUNK_SIZE) |
| 451 if not lhs_data: | 469 if not lhs_data: |
| 452 break | 470 break |
| 453 if lhs_data != rhs_data: | 471 if lhs_data != rhs_data: |
| 454 diffs += sum(l != r for l, r in zip(lhs_data, rhs_data)) | 472 diffs += sum(l != r for l, r in zip(lhs_data, rhs_data)) |
| 455 if streams is not None: | 473 if streams is not None: |
| 456 if len(streams) < MAX_STREAMS: | 474 if len(streams) < MAX_STREAMS: |
| 457 streams.append((offset, lhs_data, rhs_data)) | 475 streams.append((offset, lhs_data, rhs_data)) |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 552 # for this case. | 570 # for this case. |
| 553 print 'deps on %s are different: %s' % ( | 571 print 'deps on %s are different: %s' % ( |
| 554 target, set(first_deps).symmetric_difference(set(second_deps))) | 572 target, set(first_deps).symmetric_difference(set(second_deps))) |
| 555 continue | 573 continue |
| 556 max_filepath_len = max(len(n) for n in first_deps) | 574 max_filepath_len = max(len(n) for n in first_deps) |
| 557 for d in first_deps: | 575 for d in first_deps: |
| 558 first_file = os.path.join(first_dir, d) | 576 first_file = os.path.join(first_dir, d) |
| 559 second_file = os.path.join(second_dir, d) | 577 second_file = os.path.join(second_dir, d) |
| 560 result = compare_files(first_file, second_file) | 578 result = compare_files(first_file, second_file) |
| 561 if result: | 579 if result: |
| 562 print('%-*s: %s' % (max_filepath_len, d, result)) | 580 print(' %-*s: %s' % (max_filepath_len, d, result)) |
| 563 | 581 |
| 564 | 582 |
| 565 def compare_build_artifacts(first_dir, second_dir, target_platform, | 583 def compare_build_artifacts(first_dir, second_dir, target_platform, |
| 566 recursive=False): | 584 recursive=False): |
| 567 """Compares the artifacts from two distinct builds.""" | 585 """Compares the artifacts from two distinct builds.""" |
| 568 if not os.path.isdir(first_dir): | 586 if not os.path.isdir(first_dir): |
| 569 print >> sys.stderr, '%s isn\'t a valid directory.' % first_dir | 587 print >> sys.stderr, '%s isn\'t a valid directory.' % first_dir |
| 570 return 1 | 588 return 1 |
| 571 if not os.path.isdir(second_dir): | 589 if not os.path.isdir(second_dir): |
| 572 print >> sys.stderr, '%s isn\'t a valid directory.' % second_dir | 590 print >> sys.stderr, '%s isn\'t a valid directory.' % second_dir |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 658 parser.error('--target-platform is required') | 676 parser.error('--target-platform is required') |
| 659 | 677 |
| 660 return compare_build_artifacts(os.path.abspath(options.first_build_dir), | 678 return compare_build_artifacts(os.path.abspath(options.first_build_dir), |
| 661 os.path.abspath(options.second_build_dir), | 679 os.path.abspath(options.second_build_dir), |
| 662 options.target_platform, | 680 options.target_platform, |
| 663 options.recursive) | 681 options.recursive) |
| 664 | 682 |
| 665 | 683 |
| 666 if __name__ == '__main__': | 684 if __name__ == '__main__': |
| 667 sys.exit(main()) | 685 sys.exit(main()) |
| OLD | NEW |