OLD | NEW |
1 # Copyright 2016 The Chromium Authors. All rights reserved. | 1 # Copyright 2016 The Chromium Authors. All rights reserved. |
2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 | 4 |
5 """An interface to git-cl. | 5 """An interface to git-cl. |
6 | 6 |
7 The git-cl tool is responsible for communicating with Rietveld, Gerrit, | 7 The git-cl tool is responsible for communicating with Rietveld, Gerrit, |
8 and Buildbucket to manage changelists and try jobs associated with them. | 8 and Buildbucket to manage changelists and try jobs associated with them. |
9 """ | 9 """ |
10 | 10 |
11 import json | 11 import json |
12 import logging | 12 import logging |
| 13 import re |
| 14 |
| 15 from webkitpy.common.net.buildbot import Build, filter_latest_builds |
13 | 16 |
14 _log = logging.getLogger(__name__) | 17 _log = logging.getLogger(__name__) |
15 | 18 |
16 _COMMANDS_THAT_REQUIRE_AUTH = ( | 19 _COMMANDS_THAT_REQUIRE_AUTH = ( |
17 'archive', 'comments', 'commit', 'description', 'diff', 'land', 'lint', 'own
ers', 'patch', | 20 'archive', 'comments', 'commit', 'description', 'diff', 'land', 'lint', 'own
ers', 'patch', |
18 'presubmit', 'set-close', 'set-commit', 'status', 'try-results', 'try', 'upl
oad', | 21 'presubmit', 'set-close', 'set-commit', 'status', 'try-results', 'try', 'upl
oad', |
19 ) | 22 ) |
20 | 23 |
| 24 |
21 class GitCL(object): | 25 class GitCL(object): |
22 | 26 |
23 def __init__(self, host, auth_refresh_token_json=None, cwd=None): | 27 def __init__(self, host, auth_refresh_token_json=None, cwd=None): |
24 self._host = host | 28 self._host = host |
25 self._auth_refresh_token_json = auth_refresh_token_json | 29 self._auth_refresh_token_json = auth_refresh_token_json |
26 self._cwd = cwd | 30 self._cwd = cwd |
27 | 31 |
28 def run(self, args): | 32 def run(self, args): |
29 """Runs git-cl with the given arguments and returns the output.""" | 33 """Runs git-cl with the given arguments and returns the output.""" |
30 command = ['git', 'cl'] + args | 34 command = ['git', 'cl'] + args |
(...skipping 21 matching lines...) Expand all Loading... |
52 try_results = self.fetch_try_results() | 56 try_results = self.fetch_try_results() |
53 _log.debug('Fetched try results: %s', try_results) | 57 _log.debug('Fetched try results: %s', try_results) |
54 if self.all_jobs_finished(try_results): | 58 if self.all_jobs_finished(try_results): |
55 self._host.print_('All jobs finished.') | 59 self._host.print_('All jobs finished.') |
56 return try_results | 60 return try_results |
57 self._host.print_('Waiting. %d seconds passed.' % (self._host.time()
- start)) | 61 self._host.print_('Waiting. %d seconds passed.' % (self._host.time()
- start)) |
58 self._host.sleep(poll_delay_seconds) | 62 self._host.sleep(poll_delay_seconds) |
59 self._host.print_('Timed out waiting for try results.') | 63 self._host.print_('Timed out waiting for try results.') |
60 return None | 64 return None |
61 | 65 |
| 66 def latest_try_jobs(self, builder_names=None): |
| 67 """Returns a list of Builds for the latest jobs for the given builders."
"" |
| 68 try_results = self.fetch_try_results() |
| 69 if builder_names: |
| 70 try_results = [r for r in try_results if r['builder_name'] in builde
r_names] |
| 71 return filter_latest_builds(self._try_result_to_build(r) for r in try_re
sults) |
| 72 |
62 def fetch_try_results(self): | 73 def fetch_try_results(self): |
63 """Requests results of try jobs for the current CL.""" | 74 """Requests results f try jobs for the current CL.""" |
64 with self._host.filesystem.mkdtemp() as temp_directory: | 75 with self._host.filesystem.mkdtemp() as temp_directory: |
65 results_path = self._host.filesystem.join(temp_directory, 'try-resul
ts.json') | 76 results_path = self._host.filesystem.join(temp_directory, 'try-resul
ts.json') |
66 self.run(['try-results', '--json', results_path]) | 77 self.run(['try-results', '--json', results_path]) |
67 contents = self._host.filesystem.read_text_file(results_path) | 78 contents = self._host.filesystem.read_text_file(results_path) |
68 _log.debug('Fetched try results to file "%s".', results_path) | 79 _log.debug('Fetched try results to file "%s".', results_path) |
69 self._host.filesystem.remove(results_path) | 80 self._host.filesystem.remove(results_path) |
70 return json.loads(contents) | 81 return json.loads(contents) |
71 | 82 |
72 @staticmethod | 83 @staticmethod |
| 84 def _try_result_to_build(try_result): |
| 85 """Converts a parsed try result dict to a Build object.""" |
| 86 builder_name = try_result['builder_name'] |
| 87 url = try_result['url'] |
| 88 if url is None: |
| 89 return Build(builder_name, None) |
| 90 match = re.match(r'.*/builds/(\d+)?$', url) |
| 91 build_number = match.group(1) |
| 92 assert build_number and build_number.isdigit() |
| 93 return Build(builder_name, int(build_number)) |
| 94 |
| 95 @staticmethod |
73 def all_jobs_finished(try_results): | 96 def all_jobs_finished(try_results): |
74 return all(r.get('status') == 'COMPLETED' for r in try_results) | 97 return all(r.get('status') == 'COMPLETED' for r in try_results) |
75 | 98 |
76 @staticmethod | 99 @staticmethod |
77 def has_failing_try_results(try_results): | 100 def has_failing_try_results(try_results): |
78 return any(r.get('result') == 'FAILURE' for r in try_results) | 101 return any(r.get('result') == 'FAILURE' for r in try_results) |
OLD | NEW |