OLD | NEW |
1 #!/usr/bin/python | 1 #!/usr/bin/python |
2 # Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2006-2009 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 """Enables directory-specific presubmit checks to run at upload and/or commit. | 6 """Enables directory-specific presubmit checks to run at upload and/or commit. |
7 """ | 7 """ |
8 | 8 |
9 __version__ = '1.3.2' | 9 __version__ = '1.3.2' |
10 | 10 |
11 # TODO(joi) Add caching where appropriate/needed. The API is designed to allow | 11 # TODO(joi) Add caching where appropriate/needed. The API is designed to allow |
12 # caching (between all different invocations of presubmit scripts for a given | 12 # caching (between all different invocations of presubmit scripts for a given |
13 # change). We should add it as our presubmit scripts start feeling slow. | 13 # change). We should add it as our presubmit scripts start feeling slow. |
14 | 14 |
15 import cPickle # Exposed through the API. | 15 import cPickle # Exposed through the API. |
16 import cStringIO # Exposed through the API. | 16 import cStringIO # Exposed through the API. |
17 import exceptions | 17 import exceptions |
18 import fnmatch | 18 import fnmatch |
19 import glob | 19 import glob |
20 import logging | 20 import logging |
21 import marshal # Exposed through the API. | 21 import marshal # Exposed through the API. |
22 import optparse | 22 import optparse |
23 import os # Somewhat exposed through the API. | 23 import os # Somewhat exposed through the API. |
24 import pickle # Exposed through the API. | 24 import pickle # Exposed through the API. |
25 import random | 25 import random |
26 import re # Exposed through the API. | 26 import re # Exposed through the API. |
27 import subprocess # Exposed through the API. | 27 import subprocess # Exposed through the API. |
28 import sys # Parts exposed through API. | 28 import sys # Parts exposed through API. |
29 import tempfile # Exposed through the API. | 29 import tempfile # Exposed through the API. |
| 30 import time |
30 import traceback # Exposed through the API. | 31 import traceback # Exposed through the API. |
31 import types | 32 import types |
32 import unittest # Exposed through the API. | 33 import unittest # Exposed through the API. |
33 import urllib2 # Exposed through the API. | 34 import urllib2 # Exposed through the API. |
34 import warnings | 35 import warnings |
35 | 36 |
36 # Local imports. | 37 # Local imports. |
37 # TODO(joi) Would be cleaner to factor out utils in gcl to separate module, but | 38 # TODO(joi) Would be cleaner to factor out utils in gcl to separate module, but |
38 # for now it would only be a couple of functions so hardly worth it. | 39 # for now it would only be a couple of functions so hardly worth it. |
39 import gcl | 40 import gcl |
(...skipping 764 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
804 default_presubmit: A default presubmit script to execute in any case. | 805 default_presubmit: A default presubmit script to execute in any case. |
805 may_prompt: Enable (y/n) questions on warning or error. | 806 may_prompt: Enable (y/n) questions on warning or error. |
806 | 807 |
807 Warning: | 808 Warning: |
808 If may_prompt is true, output_stream SHOULD be sys.stdout and input_stream | 809 If may_prompt is true, output_stream SHOULD be sys.stdout and input_stream |
809 SHOULD be sys.stdin. | 810 SHOULD be sys.stdin. |
810 | 811 |
811 Return: | 812 Return: |
812 True if execution can continue, False if not. | 813 True if execution can continue, False if not. |
813 """ | 814 """ |
| 815 start_time = time.time() |
814 presubmit_files = ListRelevantPresubmitFiles(change.AbsoluteLocalPaths(True), | 816 presubmit_files = ListRelevantPresubmitFiles(change.AbsoluteLocalPaths(True), |
815 change.RepositoryRoot()) | 817 change.RepositoryRoot()) |
816 if not presubmit_files and verbose: | 818 if not presubmit_files and verbose: |
817 output_stream.write("Warning, no presubmit.py found.\n") | 819 output_stream.write("Warning, no presubmit.py found.\n") |
818 results = [] | 820 results = [] |
819 executer = PresubmitExecuter(change, committing) | 821 executer = PresubmitExecuter(change, committing) |
820 if default_presubmit: | 822 if default_presubmit: |
821 if verbose: | 823 if verbose: |
822 output_stream.write("Running default presubmit script.\n") | 824 output_stream.write("Running default presubmit script.\n") |
823 fake_path = os.path.join(change.RepositoryRoot(), 'PRESUBMIT.py') | 825 fake_path = os.path.join(change.RepositoryRoot(), 'PRESUBMIT.py') |
(...skipping 28 matching lines...) Expand all Loading... |
852 may_prompt=False): | 854 may_prompt=False): |
853 error_count += 1 | 855 error_count += 1 |
854 output_stream.write('\n') | 856 output_stream.write('\n') |
855 if not errors and warnings and may_prompt: | 857 if not errors and warnings and may_prompt: |
856 output_stream.write( | 858 output_stream.write( |
857 'There were presubmit warnings. Sure you want to continue? (y/N): ') | 859 'There were presubmit warnings. Sure you want to continue? (y/N): ') |
858 response = input_stream.readline() | 860 response = input_stream.readline() |
859 if response.strip().lower() != 'y': | 861 if response.strip().lower() != 'y': |
860 error_count += 1 | 862 error_count += 1 |
861 | 863 |
| 864 total_time = time.time() - start_time |
| 865 if total_time > 1.0: |
| 866 print "Presubmit checks took %.1fs to calculate." % total_time |
862 global _ASKED_FOR_FEEDBACK | 867 global _ASKED_FOR_FEEDBACK |
863 # Ask for feedback one time out of 5. | 868 # Ask for feedback one time out of 5. |
864 if (len(results) and random.randint(0, 4) == 0 and not _ASKED_FOR_FEEDBACK): | 869 if (len(results) and random.randint(0, 4) == 0 and not _ASKED_FOR_FEEDBACK): |
865 output_stream.write("Was the presubmit check useful? Please send feedback " | 870 output_stream.write("Was the presubmit check useful? Please send feedback " |
866 "& hate mail to maruel@chromium.org!\n") | 871 "& hate mail to maruel@chromium.org!\n") |
867 _ASKED_FOR_FEEDBACK = True | 872 _ASKED_FOR_FEEDBACK = True |
868 return (error_count == 0) | 873 return (error_count == 0) |
869 | 874 |
870 | 875 |
871 def ScanSubDirs(mask, recursive): | 876 def ScanSubDirs(mask, recursive): |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
943 options.commit, | 948 options.commit, |
944 options.verbose, | 949 options.verbose, |
945 sys.stdout, | 950 sys.stdout, |
946 sys.stdin, | 951 sys.stdin, |
947 options.default_presubmit, | 952 options.default_presubmit, |
948 options.may_prompt) | 953 options.may_prompt) |
949 | 954 |
950 | 955 |
951 if __name__ == '__main__': | 956 if __name__ == '__main__': |
952 sys.exit(Main(sys.argv)) | 957 sys.exit(Main(sys.argv)) |
OLD | NEW |