Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(75)

Side by Side Diff: appengine/findit/util_scripts/git_checkout/local_git_parsers.py

Issue 2518663002: Converting various classes to namedtuples (Closed)
Patch Set: addressing nits Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 """Parse output of local git commands into Gitile response format.""" 5 """Parse output of local git commands into Gitile response format."""
6 6
7 from collections import namedtuple
7 from collections import defaultdict 8 from collections import defaultdict
8 from datetime import datetime 9 from datetime import datetime
9 import re 10 import re
10 11
11 from lib import time_util 12 from lib import time_util
12 from lib.gitiles import commit_util 13 from lib.gitiles import commit_util
13 from lib.gitiles.blame import Blame 14 from lib.gitiles.blame import Blame
14 from lib.gitiles.blame import Region 15 from lib.gitiles.blame import Region
15 from lib.gitiles.change_log import ChangeLog 16 from lib.gitiles.change_log import ChangeLog
17 from lib.gitiles.change_log import FileChangeInfo
16 from lib.gitiles.diff import ChangeType 18 from lib.gitiles.diff import ChangeType
17 19
18 REGION_START_COUNT_PATTERN = re.compile(r'^(\S+) \d+ (\d+) (\d+)') 20 REGION_START_COUNT_PATTERN = re.compile(r'^(\S+) \d+ (\d+) (\d+)')
19 21
20 DATETIME_FORMAT = '%Y-%m-%d %H:%M:%S' 22 DATETIME_FORMAT = '%Y-%m-%d %H:%M:%S'
21 23
22 AUTHOR_NAME_PATTERN = re.compile(r'^author (.*)') 24 AUTHOR_NAME_PATTERN = re.compile(r'^author (.*)')
23 AUTHOR_MAIL_PATTERN = re.compile(r'^author-mail (\S+)') 25 AUTHOR_MAIL_PATTERN = re.compile(r'^author-mail (\S+)')
24 AUTHOR_TIME_PATTERN = re.compile(r'^author-time (.+)') 26 AUTHOR_TIME_PATTERN = re.compile(r'^author-time (.+)')
25 AUTHOR_TIMEZONE_PATTERN = re.compile(r'^author-tz (.*)') 27 AUTHOR_TIMEZONE_PATTERN = re.compile(r'^author-tz (.*)')
(...skipping 17 matching lines...) Expand all
43 45
44 INITIAL_TO_CHANGE_TYPE = { 46 INITIAL_TO_CHANGE_TYPE = {
45 'M': ChangeType.MODIFY, 47 'M': ChangeType.MODIFY,
46 'A': ChangeType.ADD, 48 'A': ChangeType.ADD,
47 'D': ChangeType.DELETE, 49 'D': ChangeType.DELETE,
48 'C': ChangeType.COPY, 50 'C': ChangeType.COPY,
49 'R': ChangeType.RENAME 51 'R': ChangeType.RENAME
50 } 52 }
51 53
52 54
55 class RegionInfo(namedtuple('RegionInfo', ['start', 'count', 'revision'])):
56 __slots__ = ()
57 def __new__(cls, start, count, revision):
58 return super(cls, RegionInfo).__new__(cls, int(start), int(count), revision)
59
60
53 class GitParser(object): 61 class GitParser(object):
54 62
55 def __call__(self, output): 63 def __call__(self, output):
56 raise NotImplementedError() 64 raise NotImplementedError()
57 65
58 66
59 class GitBlameParser(GitParser): 67 class GitBlameParser(GitParser):
60 """Parses output of 'git blame --porcelain <rev> <file_path>'. 68 """Parses output of 'git blame --porcelain <rev> <file_path>'.
61 69
62 For example: 70 For example:
(...skipping 25 matching lines...) Expand all
88 96
89 blame = Blame(revision, path) 97 blame = Blame(revision, path)
90 commit_info = defaultdict(dict) 98 commit_info = defaultdict(dict)
91 region_info = None 99 region_info = None
92 for line in output.splitlines(): 100 for line in output.splitlines():
93 # Sample: ec3ed6... 2 1 7. 101 # Sample: ec3ed6... 2 1 7.
94 match = REGION_START_COUNT_PATTERN.match(line) 102 match = REGION_START_COUNT_PATTERN.match(line)
95 if match: 103 if match:
96 if region_info: 104 if region_info:
97 blame.AddRegion( 105 blame.AddRegion(
98 Region(region_info['start'], 106 Region(region_info.start,
99 region_info['count'], 107 region_info.count,
100 region_info['revision'], 108 region_info.revision,
101 commit_info[region_info['revision']]['author_name'], 109 commit_info[region_info.revision]['author_name'],
102 commit_info[region_info['revision']]['author_email'], 110 commit_info[region_info.revision]['author_email'],
103 commit_info[region_info['revision']]['author_time'])) 111 commit_info[region_info.revision]['author_time']))
104 112
105 region_info = {'start': int(match.group(2)), 113 region_info = RegionInfo(
106 'count': int(match.group(3)), 114 start = int(match.group(2)),
107 'revision': match.group(1)} 115 count = int(match.group(3)),
116 revision = match.group(1))
117
108 elif region_info: 118 elif region_info:
109 # Sample: author test@google.com. 119 # Sample: author test@google.com.
110 if AUTHOR_NAME_PATTERN.match(line): 120 if AUTHOR_NAME_PATTERN.match(line):
111 commit_info[region_info['revision']]['author_name'] = ( 121 commit_info[region_info.revision]['author_name'] = (
112 AUTHOR_NAME_PATTERN.match(line).group(1)) 122 AUTHOR_NAME_PATTERN.match(line).group(1))
113 # Sample: author-mail <test@google.com@2eff-a529-9590-31e7-b00076f81>. 123 # Sample: author-mail <test@google.com@2eff-a529-9590-31e7-b00076f81>.
114 elif AUTHOR_MAIL_PATTERN.match(line): 124 elif AUTHOR_MAIL_PATTERN.match(line):
115 commit_info[region_info['revision']]['author_email'] = ( 125 commit_info[region_info.revision]['author_email'] = (
116 commit_util.NormalizeEmail( 126 commit_util.NormalizeEmail(
117 AUTHOR_MAIL_PATTERN.match(line).group(1).replace( 127 AUTHOR_MAIL_PATTERN.match(line).group(1).replace(
118 '<', '').replace('>', ''))) 128 '<', '').replace('>', '')))
119 # Sample: author-time 1311863160. 129 # Sample: author-time 1311863160.
120 elif AUTHOR_TIME_PATTERN.match(line): 130 elif AUTHOR_TIME_PATTERN.match(line):
121 commit_info[region_info['revision']]['author_time'] = ( 131 commit_info[region_info.revision]['author_time'] = (
122 AUTHOR_TIME_PATTERN.match(line).group(1)) 132 AUTHOR_TIME_PATTERN.match(line).group(1))
123 # Sample: author-tz +0800. 133 # Sample: author-tz +0800.
124 elif AUTHOR_TIMEZONE_PATTERN.match(line): 134 elif AUTHOR_TIMEZONE_PATTERN.match(line):
125 time_zone = time_util.TimeZoneInfo( 135 time_zone = time_util.TimeZoneInfo(
126 AUTHOR_TIMEZONE_PATTERN.match(line).group(1)) 136 AUTHOR_TIMEZONE_PATTERN.match(line).group(1))
127 commit_info[region_info['revision']]['author_time'] = ( 137 commit_info[region_info.revision]['author_time'] = (
128 time_zone.LocalToUTC(datetime.fromtimestamp( 138 time_zone.LocalToUTC(datetime.fromtimestamp(
129 int(commit_info[region_info['revision']]['author_time'])))) 139 int(commit_info[region_info.revision]['author_time']))))
130 140
131 if region_info: 141 if region_info:
132 blame.AddRegion( 142 blame.AddRegion(
133 Region(region_info['start'], 143 Region(region_info.start,
134 region_info['count'], 144 region_info.count,
135 region_info['revision'], 145 region_info.revision,
136 commit_info[region_info['revision']]['author_name'], 146 commit_info[region_info.revision]['author_name'],
137 commit_info[region_info['revision']]['author_email'], 147 commit_info[region_info.revision]['author_email'],
138 commit_info[region_info['revision']]['author_time'])) 148 commit_info[region_info.revision]['author_time']))
139 149
140 return blame if blame else None 150 return blame if blame else None
141 151
142 152
143 def GetChangeType(initial): 153 def GetChangeType(initial):
144 """Gets Change type based on the initial character.""" 154 """Gets Change type based on the initial character."""
145 return INITIAL_TO_CHANGE_TYPE.get(initial[0]) 155 return INITIAL_TO_CHANGE_TYPE.get(initial[0])
146 156
147 157
148 def GetFileChangeInfo(change_type, path1, path2): 158 def GetFileChangeInfo(change_type, path1, path2):
149 """Set old/new path and old/new mode.""" 159 """Set old/new path and old/new mode."""
150 if change_type.lower() == ChangeType.MODIFY: 160 change_type = change_type.lower()
151 return { 161 if change_type == ChangeType.MODIFY:
152 'change_type': change_type, 162 return FileChangeInfo.Modify(path1)
153 'old_path': path1,
154 'new_path': path1
155 }
156 163
157 if change_type.lower() == ChangeType.ADD: 164 if change_type == ChangeType.ADD:
158 # Stay the same as gitile. 165 return FileChangeInfo.Add(path1)
159 return {
160 'change_type': change_type,
161 'old_path': None,
162 'new_path': path1
163 }
164 166
165 if change_type.lower() == ChangeType.DELETE: 167 if change_type == ChangeType.DELETE:
166 return { 168 return FileChangeInfo.Delete(path1)
167 'change_type': change_type,
168 'old_path': path1,
169 'new_path': None
170 }
171 169
172 if (change_type.lower() == ChangeType.RENAME or 170 if change_type == ChangeType.RENAME:
173 change_type.lower() == ChangeType.COPY): 171 return FileChangeInfo.Rename(path1, path2)
174 return { 172
175 'change_type': change_type, 173 # TODO(http://crbug.com/659346): write coverage test for this branch
176 'old_path': path1, 174 if change_type.lower() == ChangeType.COPY: # pragma: no cover
177 'new_path': path2 175 return FileChangeInfo.Copy(path1, path2)
178 }
179 176
180 return None 177 return None
181 178
182 179
183 class GitChangeLogParser(GitParser): 180 class GitChangeLogParser(GitParser):
184 181
185 def __call__(self, output, repo_url): # pylint:disable=W 182 def __call__(self, output, repo_url): # pylint:disable=W
186 """Parses output of 'git log --pretty=format:<format>. 183 """Parses output of 'git log --pretty=format:<format>.
187 184
188 For example: 185 For example:
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
390 + 'printPreviewSummaryFormatShort', 387 + 'printPreviewSummaryFormatShort',
391 + '<b>' + numSheets.toLocaleString() + '</b>', 388 + '<b>' + numSheets.toLocaleString() + '</b>',
392 + '<b>' + summaryLabel + '</b>'); 389 + '<b>' + summaryLabel + '</b>');
393 label = loadTimeData.getStringF('printPreviewSummaryFormatShort', 390 label = loadTimeData.getStringF('printPreviewSummaryFormatShort',
394 - numSheets, summaryLabel); 391 - numSheets, summaryLabel);
395 + numSheets.toLocaleString(), 392 + numSheets.toLocaleString(),
396 + summaryLabel); 393 + summaryLabel);
397 } 394 }
398 """ 395 """
399 return output if output else None 396 return output if output else None
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698