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

Changeset 283373 in webkit


Ignore:
Timestamp:
Oct 1, 2021, 9:27:24 AM (5 years ago)
Author:
Jonathan Bedard
Message:

[webkitscmpy] Linkify http urls in pull-requests
https://bugs.webkit.org/show_bug.cgi?id=230655

Reviewed by Stephanie Lewis.

  • Scripts/libraries/webkitscmpy/setup.py: Bump version.
  • Scripts/libraries/webkitscmpy/webkitscmpy/init.py: Ditto.
  • Scripts/libraries/webkitscmpy/webkitscmpy/pull_request.py:

(PullRequest):
(PullRequest.escape_html): Escape any html and linkify http urls.
(PullRequest.unescape_html): Unescape escaped html and strip links from http urls.
(PullRequest.create_body): Use <pre> and escape html in commit messages.
(PullRequest.parse_body): Match both <pre> and `, escape html if <pre> was used.

  • Tools/Scripts/libraries/webkitscmpy/webkitscmpy/remote/bitbucket.py:

(BitBucket.PRGenerator.create): Opt out of linkifying http in comment body.
(BitBucket.PRGenerator.update): Ditto.

  • Scripts/libraries/webkitscmpy/webkitscmpy/test/pull_request_unittest.py:
Location:
trunk/Tools
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/Tools/ChangeLog

    r283364 r283373  
     12021-10-01  Jonathan Bedard  <jbedard@apple.com>
     2
     3        [webkitscmpy] Linkify http urls in pull-requests
     4        https://bugs.webkit.org/show_bug.cgi?id=230655
     5
     6        Reviewed by Stephanie Lewis.
     7
     8        * Scripts/libraries/webkitscmpy/setup.py: Bump version.
     9        * Scripts/libraries/webkitscmpy/webkitscmpy/__init__.py: Ditto.
     10        * Scripts/libraries/webkitscmpy/webkitscmpy/pull_request.py:
     11        (PullRequest):
     12        (PullRequest.escape_html): Escape any html and linkify http urls.
     13        (PullRequest.unescape_html): Unescape escaped html and strip links from http urls.
     14        (PullRequest.create_body): Use <pre> and escape html in commit messages.
     15        (PullRequest.parse_body): Match both <pre> and ```, escape html if <pre> was used.
     16        * Tools/Scripts/libraries/webkitscmpy/webkitscmpy/remote/bitbucket.py:
     17        (BitBucket.PRGenerator.create): Opt out of linkifying http in comment body.
     18        (BitBucket.PRGenerator.update): Ditto.
     19        * Scripts/libraries/webkitscmpy/webkitscmpy/test/pull_request_unittest.py:
     20
    1212021-10-01  Kimmo Kinnunen  <kkinnunen@apple.com>
    222
  • trunk/Tools/Scripts/libraries/webkitscmpy/setup.py

    r283292 r283373  
    3030setup(
    3131    name='webkitscmpy',
    32     version='2.2.2',
     32    version='2.2.3',
    3333    description='Library designed to interact with git and svn repositories.',
    3434    long_description=readme(),
  • trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/__init__.py

    r283292 r283373  
    4747    )
    4848
    49 version = Version(2, 2, 2)
     49version = Version(2, 2, 3)
    5050
    5151AutoInstall.register(Package('fasteners', Version(0, 15, 0)))
  • trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/pull_request.py

    r281379 r283373  
    2727
    2828class PullRequest(object):
    29     COMMIT_BODY_RE = re.compile(r'\A#### (?P<hash>[0-9a-f]+)\n```\n(?P<message>.+)\n```\n?\Z', flags=re.DOTALL)
     29    COMMIT_BODY_RES = [
     30        dict(
     31            re=re.compile(r'\A#### (?P<hash>[0-9a-f]+)\n```\n(?P<message>.+)\n```\n?\Z', flags=re.DOTALL),
     32            escaped=False,
     33        ), dict(
     34            re=re.compile(r'\A#### (?P<hash>[0-9a-f]+)\n<pre>\n(?P<message>.+)\n</pre>\n?\Z', flags=re.DOTALL),
     35            escaped=True,
     36        ),
     37    ]
    3038    DIVIDER_LEN = 70
     39    ESCAPE_TABLE = {
     40        '"': '&quot;',
     41        "'": '&apos;',
     42        '>': ' &gt;',
     43        '<': '&lt;',
     44        '&': '&amp;',
     45    }
    3146
    3247    class State(object):
     
    3550
    3651    @classmethod
    37     def create_body(cls, body, commits):
     52    def escape_html(cls, message):
     53        message = ''.join(cls.ESCAPE_TABLE.get(c, c) for c in message)
     54        return re.sub(r'(https?://[^\s<>,:;]+)', r'<a href="\1">\1</a>', message)
     55
     56    @classmethod
     57    def unescape_html(cls, message):
     58        message = re.sub(r'<a href=".+">(https?://[^\s<>,:;]+)</a>', r'\1', message)
     59        for c, escaped in cls.ESCAPE_TABLE.items():
     60            message = message.replace(escaped, c)
     61        return message
     62
     63    @classmethod
     64    def create_body(cls, body, commits, linkify=True):
    3865        body = body or ''
    3966        if not commits:
     
    4168        if body:
    4269            body = '{}\n\n{}\n'.format(body.rstrip(), '-' * cls.DIVIDER_LEN)
     70        if linkify:
     71            return body + '\n{}\n'.format('-' * cls.DIVIDER_LEN).join([
     72                '#### {}\n<pre>\n{}\n</pre>'.format(
     73                    commit.hash,
     74                    cls.escape_html(commit.message.rstrip() if commit.message else '???'),
     75                ) for commit in commits
     76            ])
    4377        return body + '\n{}\n'.format('-' * cls.DIVIDER_LEN).join([
    4478            '#### {}\n```\n{}\n```'.format(commit.hash, commit.message.rstrip() if commit.message else '???') for commit in commits
     
    5488
    5589        for part in parts:
    56             match = cls.COMMIT_BODY_RE.match(part)
    57             if match:
    58                 commits.append(Commit(
    59                     hash=match.group('hash'),
    60                     message=match.group('message') if match.group('message') != '???' else None,
    61                 ))
    62             elif body:
    63                 body = '{}\n{}\n{}\n'.format(body.rstrip(), '-' * cls.DIVIDER_LEN, part.rstrip().lstrip())
     90            for obj in cls.COMMIT_BODY_RES:
     91                match = obj['re'].match(part)
     92                if match:
     93                    message = cls.unescape_html(match.group('message')) if obj.get('escaped') else match.group('message')
     94                    commits.append(Commit(
     95                        hash=match.group('hash'),
     96                        message=message if message != '???' else None,
     97                    ))
     98                    break
    6499            else:
    65                 body = part.rstrip().lstrip()
     100                if body:
     101                    body = '{}\n{}\n{}\n'.format(body.rstrip(), '-' * cls.DIVIDER_LEN, part.rstrip().lstrip())
     102                else:
     103                    body = part.rstrip().lstrip()
    66104        return body or None, commits
    67105
  • trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/remote/bitbucket.py

    r281695 r283373  
    7575            if len(title) > self.TITLE_CHAR_LIMIT:
    7676                raise ValueError('Title length too long. Limit is: {}'.format(self.TITLE_CHAR_LIMIT))
    77             description = PullRequest.create_body(body, commits)
     77            description = PullRequest.create_body(body, commits, linkify=False)
    7878            if description and len(description) > self.BODY_CHAR_LIMIT:
    7979                raise ValueError('Body length too long. Limit is: {}'.format(self.BODY_CHAR_LIMIT))
     
    8585                ), json=dict(
    8686                    title=title,
    87                     description=PullRequest.create_body(body, commits),
     87                    description=PullRequest.create_body(body, commits, linkify=False),
    8888                    fromRef=dict(
    8989                        id='refs/heads/{}'.format(head),
     
    126126                to_change['title'] = title
    127127            if body or commits:
    128                 to_change['description'] = PullRequest.create_body(body, commits)
     128                to_change['description'] = PullRequest.create_body(body, commits, linkify=False)
    129129            if head:
    130130                to_change['fromRef'] = dict(
  • trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/test/pull_request_unittest.py

    r282409 r283373  
    3434        self.assertEqual('PR 1234', str(PullRequest(1234)))
    3535
    36     def test_create_body_single(self):
     36    def test_create_body_single_linked(self):
    3737        self.assertEqual(
    3838            PullRequest.create_body(None, [Commit(
     
    4040                message='[scoping] Bug to fix\n\nReviewed by Tim Contributor.\n',
    4141            )]), '''#### 11aa76f9fc380e9fe06157154f32b304e8dc4749
     42<pre>
     43[scoping] Bug to fix
     44
     45Reviewed by Tim Contributor.
     46</pre>''',
     47        )
     48
     49    def test_create_body_single_no_link(self):
     50        self.assertEqual(
     51            PullRequest.create_body(None, [Commit(
     52                hash='11aa76f9fc380e9fe06157154f32b304e8dc4749',
     53                message='[scoping] Bug to fix\n\nReviewed by Tim Contributor.\n',
     54            )], linkify=False), '''#### 11aa76f9fc380e9fe06157154f32b304e8dc4749
    4255```
    4356[scoping] Bug to fix
     
    5972        self.assertEqual(commits[0].message, '[scoping] Bug to fix\n\nReviewed by Tim Contributor.')
    6073
    61     def test_create_body_multiple(self):
     74    def test_create_body_multiple_linked(self):
    6275        self.assertEqual(
    6376            PullRequest.create_body(None, [Commit(
    6477                hash='11aa76f9fc380e9fe06157154f32b304e8dc4749',
    65                 message='[scoping] Bug to fix (Part 2)\n\nReviewed by Tim Contributor.\n',
     78                message='[scoping] Bug to fix (Part 2)\nhttps://bugs.webkit.org/1234\n\nReviewed by Tim Contributor.\n',
    6679            ), Commit(
    6780                hash='53ea230fcedbce327eb1c45a6ab65a88de864505',
    68                 message='[scoping] Bug to fix (Part 1)\n\nReviewed by Tim Contributor.\n',
     81                message='[scoping] Bug to fix (Part 1)\n<http://bugs.webkit.org/1234>\n\nReviewed by Tim Contributor.\n',
    6982            )]), '''#### 11aa76f9fc380e9fe06157154f32b304e8dc4749
    70 ```
     83<pre>
    7184[scoping] Bug to fix (Part 2)
    72 
    73 Reviewed by Tim Contributor.
    74 ```
     85<a href="https://bugs.webkit.org/1234">https://bugs.webkit.org/1234</a>
     86
     87Reviewed by Tim Contributor.
     88</pre>
    7589----------------------------------------------------------------------
    7690#### 53ea230fcedbce327eb1c45a6ab65a88de864505
    77 ```
     91<pre>
    7892[scoping] Bug to fix (Part 1)
     93&lt;<a href="http://bugs.webkit.org/1234">http://bugs.webkit.org/1234</a> &gt;
     94
     95Reviewed by Tim Contributor.
     96</pre>''',
     97        )
     98
     99    def test_create_body_multiple_no_link(self):
     100        self.assertEqual(
     101            PullRequest.create_body(None, [Commit(
     102                hash='11aa76f9fc380e9fe06157154f32b304e8dc4749',
     103                message='[scoping] Bug to fix (Part 2)\nhttps://bugs.webkit.org/1234\n\nReviewed by Tim Contributor.\n',
     104            ), Commit(
     105                hash='53ea230fcedbce327eb1c45a6ab65a88de864505',
     106                message='[scoping] Bug to fix (Part 1)\n<http://bugs.webkit.org/1234>\n\nReviewed by Tim Contributor.\n',
     107            )], linkify=False), '''#### 11aa76f9fc380e9fe06157154f32b304e8dc4749
     108```
     109[scoping] Bug to fix (Part 2)
     110https://bugs.webkit.org/1234
     111
     112Reviewed by Tim Contributor.
     113```
     114----------------------------------------------------------------------
     115#### 53ea230fcedbce327eb1c45a6ab65a88de864505
     116```
     117[scoping] Bug to fix (Part 1)
     118<http://bugs.webkit.org/1234>
    79119
    80120Reviewed by Tim Contributor.
     
    105145        self.assertEqual(commits[1].message, '[scoping] Bug to fix (Part 1)\n\nReviewed by Tim Contributor.')
    106146
     147    def test_parse_html_body_multiple(self):
     148        self.maxDiff = None
     149        body, commits = PullRequest.parse_body('''#### 11aa76f9fc380e9fe06157154f32b304e8dc4749
     150<pre>
     151[scoping] Bug to fix (Part 2)
     152<a href="https://bugs.webkit.org/1234">https://bugs.webkit.org/1234</a>
     153
     154Reviewed by Tim Contributor.
     155</pre>
     156----------------------------------------------------------------------
     157#### 53ea230fcedbce327eb1c45a6ab65a88de864505
     158<pre>
     159[scoping] Bug to fix (Part 1)
     160&lt;<a href="http://bugs.webkit.org/1234">http://bugs.webkit.org/1234</a> &gt;
     161
     162Reviewed by Tim Contributor.
     163</pre>''')
     164        self.assertIsNone(body)
     165        self.assertEqual(len(commits), 2)
     166
     167        self.assertEqual(commits[0].hash, '11aa76f9fc380e9fe06157154f32b304e8dc4749')
     168        self.assertEqual(commits[0].message, '[scoping] Bug to fix (Part 2)\nhttps://bugs.webkit.org/1234\n\nReviewed by Tim Contributor.')
     169
     170        self.assertEqual(commits[1].hash, '53ea230fcedbce327eb1c45a6ab65a88de864505')
     171        self.assertEqual(commits[1].message, '[scoping] Bug to fix (Part 1)\n<http://bugs.webkit.org/1234>\n\nReviewed by Tim Contributor.')
     172
    107173    def test_create_body_empty(self):
    108174        self.assertEqual(
    109175            PullRequest.create_body(None, [Commit(hash='11aa76f9fc380e9fe06157154f32b304e8dc4749')]),
    110176            '''#### 11aa76f9fc380e9fe06157154f32b304e8dc4749
    111 ```
     177<pre>
    112178???
    113 ```''',
     179</pre>''',
    114180        )
    115181
     
    124190        self.assertEqual(commits[0].message, None)
    125191
     192    def test_parse_html_body_empty(self):
     193        body, commits = PullRequest.parse_body('''#### 11aa76f9fc380e9fe06157154f32b304e8dc4749
     194<pre>
     195???
     196</pre>''')
     197        self.assertIsNone(body)
     198        self.assertEqual(len(commits), 1)
     199        self.assertEqual(commits[0].hash, '11aa76f9fc380e9fe06157154f32b304e8dc4749')
     200        self.assertEqual(commits[0].message, None)
     201
    126202    def test_create_body_comment(self):
    127203        self.assertEqual(
     
    133209----------------------------------------------------------------------
    134210#### 11aa76f9fc380e9fe06157154f32b304e8dc4749
    135 ```
    136 [scoping] Bug to fix
    137 
    138 Reviewed by Tim Contributor.
    139 ```''',
     211<pre>
     212[scoping] Bug to fix
     213
     214Reviewed by Tim Contributor.
     215</pre>''',
    140216        )
    141217
     
    150226Reviewed by Tim Contributor.
    151227```''')
     228        self.assertEqual(body, 'Comment body')
     229        self.assertEqual(len(commits), 1)
     230        self.assertEqual(commits[0].hash, '11aa76f9fc380e9fe06157154f32b304e8dc4749')
     231        self.assertEqual(commits[0].message, '[scoping] Bug to fix\n\nReviewed by Tim Contributor.')
     232
     233    def test_parse_html_body_single(self):
     234        body, commits = PullRequest.parse_body('''Comment body
     235
     236----------------------------------------------------------------------
     237#### 11aa76f9fc380e9fe06157154f32b304e8dc4749
     238<pre>
     239[scoping] Bug to fix
     240
     241Reviewed by Tim Contributor.
     242</pre>''')
    152243        self.assertEqual(body, 'Comment body')
    153244        self.assertEqual(len(commits), 1)
Note: See TracChangeset for help on using the changeset viewer.