⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 100233 in webkit


Ignore:
Timestamp:
Nov 14, 2011, 7:08:16 PM (15 years ago)
Author:
rniwa@webkit.org
Message:

Improve ChangeLogEntry's reviewer parsing algorithm part 2
https://bugs.webkit.org/show_bug.cgi?id=72340

Reviewed by Eric Seidel.

This patch improves the recognition of NOBODY, wrestler names, and parenthesized clauses,
and prepares ChangeLogEntry to support edit-distance-based reviewer-name recognition.

  • Scripts/webkitpy/common/checkout/changelog.py:
  • Scripts/webkitpy/common/checkout/changelog_unittest.py:
Location:
trunk/Tools
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Tools/ChangeLog

    r100231 r100233  
     12011-11-14  Ryosuke Niwa  <rniwa@webkit.org>
     2
     3        Improve ChangeLogEntry's reviewer parsing algorithm part 2
     4        https://bugs.webkit.org/show_bug.cgi?id=72340
     5
     6        Reviewed by Eric Seidel.
     7
     8        This patch improves the recognition of NOBODY, wrestler names, and parenthesized clauses,
     9        and prepares ChangeLogEntry to support edit-distance-based reviewer-name recognition.
     10
     11        * Scripts/webkitpy/common/checkout/changelog.py:
     12        * Scripts/webkitpy/common/checkout/changelog_unittest.py:
     13
    1142011-11-14  Eric Seidel  <eric@webkit.org>
    215
  • trunk/Tools/Scripts/webkitpy/common/checkout/changelog.py

    r100002 r100233  
    8484    reviewed_byless_regexp = r'^\s*((Review|Rubber(\s*|-)stamp)(s|ed)?|RS)(\s+|\s*=\s*)(?P<reviewer>([A-Z]\w+\s*)+)[\.,]?\s*$'
    8585
    86     contributor_name_noise_regexp = re.compile(r"""
    87     (\s+(landed|committed|)\s+by.+) # landed by, commented by, etc...
    88     |\..+ # text afetr the first period (inclusive)
     86    reviewer_name_noise_regexp = re.compile(r"""
     87    (\s+((tweaked\s+)?and\s+)?(landed|committed|okayed)\s+by.+) # "landed by", "commented by", etc...
     88    |(^(Reviewed\s+)?by\s+) # extra "Reviewed by" or "by"
     89    |\.(?:(\s.+|$)) # text after the first period followed by a space
    8990    |([(<]\s*[\w_\-\.]+@[\w_\-\.]+[>)]) # email addresses
    90     |((?<=and)\s+([a-z\-]+\s+)+by) # phrases like "given a glance-over by" and "looked over by" (no capital letters)
     91    |([(<](https?://?bugs.)webkit.org[^>)]+[>)]) # bug url
     92    |("[^"]+") # wresler names like 'Sean/Shawn/Shaun' in 'Geoffrey "Sean/Shawn/Shaun" Garen'
     93    |('[^']+') # wresler names like "The Belly" in "Sam 'The Belly' Weinig"
     94    |((Mr|Ms|Dr|Mrs|Prof)\.(\s+|$))
    9195    """, re.IGNORECASE | re.VERBOSE)
     96
     97    reviewer_name_casesensitive_noise_regexp = re.compile(r"""
     98    ((\s+|^)(and\s+)?([a-z-]+\s+){5,}by\s+) # e.g. "and given a good once-over by"
     99    |(\(\s*(?!(and|[A-Z])).+\)) # any parenthesis that doesn't start with "and" or a capital letter
     100    |(with(\s+[a-z-]+)+) # phrases with "with no hesitation" in "Sam Weinig with no hesitation"
     101    """, re.VERBOSE)
     102
     103    nobody_regexp = re.compile(r"""(\s+|^)nobody(
     104    ((,|\s+-)?\s+(\w+\s+)+fix.*) # e.g. nobody, build fix...
     105    |(\s*\([^)]+\).*) # NOBODY (..)...
     106    |$)""", re.IGNORECASE | re.VERBOSE)
    92107
    93108    # e.g. == Rolled over to ChangeLog-2011-02-16 ==
     
    114129        reviewer_text = match.group("reviewer")
    115130
    116         reviewer_text = ChangeLogEntry.contributor_name_noise_regexp.sub('', reviewer_text)
     131        reviewer_text = ChangeLogEntry.nobody_regexp.sub('', reviewer_text)
     132        reviewer_text = ChangeLogEntry.reviewer_name_noise_regexp.sub('', reviewer_text)
     133        reviewer_text = ChangeLogEntry.reviewer_name_casesensitive_noise_regexp.sub('', reviewer_text)
     134        reviewer_text = reviewer_text.replace('(', '').replace(')', '')
    117135        reviewer_text = re.sub(r'\s\s+|[,.]\s*$', ' ', reviewer_text).strip()
     136        if not len(reviewer_text):
     137            return None, None
    118138
    119139        # FIXME: Canonicalize reviewer names; e.g. Andy "First Time Reviewer" Estes
    120140        # FIXME: Ignore NOBODY (\w+) and "a spell checker"
    121         reviewer_list = re.split(r'\s*(?:(?:,(?:\s+and\s+|&)?)|(?:and\s+|&))\s*', reviewer_text)
     141        reviewer_list = re.split(r'\s*(?:(?:,(?:\s+and\s+|&)?)|(?:and\s+|&)|(?:[/+]))\s*', reviewer_text)
    122142
    123143        # Get rid of "reviewers" like "even though this is just a..." in "Reviewed by Sam Weinig, even though this is just a..."
    124         reviewer_list = [reviewer for reviewer in reviewer_list if len(reviewer.split()) <= 5]
     144        # and "who wrote the original code" in "Noam Rosenthal, who wrote the original code"
     145        reviewer_list = [reviewer for reviewer in reviewer_list if not re.match('^who\s|^([a-z]+(\s+|\.|$)){6,}$', reviewer)]
    125146
    126147        return reviewer_text, reviewer_list
    127 
    128148
    129149    def _parse_entry(self):
  • trunk/Tools/Scripts/webkitpy/common/checkout/changelog_unittest.py

    r100002 r100233  
    314314
    315315        reviewer_text, reviewer_list = ChangeLogEntry._parse_reviewer_text('Reviewed by Sam Weinig, and given a good once-over by Jeff Miller.')
    316         self.assertEquals(reviewer_text, 'Sam Weinig, and Jeff Miller')
    317316        self.assertEquals(reviewer_list, ['Sam Weinig', 'Jeff Miller'])
    318317
     
    323322        reviewer_text, reviewer_list = ChangeLogEntry._parse_reviewer_text(' Reviewed by Sam Weinig, even though this is just a...')
    324323        self.assertEquals(reviewer_list, ['Sam Weinig'])
     324
     325        reviewer_text, reviewer_list = ChangeLogEntry._parse_reviewer_text('Reviewed by rniwa@webkit.org.')
     326        self.assertEquals(reviewer_text, 'rniwa@webkit.org')
     327        self.assertEquals(reviewer_list, ['rniwa@webkit.org'])
     328
     329        reviewer_text, reviewer_list = ChangeLogEntry._parse_reviewer_text('Reviewed by Dirk Schulze / Darin Adler.')
     330        self.assertEquals(reviewer_text, 'Dirk Schulze / Darin Adler')
     331        self.assertEquals(reviewer_list, ['Dirk Schulze', 'Darin Adler'])
     332
     333        reviewer_text, reviewer_list = ChangeLogEntry._parse_reviewer_text('Reviewed by Sam Weinig + Oliver Hunt.')
     334        self.assertEquals(reviewer_text, 'Sam Weinig + Oliver Hunt')
     335        self.assertEquals(reviewer_list, ['Sam Weinig', 'Oliver Hunt'])
     336
     337        reviewer_text, reviewer_list = ChangeLogEntry._parse_reviewer_text('Reviewed by Sam Weinig + Oliver Hunt.')
     338        self.assertEquals(reviewer_text, 'Sam Weinig + Oliver Hunt')
     339        self.assertEquals(reviewer_list, ['Sam Weinig', 'Oliver Hunt'])
     340
     341        reviewer_text, reviewer_list = ChangeLogEntry._parse_reviewer_text('Rubber stamped by by Gustavo Noronha Silva')
     342        self.assertEquals(reviewer_text, 'Gustavo Noronha Silva')
     343
     344        reviewer_text, reviewer_list = ChangeLogEntry._parse_reviewer_text('Rubberstamped by Noam Rosenthal, who wrote the original code.')
     345        self.assertEquals(reviewer_list, ['Noam Rosenthal'])
     346
     347        reviewer_text, reviewer_list = ChangeLogEntry._parse_reviewer_text('Reviewed by Dan Bernstein (relanding of r47157)')
     348        self.assertEquals(reviewer_list, ['Dan Bernstein'])
     349
     350        reviewer_text, reviewer_list = ChangeLogEntry._parse_reviewer_text('Reviewed by Geoffrey "Sean/Shawn/Shaun" Garen')
     351        self.assertEquals(reviewer_list, ['Geoffrey Garen'])
     352
     353        reviewer_text, reviewer_list = ChangeLogEntry._parse_reviewer_text('Reviewed by Dave "Messy" Hyatt.')
     354        self.assertEquals(reviewer_list, ['Dave Hyatt'])
     355
     356        reviewer_text, reviewer_list = ChangeLogEntry._parse_reviewer_text('Reviewed by Sam \'The Belly\' Weinig')
     357        self.assertEquals(reviewer_list, ['Sam Weinig'])
     358
     359        reviewer_text, reviewer_list = ChangeLogEntry._parse_reviewer_text('Rubber-stamped by David "I\'d prefer not" Hyatt.')
     360        self.assertEquals(reviewer_list, ['David Hyatt'])
     361
     362        reviewer_text, reviewer_list = ChangeLogEntry._parse_reviewer_text('Reviewed by Mr. Geoffrey Garen.')
     363        self.assertEquals(reviewer_list, ['Geoffrey Garen'])
     364
     365        reviewer_text, reviewer_list = ChangeLogEntry._parse_reviewer_text('Reviewed by Darin (ages ago)')
     366        self.assertEquals(reviewer_list, ['Darin'])
     367
     368        reviewer_text, reviewer_list = ChangeLogEntry._parse_reviewer_text('Reviewed by Sam Weinig (except for a few comment and header tweaks).')
     369        self.assertEquals(reviewer_list, ['Sam Weinig'])
     370
     371        reviewer_text, reviewer_list = ChangeLogEntry._parse_reviewer_text('Reviewed by Sam Weinig (all but the FormDataListItem rename)')
     372        self.assertEquals(reviewer_list, ['Sam Weinig'])
     373
     374        reviewer_text, reviewer_list = ChangeLogEntry._parse_reviewer_text('Reviewed by Darin Adler, tweaked and landed by Beth.')
     375        self.assertEquals(reviewer_list, ['Darin Adler'])
     376
     377        reviewer_text, reviewer_list = ChangeLogEntry._parse_reviewer_text('Reviewed by Sam Weinig with no hesitation')
     378        self.assertEquals(reviewer_list, ['Sam Weinig'])
     379
     380        # For now, we let unofficial reviewers recognized as reviewers
     381        reviewer_text, reviewer_list = ChangeLogEntry._parse_reviewer_text('Reviewed by Sam Weinig, Anders Carlsson, and (unofficially) Adam Barth.')
     382        self.assertEquals(reviewer_list, ['Sam Weinig', 'Anders Carlsson', 'Adam Barth'])
     383
     384        # It's okay to have 'build fix' and 'others', etc... as a reviewer in the following cases because fuzzy-match would reject it
     385        reviewer_text, reviewer_list = ChangeLogEntry._parse_reviewer_text('Reviewed by Dimitri Glazkov, build fix')
     386        self.assertEquals(reviewer_list, ['Dimitri Glazkov', 'build fix'])
     387
     388        reviewer_text, reviewer_list = ChangeLogEntry._parse_reviewer_text('Reviewed by BUILD FIX')
     389        self.assertEquals(reviewer_list, ['BUILD FIX'])
     390
     391        reviewer_text, reviewer_list = ChangeLogEntry._parse_reviewer_text('Reviewed by Mac build fix')
     392        self.assertEquals(reviewer_list, ['Mac build fix'])
     393
     394        reviewer_text, reviewer_list = ChangeLogEntry._parse_reviewer_text('Reviewed by Darin Adler, Dan Bernstein, Adele Peterson, and others.')
     395        self.assertEquals(reviewer_text, 'Darin Adler, Dan Bernstein, Adele Peterson, and others')
     396        self.assertEquals(reviewer_list, ['Darin Adler', 'Dan Bernstein', 'Adele Peterson', 'others'])
     397
     398        reviewer_text, reviewer_list = ChangeLogEntry._parse_reviewer_text('Reviewed by George Staikos (and others)')
     399        self.assertEquals(reviewer_list, ['George Staikos', 'others'])
     400
     401        reviewer_text, reviewer_list = ChangeLogEntry._parse_reviewer_text('Reviewed by Oliver Hunt, okayed by Darin Adler.')
     402        self.assertEquals(reviewer_list, ['Oliver Hunt'])
     403
     404        reviewer_text, reviewer_list = ChangeLogEntry._parse_reviewer_text('Reviewed by Mark Rowe, but Dan Bernstein also reviewed and asked thoughtful questions.')
     405        self.assertEquals(reviewer_list, ['Mark Rowe', 'but Dan Bernstein also reviewed', 'asked thoughtful questions'])
     406
     407        # It's okay to have " in" and "by ", etc... in the following cases because we're going to fuzzy-match them later
     408        reviewer_text, reviewer_list = ChangeLogEntry._parse_reviewer_text('Reviewed by Darin Adler in <https://bugs.webkit.org/show_bug.cgi?id=47736>.')
     409        self.assertEquals(reviewer_text, 'Darin Adler in')
     410        reviewer_text, reviewer_list = ChangeLogEntry._parse_reviewer_text('Reviewed by Adam Barth.:w')
     411        self.assertEquals(reviewer_text, 'Adam Barth.:w')
     412        reviewer_text, reviewer_list = ChangeLogEntry._parse_reviewer_text('Reviewed by Darin Adler).')
     413        self.assertEquals(reviewer_text, 'Darin Adler')
     414
     415        reviewer_text, reviewer_list = ChangeLogEntry._parse_reviewer_text('Reviewed by NOBODY.')
     416        self.assertEquals(reviewer_text, None)
     417
     418        reviewer_text, reviewer_list = ChangeLogEntry._parse_reviewer_text('Reviewed by NOBODY - Build Fix.')
     419        self.assertEquals(reviewer_text, None)
     420
     421        reviewer_text, reviewer_list = ChangeLogEntry._parse_reviewer_text('Reviewed by NOBODY, layout tests fix.')
     422        self.assertEquals(reviewer_text, None)
     423
     424        reviewer_text, reviewer_list = ChangeLogEntry._parse_reviewer_text('Reviewed by NOBODY (Qt build fix pt 2).')
     425        self.assertEquals(reviewer_text, None)
     426
     427        reviewer_text, reviewer_list = ChangeLogEntry._parse_reviewer_text('Reviewed by NOBODY(rollout)')
     428        self.assertEquals(reviewer_text, None)
     429
     430        reviewer_text, reviewer_list = ChangeLogEntry._parse_reviewer_text('Reviewed by NOBODY (Build fix, forgot to svn add this file)')
     431        self.assertEquals(reviewer_text, None)
     432
     433        reviewer_text, reviewer_list = ChangeLogEntry._parse_reviewer_text('Reviewed by nobody (trivial follow up fix), Joseph Pecoraro LGTM-ed.')
     434        self.assertEquals(reviewer_text, None)
    325435
    326436    def test_latest_entry_parse(self):
Note: See TracChangeset for help on using the changeset viewer.