-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPRESUBMIT.py
140 lines (116 loc) · 4.9 KB
/
PRESUBMIT.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# Copyright (c) 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Presubmit checks for common code."""
import os
import subprocess
import sys
SKIA_TREE_STATUS_URL = 'http://skia-tree-status.appspot.com'
SKIP_RUNS_KEYWORD = '(SkipBuildbotRuns)'
def _RunPyUnitTests(input_api, output_api):
""" Run the Python unit tests and return a list of strings containing any
errors.
"""
results = []
success = True
try:
proc = subprocess.Popen(['python', os.path.join('py', 'run_unittests')],
stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
success = proc.wait() == 0
long_text = proc.communicate()[0]
except Exception:
success = False
long_text = 'Failed to run the common tests!'
if not success:
results.append(output_api.PresubmitPromptWarning(
message='One or more unit tests failed.',
long_text=long_text))
return results
def CheckChange(input_api, output_api):
"""Presubmit checks for the change on upload or commit.
The presubmit checks have been handpicked from the list of canned checks
here:
https://chromium.googlesource.com/chromium/tools/depot_tools/+/master/presubmit_canned_checks.py
The following are the presubmit checks:
* Pylint is run if the change contains any .py files.
* Enforces max length for all lines is 80.
* Checks that the user didn't add TODO(name) without an owner.
* Checks that there is no stray whitespace at source lines end.
* Checks that there are no tab characters in any of the text files.
"""
results = []
pylint_disabled_warnings = (
'F0401', # Unable to import.
'E0611', # No name in module.
'W0232', # Class has no __init__ method.
'E1002', # Use of super on an old style class.
'W0403', # Relative import used.
'R0201', # Method could be a function.
'E1003', # Using class name in super.
'W0613', # Unused argument.
)
# Run Pylint on only the modified python files. Unfortunately it still runs
# Pylint on the whole file instead of just the modified lines.
affected_python_files = []
for affected_file in input_api.AffectedSourceFiles(None):
affected_file_path = affected_file.LocalPath()
if affected_file_path.endswith('.py'):
affected_python_files.append(affected_file_path)
results += input_api.canned_checks.RunPylint(
input_api, output_api,
disabled_warnings=pylint_disabled_warnings,
white_list=affected_python_files)
# Use 100 for max length for files other than python. Python length is
# already checked during the Pylint above.
results += input_api.canned_checks.CheckLongLines(input_api, output_api, 100)
results += input_api.canned_checks.CheckChangeTodoHasOwner(
input_api, output_api)
results += input_api.canned_checks.CheckChangeHasNoStrayWhitespace(
input_api, output_api)
results += input_api.canned_checks.CheckChangeHasNoTabs(input_api, output_api)
results += _RunPyUnitTests(input_api, output_api)
return results
def _CheckTreeStatus(input_api, output_api, json_url):
"""Check whether to allow commit.
Args:
input_api: input related apis.
output_api: output related apis.
json_url: url to download json style status.
"""
results = []
tree_status_results = input_api.canned_checks.CheckTreeIsOpen(
input_api, output_api, json_url=json_url)
display_skip_keyword_prompt = False
tree_status = None
if not tree_status_results:
# Check for caution state only if tree is not closed.
connection = input_api.urllib2.urlopen(json_url)
status = input_api.json.loads(connection.read())
connection.close()
tree_status = status['message']
if 'caution' in tree_status.lower():
# Display a prompt only if we are in an interactive shell. Without this
# check the commit queue behaves incorrectly because it considers
# prompts to be failures.
display_skip_keyword_prompt = True
else:
tree_status = tree_status_results[0]._message # pylint: disable=W0212
display_skip_keyword_prompt = True
if (display_skip_keyword_prompt
and os.isatty(sys.stdout.fileno())
and not SKIP_RUNS_KEYWORD in input_api.change.DescriptionText()):
long_text = (
'%s\nAre you sure the change should be submitted. If it should be '
'submitted but not run on the buildbots you can use the %s keyword.' % (
tree_status, SKIP_RUNS_KEYWORD))
results.append(output_api.PresubmitPromptWarning(
message=tree_status, long_text=long_text))
return results
def CheckChangeOnUpload(input_api, output_api):
return CheckChange(input_api, output_api)
def CheckChangeOnCommit(input_api, output_api):
results = CheckChange(input_api, output_api)
results.extend(
_CheckTreeStatus(input_api, output_api, json_url=(
SKIA_TREE_STATUS_URL + '/banner-status?format=json')))
return results