OLD | NEW |
1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 # Copyright (c) 2012 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 | 7 |
8 ### Description checks | 8 ### Description checks |
9 | 9 |
10 def CheckChangeHasTestField(input_api, output_api): | 10 def CheckChangeHasTestField(input_api, output_api): |
(...skipping 711 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
722 (builder_name, pending_builds_len)) | 722 (builder_name, pending_builds_len)) |
723 if out: | 723 if out: |
724 return [output_api.PresubmitPromptWarning( | 724 return [output_api.PresubmitPromptWarning( |
725 'Build(s) pending. It is suggested to wait that no more than %d ' | 725 'Build(s) pending. It is suggested to wait that no more than %d ' |
726 'builds are pending.' % max_pendings, | 726 'builds are pending.' % max_pendings, |
727 long_text='\n'.join(out))] | 727 long_text='\n'.join(out))] |
728 return [] | 728 return [] |
729 | 729 |
730 | 730 |
731 def CheckOwners(input_api, output_api, source_file_filter=None): | 731 def CheckOwners(input_api, output_api, source_file_filter=None): |
732 if not input_api.is_committing: | 732 if input_api.is_committing: |
733 return [] | 733 if input_api.tbr: |
734 if input_api.tbr: | 734 return [output_api.PresubmitNotifyResult( |
735 return [output_api.PresubmitNotifyResult( | 735 '--tbr was specified, skipping OWNERS check')] |
736 '--tbr was specified, skipping OWNERS check')] | 736 if not input_api.change.issue: |
737 if not input_api.change.issue: | 737 return [output_api.PresubmitError("OWNERS check failed: this change has " |
738 return [output_api.PresubmitError( | 738 "no Rietveld issue number, so we can't check it for approvals.")] |
739 "OWNERS check failed: this change has no Rietveld issue number, so " | 739 needed = 'LGTM from an OWNER' |
740 "we can't check it for approvals.")] | 740 output = output_api.PresubmitError |
| 741 else: |
| 742 needed = 'OWNER reviewers' |
| 743 output = output_api.PresubmitNotifyResult |
741 | 744 |
742 affected_files = set([f.LocalPath() for f in | 745 affected_files = set([f.LocalPath() for f in |
743 input_api.change.AffectedFiles(file_filter=source_file_filter)]) | 746 input_api.change.AffectedFiles(file_filter=source_file_filter)]) |
744 | 747 |
745 owners_db = input_api.owners_db | 748 owners_db = input_api.owners_db |
746 owner_email, approvers = _RietveldOwnerAndApprovers(input_api, | 749 owner_email, reviewers = _RietveldOwnerAndReviewers( |
747 owners_db.email_regexp) | 750 input_api, |
748 if not owner_email: | 751 owners_db.email_regexp, |
| 752 approval_needed=input_api.is_committing) |
| 753 |
| 754 if owner_email: |
| 755 reviewers_plus_owner = reviewers.union(set([owner_email])) |
| 756 elif input_api.is_committing: |
749 return [output_api.PresubmitWarning( | 757 return [output_api.PresubmitWarning( |
750 'The issue was not uploaded so you have no OWNER approval.')] | 758 'The issue was not uploaded so you have no OWNER approval.')] |
| 759 else: |
| 760 owner_email = '' |
| 761 reviewers_plus_owner = set() |
751 | 762 |
752 approvers_plus_owner = approvers.union(set([owner_email])) | 763 missing_directories = owners_db.directories_not_covered_by(affected_files, |
| 764 reviewers_plus_owner) |
| 765 if missing_directories: |
| 766 return [output('Missing %s for files in these directories:\n %s' % |
| 767 (needed, '\n '.join(missing_directories)))] |
753 | 768 |
754 missing_files = owners_db.files_not_covered_by(affected_files, | 769 if input_api.is_committing and not reviewers: |
755 approvers_plus_owner) | 770 return [output('Missing LGTM from someone other than %s' % owner_email)] |
756 if missing_files: | |
757 return [output_api.PresubmitError('Missing LGTM from an OWNER for: %s' % | |
758 ','.join(missing_files))] | |
759 | |
760 if not approvers: | |
761 return [output_api.PresubmitError('Missing LGTM from someone other than %s' | |
762 % owner_email)] | |
763 return [] | 771 return [] |
764 | 772 |
765 | 773 |
766 def _RietveldOwnerAndApprovers(input_api, email_regexp): | 774 def _RietveldOwnerAndReviewers(input_api, email_regexp, approval_needed=False): |
767 """Return the owner and approvers of a change, if any.""" | 775 """Return the owner and reviewers of a change, if any. |
| 776 |
| 777 If approval_needed is True, only reviewers who have approved the change |
| 778 will be returned. |
| 779 """ |
768 if not input_api.change.issue: | 780 if not input_api.change.issue: |
769 return None, None | 781 return None, None |
770 | 782 |
771 issue_props = input_api.rietveld.get_issue_properties( | 783 issue_props = input_api.rietveld.get_issue_properties( |
772 int(input_api.change.issue), True) | 784 int(input_api.change.issue), True) |
| 785 if not approval_needed: |
| 786 return issue_props['owner_email'], set(issue_props['reviewers']) |
| 787 |
773 owner_email = issue_props['owner_email'] | 788 owner_email = issue_props['owner_email'] |
774 | 789 |
775 def match_reviewer(r): | 790 def match_reviewer(r): |
776 return email_regexp.match(r) and r != owner_email | 791 return email_regexp.match(r) and r != owner_email |
777 | 792 |
778 messages = issue_props.get('messages', []) | 793 messages = issue_props.get('messages', []) |
779 approvers = set( | 794 approvers = set( |
780 m['sender'] for m in messages | 795 m['sender'] for m in messages |
781 if m.get('approval') and match_reviewer(m['sender'])) | 796 if m.get('approval') and match_reviewer(m['sender'])) |
782 | 797 |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
922 results.extend(input_api.canned_checks.CheckSvnForCommonMimeTypes( | 937 results.extend(input_api.canned_checks.CheckSvnForCommonMimeTypes( |
923 input_api, output_api)) | 938 input_api, output_api)) |
924 snapshot("checking license") | 939 snapshot("checking license") |
925 results.extend(input_api.canned_checks.CheckLicense( | 940 results.extend(input_api.canned_checks.CheckLicense( |
926 input_api, output_api, license_header, source_file_filter=sources)) | 941 input_api, output_api, license_header, source_file_filter=sources)) |
927 snapshot("checking was uploaded") | 942 snapshot("checking was uploaded") |
928 results.extend(input_api.canned_checks.CheckChangeWasUploaded( | 943 results.extend(input_api.canned_checks.CheckChangeWasUploaded( |
929 input_api, output_api)) | 944 input_api, output_api)) |
930 snapshot("done") | 945 snapshot("done") |
931 return results | 946 return results |
OLD | NEW |