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.
Files changed (195) hide show
  1. checksums.yaml +5 -5
  2. data/.travis.yml +10 -34
  3. data/CHANGELOG.md +16 -0
  4. data/README.md +9 -63
  5. data/Rakefile +2 -2
  6. data/ext/libv8/builder.rb +22 -87
  7. data/ext/libv8/extconf.rb +1 -1
  8. data/ext/libv8/paths.rb +5 -18
  9. data/lib/libv8/version.rb +1 -1
  10. data/spec/location_spec.rb +1 -2
  11. data/spec/spec_helper.rb +0 -1
  12. data/vendor/depot_tools/.gitattributes +1 -2
  13. data/vendor/depot_tools/OWNERS +0 -1
  14. data/vendor/depot_tools/PRESUBMIT.py +11 -6
  15. data/vendor/depot_tools/README.md +0 -1
  16. data/vendor/depot_tools/WATCHLISTS +0 -6
  17. data/vendor/depot_tools/auth.py +129 -87
  18. data/vendor/depot_tools/autoninja +11 -1
  19. data/vendor/depot_tools/autoninja.bat +7 -1
  20. data/vendor/depot_tools/autoninja.py +14 -6
  21. data/vendor/depot_tools/bootstrap/win/manifest.txt +1 -1
  22. data/vendor/depot_tools/bootstrap/win/manifest_bleeding_edge.txt +1 -1
  23. data/vendor/depot_tools/cipd +23 -2
  24. data/vendor/depot_tools/cipd.bat +2 -2
  25. data/vendor/depot_tools/cipd_client_version +1 -1
  26. data/vendor/depot_tools/cipd_manifest.txt +17 -7
  27. data/vendor/depot_tools/cit.py +7 -6
  28. data/vendor/depot_tools/cpplint.py +195 -35
  29. data/vendor/depot_tools/detect_host_arch.py +51 -0
  30. data/vendor/depot_tools/download_from_google_storage.py +85 -26
  31. data/vendor/depot_tools/fetch.py +11 -6
  32. data/vendor/depot_tools/fetch_configs/chromium.py +0 -1
  33. data/vendor/depot_tools/fetch_configs/goma_client.py +41 -0
  34. data/vendor/depot_tools/fetch_configs/infra.py +0 -1
  35. data/vendor/depot_tools/fetch_configs/infra_internal.py +0 -1
  36. data/vendor/depot_tools/gclient-new-workdir.py +4 -0
  37. data/vendor/depot_tools/gclient.py +732 -476
  38. data/vendor/depot_tools/gclient_eval.py +569 -58
  39. data/vendor/depot_tools/gclient_scm.py +258 -46
  40. data/vendor/depot_tools/gclient_utils.py +17 -1
  41. data/vendor/depot_tools/gerrit_util.py +46 -13
  42. data/vendor/depot_tools/git_cache.py +0 -2
  43. data/vendor/depot_tools/git_cl.py +176 -335
  44. data/vendor/depot_tools/git_common.py +19 -16
  45. data/vendor/depot_tools/git_footers.py +19 -5
  46. data/vendor/depot_tools/git_hyper_blame.py +9 -3
  47. data/vendor/depot_tools/git_new_branch.py +15 -3
  48. data/vendor/depot_tools/git_upstream_diff.py +7 -2
  49. data/vendor/depot_tools/gsutil.py +1 -1
  50. data/vendor/depot_tools/infra/config/cq.cfg +1 -2
  51. data/vendor/depot_tools/infra/config/recipes.cfg +1 -1
  52. data/vendor/depot_tools/luci-auth +13 -0
  53. data/vendor/depot_tools/luci-auth.bat +8 -0
  54. data/vendor/depot_tools/man/html/depot_tools.html +0 -8
  55. data/vendor/depot_tools/man/html/git-upstream-diff.html +20 -3
  56. data/vendor/depot_tools/man/man1/git-upstream-diff.1 +27 -6
  57. data/vendor/depot_tools/man/man7/depot_tools.7 +0 -5
  58. data/vendor/depot_tools/man/man7/depot_tools_tutorial.7 +2 -2
  59. data/vendor/depot_tools/man/src/git-upstream-diff.txt +21 -3
  60. data/vendor/depot_tools/man/src/make_docs.sh +6 -0
  61. data/vendor/depot_tools/my_activity.py +283 -93
  62. data/vendor/depot_tools/owners.py +9 -4
  63. data/vendor/depot_tools/owners_finder.py +7 -3
  64. data/vendor/depot_tools/post_build_ninja_summary.py +322 -0
  65. data/vendor/depot_tools/presubmit_canned_checks.py +91 -106
  66. data/vendor/depot_tools/presubmit_support.py +219 -157
  67. data/vendor/depot_tools/prpc +13 -0
  68. data/vendor/depot_tools/prpc.bat +8 -0
  69. data/vendor/depot_tools/recipes/OWNERS +3 -1
  70. data/vendor/depot_tools/recipes/README.recipes.md +70 -111
  71. data/vendor/depot_tools/recipes/recipe_modules/bot_update/__init__.py +12 -5
  72. data/vendor/depot_tools/recipes/recipe_modules/bot_update/api.py +36 -68
  73. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/deprecated_got_revision_mapping.json +0 -8
  74. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/{trychange_oauth2_json.json → no_apply_patch_on_gclient.json} +64 -10
  75. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/{no_shallow.json → shallow.json} +1 -1
  76. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob.json +0 -8
  77. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_empty_revision.json +0 -8
  78. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_fail.json +0 -6
  79. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_fail_patch.json +0 -7
  80. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_fail_patch_download.json +0 -6
  81. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_gerrit_angle_deprecated.json +44 -0
  82. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/{trychange_oauth2_buildbot.json → tryjob_gerrit_branch_heads.json} +51 -5
  83. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_v8.json +0 -8
  84. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_v8_head_by_default.json +48 -8
  85. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.py +19 -26
  86. data/vendor/depot_tools/recipes/recipe_modules/bot_update/resources/bot_update.py +193 -155
  87. data/vendor/depot_tools/recipes/recipe_modules/bot_update/test_api.py +9 -0
  88. data/vendor/depot_tools/recipes/recipe_modules/gclient/api.py +2 -7
  89. data/vendor/depot_tools/recipes/recipe_modules/gclient/config.py +31 -5
  90. data/vendor/depot_tools/recipes/recipe_modules/gclient/examples/full.expected/basic.json +37 -19
  91. data/vendor/depot_tools/recipes/recipe_modules/gclient/examples/full.expected/buildbot.json +37 -19
  92. data/vendor/depot_tools/recipes/recipe_modules/gclient/examples/full.expected/revision.json +37 -19
  93. data/vendor/depot_tools/recipes/recipe_modules/gclient/examples/full.expected/tryserver.json +37 -23
  94. data/vendor/depot_tools/recipes/recipe_modules/gclient/examples/full.py +4 -0
  95. data/vendor/depot_tools/recipes/recipe_modules/gerrit/api.py +40 -8
  96. data/vendor/depot_tools/recipes/recipe_modules/gerrit/examples/full.expected/basic.json +3 -3
  97. data/vendor/depot_tools/recipes/recipe_modules/gerrit/examples/full.py +6 -3
  98. data/vendor/depot_tools/recipes/recipe_modules/gitiles/OWNERS +0 -1
  99. data/vendor/depot_tools/recipes/recipe_modules/tryserver/__init__.py +0 -1
  100. data/vendor/depot_tools/recipes/recipe_modules/tryserver/api.py +7 -56
  101. data/vendor/depot_tools/recipes/recipe_modules/tryserver/examples/full.expected/with_wrong_patch.json +0 -1
  102. data/vendor/depot_tools/recipes/recipe_modules/tryserver/examples/full.py +15 -16
  103. data/vendor/depot_tools/recipes/recipes.py +4 -2
  104. data/vendor/depot_tools/recipes/trigger_recipe_roller.txt +12 -0
  105. data/vendor/depot_tools/roll_dep.py +35 -37
  106. data/vendor/depot_tools/support/chromite_wrapper +1 -1
  107. data/vendor/depot_tools/third_party/logilab/astroid/README.chromium +3 -3
  108. data/vendor/depot_tools/third_party/logilab/astroid/__pkginfo__.py +2 -2
  109. data/vendor/depot_tools/third_party/logilab/astroid/astpeephole.py +86 -0
  110. data/vendor/depot_tools/third_party/logilab/astroid/bases.py +53 -66
  111. data/vendor/depot_tools/third_party/logilab/astroid/brain/py2pytest.py +31 -31
  112. data/vendor/depot_tools/third_party/logilab/astroid/brain/pynose.py +39 -16
  113. data/vendor/depot_tools/third_party/logilab/astroid/brain/pysix_moves.py +225 -189
  114. data/vendor/depot_tools/third_party/logilab/astroid/inference.py +45 -41
  115. data/vendor/depot_tools/third_party/logilab/astroid/manager.py +1 -0
  116. data/vendor/depot_tools/third_party/logilab/astroid/modutils.py +2 -2
  117. data/vendor/depot_tools/third_party/logilab/astroid/node_classes.py +3 -2
  118. data/vendor/depot_tools/third_party/logilab/astroid/nodes.py +1 -0
  119. data/vendor/depot_tools/third_party/logilab/astroid/protocols.py +57 -3
  120. data/vendor/depot_tools/third_party/logilab/astroid/raw_building.py +1 -1
  121. data/vendor/depot_tools/third_party/logilab/astroid/rebuilder.py +21 -1
  122. data/vendor/depot_tools/third_party/logilab/astroid/scoped_nodes.py +58 -33
  123. data/vendor/depot_tools/third_party/pylint/README.chromium +2 -2
  124. data/vendor/depot_tools/third_party/pylint/__pkginfo__.py +3 -3
  125. data/vendor/depot_tools/third_party/pylint/checkers/base.py +6 -18
  126. data/vendor/depot_tools/third_party/pylint/checkers/classes.py +64 -63
  127. data/vendor/depot_tools/third_party/pylint/checkers/design_analysis.py +25 -57
  128. data/vendor/depot_tools/third_party/pylint/checkers/format.py +14 -10
  129. data/vendor/depot_tools/third_party/pylint/checkers/python3.py +142 -37
  130. data/vendor/depot_tools/third_party/pylint/checkers/spelling.py +10 -1
  131. data/vendor/depot_tools/third_party/pylint/checkers/stdlib.py +50 -7
  132. data/vendor/depot_tools/third_party/pylint/checkers/strings.py +1 -1
  133. data/vendor/depot_tools/third_party/pylint/epylint.py +2 -1
  134. data/vendor/depot_tools/third_party/pylint/gui.py +1 -1
  135. data/vendor/depot_tools/third_party/pylint/lint.py +88 -23
  136. data/vendor/depot_tools/third_party/pylint/reporters/html.py +37 -5
  137. data/vendor/depot_tools/third_party/pylint/testutils.py +1 -1
  138. data/vendor/depot_tools/third_party/pylint/utils.py +5 -0
  139. data/vendor/depot_tools/vpython +31 -1
  140. data/vendor/depot_tools/win_toolchain/get_toolchain_if_necessary.py +35 -2
  141. data/vendor/depot_tools/win_toolchain/package_from_installed.py +0 -15
  142. data/vendor/depot_tools/yapf +17 -0
  143. data/vendor/depot_tools/{apply_issue.bat → yapf.bat} +2 -2
  144. metadata +16 -58
  145. data/ext/libv8/compiler.rb +0 -39
  146. data/ext/libv8/compiler/apple_llvm.rb +0 -22
  147. data/ext/libv8/compiler/clang.rb +0 -22
  148. data/ext/libv8/compiler/gcc.rb +0 -22
  149. data/ext/libv8/compiler/generic_compiler.rb +0 -66
  150. data/ext/libv8/make.rb +0 -13
  151. data/ext/libv8/patcher.rb +0 -21
  152. data/patches/0001-Build-a-standalone-static-library.patch +0 -26
  153. data/patches/0002-Don-t-compile-unnecessary-stuff.patch +0 -85
  154. data/patches/0003-Use-the-fPIC-flag-for-the-static-library.patch +0 -25
  155. data/patches/0004-Do-not-embed-debug-symbols-in-macOS-libraries.patch +0 -25
  156. data/patches/0005-Remove-TryInstallOptimizedCode.patch +0 -321
  157. data/patches/mingw-generate-makefiles.sh +0 -97
  158. data/spec/compiler/apple_llvm_spec.rb +0 -37
  159. data/spec/compiler/clang_spec.rb +0 -37
  160. data/spec/compiler/gcc_spec.rb +0 -37
  161. data/spec/compiler/generic_compiler_spec.rb +0 -50
  162. data/spec/compiler_spec.rb +0 -45
  163. data/spec/support/compiler_helpers.rb +0 -47
  164. data/vendor/depot_tools/apply_issue +0 -8
  165. data/vendor/depot_tools/apply_issue.py +0 -315
  166. data/vendor/depot_tools/man/html/git-cherry-pick-upload.html +0 -815
  167. data/vendor/depot_tools/man/man1/git-cherry-pick-upload.1 +0 -80
  168. data/vendor/depot_tools/man/src/_git-cherry-pick-upload_desc.helper.txt +0 -1
  169. data/vendor/depot_tools/man/src/git-cherry-pick-upload.demo.1.sh +0 -17
  170. data/vendor/depot_tools/man/src/git-cherry-pick-upload.txt +0 -35
  171. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/trychange_oauth2.json +0 -8
  172. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/trychange_oauth2_json_win.json +0 -196
  173. data/vendor/depot_tools/recipes/recipe_modules/rietveld/__init__.py +0 -6
  174. data/vendor/depot_tools/recipes/recipe_modules/rietveld/api.py +0 -97
  175. data/vendor/depot_tools/recipes/recipe_modules/rietveld/examples/full.expected/basic.json +0 -8
  176. data/vendor/depot_tools/recipes/recipe_modules/rietveld/examples/full.expected/buildbot.json +0 -30
  177. data/vendor/depot_tools/recipes/recipe_modules/rietveld/examples/full.expected/no_auth.json +0 -27
  178. data/vendor/depot_tools/recipes/recipe_modules/rietveld/examples/full.py +0 -38
  179. data/vendor/depot_tools/recipes/recipe_modules/tryserver/examples/full.expected/with_rietveld_patch.json +0 -69
  180. data/vendor/depot_tools/recipes/recipe_modules/tryserver/examples/full.expected/with_rietveld_patch_new.json +0 -69
  181. data/vendor/depot_tools/third_party/cq_client/OWNERS +0 -2
  182. data/vendor/depot_tools/third_party/cq_client/README.depot_tools.md +0 -2
  183. data/vendor/depot_tools/third_party/cq_client/README.md +0 -59
  184. data/vendor/depot_tools/third_party/cq_client/__init__.py +0 -3
  185. data/vendor/depot_tools/third_party/cq_client/v1/__init__.py +0 -3
  186. data/vendor/depot_tools/third_party/cq_client/v1/cq.pb.go +0 -810
  187. data/vendor/depot_tools/third_party/cq_client/v1/cq.proto +0 -281
  188. data/vendor/depot_tools/third_party/cq_client/v1/cq_pb2.py +0 -794
  189. data/vendor/depot_tools/third_party/cq_client/v1/testdata/cq_both.cfg +0 -71
  190. data/vendor/depot_tools/third_party/cq_client/v1/testdata/cq_gerrit.cfg +0 -58
  191. data/vendor/depot_tools/third_party/cq_client/v1/testdata/cq_rietveld.cfg +0 -60
  192. data/vendor/depot_tools/third_party/cq_client/v2/__init__.py +0 -3
  193. data/vendor/depot_tools/third_party/cq_client/v2/cq.pb.go +0 -792
  194. data/vendor/depot_tools/third_party/cq_client/v2/cq.proto +0 -270
  195. 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
