-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPRESUBMIT.py
137 lines (120 loc) · 5.31 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
maxlen = 100
def CheckChange(input_api, output_api):
results = []
# Check for presence of DO\ NOT\ SUBMIT in files to be committed.
results += input_api.canned_checks.CheckDoNotSubmit(input_api, output_api)
# Checks that all input files do not contain any <TAB> characters.
results += input_api.canned_checks.CheckChangeHasNoTabs(input_api,
output_api)
# Checks for lines longer than maxlen.
results += input_api.canned_checks.CheckLongLines(input_api,
output_api,
maxlen)
# Clean and build the app before linting it so that the currect and current
# .class files are present for lint.
# BuckClean(input_api, output_api)
results += BuckBuild(input_api, output_api)
# Lint.
results += RunAndroidLint(input_api, output_api)
# Run the unit tests.
results += BuckTest(input_api, output_api)
return results
# Runs buck test --all and checks for failed tests.
def BuckTest(input_api, output_api):
source_directory = str(input_api.PresubmitLocalPath())
args = 'buck test --all --no-results-cache'.split()
env = input_api.environ.copy()
subproc = input_api.subprocess.Popen(
args,
cwd=source_directory,
env=env,
stdin=input_api.subprocess.PIPE,
stdout=input_api.subprocess.PIPE,
stderr=input_api.subprocess.STDOUT)
stdout_data = subproc.communicate()[0]
failed_test = lambda line: (input_api.re.match(r'^TESTS FAILED:', line))
test_failure_lines = filter(failed_test, stdout_data.splitlines())
if test_failure_lines:
return [output_api.PresubmitError('Unit tests failed.')]
else:
return [output_api.PresubmitNotifyResult('Unit tests passed.')]
# Runs `buck clean`, which deletes all built files in buck-out.
def BuckClean(input_api, output_api):
source_directory = str(input_api.PresubmitLocalPath())
args = 'buck clean'.split()
env = input_api.environ.copy()
subproc = input_api.subprocess.Popen(
args,
cwd=source_directory,
env=env,
stdin=input_api.subprocess.PIPE,
stdout=input_api.subprocess.PIPE,
stderr=input_api.subprocess.STDOUT)
stdout_data = subproc.communicate()[0]
# Runs `buck build rangzen` which compiles an APK of the app (and all of
# its prerequisites).
# Runs before Android Lint so that the appropriate .class files can be linted.
def BuckBuild(input_api, output_api):
source_directory = str(input_api.PresubmitLocalPath())
buildTargetName = 'experimentalApp'
args = ('buck build %s' % (buildTargetName,)).split()
env = input_api.environ.copy()
subproc = input_api.subprocess.Popen(
args,
cwd=source_directory,
env=env,
stdin=input_api.subprocess.PIPE,
stdout=input_api.subprocess.PIPE,
stderr=input_api.subprocess.STDOUT)
stdout_data = subproc.communicate()[0]
# did_build_apk = lambda line: (input_api.re.match(r'^built APK', line))
did_not_build_apk = lambda line: (input_api.re.match(r'^BUILD FAILED:', line))
build_failure_lines = filter(did_not_build_apk, stdout_data.splitlines())
if build_failure_lines:
return [output_api.PresubmitError('Did not build Rangzen APK successfully.')]
else:
return [output_api.PresubmitNotifyResult('Built Rangzen APK successfully.')]
# Runs Android lint on the project, manually specifying the java sources, test
# sources, resources and classpath (compiled .class files locations).
def RunAndroidLint(input_api, output_api):
error, stdout_data = LintSourceDirectories('java/org/denovogroup/rangzen',
'tests/rog/denovogroup/rangzen',
input_api, output_api)
if error:
return [output_api.PresubmitError('Lint error\n%s' % '\n'.join(error),
long_text=stdout_data)]
else:
return [output_api.PresubmitNotifyResult('Android lint is clean.')]
pass
# Utility function which lints the given java and tests directories.
def LintSourceDirectories(java_directory, tests_directory, input_api, output_api):
repo_directory = input_api.PresubmitLocalPath()
resources_directory = 'res/org/denovogroup/rangzen/res'
classes_directory = 'buck-out'
command = ('lint %s --sources %s --sources %s --classpath %s --resources %s -Wall' %
(repo_directory,
java_directory,
tests_directory,
classes_directory,
resources_directory))
args = command.split()
env = input_api.environ.copy()
subproc = input_api.subprocess.Popen(
args,
cwd=repo_directory,
env=env,
stdin=input_api.subprocess.PIPE,
stdout=input_api.subprocess.PIPE,
stderr=input_api.subprocess.STDOUT)
stdout_data = subproc.communicate()[0]
is_error_summary = lambda line: (input_api.re.match(r'^\d+ errors, \d+ warnings', line))
error = filter(is_error_summary, stdout_data.splitlines())
if error:
return error, stdout_data + input_api.PresubmitLocalPath()
return [], stdout_data
# This method is run when git cl upload is run.
def CheckChangeOnUpload(input_api, output_api):
return CheckChange(input_api, output_api)
# This method is run on git cl push.
def CheckChangeOnCommit(input_api, output_api):
return CheckChange(input_api, output_api)