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 """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 Loading... |
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 Loading... |
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 |
OLD | NEW |