Mercurial > public > mercurial-scm > hg-stable
comparison mercurial/utils/stringutil.py @ 37248:0e7550b0964c
stringutil: improve check for failed mailmap line parsing
The existing check for a bad mailmap file entry fails with inputs
like b'>@<'. This commit adds a function to check if a sufficient
amount of information has been parsed from a mailmap file entry.
At minimum, one email must be found (assumed to be the commit email).
If email is not empty and no names are found, then there must be
two emails. If there are at least one email and name, the mapping
is valid.
Differential Revision: https://phab.mercurial-scm.org/D3003
author | Connor Sheehan <sheehan@mozilla.com> |
---|---|
date | Sat, 31 Mar 2018 11:36:55 -0400 |
parents | 54b896f195d1 |
children | 2ed180117f76 |
comparison
equal
deleted
inserted
replaced
37247:54b896f195d1 | 37248:0e7550b0964c |
---|---|
163 class mailmapping(object): | 163 class mailmapping(object): |
164 '''Represents a username/email key or value in | 164 '''Represents a username/email key or value in |
165 a mailmap file''' | 165 a mailmap file''' |
166 email = attr.ib() | 166 email = attr.ib() |
167 name = attr.ib(default=None) | 167 name = attr.ib(default=None) |
168 | |
169 def _ismailmaplineinvalid(names, emails): | |
170 '''Returns True if the parsed names and emails | |
171 in a mailmap entry are invalid. | |
172 | |
173 >>> # No names or emails fails | |
174 >>> names, emails = [], [] | |
175 >>> _ismailmaplineinvalid(names, emails) | |
176 True | |
177 >>> # Only one email fails | |
178 >>> emails = [b'email@email.com'] | |
179 >>> _ismailmaplineinvalid(names, emails) | |
180 True | |
181 >>> # One email and one name passes | |
182 >>> names = [b'Test Name'] | |
183 >>> _ismailmaplineinvalid(names, emails) | |
184 False | |
185 >>> # No names but two emails passes | |
186 >>> names = [] | |
187 >>> emails = [b'proper@email.com', b'commit@email.com'] | |
188 >>> _ismailmaplineinvalid(names, emails) | |
189 False | |
190 ''' | |
191 return not emails or not names and len(emails) < 2 | |
168 | 192 |
169 def parsemailmap(mailmapcontent): | 193 def parsemailmap(mailmapcontent): |
170 """Parses data in the .mailmap format | 194 """Parses data in the .mailmap format |
171 | 195 |
172 >>> mmdata = b"\\n".join([ | 196 >>> mmdata = b"\\n".join([ |
197 | 221 |
198 for line in mailmapcontent.splitlines(): | 222 for line in mailmapcontent.splitlines(): |
199 | 223 |
200 # Don't bother checking the line if it is a comment or | 224 # Don't bother checking the line if it is a comment or |
201 # is an improperly formed author field | 225 # is an improperly formed author field |
202 if line.lstrip().startswith('#') or any(c not in line for c in '<>@'): | 226 if line.lstrip().startswith('#'): |
203 continue | 227 continue |
204 | 228 |
205 # names, emails hold the parsed emails and names for each line | 229 # names, emails hold the parsed emails and names for each line |
206 # name_builder holds the words in a persons name | 230 # name_builder holds the words in a persons name |
207 names, emails = [], [] | 231 names, emails = [], [] |
227 break | 251 break |
228 | 252 |
229 else: | 253 else: |
230 # We have found another word in the committers name | 254 # We have found another word in the committers name |
231 namebuilder.append(element) | 255 namebuilder.append(element) |
256 | |
257 # Check to see if we have parsed the line into a valid form | |
258 # We require at least one email, and either at least one | |
259 # name or a second email | |
260 if _ismailmaplineinvalid(names, emails): | |
261 continue | |
232 | 262 |
233 mailmapkey = mailmapping( | 263 mailmapkey = mailmapping( |
234 email=emails[-1], | 264 email=emails[-1], |
235 name=names[-1] if len(names) == 2 else None, | 265 name=names[-1] if len(names) == 2 else None, |
236 ) | 266 ) |