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

Side by Side Diff: presubmit_support.py

Issue 147162: Ask for feedback one time out of 5, only when there is presubmit check notification. (Closed)
Patch Set: . Created 11 years, 6 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
« no previous file with comments | « no previous file | tests/presubmit_unittest.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 #!/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 re # Exposed through the API. 26 import re # Exposed through the API.
26 import subprocess # Exposed through the API. 27 import subprocess # Exposed through the API.
27 import sys # Parts exposed through API. 28 import sys # Parts exposed through API.
28 import tempfile # Exposed through the API. 29 import tempfile # Exposed through the API.
29 import traceback # Exposed through the API. 30 import traceback # Exposed through the API.
30 import types 31 import types
31 import unittest # Exposed through the API. 32 import unittest # Exposed through the API.
32 import urllib2 # Exposed through the API. 33 import urllib2 # Exposed through the API.
33 import warnings 34 import warnings
34 35
35 # Local imports. 36 # Local imports.
36 # TODO(joi) Would be cleaner to factor out utils in gcl to separate module, but 37 # TODO(joi) Would be cleaner to factor out utils in gcl to separate module, but
37 # for now it would only be a couple of functions so hardly worth it. 38 # for now it would only be a couple of functions so hardly worth it.
38 import gcl 39 import gcl
39 import gclient 40 import gclient
40 import presubmit_canned_checks 41 import presubmit_canned_checks
41 42
42 43
44 # Ask for feedback only once in program lifetime.
45 _ASKED_FOR_FEEDBACK = False
46
47
43 class NotImplementedException(Exception): 48 class NotImplementedException(Exception):
44 """We're leaving placeholders in a bunch of places to remind us of the 49 """We're leaving placeholders in a bunch of places to remind us of the
45 design of the API, but we have not implemented all of it yet. Implement as 50 design of the API, but we have not implemented all of it yet. Implement as
46 the need arises. 51 the need arises.
47 """ 52 """
48 pass 53 pass
49 54
50 55
51 def normpath(path): 56 def normpath(path):
52 '''Version of os.path.normpath that also changes backward slashes to 57 '''Version of os.path.normpath that also changes backward slashes to
(...skipping 720 matching lines...) Expand 10 before | Expand all | Expand 10 after
773 778
774 Args: 779 Args:
775 change: The Change object. 780 change: The Change object.
776 committing: True if 'gcl commit' is running, False if 'gcl upload' is. 781 committing: True if 'gcl commit' is running, False if 'gcl upload' is.
777 verbose: Prints debug info. 782 verbose: Prints debug info.
778 output_stream: A stream to write output from presubmit tests to. 783 output_stream: A stream to write output from presubmit tests to.
779 input_stream: A stream to read input from the user. 784 input_stream: A stream to read input from the user.
780 default_presubmit: A default presubmit script to execute in any case. 785 default_presubmit: A default presubmit script to execute in any case.
781 may_prompt: Enable (y/n) questions on warning or error. 786 may_prompt: Enable (y/n) questions on warning or error.
782 787
788 Warning:
789 If may_prompt is true, output_streeam SHOULD be sys.stdout and input_stream
Jói Sigurðsson 2009/06/25 21:19:28 output_streeam -> output_stream
790 SHOULD be sys.stdin.
791
783 Return: 792 Return:
784 True if execution can continue, False if not. 793 True if execution can continue, False if not.
785 """ 794 """
786 presubmit_files = ListRelevantPresubmitFiles(change.AbsoluteLocalPaths(True), 795 presubmit_files = ListRelevantPresubmitFiles(change.AbsoluteLocalPaths(True),
787 change.RepositoryRoot()) 796 change.RepositoryRoot())
788 if not presubmit_files and verbose: 797 if not presubmit_files and verbose:
789 output_stream.write("Warning, no presubmit.py found.\n") 798 output_stream.write("Warning, no presubmit.py found.\n")
790 results = [] 799 results = []
791 executer = PresubmitExecuter(change, committing) 800 executer = PresubmitExecuter(change, committing)
792 if default_presubmit: 801 if default_presubmit:
(...skipping 30 matching lines...) Expand all
823 if not item._Handle(output_stream, input_stream, 832 if not item._Handle(output_stream, input_stream,
824 may_prompt=False): 833 may_prompt=False):
825 error_count += 1 834 error_count += 1
826 output_stream.write('\n') 835 output_stream.write('\n')
827 if not errors and warnings and may_prompt: 836 if not errors and warnings and may_prompt:
828 output_stream.write( 837 output_stream.write(
829 'There were presubmit warnings. Sure you want to continue? (y/N): ') 838 'There were presubmit warnings. Sure you want to continue? (y/N): ')
830 response = input_stream.readline() 839 response = input_stream.readline()
831 if response.strip().lower() != 'y': 840 if response.strip().lower() != 'y':
832 error_count += 1 841 error_count += 1
842
843 global _ASKED_FOR_FEEDBACK
844 # Ask for feedback one time out of 5.
845 if (len(results) and random.randint(0, 4) == 0 and not _ASKED_FOR_FEEDBACK):
846 output_stream.write("Was the presubmit check useful? Please send feedback "
847 "& hate mail to maruel@chromium.org!\n")
848 _ASKED_FOR_FEEDBACK = True
833 return (error_count == 0) 849 return (error_count == 0)
834 850
835 851
836 def ScanSubDirs(mask, recursive): 852 def ScanSubDirs(mask, recursive):
837 if not recursive: 853 if not recursive:
838 return [x for x in glob.glob(mask) if '.svn' not in x and '.git' not in x] 854 return [x for x in glob.glob(mask) if '.svn' not in x and '.git' not in x]
839 else: 855 else:
840 results = [] 856 results = []
841 for root, dirs, files in os.walk('.'): 857 for root, dirs, files in os.walk('.'):
842 if '.svn' in dirs: 858 if '.svn' in dirs:
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
908 options.commit, 924 options.commit,
909 options.verbose, 925 options.verbose,
910 sys.stdout, 926 sys.stdout,
911 sys.stdin, 927 sys.stdin,
912 options.default_presubmit, 928 options.default_presubmit,
913 options.may_prompt) 929 options.may_prompt)
914 930
915 931
916 if __name__ == '__main__': 932 if __name__ == '__main__':
917 sys.exit(Main(sys.argv)) 933 sys.exit(Main(sys.argv))
OLDNEW
« no previous file with comments | « no previous file | tests/presubmit_unittest.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698