blob: faf290ae1371e120dbe061e94469e12db5f3302d [file] [log] [blame]
[email protected]fb2b8eb2009-04-23 21:03:421#!/usr/bin/env python
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
4# found in the LICENSE file.
5
6"""Generic presubmit checks that can be reused by other presubmit checks."""
7
8
[email protected]00c41e42009-05-12 21:43:139def CheckChangeHasTestField(input_api, output_api):
10 """Requires that the changelist have a TEST= field."""
[email protected]e1a524f2009-05-27 14:43:4611 if input_api.change.TEST:
[email protected]00c41e42009-05-12 21:43:1312 return []
13 else:
14 return [output_api.PresubmitNotifyResult(
15 "Changelist should have a TEST= field. TEST=none is allowed.")]
16
17
18def CheckChangeHasBugField(input_api, output_api):
19 """Requires that the changelist have a BUG= field."""
[email protected]e1a524f2009-05-27 14:43:4620 if input_api.change.BUG:
[email protected]00c41e42009-05-12 21:43:1321 return []
22 else:
23 return [output_api.PresubmitNotifyResult(
24 "Changelist should have a BUG= field. BUG=none is allowed.")]
25
26
[email protected]fb2b8eb2009-04-23 21:03:4227def CheckChangeHasTestedField(input_api, output_api):
28 """Requires that the changelist have a TESTED= field."""
[email protected]e1a524f2009-05-27 14:43:4629 if input_api.change.TESTED:
[email protected]fb2b8eb2009-04-23 21:03:4230 return []
31 else:
32 return [output_api.PresubmitError("Changelist must have a TESTED= field.")]
33
34
35def CheckChangeHasQaField(input_api, output_api):
36 """Requires that the changelist have a QA= field."""
37 if input_api.change.QA:
38 return []
39 else:
40 return [output_api.PresubmitError("Changelist must have a QA= field.")]
41
42
43def CheckDoNotSubmitInDescription(input_api, output_api):
44 """Checks that the user didn't add 'DO NOT ' + 'SUBMIT' to the CL description.
45 """
46 keyword = 'DO NOT ' + 'SUBMIT'
47 if keyword in input_api.change.DescriptionText():
48 return [output_api.PresubmitError(
49 keyword + " is present in the changelist description.")]
50 else:
51 return []
52
53
54def CheckDoNotSubmitInFiles(input_api, output_api):
55 """Checks that the user didn't add 'DO NOT ' + 'SUBMIT' to any files."""
56 keyword = 'DO NOT ' + 'SUBMIT'
57 for f, line_num, line in input_api.RightHandSideLines():
58 if keyword in line:
59 text = 'Found ' + keyword + ' in %s, line %s' % (f.LocalPath(), line_num)
60 return [output_api.PresubmitError(text)]
61 return []
62
63
64def CheckDoNotSubmit(input_api, output_api):
65 return (
66 CheckDoNotSubmitInDescription(input_api, output_api) +
67 CheckDoNotSubmitInFiles(input_api, output_api)
68 )
69
70
71def CheckChangeHasNoTabs(input_api, output_api):
72 """Checks that there are no tab characters in any of the text files to be
73 submitted.
74 """
75 for f, line_num, line in input_api.RightHandSideLines():
76 if '\t' in line:
77 return [output_api.PresubmitError(
78 "Found a tab character in %s, line %s" %
79 (f.LocalPath(), line_num))]
80 return []
81
82
83def CheckLongLines(input_api, output_api, maxlen=80):
84 """Checks that there aren't any lines longer than maxlen characters in any of
85 the text files to be submitted.
86 """
87 basename = input_api.basename
88
89 bad = []
90 for f, line_num, line in input_api.RightHandSideLines():
91 if line.endswith('\n'):
92 line = line[:-1]
93 if len(line) > maxlen:
94 bad.append(
95 '%s, line %s, %s chars' %
96 (basename(f.LocalPath()), line_num, len(line)))
97 if len(bad) == 5: # Just show the first 5 errors.
98 break
99
100 if bad:
101 msg = "Found lines longer than %s characters (first 5 shown)." % maxlen
102 return [output_api.PresubmitPromptWarning(msg, items=bad)]
103 else:
104 return []
105
106
107def CheckTreeIsOpen(input_api, output_api, url, closed):
108 """Checks that an url's content doesn't match a regexp that would mean that
109 the tree is closed."""
110 try:
111 connection = input_api.urllib2.urlopen(url)
112 status = connection.read()
113 connection.close()
114 if input_api.re.match(closed, status):
115 long_text = status + '\n' + url
116 return [output_api.PresubmitError("The tree is closed.",
117 long_text=long_text)]
118 except IOError:
119 pass
120 return []
[email protected]7b305e82009-05-19 18:24:20121
122
123def RunPythonUnitTests(input_api, output_api, unit_tests):
124 """Imports the unit_tests modules and run them."""
125 import unittest
126 tests_suite = []
127 test_loader = unittest.TestLoader()
128 def LoadTests(module_name):
129 module = __import__(module_name)
130 for part in module_name.split('.')[1:]:
131 module = getattr(module, part)
132 tests_suite.extend(test_loader.loadTestsFromModule(module)._tests)
133
134 outputs = []
135 for unit_test in unit_tests:
136 try:
137 LoadTests(unit_test)
138 except ImportError:
139 outputs.Append(output_api.PresubmitError("Failed to load %s" % unit_test))
140 raise
141
142 results = unittest.TextTestRunner(verbosity=0).run(unittest.TestSuite(
143 tests_suite))
144 if not results.wasSuccessful():
145 outputs.append(output_api.PresubmitError(
146 "%d unit tests failed." % (results.failures + results.errors)))
147 return outputs