libv8 6.3.292.48.1 → 6.7.288.46.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.travis.yml +10 -34
- data/CHANGELOG.md +16 -0
- data/README.md +9 -63
- data/Rakefile +2 -2
- data/ext/libv8/builder.rb +22 -87
- data/ext/libv8/extconf.rb +1 -1
- data/ext/libv8/paths.rb +5 -18
- data/lib/libv8/version.rb +1 -1
- data/spec/location_spec.rb +1 -2
- data/spec/spec_helper.rb +0 -1
- data/vendor/depot_tools/.gitattributes +1 -2
- data/vendor/depot_tools/OWNERS +0 -1
- data/vendor/depot_tools/PRESUBMIT.py +11 -6
- data/vendor/depot_tools/README.md +0 -1
- data/vendor/depot_tools/WATCHLISTS +0 -6
- data/vendor/depot_tools/auth.py +129 -87
- data/vendor/depot_tools/autoninja +11 -1
- data/vendor/depot_tools/autoninja.bat +7 -1
- data/vendor/depot_tools/autoninja.py +14 -6
- data/vendor/depot_tools/bootstrap/win/manifest.txt +1 -1
- data/vendor/depot_tools/bootstrap/win/manifest_bleeding_edge.txt +1 -1
- data/vendor/depot_tools/cipd +23 -2
- data/vendor/depot_tools/cipd.bat +2 -2
- data/vendor/depot_tools/cipd_client_version +1 -1
- data/vendor/depot_tools/cipd_manifest.txt +17 -7
- data/vendor/depot_tools/cit.py +7 -6
- data/vendor/depot_tools/cpplint.py +195 -35
- data/vendor/depot_tools/detect_host_arch.py +51 -0
- data/vendor/depot_tools/download_from_google_storage.py +85 -26
- data/vendor/depot_tools/fetch.py +11 -6
- data/vendor/depot_tools/fetch_configs/chromium.py +0 -1
- data/vendor/depot_tools/fetch_configs/goma_client.py +41 -0
- data/vendor/depot_tools/fetch_configs/infra.py +0 -1
- data/vendor/depot_tools/fetch_configs/infra_internal.py +0 -1
- data/vendor/depot_tools/gclient-new-workdir.py +4 -0
- data/vendor/depot_tools/gclient.py +732 -476
- data/vendor/depot_tools/gclient_eval.py +569 -58
- data/vendor/depot_tools/gclient_scm.py +258 -46
- data/vendor/depot_tools/gclient_utils.py +17 -1
- data/vendor/depot_tools/gerrit_util.py +46 -13
- data/vendor/depot_tools/git_cache.py +0 -2
- data/vendor/depot_tools/git_cl.py +176 -335
- data/vendor/depot_tools/git_common.py +19 -16
- data/vendor/depot_tools/git_footers.py +19 -5
- data/vendor/depot_tools/git_hyper_blame.py +9 -3
- data/vendor/depot_tools/git_new_branch.py +15 -3
- data/vendor/depot_tools/git_upstream_diff.py +7 -2
- data/vendor/depot_tools/gsutil.py +1 -1
- data/vendor/depot_tools/infra/config/cq.cfg +1 -2
- data/vendor/depot_tools/infra/config/recipes.cfg +1 -1
- data/vendor/depot_tools/luci-auth +13 -0
- data/vendor/depot_tools/luci-auth.bat +8 -0
- data/vendor/depot_tools/man/html/depot_tools.html +0 -8
- data/vendor/depot_tools/man/html/git-upstream-diff.html +20 -3
- data/vendor/depot_tools/man/man1/git-upstream-diff.1 +27 -6
- data/vendor/depot_tools/man/man7/depot_tools.7 +0 -5
- data/vendor/depot_tools/man/man7/depot_tools_tutorial.7 +2 -2
- data/vendor/depot_tools/man/src/git-upstream-diff.txt +21 -3
- data/vendor/depot_tools/man/src/make_docs.sh +6 -0
- data/vendor/depot_tools/my_activity.py +283 -93
- data/vendor/depot_tools/owners.py +9 -4
- data/vendor/depot_tools/owners_finder.py +7 -3
- data/vendor/depot_tools/post_build_ninja_summary.py +322 -0
- data/vendor/depot_tools/presubmit_canned_checks.py +91 -106
- data/vendor/depot_tools/presubmit_support.py +219 -157
- data/vendor/depot_tools/prpc +13 -0
- data/vendor/depot_tools/prpc.bat +8 -0
- data/vendor/depot_tools/recipes/OWNERS +3 -1
- data/vendor/depot_tools/recipes/README.recipes.md +70 -111
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/__init__.py +12 -5
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/api.py +36 -68
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/deprecated_got_revision_mapping.json +0 -8
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/{trychange_oauth2_json.json → no_apply_patch_on_gclient.json} +64 -10
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/{no_shallow.json → shallow.json} +1 -1
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob.json +0 -8
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_empty_revision.json +0 -8
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_fail.json +0 -6
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_fail_patch.json +0 -7
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_fail_patch_download.json +0 -6
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_gerrit_angle_deprecated.json +44 -0
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/{trychange_oauth2_buildbot.json → tryjob_gerrit_branch_heads.json} +51 -5
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_v8.json +0 -8
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_v8_head_by_default.json +48 -8
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.py +19 -26
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/resources/bot_update.py +193 -155
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/test_api.py +9 -0
- data/vendor/depot_tools/recipes/recipe_modules/gclient/api.py +2 -7
- data/vendor/depot_tools/recipes/recipe_modules/gclient/config.py +31 -5
- data/vendor/depot_tools/recipes/recipe_modules/gclient/examples/full.expected/basic.json +37 -19
- data/vendor/depot_tools/recipes/recipe_modules/gclient/examples/full.expected/buildbot.json +37 -19
- data/vendor/depot_tools/recipes/recipe_modules/gclient/examples/full.expected/revision.json +37 -19
- data/vendor/depot_tools/recipes/recipe_modules/gclient/examples/full.expected/tryserver.json +37 -23
- data/vendor/depot_tools/recipes/recipe_modules/gclient/examples/full.py +4 -0
- data/vendor/depot_tools/recipes/recipe_modules/gerrit/api.py +40 -8
- data/vendor/depot_tools/recipes/recipe_modules/gerrit/examples/full.expected/basic.json +3 -3
- data/vendor/depot_tools/recipes/recipe_modules/gerrit/examples/full.py +6 -3
- data/vendor/depot_tools/recipes/recipe_modules/gitiles/OWNERS +0 -1
- data/vendor/depot_tools/recipes/recipe_modules/tryserver/__init__.py +0 -1
- data/vendor/depot_tools/recipes/recipe_modules/tryserver/api.py +7 -56
- data/vendor/depot_tools/recipes/recipe_modules/tryserver/examples/full.expected/with_wrong_patch.json +0 -1
- data/vendor/depot_tools/recipes/recipe_modules/tryserver/examples/full.py +15 -16
- data/vendor/depot_tools/recipes/recipes.py +4 -2
- data/vendor/depot_tools/recipes/trigger_recipe_roller.txt +12 -0
- data/vendor/depot_tools/roll_dep.py +35 -37
- data/vendor/depot_tools/support/chromite_wrapper +1 -1
- data/vendor/depot_tools/third_party/logilab/astroid/README.chromium +3 -3
- data/vendor/depot_tools/third_party/logilab/astroid/__pkginfo__.py +2 -2
- data/vendor/depot_tools/third_party/logilab/astroid/astpeephole.py +86 -0
- data/vendor/depot_tools/third_party/logilab/astroid/bases.py +53 -66
- data/vendor/depot_tools/third_party/logilab/astroid/brain/py2pytest.py +31 -31
- data/vendor/depot_tools/third_party/logilab/astroid/brain/pynose.py +39 -16
- data/vendor/depot_tools/third_party/logilab/astroid/brain/pysix_moves.py +225 -189
- data/vendor/depot_tools/third_party/logilab/astroid/inference.py +45 -41
- data/vendor/depot_tools/third_party/logilab/astroid/manager.py +1 -0
- data/vendor/depot_tools/third_party/logilab/astroid/modutils.py +2 -2
- data/vendor/depot_tools/third_party/logilab/astroid/node_classes.py +3 -2
- data/vendor/depot_tools/third_party/logilab/astroid/nodes.py +1 -0
- data/vendor/depot_tools/third_party/logilab/astroid/protocols.py +57 -3
- data/vendor/depot_tools/third_party/logilab/astroid/raw_building.py +1 -1
- data/vendor/depot_tools/third_party/logilab/astroid/rebuilder.py +21 -1
- data/vendor/depot_tools/third_party/logilab/astroid/scoped_nodes.py +58 -33
- data/vendor/depot_tools/third_party/pylint/README.chromium +2 -2
- data/vendor/depot_tools/third_party/pylint/__pkginfo__.py +3 -3
- data/vendor/depot_tools/third_party/pylint/checkers/base.py +6 -18
- data/vendor/depot_tools/third_party/pylint/checkers/classes.py +64 -63
- data/vendor/depot_tools/third_party/pylint/checkers/design_analysis.py +25 -57
- data/vendor/depot_tools/third_party/pylint/checkers/format.py +14 -10
- data/vendor/depot_tools/third_party/pylint/checkers/python3.py +142 -37
- data/vendor/depot_tools/third_party/pylint/checkers/spelling.py +10 -1
- data/vendor/depot_tools/third_party/pylint/checkers/stdlib.py +50 -7
- data/vendor/depot_tools/third_party/pylint/checkers/strings.py +1 -1
- data/vendor/depot_tools/third_party/pylint/epylint.py +2 -1
- data/vendor/depot_tools/third_party/pylint/gui.py +1 -1
- data/vendor/depot_tools/third_party/pylint/lint.py +88 -23
- data/vendor/depot_tools/third_party/pylint/reporters/html.py +37 -5
- data/vendor/depot_tools/third_party/pylint/testutils.py +1 -1
- data/vendor/depot_tools/third_party/pylint/utils.py +5 -0
- data/vendor/depot_tools/vpython +31 -1
- data/vendor/depot_tools/win_toolchain/get_toolchain_if_necessary.py +35 -2
- data/vendor/depot_tools/win_toolchain/package_from_installed.py +0 -15
- data/vendor/depot_tools/yapf +17 -0
- data/vendor/depot_tools/{apply_issue.bat → yapf.bat} +2 -2
- metadata +16 -58
- data/ext/libv8/compiler.rb +0 -39
- data/ext/libv8/compiler/apple_llvm.rb +0 -22
- data/ext/libv8/compiler/clang.rb +0 -22
- data/ext/libv8/compiler/gcc.rb +0 -22
- data/ext/libv8/compiler/generic_compiler.rb +0 -66
- data/ext/libv8/make.rb +0 -13
- data/ext/libv8/patcher.rb +0 -21
- data/patches/0001-Build-a-standalone-static-library.patch +0 -26
- data/patches/0002-Don-t-compile-unnecessary-stuff.patch +0 -85
- data/patches/0003-Use-the-fPIC-flag-for-the-static-library.patch +0 -25
- data/patches/0004-Do-not-embed-debug-symbols-in-macOS-libraries.patch +0 -25
- data/patches/0005-Remove-TryInstallOptimizedCode.patch +0 -321
- data/patches/mingw-generate-makefiles.sh +0 -97
- data/spec/compiler/apple_llvm_spec.rb +0 -37
- data/spec/compiler/clang_spec.rb +0 -37
- data/spec/compiler/gcc_spec.rb +0 -37
- data/spec/compiler/generic_compiler_spec.rb +0 -50
- data/spec/compiler_spec.rb +0 -45
- data/spec/support/compiler_helpers.rb +0 -47
- data/vendor/depot_tools/apply_issue +0 -8
- data/vendor/depot_tools/apply_issue.py +0 -315
- data/vendor/depot_tools/man/html/git-cherry-pick-upload.html +0 -815
- data/vendor/depot_tools/man/man1/git-cherry-pick-upload.1 +0 -80
- data/vendor/depot_tools/man/src/_git-cherry-pick-upload_desc.helper.txt +0 -1
- data/vendor/depot_tools/man/src/git-cherry-pick-upload.demo.1.sh +0 -17
- data/vendor/depot_tools/man/src/git-cherry-pick-upload.txt +0 -35
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/trychange_oauth2.json +0 -8
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/trychange_oauth2_json_win.json +0 -196
- data/vendor/depot_tools/recipes/recipe_modules/rietveld/__init__.py +0 -6
- data/vendor/depot_tools/recipes/recipe_modules/rietveld/api.py +0 -97
- data/vendor/depot_tools/recipes/recipe_modules/rietveld/examples/full.expected/basic.json +0 -8
- data/vendor/depot_tools/recipes/recipe_modules/rietveld/examples/full.expected/buildbot.json +0 -30
- data/vendor/depot_tools/recipes/recipe_modules/rietveld/examples/full.expected/no_auth.json +0 -27
- data/vendor/depot_tools/recipes/recipe_modules/rietveld/examples/full.py +0 -38
- data/vendor/depot_tools/recipes/recipe_modules/tryserver/examples/full.expected/with_rietveld_patch.json +0 -69
- data/vendor/depot_tools/recipes/recipe_modules/tryserver/examples/full.expected/with_rietveld_patch_new.json +0 -69
- data/vendor/depot_tools/third_party/cq_client/OWNERS +0 -2
- data/vendor/depot_tools/third_party/cq_client/README.depot_tools.md +0 -2
- data/vendor/depot_tools/third_party/cq_client/README.md +0 -59
- data/vendor/depot_tools/third_party/cq_client/__init__.py +0 -3
- data/vendor/depot_tools/third_party/cq_client/v1/__init__.py +0 -3
- data/vendor/depot_tools/third_party/cq_client/v1/cq.pb.go +0 -810
- data/vendor/depot_tools/third_party/cq_client/v1/cq.proto +0 -281
- data/vendor/depot_tools/third_party/cq_client/v1/cq_pb2.py +0 -794
- data/vendor/depot_tools/third_party/cq_client/v1/testdata/cq_both.cfg +0 -71
- data/vendor/depot_tools/third_party/cq_client/v1/testdata/cq_gerrit.cfg +0 -58
- data/vendor/depot_tools/third_party/cq_client/v1/testdata/cq_rietveld.cfg +0 -60
- data/vendor/depot_tools/third_party/cq_client/v2/__init__.py +0 -3
- data/vendor/depot_tools/third_party/cq_client/v2/cq.pb.go +0 -792
- data/vendor/depot_tools/third_party/cq_client/v2/cq.proto +0 -270
- data/vendor/depot_tools/third_party/cq_client/v2/cq_pb2.py +0 -841
@@ -30,8 +30,10 @@ import os # Somewhat exposed through the API.
|
|
30
30
|
import pickle # Exposed through the API.
|
31
31
|
import random
|
32
32
|
import re # Exposed through the API.
|
33
|
+
import signal
|
33
34
|
import sys # Parts exposed through API.
|
34
35
|
import tempfile # Exposed through the API.
|
36
|
+
import threading
|
35
37
|
import time
|
36
38
|
import traceback # Exposed through the API.
|
37
39
|
import types
|
@@ -41,7 +43,6 @@ import urlparse
|
|
41
43
|
from warnings import warn
|
42
44
|
|
43
45
|
# Local imports.
|
44
|
-
import auth
|
45
46
|
import fix_encoding
|
46
47
|
import gclient_utils
|
47
48
|
import git_footers
|
@@ -49,7 +50,6 @@ import gerrit_util
|
|
49
50
|
import owners
|
50
51
|
import owners_finder
|
51
52
|
import presubmit_canned_checks
|
52
|
-
import rietveld
|
53
53
|
import scm
|
54
54
|
import subprocess2 as subprocess # Exposed through the API.
|
55
55
|
|
@@ -66,11 +66,154 @@ class CommandData(object):
|
|
66
66
|
def __init__(self, name, cmd, kwargs, message):
|
67
67
|
self.name = name
|
68
68
|
self.cmd = cmd
|
69
|
+
self.stdin = kwargs.get('stdin', None)
|
69
70
|
self.kwargs = kwargs
|
71
|
+
self.kwargs['stdout'] = subprocess.PIPE
|
72
|
+
self.kwargs['stderr'] = subprocess.STDOUT
|
73
|
+
self.kwargs['stdin'] = subprocess.PIPE
|
70
74
|
self.message = message
|
71
75
|
self.info = None
|
72
76
|
|
73
77
|
|
78
|
+
# Adapted from
|
79
|
+
# https://github.com/google/gtest-parallel/blob/master/gtest_parallel.py#L37
|
80
|
+
#
|
81
|
+
# An object that catches SIGINT sent to the Python process and notices
|
82
|
+
# if processes passed to wait() die by SIGINT (we need to look for
|
83
|
+
# both of those cases, because pressing Ctrl+C can result in either
|
84
|
+
# the main process or one of the subprocesses getting the signal).
|
85
|
+
#
|
86
|
+
# Before a SIGINT is seen, wait(p) will simply call p.wait() and
|
87
|
+
# return the result. Once a SIGINT has been seen (in the main process
|
88
|
+
# or a subprocess, including the one the current call is waiting for),
|
89
|
+
# wait(p) will call p.terminate() and raise ProcessWasInterrupted.
|
90
|
+
class SigintHandler(object):
|
91
|
+
class ProcessWasInterrupted(Exception):
|
92
|
+
pass
|
93
|
+
|
94
|
+
sigint_returncodes = {-signal.SIGINT, # Unix
|
95
|
+
-1073741510, # Windows
|
96
|
+
}
|
97
|
+
def __init__(self):
|
98
|
+
self.__lock = threading.Lock()
|
99
|
+
self.__processes = set()
|
100
|
+
self.__got_sigint = False
|
101
|
+
signal.signal(signal.SIGINT, lambda signal_num, frame: self.interrupt())
|
102
|
+
|
103
|
+
def __on_sigint(self):
|
104
|
+
self.__got_sigint = True
|
105
|
+
while self.__processes:
|
106
|
+
try:
|
107
|
+
self.__processes.pop().terminate()
|
108
|
+
except OSError:
|
109
|
+
pass
|
110
|
+
|
111
|
+
def interrupt(self):
|
112
|
+
with self.__lock:
|
113
|
+
self.__on_sigint()
|
114
|
+
|
115
|
+
def got_sigint(self):
|
116
|
+
with self.__lock:
|
117
|
+
return self.__got_sigint
|
118
|
+
|
119
|
+
def wait(self, p, stdin):
|
120
|
+
with self.__lock:
|
121
|
+
if self.__got_sigint:
|
122
|
+
p.terminate()
|
123
|
+
self.__processes.add(p)
|
124
|
+
stdout, stderr = p.communicate(stdin)
|
125
|
+
code = p.returncode
|
126
|
+
with self.__lock:
|
127
|
+
self.__processes.discard(p)
|
128
|
+
if code in self.sigint_returncodes:
|
129
|
+
self.__on_sigint()
|
130
|
+
if self.__got_sigint:
|
131
|
+
raise self.ProcessWasInterrupted
|
132
|
+
return stdout, stderr
|
133
|
+
|
134
|
+
sigint_handler = SigintHandler()
|
135
|
+
|
136
|
+
|
137
|
+
class ThreadPool(object):
|
138
|
+
def __init__(self, pool_size=None):
|
139
|
+
self._pool_size = pool_size or multiprocessing.cpu_count()
|
140
|
+
self._messages = []
|
141
|
+
self._messages_lock = threading.Lock()
|
142
|
+
self._tests = []
|
143
|
+
self._tests_lock = threading.Lock()
|
144
|
+
self._nonparallel_tests = []
|
145
|
+
|
146
|
+
def CallCommand(self, test):
|
147
|
+
"""Runs an external program.
|
148
|
+
|
149
|
+
This function converts invocation of .py files and invocations of "python"
|
150
|
+
to vpython invocations.
|
151
|
+
"""
|
152
|
+
vpython = 'vpython.bat' if sys.platform == 'win32' else 'vpython'
|
153
|
+
|
154
|
+
cmd = test.cmd
|
155
|
+
if cmd[0] == 'python':
|
156
|
+
cmd = list(cmd)
|
157
|
+
cmd[0] = vpython
|
158
|
+
elif cmd[0].endswith('.py'):
|
159
|
+
cmd = [vpython] + cmd
|
160
|
+
|
161
|
+
try:
|
162
|
+
start = time.time()
|
163
|
+
p = subprocess.Popen(cmd, **test.kwargs)
|
164
|
+
stdout, _ = sigint_handler.wait(p, test.stdin)
|
165
|
+
duration = time.time() - start
|
166
|
+
except OSError as e:
|
167
|
+
duration = time.time() - start
|
168
|
+
return test.message(
|
169
|
+
'%s exec failure (%4.2fs)\n %s' % (test.name, duration, e))
|
170
|
+
if p.returncode != 0:
|
171
|
+
return test.message(
|
172
|
+
'%s (%4.2fs) failed\n%s' % (test.name, duration, stdout))
|
173
|
+
if test.info:
|
174
|
+
return test.info('%s (%4.2fs)' % (test.name, duration))
|
175
|
+
|
176
|
+
def AddTests(self, tests, parallel=True):
|
177
|
+
if parallel:
|
178
|
+
self._tests.extend(tests)
|
179
|
+
else:
|
180
|
+
self._nonparallel_tests.extend(tests)
|
181
|
+
|
182
|
+
def RunAsync(self):
|
183
|
+
self._messages = []
|
184
|
+
|
185
|
+
def _WorkerFn():
|
186
|
+
while True:
|
187
|
+
test = None
|
188
|
+
with self._tests_lock:
|
189
|
+
if not self._tests:
|
190
|
+
break
|
191
|
+
test = self._tests.pop()
|
192
|
+
result = self.CallCommand(test)
|
193
|
+
if result:
|
194
|
+
with self._messages_lock:
|
195
|
+
self._messages.append(result)
|
196
|
+
|
197
|
+
def _StartDaemon():
|
198
|
+
t = threading.Thread(target=_WorkerFn)
|
199
|
+
t.daemon = True
|
200
|
+
t.start()
|
201
|
+
return t
|
202
|
+
|
203
|
+
while self._nonparallel_tests:
|
204
|
+
test = self._nonparallel_tests.pop()
|
205
|
+
result = self.CallCommand(test)
|
206
|
+
if result:
|
207
|
+
self._messages.append(result)
|
208
|
+
|
209
|
+
if self._tests:
|
210
|
+
threads = [_StartDaemon() for _ in range(self._pool_size)]
|
211
|
+
for worker in threads:
|
212
|
+
worker.join()
|
213
|
+
|
214
|
+
return self._messages
|
215
|
+
|
216
|
+
|
74
217
|
def normpath(path):
|
75
218
|
'''Version of os.path.normpath that also changes backward slashes to
|
76
219
|
forward slashes when not running on Windows.
|
@@ -137,8 +280,6 @@ class _PresubmitResult(object):
|
|
137
280
|
"""
|
138
281
|
self._message = message
|
139
282
|
self._items = items or []
|
140
|
-
if items:
|
141
|
-
self._items = items
|
142
283
|
self._long_text = long_text.rstrip()
|
143
284
|
|
144
285
|
def handle(self, output):
|
@@ -245,6 +386,14 @@ class GerritAccessor(object):
|
|
245
386
|
|
246
387
|
return rev_info['commit']['message']
|
247
388
|
|
389
|
+
def GetDestRef(self, issue):
|
390
|
+
ref = self.GetChangeInfo(issue)['branch']
|
391
|
+
if not ref.startswith('refs/'):
|
392
|
+
# NOTE: it is possible to create 'refs/x' branch,
|
393
|
+
# aka 'refs/heads/refs/x'. However, this is ill-advised.
|
394
|
+
ref = 'refs/heads/%s' % ref
|
395
|
+
return ref
|
396
|
+
|
248
397
|
def GetChangeOwner(self, issue):
|
249
398
|
return self.GetChangeInfo(issue)['owner']['email']
|
250
399
|
|
@@ -303,36 +452,20 @@ class OutputApi(object):
|
|
303
452
|
CQ_INCLUDE_TRYBOTS was updated.
|
304
453
|
"""
|
305
454
|
description = cl.GetDescription(force=True)
|
306
|
-
|
307
|
-
|
455
|
+
trybot_footers = git_footers.parse_footers(description).get(
|
456
|
+
git_footers.normalize_name('Cq-Include-Trybots'), [])
|
308
457
|
prior_bots = []
|
309
|
-
|
310
|
-
|
311
|
-
git_footers.normalize_name('Cq-Include-Trybots'), [])
|
312
|
-
for f in trybot_footers:
|
313
|
-
prior_bots += [b.strip() for b in f.split(';') if b.strip()]
|
314
|
-
else:
|
315
|
-
trybot_tags = include_re.finditer(description)
|
316
|
-
for t in trybot_tags:
|
317
|
-
prior_bots += [b.strip() for b in t.group(1).split(';') if b.strip()]
|
458
|
+
for f in trybot_footers:
|
459
|
+
prior_bots += [b.strip() for b in f.split(';') if b.strip()]
|
318
460
|
|
319
461
|
if set(prior_bots) >= set(bots_to_include):
|
320
462
|
return []
|
321
463
|
all_bots = ';'.join(sorted(set(prior_bots) | set(bots_to_include)))
|
322
464
|
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
description, 'Cq-Include-Trybots', all_bots,
|
328
|
-
before_keys=['Change-Id'])
|
329
|
-
else:
|
330
|
-
new_include_trybots = 'CQ_INCLUDE_TRYBOTS=%s' % all_bots
|
331
|
-
m = include_re.search(description)
|
332
|
-
if m:
|
333
|
-
description = include_re.sub(new_include_trybots, description)
|
334
|
-
else:
|
335
|
-
description = '%s\n%s\n' % (description, new_include_trybots)
|
465
|
+
description = git_footers.remove_footer(description, 'Cq-Include-Trybots')
|
466
|
+
description = git_footers.add_footer(
|
467
|
+
description, 'Cq-Include-Trybots', all_bots,
|
468
|
+
before_keys=['Change-Id'])
|
336
469
|
|
337
470
|
cl.UpdateDescription(description, force=True)
|
338
471
|
return [self.PresubmitNotifyResult(message)]
|
@@ -358,7 +491,8 @@ class InputApi(object):
|
|
358
491
|
# Scripts
|
359
492
|
r".+\.js$", r".+\.py$", r".+\.sh$", r".+\.rb$", r".+\.pl$", r".+\.pm$",
|
360
493
|
# Other
|
361
|
-
r".+\.java$", r".+\.mk$", r".+\.am$", r".+\.css$"
|
494
|
+
r".+\.java$", r".+\.mk$", r".+\.am$", r".+\.css$", r".+\.mojom$",
|
495
|
+
r".+\.fidl$"
|
362
496
|
)
|
363
497
|
|
364
498
|
# Path regexp that should be excluded from being considered containing source
|
@@ -366,8 +500,9 @@ class InputApi(object):
|
|
366
500
|
DEFAULT_BLACK_LIST = (
|
367
501
|
r"testing_support[\\\/]google_appengine[\\\/].*",
|
368
502
|
r".*\bexperimental[\\\/].*",
|
369
|
-
# Exclude third_party/.* but NOT third_party/WebKit
|
370
|
-
|
503
|
+
# Exclude third_party/.* but NOT third_party/{WebKit,blink}
|
504
|
+
# (crbug.com/539768 and crbug.com/836555).
|
505
|
+
r".*\bthird_party[\\\/](?!(WebKit|blink)[\\\/]).*",
|
371
506
|
# Output directories (just in case)
|
372
507
|
r".*\bDebug[\\\/].*",
|
373
508
|
r".*\bRelease[\\\/].*",
|
@@ -384,28 +519,27 @@ class InputApi(object):
|
|
384
519
|
)
|
385
520
|
|
386
521
|
def __init__(self, change, presubmit_path, is_committing,
|
387
|
-
|
522
|
+
verbose, gerrit_obj, dry_run=None, thread_pool=None, parallel=False):
|
388
523
|
"""Builds an InputApi object.
|
389
524
|
|
390
525
|
Args:
|
391
526
|
change: A presubmit.Change object.
|
392
527
|
presubmit_path: The path to the presubmit script being processed.
|
393
528
|
is_committing: True if the change is about to be committed.
|
394
|
-
rietveld_obj: rietveld.Rietveld client object
|
395
529
|
gerrit_obj: provides basic Gerrit codereview functionality.
|
396
530
|
dry_run: if true, some Checks will be skipped.
|
531
|
+
parallel: if true, all tests reported via input_api.RunTests for all
|
532
|
+
PRESUBMIT files will be run in parallel.
|
397
533
|
"""
|
398
534
|
# Version number of the presubmit_support script.
|
399
535
|
self.version = [int(x) for x in __version__.split('.')]
|
400
536
|
self.change = change
|
401
537
|
self.is_committing = is_committing
|
402
|
-
self.rietveld = rietveld_obj
|
403
538
|
self.gerrit = gerrit_obj
|
404
539
|
self.dry_run = dry_run
|
405
|
-
|
406
|
-
self.
|
407
|
-
|
408
|
-
self.host_url = self.rietveld.url
|
540
|
+
|
541
|
+
self.parallel = parallel
|
542
|
+
self.thread_pool = thread_pool or ThreadPool()
|
409
543
|
|
410
544
|
# We expose various modules and functions as attributes of the input_api
|
411
545
|
# so that presubmit scripts don't have to import them.
|
@@ -432,8 +566,13 @@ class InputApi(object):
|
|
432
566
|
self.unittest = unittest
|
433
567
|
self.urllib2 = urllib2
|
434
568
|
|
435
|
-
|
436
|
-
|
569
|
+
self.is_windows = sys.platform == 'win32'
|
570
|
+
|
571
|
+
# Set python_executable to 'python'. This is interpreted in CallCommand to
|
572
|
+
# convert to vpython in order to allow scripts in other repos (e.g. src.git)
|
573
|
+
# to automatically pick up that repo's .vpython file, instead of inheriting
|
574
|
+
# the one in depot_tools.
|
575
|
+
self.python_executable = 'python'
|
437
576
|
self.environ = os.environ
|
438
577
|
|
439
578
|
# InputApi.platform is the platform you're currently running on.
|
@@ -441,12 +580,6 @@ class InputApi(object):
|
|
441
580
|
|
442
581
|
self.cpu_count = multiprocessing.cpu_count()
|
443
582
|
|
444
|
-
# this is done here because in RunTests, the current working directory has
|
445
|
-
# changed, which causes Pool() to explode fantastically when run on windows
|
446
|
-
# (because it tries to load the __main__ module, which imports lots of
|
447
|
-
# things relative to the current working directory).
|
448
|
-
self._run_tests_pool = multiprocessing.Pool(self.cpu_count)
|
449
|
-
|
450
583
|
# The local path of the currently-being-processed presubmit script.
|
451
584
|
self._current_presubmit_path = os.path.dirname(presubmit_path)
|
452
585
|
|
@@ -462,7 +595,6 @@ class InputApi(object):
|
|
462
595
|
fopen=file, os_path=self.os_path)
|
463
596
|
self.owners_finder = owners_finder.OwnersFinder
|
464
597
|
self.verbose = verbose
|
465
|
-
self.is_windows = sys.platform == 'win32'
|
466
598
|
self.Command = CommandData
|
467
599
|
|
468
600
|
# Replace <hash_map> and <hash_set> as headers that need to be included
|
@@ -508,7 +640,7 @@ class InputApi(object):
|
|
508
640
|
"""Returns absolute local paths of input_api.AffectedFiles()."""
|
509
641
|
return [af.AbsoluteLocalPath() for af in self.AffectedFiles()]
|
510
642
|
|
511
|
-
def AffectedTestableFiles(self, include_deletes=None):
|
643
|
+
def AffectedTestableFiles(self, include_deletes=None, **kwargs):
|
512
644
|
"""Same as input_api.change.AffectedTestableFiles() except only lists files
|
513
645
|
in the same directory as the current presubmit script, or subdirectories
|
514
646
|
thereof.
|
@@ -519,7 +651,7 @@ class InputApi(object):
|
|
519
651
|
category=DeprecationWarning,
|
520
652
|
stacklevel=2)
|
521
653
|
return filter(lambda x: x.IsTestableFile(),
|
522
|
-
self.AffectedFiles(include_deletes=False))
|
654
|
+
self.AffectedFiles(include_deletes=False, **kwargs))
|
523
655
|
|
524
656
|
def AffectedTextFiles(self, include_deletes=None):
|
525
657
|
"""An alias to AffectedTestableFiles for backwards compatibility."""
|
@@ -625,27 +757,24 @@ class InputApi(object):
|
|
625
757
|
return 'TBR' in self.change.tags or self.change.TBRsFromDescription()
|
626
758
|
|
627
759
|
def RunTests(self, tests_mix, parallel=True):
|
760
|
+
# RunTests doesn't actually run tests. It adds them to a ThreadPool that
|
761
|
+
# will run all tests once all PRESUBMIT files are processed.
|
628
762
|
tests = []
|
629
763
|
msgs = []
|
630
764
|
for t in tests_mix:
|
631
|
-
if isinstance(t, OutputApi.PresubmitResult):
|
765
|
+
if isinstance(t, OutputApi.PresubmitResult) and t:
|
632
766
|
msgs.append(t)
|
633
767
|
else:
|
634
768
|
assert issubclass(t.message, _PresubmitResult)
|
635
769
|
tests.append(t)
|
636
770
|
if self.verbose:
|
637
771
|
t.info = _PresubmitNotifyResult
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
msgs.extend(
|
643
|
-
return
|
644
|
-
|
645
|
-
def ShutdownPool(self):
|
646
|
-
self._run_tests_pool.close()
|
647
|
-
self._run_tests_pool.join()
|
648
|
-
self._run_tests_pool = None
|
772
|
+
if not t.kwargs.get('cwd'):
|
773
|
+
t.kwargs['cwd'] = self.PresubmitLocalPath()
|
774
|
+
self.thread_pool.AddTests(tests, parallel)
|
775
|
+
if not self.parallel:
|
776
|
+
msgs.extend(self.thread_pool.RunAsync())
|
777
|
+
return msgs
|
649
778
|
|
650
779
|
|
651
780
|
class _DiffCache(object):
|
@@ -982,7 +1111,7 @@ class Change(object):
|
|
982
1111
|
return affected
|
983
1112
|
return filter(lambda x: x.Action() != 'D', affected)
|
984
1113
|
|
985
|
-
def AffectedTestableFiles(self, include_deletes=None):
|
1114
|
+
def AffectedTestableFiles(self, include_deletes=None, **kwargs):
|
986
1115
|
"""Return a list of the existing text files in a change."""
|
987
1116
|
if include_deletes is not None:
|
988
1117
|
warn("AffectedTeestableFiles(include_deletes=%s)"
|
@@ -990,7 +1119,7 @@ class Change(object):
|
|
990
1119
|
category=DeprecationWarning,
|
991
1120
|
stacklevel=2)
|
992
1121
|
return filter(lambda x: x.IsTestableFile(),
|
993
|
-
self.AffectedFiles(include_deletes=False))
|
1122
|
+
self.AffectedFiles(include_deletes=False, **kwargs))
|
994
1123
|
|
995
1124
|
def AffectedTextFiles(self, include_deletes=None):
|
996
1125
|
"""An alias to AffectedTestableFiles for backwards compatibility."""
|
@@ -1262,23 +1391,25 @@ def DoPostUploadExecuter(change,
|
|
1262
1391
|
|
1263
1392
|
|
1264
1393
|
class PresubmitExecuter(object):
|
1265
|
-
def __init__(self, change, committing,
|
1266
|
-
gerrit_obj=None,
|
1394
|
+
def __init__(self, change, committing, verbose,
|
1395
|
+
gerrit_obj, dry_run=None, thread_pool=None, parallel=False):
|
1267
1396
|
"""
|
1268
1397
|
Args:
|
1269
1398
|
change: The Change object.
|
1270
1399
|
committing: True if 'git cl land' is running, False if 'git cl upload' is.
|
1271
|
-
rietveld_obj: rietveld.Rietveld client object.
|
1272
1400
|
gerrit_obj: provides basic Gerrit codereview functionality.
|
1273
1401
|
dry_run: if true, some Checks will be skipped.
|
1402
|
+
parallel: if true, all tests reported via input_api.RunTests for all
|
1403
|
+
PRESUBMIT files will be run in parallel.
|
1274
1404
|
"""
|
1275
1405
|
self.change = change
|
1276
1406
|
self.committing = committing
|
1277
|
-
self.rietveld = rietveld_obj
|
1278
1407
|
self.gerrit = gerrit_obj
|
1279
1408
|
self.verbose = verbose
|
1280
1409
|
self.dry_run = dry_run
|
1281
1410
|
self.more_cc = []
|
1411
|
+
self.thread_pool = thread_pool
|
1412
|
+
self.parallel = parallel
|
1282
1413
|
|
1283
1414
|
def ExecPresubmitScript(self, script_text, presubmit_path):
|
1284
1415
|
"""Executes a single presubmit script.
|
@@ -1298,8 +1429,9 @@ class PresubmitExecuter(object):
|
|
1298
1429
|
|
1299
1430
|
# Load the presubmit script into context.
|
1300
1431
|
input_api = InputApi(self.change, presubmit_path, self.committing,
|
1301
|
-
self.
|
1302
|
-
|
1432
|
+
self.verbose, gerrit_obj=self.gerrit,
|
1433
|
+
dry_run=self.dry_run, thread_pool=self.thread_pool,
|
1434
|
+
parallel=self.parallel)
|
1303
1435
|
output_api = OutputApi(self.committing)
|
1304
1436
|
context = {}
|
1305
1437
|
try:
|
@@ -1334,8 +1466,6 @@ class PresubmitExecuter(object):
|
|
1334
1466
|
else:
|
1335
1467
|
result = () # no error since the script doesn't care about current event.
|
1336
1468
|
|
1337
|
-
input_api.ShutdownPool()
|
1338
|
-
|
1339
1469
|
# Return the process to the original working directory.
|
1340
1470
|
os.chdir(main_path)
|
1341
1471
|
return result
|
@@ -1347,9 +1477,9 @@ def DoPresubmitChecks(change,
|
|
1347
1477
|
input_stream,
|
1348
1478
|
default_presubmit,
|
1349
1479
|
may_prompt,
|
1350
|
-
|
1351
|
-
|
1352
|
-
|
1480
|
+
gerrit_obj,
|
1481
|
+
dry_run=None,
|
1482
|
+
parallel=False):
|
1353
1483
|
"""Runs all presubmit checks that apply to the files in the change.
|
1354
1484
|
|
1355
1485
|
This finds all PRESUBMIT.py files in directories enclosing the files in the
|
@@ -1368,9 +1498,10 @@ def DoPresubmitChecks(change,
|
|
1368
1498
|
default_presubmit: A default presubmit script to execute in any case.
|
1369
1499
|
may_prompt: Enable (y/n) questions on warning or error. If False,
|
1370
1500
|
any questions are answered with yes by default.
|
1371
|
-
rietveld_obj: rietveld.Rietveld object.
|
1372
1501
|
gerrit_obj: provides basic Gerrit codereview functionality.
|
1373
1502
|
dry_run: if true, some Checks will be skipped.
|
1503
|
+
parallel: if true, all tests specified by input_api.RunTests in all
|
1504
|
+
PRESUBMIT files will be run in parallel.
|
1374
1505
|
|
1375
1506
|
Warning:
|
1376
1507
|
If may_prompt is true, output_stream SHOULD be sys.stdout and input_stream
|
@@ -1397,8 +1528,9 @@ def DoPresubmitChecks(change,
|
|
1397
1528
|
if not presubmit_files and verbose:
|
1398
1529
|
output.write("Warning, no PRESUBMIT.py found.\n")
|
1399
1530
|
results = []
|
1400
|
-
|
1401
|
-
|
1531
|
+
thread_pool = ThreadPool()
|
1532
|
+
executer = PresubmitExecuter(change, committing, verbose,
|
1533
|
+
gerrit_obj, dry_run, thread_pool)
|
1402
1534
|
if default_presubmit:
|
1403
1535
|
if verbose:
|
1404
1536
|
output.write("Running default presubmit script.\n")
|
@@ -1412,6 +1544,8 @@ def DoPresubmitChecks(change,
|
|
1412
1544
|
presubmit_script = gclient_utils.FileRead(filename, 'rU')
|
1413
1545
|
results += executer.ExecPresubmitScript(presubmit_script, filename)
|
1414
1546
|
|
1547
|
+
results += thread_pool.RunAsync()
|
1548
|
+
|
1415
1549
|
output.more_cc.extend(executer.more_cc)
|
1416
1550
|
errors = []
|
1417
1551
|
notifications = []
|
@@ -1503,17 +1637,14 @@ def load_files(options, args):
|
|
1503
1637
|
return change_class, files
|
1504
1638
|
|
1505
1639
|
|
1506
|
-
class NonexistantCannedCheckFilter(Exception):
|
1507
|
-
pass
|
1508
|
-
|
1509
|
-
|
1510
1640
|
@contextlib.contextmanager
|
1511
1641
|
def canned_check_filter(method_names):
|
1512
1642
|
filtered = {}
|
1513
1643
|
try:
|
1514
1644
|
for method_name in method_names:
|
1515
1645
|
if not hasattr(presubmit_canned_checks, method_name):
|
1516
|
-
|
1646
|
+
logging.warn('Skipping unknown "canned" check %s' % method_name)
|
1647
|
+
continue
|
1517
1648
|
filtered[method_name] = getattr(presubmit_canned_checks, method_name)
|
1518
1649
|
setattr(presubmit_canned_checks, method_name, lambda *_a, **_kw: [])
|
1519
1650
|
yield
|
@@ -1522,29 +1653,6 @@ def canned_check_filter(method_names):
|
|
1522
1653
|
setattr(presubmit_canned_checks, name, method)
|
1523
1654
|
|
1524
1655
|
|
1525
|
-
def CallCommand(cmd_data):
|
1526
|
-
"""Runs an external program, potentially from a child process created by the
|
1527
|
-
multiprocessing module.
|
1528
|
-
|
1529
|
-
multiprocessing needs a top level function with a single argument.
|
1530
|
-
"""
|
1531
|
-
cmd_data.kwargs['stdout'] = subprocess.PIPE
|
1532
|
-
cmd_data.kwargs['stderr'] = subprocess.STDOUT
|
1533
|
-
try:
|
1534
|
-
start = time.time()
|
1535
|
-
(out, _), code = subprocess.communicate(cmd_data.cmd, **cmd_data.kwargs)
|
1536
|
-
duration = time.time() - start
|
1537
|
-
except OSError as e:
|
1538
|
-
duration = time.time() - start
|
1539
|
-
return cmd_data.message(
|
1540
|
-
'%s exec failure (%4.2fs)\n %s' % (cmd_data.name, duration, e))
|
1541
|
-
if code != 0:
|
1542
|
-
return cmd_data.message(
|
1543
|
-
'%s (%4.2fs) failed\n%s' % (cmd_data.name, duration, out))
|
1544
|
-
if cmd_data.info:
|
1545
|
-
return cmd_data.info('%s (%4.2fs)' % (cmd_data.name, duration))
|
1546
|
-
|
1547
|
-
|
1548
1656
|
def main(argv=None):
|
1549
1657
|
parser = optparse.OptionParser(usage="%prog [options] <files...>",
|
1550
1658
|
version="%prog " + str(__version__))
|
@@ -1580,17 +1688,11 @@ def main(argv=None):
|
|
1580
1688
|
parser.add_option("--gerrit_url", help=optparse.SUPPRESS_HELP)
|
1581
1689
|
parser.add_option("--gerrit_fetch", action='store_true',
|
1582
1690
|
help=optparse.SUPPRESS_HELP)
|
1583
|
-
parser.add_option(
|
1584
|
-
|
1585
|
-
|
1586
|
-
help=optparse.SUPPRESS_HELP)
|
1587
|
-
# These are for OAuth2 authentication for bots. See also apply_issue.py
|
1588
|
-
parser.add_option("--rietveld_email_file", help=optparse.SUPPRESS_HELP)
|
1589
|
-
parser.add_option("--rietveld_private_key_file", help=optparse.SUPPRESS_HELP)
|
1691
|
+
parser.add_option('--parallel', action='store_true',
|
1692
|
+
help='Run all tests specified by input_api.RunTests in all '
|
1693
|
+
'PRESUBMIT files in parallel.')
|
1590
1694
|
|
1591
|
-
auth.add_auth_options(parser)
|
1592
1695
|
options, args = parser.parse_args(argv)
|
1593
|
-
auth_config = auth.extract_auth_config_from_options(options)
|
1594
1696
|
|
1595
1697
|
if options.verbose >= 2:
|
1596
1698
|
logging.basicConfig(level=logging.DEBUG)
|
@@ -1599,49 +1701,14 @@ def main(argv=None):
|
|
1599
1701
|
else:
|
1600
1702
|
logging.basicConfig(level=logging.ERROR)
|
1601
1703
|
|
1602
|
-
if (any((options.rietveld_url, options.rietveld_email_file,
|
1603
|
-
options.rietveld_fetch, options.rietveld_private_key_file))
|
1604
|
-
and any((options.gerrit_url, options.gerrit_fetch))):
|
1605
|
-
parser.error('Options for only codereview --rietveld_* or --gerrit_* '
|
1606
|
-
'allowed')
|
1607
|
-
|
1608
|
-
if options.rietveld_email and options.rietveld_email_file:
|
1609
|
-
parser.error("Only one of --rietveld_email or --rietveld_email_file "
|
1610
|
-
"can be passed to this program.")
|
1611
|
-
if options.rietveld_email_file:
|
1612
|
-
with open(options.rietveld_email_file, "rb") as f:
|
1613
|
-
options.rietveld_email = f.read().strip()
|
1614
|
-
|
1615
1704
|
change_class, files = load_files(options, args)
|
1616
1705
|
if not change_class:
|
1617
1706
|
parser.error('For unversioned directory, <files> is not optional.')
|
1618
1707
|
logging.info('Found %d file(s).', len(files))
|
1619
1708
|
|
1620
|
-
|
1621
|
-
|
1622
|
-
if options.rietveld_url:
|
1623
|
-
# The empty password is permitted: '' is not None.
|
1624
|
-
if options.rietveld_private_key_file:
|
1625
|
-
rietveld_obj = rietveld.JwtOAuth2Rietveld(
|
1626
|
-
options.rietveld_url,
|
1627
|
-
options.rietveld_email,
|
1628
|
-
options.rietveld_private_key_file)
|
1629
|
-
else:
|
1630
|
-
rietveld_obj = rietveld.CachingRietveld(
|
1631
|
-
options.rietveld_url,
|
1632
|
-
auth_config,
|
1633
|
-
options.rietveld_email)
|
1634
|
-
if options.rietveld_fetch:
|
1635
|
-
assert options.issue
|
1636
|
-
props = rietveld_obj.get_issue_properties(options.issue, False)
|
1637
|
-
options.author = props['owner_email']
|
1638
|
-
options.description = props['description']
|
1639
|
-
logging.info('Got author: "%s"', options.author)
|
1640
|
-
logging.info('Got description: """\n%s\n"""', options.description)
|
1641
|
-
|
1709
|
+
gerrit_obj = None
|
1642
1710
|
if options.gerrit_url and options.gerrit_fetch:
|
1643
1711
|
assert options.issue and options.patchset
|
1644
|
-
rietveld_obj = None
|
1645
1712
|
gerrit_obj = GerritAccessor(urlparse.urlparse(options.gerrit_url).netloc)
|
1646
1713
|
options.author = gerrit_obj.GetChangeOwner(options.issue)
|
1647
1714
|
options.description = gerrit_obj.GetChangeDescription(options.issue,
|
@@ -1666,18 +1733,13 @@ def main(argv=None):
|
|
1666
1733
|
sys.stdin,
|
1667
1734
|
options.default_presubmit,
|
1668
1735
|
options.may_prompt,
|
1669
|
-
rietveld_obj,
|
1670
1736
|
gerrit_obj,
|
1671
|
-
options.dry_run
|
1737
|
+
options.dry_run,
|
1738
|
+
options.parallel)
|
1672
1739
|
return not results.should_continue()
|
1673
|
-
except NonexistantCannedCheckFilter, e:
|
1674
|
-
print >> sys.stderr, (
|
1675
|
-
'Attempted to skip nonexistent canned presubmit check: %s' % e.message)
|
1676
|
-
return 2
|
1677
1740
|
except PresubmitFailure, e:
|
1678
1741
|
print >> sys.stderr, e
|
1679
1742
|
print >> sys.stderr, 'Maybe your depot_tools is out of date?'
|
1680
|
-
print >> sys.stderr, 'If all fails, contact maruel@'
|
1681
1743
|
return 2
|
1682
1744
|
|
1683
1745
|
|