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

Side by Side Diff: PRESUBMIT.py

Issue 116443011: Do per-file OWNERS check for per-file DEPS changes. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 6 years, 11 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | PRESUBMIT_test.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 """Top-level presubmit script for Chromium. 5 """Top-level presubmit script for Chromium.
6 6
7 See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts 7 See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts
8 for more details about the presubmit API built into gcl. 8 for more details about the presubmit API built into gcl.
9 """ 9 """
10 10
(...skipping 765 matching lines...) Expand 10 before | Expand all | Expand 10 after
776 776
777 results = [] 777 results = []
778 if errors: 778 if errors:
779 results.append(output_api.PresubmitError( 779 results.append(output_api.PresubmitError(
780 'The name of PNG files should not have abbreviations. \n' 780 'The name of PNG files should not have abbreviations. \n'
781 'Use _hover.png, _center.png, instead of _h.png, _c.png.\n' 781 'Use _hover.png, _center.png, instead of _h.png, _c.png.\n'
782 'Contact oshima@chromium.org if you have questions.', errors)) 782 'Contact oshima@chromium.org if you have questions.', errors))
783 return results 783 return results
784 784
785 785
786 def _DepsFilesToCheck(re, changed_lines): 786 def _FilesToCheckForIncomingDeps(re, changed_lines):
787 """Helper method for _CheckAddedDepsHaveTargetApprovals. Returns 787 """Helper method for _CheckAddedDepsHaveTargetApprovals. Returns
788 a set of DEPS entries that we should look up.""" 788 a set of DEPS entries that we should look up.
789
790 For a directory (rather than a specific filename) we fake a path to
791 a specific filename by adding /DEPS. This is chosen as a file that
792 will seldom or never be subject to per-file include_rules.
793 """
789 # We ignore deps entries on auto-generated directories. 794 # We ignore deps entries on auto-generated directories.
790 AUTO_GENERATED_DIRS = ['grit', 'jni'] 795 AUTO_GENERATED_DIRS = ['grit', 'jni']
791 796
792 # This pattern grabs the path without basename in the first 797 # This pattern grabs the path without basename in the first
793 # parentheses, and the basename (if present) in the second. It 798 # parentheses, and the basename (if present) in the second. It
794 # relies on the simple heuristic that if there is a basename it will 799 # relies on the simple heuristic that if there is a basename it will
795 # be a header file ending in ".h". 800 # be a header file ending in ".h".
796 pattern = re.compile( 801 pattern = re.compile(
797 r"""['"]\+([^'"]+?)(/[a-zA-Z0-9_]+\.h)?['"].*""") 802 r"""['"]\+([^'"]+?)(/[a-zA-Z0-9_]+\.h)?['"].*""")
798 results = set() 803 results = set()
799 for changed_line in changed_lines: 804 for changed_line in changed_lines:
800 m = pattern.match(changed_line) 805 m = pattern.match(changed_line)
801 if m: 806 if m:
802 path = m.group(1) 807 path = m.group(1)
803 if path.split('/')[0] not in AUTO_GENERATED_DIRS: 808 if path.split('/')[0] not in AUTO_GENERATED_DIRS:
804 results.add('%s/DEPS' % m.group(1)) 809 if m.group(2):
810 results.add('%s%s' % (path, m.group(2)))
811 else:
812 results.add('%s/DEPS' % path)
805 return results 813 return results
806 814
807 815
808 def _CheckAddedDepsHaveTargetApprovals(input_api, output_api): 816 def _CheckAddedDepsHaveTargetApprovals(input_api, output_api):
809 """When a dependency prefixed with + is added to a DEPS file, we 817 """When a dependency prefixed with + is added to a DEPS file, we
810 want to make sure that the change is reviewed by an OWNER of the 818 want to make sure that the change is reviewed by an OWNER of the
811 target file or directory, to avoid layering violations from being 819 target file or directory, to avoid layering violations from being
812 introduced. This check verifies that this happens. 820 introduced. This check verifies that this happens.
813 """ 821 """
814 changed_lines = set() 822 changed_lines = set()
815 for f in input_api.AffectedFiles(): 823 for f in input_api.AffectedFiles():
816 filename = input_api.os_path.basename(f.LocalPath()) 824 filename = input_api.os_path.basename(f.LocalPath())
817 if filename == 'DEPS': 825 if filename == 'DEPS':
818 changed_lines |= set(line.strip() 826 changed_lines |= set(line.strip()
819 for line_num, line 827 for line_num, line
820 in f.ChangedContents()) 828 in f.ChangedContents())
821 if not changed_lines: 829 if not changed_lines:
822 return [] 830 return []
823 831
824 virtual_depended_on_files = _DepsFilesToCheck(input_api.re, changed_lines) 832 virtual_depended_on_files = _FilesToCheckForIncomingDeps(input_api.re,
833 changed_lines)
825 if not virtual_depended_on_files: 834 if not virtual_depended_on_files:
826 return [] 835 return []
827 836
828 if input_api.is_committing: 837 if input_api.is_committing:
829 if input_api.tbr: 838 if input_api.tbr:
830 return [output_api.PresubmitNotifyResult( 839 return [output_api.PresubmitNotifyResult(
831 '--tbr was specified, skipping OWNERS check for DEPS additions')] 840 '--tbr was specified, skipping OWNERS check for DEPS additions')]
832 if not input_api.change.issue: 841 if not input_api.change.issue:
833 return [output_api.PresubmitError( 842 return [output_api.PresubmitError(
834 "DEPS approval by OWNERS check failed: this change has " 843 "DEPS approval by OWNERS check failed: this change has "
835 "no Rietveld issue number, so we can't check it for approvals.")] 844 "no Rietveld issue number, so we can't check it for approvals.")]
836 output = output_api.PresubmitError 845 output = output_api.PresubmitError
837 else: 846 else:
838 output = output_api.PresubmitNotifyResult 847 output = output_api.PresubmitNotifyResult
839 848
840 owners_db = input_api.owners_db 849 owners_db = input_api.owners_db
841 owner_email, reviewers = input_api.canned_checks._RietveldOwnerAndReviewers( 850 owner_email, reviewers = input_api.canned_checks._RietveldOwnerAndReviewers(
842 input_api, 851 input_api,
843 owners_db.email_regexp, 852 owners_db.email_regexp,
844 approval_needed=input_api.is_committing) 853 approval_needed=input_api.is_committing)
845 854
846 owner_email = owner_email or input_api.change.author_email 855 owner_email = owner_email or input_api.change.author_email
847 856
848 reviewers_plus_owner = set(reviewers) 857 reviewers_plus_owner = set(reviewers)
849 if owner_email: 858 if owner_email:
850 reviewers_plus_owner.add(owner_email) 859 reviewers_plus_owner.add(owner_email)
851 missing_files = owners_db.files_not_covered_by(virtual_depended_on_files, 860 missing_files = owners_db.files_not_covered_by(virtual_depended_on_files,
852 reviewers_plus_owner) 861 reviewers_plus_owner)
853 unapproved_dependencies = ["'+%s'," % path[:-len('/DEPS')] 862
863 # We strip the /DEPS part that was added by
864 # _FilesToCheckForIncomingDeps to fake a path to a file in a
865 # directory.
866 def StripDeps(path):
867 start_deps = path.rfind('/DEPS')
868 if start_deps != -1:
869 return path[:start_deps]
870 else:
871 return path
872 unapproved_dependencies = ["'+%s'," % StripDeps(path)
854 for path in missing_files] 873 for path in missing_files]
855 874
856 if unapproved_dependencies: 875 if unapproved_dependencies:
857 output_list = [ 876 output_list = [
858 output('Missing LGTM from OWNERS of directories added to DEPS:\n %s' % 877 output('Missing LGTM from OWNERS of dependencies added to DEPS:\n %s' %
859 '\n '.join(sorted(unapproved_dependencies)))] 878 '\n '.join(sorted(unapproved_dependencies)))]
860 if not input_api.is_committing: 879 if not input_api.is_committing:
861 suggested_owners = owners_db.reviewers_for(missing_files, owner_email) 880 suggested_owners = owners_db.reviewers_for(missing_files, owner_email)
862 output_list.append(output( 881 output_list.append(output(
863 'Suggested missing target path OWNERS:\n %s' % 882 'Suggested missing target path OWNERS:\n %s' %
864 '\n '.join(suggested_owners or []))) 883 '\n '.join(suggested_owners or [])))
865 return output_list 884 return output_list
866 885
867 return [] 886 return []
868 887
(...skipping 559 matching lines...) Expand 10 before | Expand all | Expand 10 after
1428 trybots.extend(GetDefaultTryConfigs(['cros_x86'])) 1447 trybots.extend(GetDefaultTryConfigs(['cros_x86']))
1429 1448
1430 # The AOSP bot doesn't build the chrome/ layer, so ignore any changes to it 1449 # The AOSP bot doesn't build the chrome/ layer, so ignore any changes to it
1431 # unless they're .gyp(i) files as changes to those files can break the gyp 1450 # unless they're .gyp(i) files as changes to those files can break the gyp
1432 # step on that bot. 1451 # step on that bot.
1433 if (not all(re.search('^chrome', f) for f in files) or 1452 if (not all(re.search('^chrome', f) for f in files) or
1434 any(re.search('\.gypi?$', f) for f in files)): 1453 any(re.search('\.gypi?$', f) for f in files)):
1435 trybots.extend(GetDefaultTryConfigs(['android_aosp'])) 1454 trybots.extend(GetDefaultTryConfigs(['android_aosp']))
1436 1455
1437 return trybots 1456 return trybots
OLDNEW
« no previous file with comments | « no previous file | PRESUBMIT_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698