Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 # Copyright 2014 The Chromium Authors. All rights reserved. | 1 # Copyright 2014 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 # TODO(http://crbug.com/661822): convert this into a namedtuple. | 5 from collections import namedtuple |
| 6 class FileChangeInfo(object): | 6 |
| 7 from lib.gitiles.diff import ChangeType | |
| 8 | |
| 9 # TODO(wrengr): it'd be better to have a class hierarchy here, so we can | |
| 10 # avoid playing around with None, and so the change_type can be stored | |
| 11 # once (in the class itself; rather than once per instance). | |
| 12 # TODO(http://crbug/644476): better name for this class; i.e., without | |
| 13 # the extraneous \"Info\" at the very least. | |
| 14 # TODO(http://crbug.com/659346): coverage tests for the smart constructors. | |
| 15 class FileChangeInfo(namedtuple('FileChangeInfo', | |
| 16 ['change_type', 'old_path', 'new_path'])): | |
| 7 """Represents a file change (add/delete/modify/rename/copy/etc).""" | 17 """Represents a file change (add/delete/modify/rename/copy/etc).""" |
| 8 def __init__(self, change_type, old_path, new_path): | 18 __slots__ = () |
| 9 self.change_type = change_type | 19 |
| 10 self.old_path = old_path | 20 @classmethod |
| 11 self.new_path = new_path | 21 def Modify(cls, path): # pragma: no cover |
| 22 return cls(ChangeType.MODIFY, path, path) | |
| 23 | |
| 24 @classmethod | |
| 25 def Add(cls, path): # pragma: no cover | |
| 26 # Stay the same as gitile. | |
| 27 return cls(ChangeType.ADD, None, path) | |
| 28 | |
| 29 @classmethod | |
| 30 def Delete(cls, path): # pragma: no cover | |
| 31 return cls(ChangeType.DELETE, path, None) | |
| 32 | |
| 33 @classmethod | |
| 34 def Rename(cls, old_path, new_path): # pragma: no cover | |
| 35 return cls(ChangeType.RENAME, old_path, new_path) | |
| 36 | |
| 37 @classmethod | |
| 38 def Copy(cls, old_path, new_path): # pragma: no cover | |
| 39 return cls(ChangeType.COPY, old_path, new_path) | |
| 40 | |
| 41 @classmethod | |
| 42 def FromDict(cls, info): | |
| 43 return cls(info['change_type'].lower(), info['old_path'], info['new_path']) | |
| 12 | 44 |
| 13 def ToDict(self): | 45 def ToDict(self): |
| 14 return { | 46 return { |
|
stgao
2016/11/22 21:22:59
IIRC, namedtuple has an equivalent func of this, b
wrengr
2016/11/22 21:32:39
There's the ``_asdict`` method, which returns an `
stgao
2016/11/22 21:50:39
Good point. Sgtm!
| |
| 15 'change_type': self.change_type, | 47 'change_type': self.change_type, |
| 16 'old_path': self.old_path, | 48 'old_path': self.old_path, |
| 17 'new_path': self.new_path | 49 'new_path': self.new_path |
| 18 } | 50 } |
| 19 | 51 |
| 20 @staticmethod | |
| 21 def FromDict(info): | |
| 22 return FileChangeInfo( | |
| 23 info['change_type'], info['old_path'], info['new_path']) | |
| 24 | 52 |
| 53 class ChangeLog(namedtuple('ChangeLog', | |
| 54 ['author_name', 'author_email', 'author_time', 'committer_name', | |
| 55 'committer_email', 'committer_time', 'revision', 'commit_position', | |
| 56 'message', 'touched_files', 'commit_url', 'code_review_url', | |
| 57 'reverted_revision'])): | |
| 58 """Represents the change log of a revision.""" | |
| 59 __slots__ = () | |
| 25 | 60 |
| 26 # TODO(http://crbug.com/661822): convert this into a namedtuple. | 61 def __new__(cls, author_name, author_email, author_time, committer_name, |
| 27 class ChangeLog(object): | 62 committer_email, committer_time, revision, commit_position, |
| 28 """Represents the change log of a revision.""" | 63 message, touched_files, commit_url, code_review_url=None, |
| 29 | 64 reverted_revision=None): |
| 30 def __init__(self, author_name, author_email, author_time, committer_name, | 65 return super(cls, ChangeLog).__new__(cls, |
| 31 committer_email, committer_time, revision, commit_position, | 66 author_name, author_email, author_time, committer_name, |
| 32 message, touched_files, commit_url, code_review_url=None, | 67 committer_email, committer_time, revision, commit_position, |
| 33 reverted_revision=None): | 68 message, touched_files, commit_url, code_review_url, |
| 34 self.author_name = author_name | 69 reverted_revision) |
| 35 self.author_email = author_email | |
| 36 self.author_time = author_time | |
| 37 self.committer_name = committer_name | |
| 38 self.committer_email = committer_email | |
| 39 self.committer_time = committer_time | |
| 40 self.revision = revision | |
| 41 self.commit_position = commit_position | |
| 42 self.touched_files = touched_files | |
| 43 self.message = message | |
| 44 self.commit_url = commit_url | |
| 45 self.code_review_url = code_review_url | |
| 46 self.reverted_revision = reverted_revision | |
| 47 | 70 |
| 48 def ToDict(self): | 71 def ToDict(self): |
| 49 """Returns the change log as a JSON object.""" | 72 """Returns the change log as a JSON object.""" |
| 50 json_data = { | 73 json_data = { |
| 51 'author_name': self.author_name, | 74 'author_name': self.author_name, |
| 52 'author_email': self.author_email, | 75 'author_email': self.author_email, |
| 53 'author_time': self.author_time, | 76 'author_time': self.author_time, |
| 54 'committer_name': self.committer_name, | 77 'committer_name': self.committer_name, |
| 55 'committer_email': self.committer_email, | 78 'committer_email': self.committer_email, |
| 56 'committer_time': self.committer_time, | 79 'committer_time': self.committer_time, |
| 57 'revision': self.revision, | 80 'revision': self.revision, |
| 58 'commit_position': self.commit_position, | 81 'commit_position': self.commit_position, |
| 59 'touched_files': [], | 82 'touched_files': [], |
| 60 'message': self.message, | 83 'message': self.message, |
| 61 'commit_url': self.commit_url, | 84 'commit_url': self.commit_url, |
| 62 'code_review_url': self.code_review_url, | 85 'code_review_url': self.code_review_url, |
| 63 'reverted_revision': self.reverted_revision, | 86 'reverted_revision': self.reverted_revision, |
| 64 } | 87 } |
| 65 for touched_file in self.touched_files: | 88 for touched_file in self.touched_files: |
| 66 json_data['touched_files'].append(touched_file.ToDict()) | 89 json_data['touched_files'].append(touched_file.ToDict()) |
| 67 return json_data | 90 return json_data |
| 68 | 91 |
| 69 @staticmethod | 92 @staticmethod |
| 70 def FromDict(info): | 93 def FromDict(info): |
| 71 """Returns a ChangeLog instance represented by the given JSON info.""" | 94 """Returns a ChangeLog instance represented by the given JSON info.""" |
| 72 touched_files = [] | 95 touched_files = [] |
| 73 for touched_file_info in info['touched_files']: | 96 for touched_file_info in info['touched_files']: |
| 74 touched_files.append(FileChangeInfo.FromDict(touched_file_info)) | 97 if isinstance(touched_file_info, dict): |
| 98 touched_file_info = FileChangeInfo.FromDict(touched_file_info) | |
| 99 if not isinstance(touched_file_info, FileChangeInfo): # pragma: no cover | |
| 100 raise TypeError("expected FileChangeInfo but got %s" | |
| 101 % touched_file_info.__class__.__name__) | |
| 102 touched_files.append(touched_file_info) | |
| 75 | 103 |
| 76 return ChangeLog( | 104 return ChangeLog( |
| 77 info['author_name'], info['author_email'], info['author_time'], | 105 info['author_name'], info['author_email'], info['author_time'], |
| 78 info['committer_name'], info['committer_email'], info['committer_time'], | 106 info['committer_name'], info['committer_email'], info['committer_time'], |
| 79 info['revision'], info['commit_position'], info['message'], | 107 info['revision'], info['commit_position'], info['message'], |
| 80 touched_files, info['commit_url'], info['code_review_url'], | 108 touched_files, info['commit_url'], info['code_review_url'], |
| 81 info['reverted_revision'] | 109 info['reverted_revision'] |
| 82 ) | 110 ) |
| OLD | NEW |