Chromium Code Reviews| 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 import collections | 5 import collections |
| 6 import urlparse | |
| 7 | |
| 8 from dashboard.services import gerrit_service | |
| 6 | 9 |
| 7 | 10 |
| 8 class Patch(collections.namedtuple('Patch', ('server', 'issue', 'patchset'))): | 11 def FromDict(data): |
| 9 """A patch in Rietveld.""" | 12 # If we have more Patch types in the future, we can loop |
| 10 # TODO: Support Gerrit. | 13 # through them all and try each one's FromDict() in turn. |
| 11 # https://github.com/catapult-project/catapult/issues/3599 | 14 return GerritPatch.FromDict(data) |
| 15 | |
| 16 | |
| 17 class GerritPatch(collections.namedtuple( | |
| 18 'GerritPatch', ('server', 'change', 'revision'))): | |
| 19 """A patch in Gerrit. | |
| 20 | |
| 21 change is a change ID of the format '<project>~<branch>~<Change-Id>' and | |
| 22 revision is a commit ID. Both are described in the Gerrit API documentation. | |
| 23 https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#ids | |
| 24 | |
| 25 They must be in a canonical format so we can look up builds precisely. | |
| 26 """ | |
| 12 | 27 |
| 13 def __str__(self): | 28 def __str__(self): |
| 14 return self.id_string | 29 return self.id_string |
| 15 | 30 |
| 16 @property | 31 @property |
| 17 def id_string(self): | 32 def id_string(self): |
| 18 return '%s/%d/%d' % (self.server, self.issue, self.patchset) | 33 return '%s/%s/%s' % (self.server, self.change, self.revision) |
| 34 | |
| 35 def BuildParameters(self): | |
| 36 patch_info = gerrit_service.GetChange( | |
| 37 self.server, self.change, fields=('ALL_REVISIONS',)) | |
| 38 revision_info = patch_info['revisions'][self.revision] | |
| 39 return { | |
| 40 'patch_gerrit_url': self.server, | |
| 41 'patch_issue': patch_info['_number'], | |
| 42 'patch_project': patch_info['project'], | |
| 43 'patch_ref': revision_info['fetch']['http']['ref'], | |
| 44 'patch_repository_url': revision_info['fetch']['http']['url'], | |
| 45 'patch_set': revision_info['_number'], | |
| 46 'patch_storage': 'gerrit', | |
| 47 } | |
| 19 | 48 |
| 20 def AsDict(self): | 49 def AsDict(self): |
| 21 return self._asdict() | 50 return self._asdict() |
| 22 | 51 |
| 23 @classmethod | 52 @classmethod |
| 24 def FromDict(cls, data): | 53 def FromDict(cls, data): |
| 25 # TODO: Validate to ensure the patch exists on the server. | 54 """Creates a new GerritPatch from the given data. |
| 26 return cls(data['server'], data['issue'], data['patchset']) | 55 |
| 56 Args: | |
| 57 data: A patch URL string, or | |
| 58 A dict containing {server, change, revision [optional]}. | |
| 59 change is a {change-id} as described in the Gerrit API documentation. | |
| 60 revision is a commit ID hash or numeric patch number. | |
| 61 If revision is omitted, it is the change's current revision. | |
| 62 | |
| 63 Returns: | |
| 64 A GerritPatch. | |
| 65 | |
| 66 Raises: | |
| 67 KeyError: The patch doesn't have the given revision. | |
| 68 """ | |
| 69 if isinstance(data, basestring): | |
| 70 url_parts = urlparse.urlparse(data) | |
|
perezju
2017/09/25 09:22:21
nit: Add a small comment with an example of how su
dtu
2017/09/25 20:29:55
Done.
| |
| 71 server = urlparse.urlunsplit( | |
| 72 (url_parts.scheme, url_parts.netloc, '', '', '')) | |
| 73 change = url_parts.path.rsplit('/', 1)[-1] | |
| 74 revision = None | |
| 75 else: | |
| 76 server = data['server'] | |
| 77 change = data['change'] | |
| 78 revision = data.get('revision') | |
| 79 | |
| 80 # Look up the patch and convert everything to a canonical format. | |
| 81 patch_info = gerrit_service.GetChange( | |
| 82 server, change, fields=('ALL_REVISIONS',)) | |
| 83 change = patch_info['id'] | |
| 84 | |
| 85 # Revision can be a revision ID or numeric patch number. | |
| 86 if not revision: | |
| 87 revision = patch_info['current_revision'] | |
| 88 for revision_id, revision_info in patch_info['revisions'].iteritems(): | |
| 89 if revision == revision_id or revision == revision_info['_number']: | |
| 90 revision = revision_id | |
| 91 break | |
| 92 else: | |
| 93 raise KeyError('Patch revision not found: %s/%s revision %s' % | |
| 94 (server, change, revision)) | |
| 95 | |
| 96 return cls(server, change, revision) | |
| OLD | NEW |