- include_re = re.compile(r'^CQ_INCLUDE_TRYBOTS=(.*)$', re.M | re.I)
307
-
455
+ trybot_footers = git_footers.parse_footers(description).get(
456
+ git_footers.normalize_name('Cq-Include-Trybots'), [])
308
457
  prior_bots = []
309
- if cl.IsGerrit():
310
- trybot_footers = git_footers.parse_footers(description).get(
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
- if cl.IsGerrit():
324
- description = git_footers.remove_footer(
325
- description, 'Cq-Include-Trybots')
326
- description = git_footers.add_footer(
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 (crbug.com/539768).
370
- r".*\bthird_party[\\\/](?!WebKit[\\\/]).*",
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
- rietveld_obj, verbose, gerrit_obj=None, dry_run=None):
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
- # TBD
406
- self.host_url = 'http://codereview.chromium.org'
407
- if self.rietveld:
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
- # To easily fork python.
436
- self.python_executable = sys.executable
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
- if len(tests) > 1 and parallel:
639
- # async recipe works around multiprocessing bug handling Ctrl-C
640
- msgs.extend(self._run_tests_pool.map_async(CallCommand, tests).get(99999))
641
- else:
642
- msgs.extend(map(CallCommand, tests))
643
- return [m for m in msgs if m]
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, rietveld_obj, verbose,
1266
- gerrit_obj=None, dry_run=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.rietveld, self.verbose,
1302
- gerrit_obj=self.gerrit, dry_run=self.dry_run)
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
- rietveld_obj,
1351
- gerrit_obj=None,
1352
- dry_run=None):
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
- executer = PresubmitExecuter(change, committing, rietveld_obj, verbose,
1401
- gerrit_obj, dry_run)
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
- raise NonexistantCannedCheckFilter(method_name)
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("--rietveld_url", help=optparse.SUPPRESS_HELP)
1584
- parser.add_option("--rietveld_email", help=optparse.SUPPRESS_HELP)
1585
- parser.add_option("--rietveld_fetch", action='store_true', default=False,
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
- rietveld_obj, gerrit_obj = None, None
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