Extract authors from entry text. Returns: Tuple of (cleaned_text, list_of_authors) Patterns handled: - (Author Name) - (Author1, Author2) - (Author Name via CommitterName) - (Author1 via Committer1, Author2 via Committer2)
(entry_text: str)
| 189 | |
| 190 | @staticmethod |
| 191 | def parse_authors(entry_text: str) -> Tuple[str, List[Author]]: |
| 192 | """ |
| 193 | Extract authors from entry text. |
| 194 | |
| 195 | Returns: |
| 196 | Tuple of (cleaned_text, list_of_authors) |
| 197 | |
| 198 | Patterns handled: |
| 199 | - (Author Name) |
| 200 | - (Author1, Author2) |
| 201 | - (Author Name via CommitterName) |
| 202 | - (Author1 via Committer1, Author2 via Committer2) |
| 203 | |
| 204 | Only matches author attribution at the END of the entry text, |
| 205 | not in the middle of descriptions like (aka Standalone) |
| 206 | |
| 207 | Note: JIRA/GitHub issue IDs found in the author section are NOT added as authors, |
| 208 | but are preserved in the returned text so IssueExtractor can process them as links. |
| 209 | """ |
| 210 | # Find ALL matches and use the LAST one (rightmost) |
| 211 | # This ensures we get the actual author attribution, not mid-text parentheses |
| 212 | matches = list(AuthorParser.AUTHOR_PATTERN.finditer(entry_text)) |
| 213 | if not matches: |
| 214 | return entry_text, [] |
| 215 | |
| 216 | # Use the last match (rightmost) |
| 217 | match = matches[-1] |
| 218 | |
| 219 | author_text = match.group(1) |
| 220 | # Include the space before the parenthesis in what we remove |
| 221 | cleaned_text = entry_text[:match.start()].rstrip() |
| 222 | |
| 223 | authors = [] |
| 224 | found_issues = [] # Track JIRA issues found in author section |
| 225 | |
| 226 | # Split by comma and slash, which are both used as delimiters in author sections |
| 227 | # Patterns handled: |
| 228 | # - "Author1, Author2" (comma delimiter) |
| 229 | # - "Author1 / Author2" (slash delimiter) |
| 230 | # - "Author1, Issue1 / Author2" (mixed delimiters) |
| 231 | # Also aware of "via" keyword: "Author via Committer" |
| 232 | segments = [seg.strip() for seg in re.split(r'[,/]', author_text)] |
| 233 | |
| 234 | for segment in segments: |
| 235 | segment = segment.strip() |
| 236 | if not segment: |
| 237 | continue |
| 238 | |
| 239 | # Check if this is a JIRA/GitHub issue reference |
| 240 | if AuthorParser.ISSUE_PATTERN.match(segment): |
| 241 | # Don't add as author, but remember to add it back to text for IssueExtractor |
| 242 | found_issues.append(segment) |
| 243 | continue |
| 244 | |
| 245 | # Handle "via" prefix (standalone or after author name) |
| 246 | if segment.startswith('via '): |
| 247 | # Malformed: standalone "via Committer" (comma was added incorrectly) |
| 248 | # Extract just the committer name |