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 |