OLD | NEW |
1 # Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 # Copyright (c) 2010 The Chromium Authors. All rights reserved. |
2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 | 4 |
5 """Generic presubmit checks that can be reused by other presubmit checks.""" | 5 """Generic presubmit checks that can be reused by other presubmit checks.""" |
6 | 6 |
| 7 import time |
| 8 |
| 9 |
7 ### Description checks | 10 ### Description checks |
8 | 11 |
9 def CheckChangeHasTestField(input_api, output_api): | 12 def CheckChangeHasTestField(input_api, output_api): |
10 """Requires that the changelist have a TEST= field.""" | 13 """Requires that the changelist have a TEST= field.""" |
11 if input_api.change.TEST: | 14 if input_api.change.TEST: |
12 return [] | 15 return [] |
13 else: | 16 else: |
14 return [output_api.PresubmitNotifyResult( | 17 return [output_api.PresubmitNotifyResult( |
15 'If this change requires manual test instructions to QA team, add ' | 18 'If this change requires manual test instructions to QA team, add ' |
16 'TEST=[instructions].')] | 19 'TEST=[instructions].')] |
(...skipping 655 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
672 # redundant (since the commit queue also enforces the presubmit checks). | 675 # redundant (since the commit queue also enforces the presubmit checks). |
673 def match_reviewer(r): | 676 def match_reviewer(r): |
674 return email_regexp.match(r) and not input_api.re.match(owner, r) | 677 return email_regexp.match(r) and not input_api.re.match(owner, r) |
675 | 678 |
676 approvers = [] | 679 approvers = [] |
677 for m in issue_props.get('messages', []): | 680 for m in issue_props.get('messages', []): |
678 if 'lgtm' in m['text'].lower() and match_reviewer(m['sender']): | 681 if 'lgtm' in m['text'].lower() and match_reviewer(m['sender']): |
679 approvers.append(m['sender']) | 682 approvers.append(m['sender']) |
680 return set(approvers) | 683 return set(approvers) |
681 | 684 |
| 685 |
| 686 def _CheckConstNSObject(input_api, output_api, source_file_filter): |
| 687 """Checks to make sure no objective-c files have |const NSSomeClass*|.""" |
| 688 pattern = input_api.re.compile(r'const\s+NS\w*\s*\*') |
| 689 |
| 690 def objective_c_filter(f): |
| 691 return (source_file_filter(f) and |
| 692 input_api.os_path.splitext(f.LocalPath())[1] in ('.h', '.mm')) |
| 693 |
| 694 files = [] |
| 695 for f in input_api.AffectedSourceFiles(objective_c_filter): |
| 696 contents = input_api.ReadFile(f) |
| 697 if pattern.search(contents): |
| 698 files.append(f) |
| 699 |
| 700 if files: |
| 701 if input_api.is_committing: |
| 702 res_type = output_api.PresubmitPromptWarning |
| 703 else: |
| 704 res_type = output_api.PresubmitNotifyResult |
| 705 return [ res_type('|const NSClass*| is wrong, see ' + |
| 706 'http://dev.chromium.org/developers/clang-mac', |
| 707 files) ] |
| 708 return [] |
| 709 |
| 710 |
| 711 def _CheckSingletonInHeaders(input_api, output_api, source_file_filter): |
| 712 """Checks to make sure no header files have |Singleton<|.""" |
| 713 pattern = input_api.re.compile(r'Singleton<') |
| 714 files = [] |
| 715 for f in input_api.AffectedSourceFiles(source_file_filter): |
| 716 if (f.LocalPath().endswith('.h') or f.LocalPath().endswith('.hxx') or |
| 717 f.LocalPath().endswith('.hpp') or f.LocalPath().endswith('.inl')): |
| 718 contents = input_api.ReadFile(f) |
| 719 if pattern.search(contents): |
| 720 files.append(f) |
| 721 |
| 722 if files: |
| 723 return [ output_api.PresubmitError( |
| 724 'Found Singleton<T> in the following header files.\n' + |
| 725 'Please move them to an appropriate source file so that the ' + |
| 726 'template gets instantiated in a single compilation unit.', |
| 727 files) ] |
| 728 return [] |
| 729 |
| 730 |
| 731 def PanProjectChecks(input_api, output_api, |
| 732 excluded_paths=None, text_files=None, |
| 733 license_header=None, project_name=None): |
| 734 """Checks that ALL chromium orbit projects should use. |
| 735 |
| 736 These are checks to be run on all Chromium orbit project, including: |
| 737 Chromium |
| 738 Native Client |
| 739 V8 |
| 740 When you update this function, please take this broad scope into account. |
| 741 Args: |
| 742 input_api: Bag of input related interfaces. |
| 743 output_api: Bag of output related interfaces. |
| 744 excluded_paths: Don't include these paths in common checks. |
| 745 text_files: Which file are to be treated as documentation text files. |
| 746 license_header: What license header should be on files. |
| 747 project_name: What is the name of the project as it appears in the license. |
| 748 Returns: |
| 749 A list of warning or error objects. |
| 750 """ |
| 751 excluded_paths = excluded_paths or tuple() |
| 752 text_files = text_files or ( |
| 753 r'.*\.txt', |
| 754 r'.*\.json', |
| 755 ) |
| 756 project_name = project_name or 'Chromium' |
| 757 license_header = license_header or ( |
| 758 r'.*? Copyright \(c\) %(year)s The %(project)s Authors\. ' |
| 759 r'All rights reserved\.\n' |
| 760 r'.*? Use of this source code is governed by a BSD-style license that ' |
| 761 r'can be\n' |
| 762 r'.*? found in the LICENSE file\.\n' |
| 763 ) % { |
| 764 'year': time.strftime('%Y'), |
| 765 'project': project_name, |
| 766 } |
| 767 |
| 768 results = [] |
| 769 # This code loads the default black list (e.g. third_party, experimental, etc) |
| 770 # and add our black list (breakpad, skia and v8 are still not following |
| 771 # google style and are not really living this repository). |
| 772 # See presubmit_support.py InputApi.FilterSourceFile for the (simple) usage. |
| 773 black_list = input_api.DEFAULT_BLACK_LIST + excluded_paths |
| 774 white_list = input_api.DEFAULT_WHITE_LIST + text_files |
| 775 sources = lambda x: input_api.FilterSourceFile(x, black_list=black_list) |
| 776 text_files = lambda x: input_api.FilterSourceFile(x, black_list=black_list, |
| 777 white_list=white_list) |
| 778 |
| 779 # TODO(dpranke): enable upload as well |
| 780 if input_api.is_committing: |
| 781 results.extend(input_api.canned_checks.CheckOwners( |
| 782 input_api, output_api, source_file_filter=sources)) |
| 783 |
| 784 results.extend(input_api.canned_checks.CheckLongLines( |
| 785 input_api, output_api, source_file_filter=sources)) |
| 786 results.extend(input_api.canned_checks.CheckChangeHasNoTabs( |
| 787 input_api, output_api, source_file_filter=sources)) |
| 788 results.extend(input_api.canned_checks.CheckChangeHasNoStrayWhitespace( |
| 789 input_api, output_api, source_file_filter=sources)) |
| 790 results.extend(input_api.canned_checks.CheckChangeSvnEolStyle( |
| 791 input_api, output_api, source_file_filter=text_files)) |
| 792 results.extend(input_api.canned_checks.CheckSvnForCommonMimeTypes( |
| 793 input_api, output_api)) |
| 794 results.extend(input_api.canned_checks.CheckLicense( |
| 795 input_api, output_api, license_header, source_file_filter=sources)) |
| 796 results.extend(_CheckConstNSObject( |
| 797 input_api, output_api, source_file_filter=sources)) |
| 798 results.extend(_CheckSingletonInHeaders( |
| 799 input_api, output_api, source_file_filter=sources)) |
| 800 return results |
OLD | NEW |