WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
[patch]
Patch
bug-217732-20201203141340.patch (text/plain), 25.46 KB, created by
Jonathan Bedard
on 2020-12-03 12:13:41 PST
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Jonathan Bedard
Created:
2020-12-03 12:13:41 PST
Size:
25.46 KB
patch
obsolete
>Index: Tools/ChangeLog >=================================================================== >--- Tools/ChangeLog (revision 270400) >+++ Tools/ChangeLog (working copy) >@@ -1,3 +1,65 @@ >+2020-12-03 Jonathan Bedard <jbedard@apple.com> >+ >+ [git-webkit] Use contributors.json >+ https://bugs.webkit.org/show_bug.cgi?id=217732 >+ <rdar://problem/70309518> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ The interaction between Git, Svn and old commits means that our canonical record of >+ commit authors is somewhat incomplete. contributors.json has most of the information >+ we are missing, we should rely on it to map non-standard author names to their canonical >+ names and email addresses. >+ >+ Additionally, making the record of Contributors owned by the repository instead of being global >+ to the entire process. >+ >+ * Scripts/git-webkit: Parse contributors.json and add it to a Contributor.Bank mapping. >+ * Scripts/libraries/webkitscmpy/webkitscmpy/__init__.py: Bump version. >+ * Scripts/libraries/webkitscmpy/webkitscmpy/commit.py: >+ (Commit): Contributor class object no longer owns record of contributors. >+ * Scripts/libraries/webkitscmpy/webkitscmpy/contributor.py: >+ (Contributor): >+ (Contributor.Bank): Dictionary mapping Contributors and their potential aliases. >+ (Contributor.Bank.__init__): >+ (Contributor.Bank.add): Add Contributor to bank. >+ (Contributor.Bank.create): Find or create a contributor with the specified name and email >+ addresses and bind it to the record of contributors. >+ (Contributor.from_scm_log): Leverage Contributor.Bank provided by caller. >+ (Contributor.clear): Deleted. >+ * Scripts/libraries/webkitscmpy/webkitscmpy/local/git.py: >+ (Git.__init__): Instantiate repository with existing Contributor.Bank. >+ (Git.commit): Repository now owns the record of contributors. >+ * Scripts/libraries/webkitscmpy/webkitscmpy/local/scm.py: >+ (Scm.from_path): Instantiate repository with existing Contributor.Bank. >+ (Scm.__init__): Ditto. >+ * Scripts/libraries/webkitscmpy/webkitscmpy/local/svn.py: >+ (Svn.__init__): Instantiate repository with existing Contributor.Bank. >+ (Svn.commit): Repository now owns the record of contributors. >+ * Scripts/libraries/webkitscmpy/webkitscmpy/program.py: >+ (main): Allow caller to pass an existing record of contributors. >+ * Scripts/libraries/webkitscmpy/webkitscmpy/remote/scm.py: >+ (Scm.from_url): Instantiate repository with existing Contributor.Bank. >+ (Scm.__init__): Ditto. >+ * Scripts/libraries/webkitscmpy/webkitscmpy/remote/svn.py: >+ (Svn.__init__): Instantiate repository with existing Contributor.Bank. >+ (Svn.commit): Repository now owns the record of contributors. >+ * Scripts/libraries/webkitscmpy/webkitscmpy/scm_base.py: >+ (ScmBase.__init__): Instantiate repository with existing Contributor.Bank. >+ * Scripts/libraries/webkitscmpy/webkitscmpy/test/commit_unittest.py: >+ * Scripts/libraries/webkitscmpy/webkitscmpy/test/contributor_unittest.py: >+ (TestContributor.test_git_log): No more global contributor record. >+ (TestContributor.test_git_svn_log): Ditto. >+ (TestContributor.test_git_no_author): Ditto. >+ (TestContributor.test_git_svn_no_author): Ditto. >+ (TestContributor.test_svn_log): Ditto. >+ (TestContributor.test_short_svn_log): Ditto. >+ (TestContributor.test_svn_patch_by_log): Ditto. >+ (TestContributor.test_author_mapping): Contributor record is owned by the caller of the caller >+ of Contributor management. >+ (TestContributor.test_email_mapping): Ditto. >+ (TestContributor.test_invalid_log): No more global contributor record. >+ > 2020-12-02 Tim Horton <timothy_horton@apple.com> > > Many different assertion failures on the GPU process bot after r270366 >Index: Tools/Scripts/git-webkit >=================================================================== >--- Tools/Scripts/git-webkit (revision 270400) >+++ Tools/Scripts/git-webkit (working copy) >@@ -23,10 +23,24 @@ > # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. > > import os >-import webkitpy > import sys > >-from webkitscmpy import program >+from webkitpy.common.config.committers import CommitterList >+from webkitscmpy import program, Contributor > >-sys.exit(program.main(path=os.path.dirname(__file__))) >+ >+bank = Contributor.Bank() >+for contributor in CommitterList().contributors(): >+ c = bank.create(contributor.full_name, *contributor.emails) >+ if not c: >+ continue >+ for alias in contributor.aliases or []: >+ if alias not in bank: >+ bank[alias] = c >+ for nick in contributor.irc_nicknames or []: >+ if nick not in bank: >+ bank[nick] = c >+ >+ >+sys.exit(program.main(path=os.path.dirname(__file__), contributors=bank)) > >Index: Tools/Scripts/libraries/webkitscmpy/webkitscmpy/__init__.py >=================================================================== >--- Tools/Scripts/libraries/webkitscmpy/webkitscmpy/__init__.py (revision 270400) >+++ Tools/Scripts/libraries/webkitscmpy/webkitscmpy/__init__.py (working copy) >@@ -46,7 +46,7 @@ except ImportError: > "Please install webkitcorepy with `pip install webkitcorepy --extra-index-url <package index URL>`" > ) > >-version = Version(0, 4, 4) >+version = Version(0, 5, 0) > > AutoInstall.register(Package('dateutil', Version(2, 8, 1), pypi_name='python-dateutil')) > AutoInstall.register(Package('fasteners', Version(0, 15, 0))) >Index: Tools/Scripts/libraries/webkitscmpy/webkitscmpy/commit.py >=================================================================== >--- Tools/Scripts/libraries/webkitscmpy/webkitscmpy/commit.py (revision 270400) >+++ Tools/Scripts/libraries/webkitscmpy/webkitscmpy/commit.py (working copy) >@@ -187,14 +187,7 @@ class Commit(object): > raise TypeError("Expected 'timestamp' to be of type int, got '{}'".format(timestamp)) > self.timestamp = timestamp > >- if author and isinstance(author, six.string_types): >- self.author = Contributor.by_email.get( >- author, >- Contributor.by_name.get(author), >- ) >- if not self.author: >- raise ValueError("'{}' does not match a known contributor") >- elif author and isinstance(author, dict) and author.get('name'): >+ if author and isinstance(author, dict) and author.get('name'): > self.author = Contributor(author.get('name'), author.get('emails')) > elif author and not isinstance(author, Contributor): > raise TypeError("Expected 'author' to be of type {}, got '{}'".format(Contributor, author)) >Index: Tools/Scripts/libraries/webkitscmpy/webkitscmpy/contributor.py >=================================================================== >--- Tools/Scripts/libraries/webkitscmpy/webkitscmpy/contributor.py (revision 270400) >+++ Tools/Scripts/libraries/webkitscmpy/webkitscmpy/contributor.py (working copy) >@@ -23,6 +23,7 @@ > import json > import re > >+from collections import defaultdict > from webkitcorepy import string_utils > > >@@ -32,9 +33,6 @@ class Contributor(object): > SVN_AUTHOR_RE = re.compile(r'r\d+ \| (?P<email>.*) \| (?P<date>.*) \| \d+ lines?') > SVN_PATCH_FROM_RE = re.compile(r'Patch by (?P<author>.*) <(?P<email>.*)> on \d+-\d+-\d+') > >- by_email = dict() >- by_name = dict() >- > class Encoder(json.JSONEncoder): > > def default(self, obj): >@@ -47,13 +45,43 @@ class Contributor(object): > > return result > >- @classmethod >- def clear(cls): >- cls.by_email = dict() >- cls.by_name = dict() >+ class Bank(defaultdict): >+ def __init__(self): >+ super(Contributor.Bank, self).__init__(lambda: None) >+ >+ def add(self, contributor): >+ if not isinstance(contributor, Contributor): >+ raise ValueError("'{}' is not a Contributor object".format(type(contributor))) >+ return self.create(name=contributor.name, *contributor.emails) >+ >+ def create(self, name=None, *emails): >+ emails = [email for email in emails or []] >+ if not name and not emails: >+ return None >+ >+ contributor = None >+ for argument in [name] + (emails or []): >+ contributor = self[argument] >+ if contributor: >+ break >+ >+ if contributor: >+ for email in emails or []: >+ if email not in contributor.emails: >+ contributor.emails.append(email) >+ if contributor.name in contributor.emails and name: >+ contributor.name = name >+ else: >+ contributor = Contributor(name or emails[0], emails=emails) >+ >+ self[contributor.name] = contributor >+ for email in contributor.emails or []: >+ self[email] = contributor >+ return contributor >+ > > @classmethod >- def from_scm_log(cls, line): >+ def from_scm_log(cls, line, bank=None): > email = None > author = None > >@@ -75,18 +103,9 @@ class Contributor(object): > if not email and not author: > return None > >- contributor = cls.by_name.get(author or email) >- if not contributor: >- contributor = cls.by_email.get(email) >- >- if not contributor: >- contributor = cls(author or email, emails=[email]) >- cls.by_name[contributor.name] = contributor >- elif email not in contributor.emails: >- contributor.emails.append(email) >- >- cls.by_name[email] = contributor >- return contributor >+ if bank is not None: >+ return bank.create(author, email) >+ return cls(author or email, emails=[email]) > > def __init__(self, name, emails=None): > self.name = string_utils.decode(name) >Index: Tools/Scripts/libraries/webkitscmpy/webkitscmpy/program.py >=================================================================== >--- Tools/Scripts/libraries/webkitscmpy/webkitscmpy/program.py (revision 270400) >+++ Tools/Scripts/libraries/webkitscmpy/webkitscmpy/program.py (working copy) >@@ -162,7 +162,7 @@ class Checkout(Command): > return 0 > > >-def main(args=None, path=None, loggers=None): >+def main(args=None, path=None, loggers=None, contributors=None): > logging.basicConfig(level=logging.WARNING) > > loggers = [logging.getLogger(), webkitcorepy_log, log] + (loggers or []) >@@ -191,8 +191,8 @@ def main(args=None, path=None, loggers=N > parsed = parser.parse_args(args=args) > > if parsed.repository.startswith(('https://', 'http://')): >- repository = remote.Scm.from_url(parsed.repository) >+ repository = remote.Scm.from_url(parsed.repository, contributors=contributors) > else: >- repository = local.Scm.from_path(path=parsed.repository) >+ repository = local.Scm.from_path(path=parsed.repository, contributors=contributors) > > return parsed.main(args=parsed, repository=repository) >Index: Tools/Scripts/libraries/webkitscmpy/webkitscmpy/scm_base.py >=================================================================== >--- Tools/Scripts/libraries/webkitscmpy/webkitscmpy/scm_base.py (revision 270400) >+++ Tools/Scripts/libraries/webkitscmpy/webkitscmpy/scm_base.py (working copy) >@@ -26,7 +26,7 @@ import six > import sys > > from logging import NullHandler >-from webkitscmpy import Commit, log >+from webkitscmpy import Commit, Contributor, log > > > class ScmBase(object): >@@ -38,10 +38,11 @@ class ScmBase(object): > DEV_BRANCHES = re.compile(r'.*[(eng)(dev)(bug)]/.+') > PROD_BRANCHES = re.compile(r'\S+-[\d+\.]+-branch') > >- def __init__(self, dev_branches=None, prod_branches=None): >+ def __init__(self, dev_branches=None, prod_branches=None, contributors=None): > self.dev_branches = dev_branches or self.DEV_BRANCHES > self.prod_branches = prod_branches or self.PROD_BRANCHES > self.path = None >+ self.contributors = Contributor.Bank() if contributors is None else None > > @property > def is_svn(self): >Index: Tools/Scripts/libraries/webkitscmpy/webkitscmpy/local/git.py >=================================================================== >--- Tools/Scripts/libraries/webkitscmpy/webkitscmpy/local/git.py (revision 270400) >+++ Tools/Scripts/libraries/webkitscmpy/webkitscmpy/local/git.py (working copy) >@@ -42,8 +42,8 @@ class Git(Scm): > def is_checkout(cls, path): > return run([cls.executable(), 'rev-parse', '--show-toplevel'], cwd=path, capture_output=True).returncode == 0 > >- def __init__(self, path, dev_branches=None, prod_branches=None): >- super(Git, self).__init__(path, dev_branches=dev_branches, prod_branches=prod_branches) >+ def __init__(self, path, dev_branches=None, prod_branches=None, contributors=None): >+ super(Git, self).__init__(path, dev_branches=dev_branches, prod_branches=prod_branches, contributors=contributors) > if not self.root_path: > raise OSError('Provided path {} is not a git repository'.format(path)) > >@@ -265,7 +265,7 @@ class Git(Scm): > branch_point=branch_point, > branch=branch, > timestamp=int(commit_time.stdout.lstrip()), >- author=Contributor.from_scm_log(log.stdout.splitlines()[1]), >+ author=Contributor.from_scm_log(log.stdout.splitlines()[1], self.contributors), > message='\n'.join(line[4:] for line in log.stdout.splitlines()[4:]) if include_log else None, > ) > >Index: Tools/Scripts/libraries/webkitscmpy/webkitscmpy/local/scm.py >=================================================================== >--- Tools/Scripts/libraries/webkitscmpy/webkitscmpy/local/scm.py (revision 270400) >+++ Tools/Scripts/libraries/webkitscmpy/webkitscmpy/local/scm.py (working copy) >@@ -48,17 +48,17 @@ class Scm(ScmBase): > raise OSError("Cannot find '{}' program".format(program)) > > @classmethod >- def from_path(cls, path): >+ def from_path(cls, path, contributors=None): > from webkitscmpy import local > > if local.Git.is_checkout(path): >- return local.Git(path) >+ return local.Git(path, contributors=contributors) > if local.Svn.is_checkout(path): >- return local.Svn(path) >+ return local.Svn(path, contributors=contributors) > raise OSError("'{}' is not a known SCM type".format(path)) > >- def __init__(self, path, dev_branches=None, prod_branches=None): >- super(Scm, self).__init__(dev_branches=dev_branches, prod_branches=prod_branches) >+ def __init__(self, path, dev_branches=None, prod_branches=None, contributors=None): >+ super(Scm, self).__init__(dev_branches=dev_branches, prod_branches=prod_branches, contributors=contributors) > > if not isinstance(path, six.string_types): > raise ValueError("Expected 'path' to be a string type, not '{}'".format(type(path))) >Index: Tools/Scripts/libraries/webkitscmpy/webkitscmpy/local/svn.py >=================================================================== >--- Tools/Scripts/libraries/webkitscmpy/webkitscmpy/local/svn.py (revision 270400) >+++ Tools/Scripts/libraries/webkitscmpy/webkitscmpy/local/svn.py (working copy) >@@ -50,8 +50,8 @@ class Svn(Scm): > def is_checkout(cls, path): > return run([cls.executable(), 'info'], cwd=path, capture_output=True).returncode == 0 > >- def __init__(self, path, dev_branches=None, prod_branches=None): >- super(Svn, self).__init__(path, dev_branches=dev_branches, prod_branches=prod_branches) >+ def __init__(self, path, dev_branches=None, prod_branches=None, contributors=None): >+ super(Svn, self).__init__(path, dev_branches=dev_branches, prod_branches=prod_branches, contributors=contributors) > > self._root_path = self.path > self._root_path = self.info(cached=False).get('Working Copy Root Path') >@@ -370,19 +370,13 @@ class Svn(Scm): > author_line = line > break > >- author = Contributor.from_scm_log(author_line) >+ author = Contributor.from_scm_log(author_line, self.contributors) > message = '\n'.join(split_log[3:-1]) > else: > if include_log: > self.log('Failed to connect to remote, cannot compute commit message') > email = info.get('Last Changed Author') >- author = Contributor.by_email.get( >- email, >- Contributor.by_name.get( >- email, >- Contributor(name=email, emails=[email]), >- ), >- ) if email else None >+ author = self.contributors.create(email, email) if '@' in email else self.contributors.create(email) > message = None > > return Commit( >Index: Tools/Scripts/libraries/webkitscmpy/webkitscmpy/remote/scm.py >=================================================================== >--- Tools/Scripts/libraries/webkitscmpy/webkitscmpy/remote/scm.py (revision 270400) >+++ Tools/Scripts/libraries/webkitscmpy/webkitscmpy/remote/scm.py (working copy) >@@ -27,15 +27,15 @@ from webkitscmpy.scm_base import ScmBase > > class Scm(ScmBase): > @classmethod >- def from_url(cls, url): >+ def from_url(cls, url, contributors=None): > from webkitscmpy import remote > > if remote.Svn.is_webserver(url): >- return remote.Svn(url) >+ return remote.Svn(url, contributors=contributors) > raise OSError("'{}' is not a known SCM server".format(url)) > >- def __init__(self, url, dev_branches=None, prod_branches=None): >- super(Scm, self).__init__(dev_branches=dev_branches, prod_branches=prod_branches) >+ def __init__(self, url, dev_branches=None, prod_branches=None, contributors=None): >+ super(Scm, self).__init__(dev_branches=dev_branches, prod_branches=prod_branches, contributors=contributors) > > if not isinstance(url, six.string_types): > raise ValueError("Expected 'url' to be a string type, not '{}'".format(type(url))) >Index: Tools/Scripts/libraries/webkitscmpy/webkitscmpy/remote/svn.py >=================================================================== >--- Tools/Scripts/libraries/webkitscmpy/webkitscmpy/remote/svn.py (revision 270400) >+++ Tools/Scripts/libraries/webkitscmpy/webkitscmpy/remote/svn.py (working copy) >@@ -46,12 +46,12 @@ class Svn(Scm): > def is_webserver(cls, url): > return True if cls.URL_RE.match(url) else False > >- def __init__(self, url, dev_branches=None, prod_branches=None): >+ def __init__(self, url, dev_branches=None, prod_branches=None, contributors=None): > if url[-1] != '/': > url += '/' > if not self.is_webserver(url): > raise self.Exception("'{}' is not a valid SVN webserver".format(url)) >- super(Svn, self).__init__(url, dev_branches=dev_branches, prod_branches=prod_branches) >+ super(Svn, self).__init__(url, dev_branches=dev_branches, prod_branches=prod_branches, contributors=contributors) > > if os.path.exists(self._cache_path): > try: >@@ -426,13 +426,7 @@ class Svn(Scm): > message = None > name = info.get('Last Changed Author') > >- author = Contributor.by_email.get( >- name, >- Contributor.by_name.get( >- name, >- Contributor(name=name, emails=[name] if '@' in name else []), >- ), >- ) if name else None >+ author = self.contributors.create(name, name) if '@' in name else self.contributors.create(name) > > return Commit( > revision=int(revision), >Index: Tools/Scripts/libraries/webkitscmpy/webkitscmpy/test/commit_unittest.py >=================================================================== >--- Tools/Scripts/libraries/webkitscmpy/webkitscmpy/test/commit_unittest.py (revision 270400) >+++ Tools/Scripts/libraries/webkitscmpy/webkitscmpy/test/commit_unittest.py (working copy) >@@ -195,21 +195,16 @@ PRINTED > Commit(revision=1, timestamp=100).__cmp__(Commit(identifier=2, timestamp=100)) > > def test_contributor(self): >- Contributor.clear() > contributor = Contributor.from_scm_log('Author: Jonathan Bedard <jbedard@apple.com>') > > commit = Commit(revision=1, identifier=1, author=contributor) > self.assertEqual(commit.author, contributor) > >- commit = Commit(revision=1, identifier=1, author='Jonathan Bedard') >- self.assertEqual(commit.author, contributor) >- >- commit = Commit(revision=1, identifier=1, author='jbedard@apple.com') >+ commit = Commit(revision=1, identifier=1, author=Contributor.Encoder().default(contributor)) > self.assertEqual(commit.author, contributor) > > def test_invalid_contributor(self): >- Contributor.clear() >- with self.assertRaises(ValueError): >+ with self.assertRaises(TypeError): > Commit(revision=1, identifier=1, author='Jonathan Bedard') > > def test_branch_point(self): >@@ -218,7 +213,6 @@ PRINTED > self.assertEqual('1234.0@branch-a', str(Commit(branch_point=1234, identifier=0, branch='branch-a'))) > > def test_json_encode(self): >- Contributor.clear() > contributor = Contributor.from_scm_log('Author: Jonathan Bedard <jbedard@apple.com>') > > self.assertDictEqual( >@@ -243,7 +237,6 @@ PRINTED > ) > > def test_json_decode(self): >- Contributor.clear() > contributor = Contributor.from_scm_log('Author: Jonathan Bedard <jbedard@apple.com>') > > commit_a = Commit( >@@ -251,7 +244,7 @@ PRINTED > hash='c3bd784f8b88bd03f64467ddd3304ed8be28acbe', > identifier='1@main', > timestamp=1000, >- author=contributor, >+ author=Contributor.Encoder().default(contributor), > message='Message' > ) > >Index: Tools/Scripts/libraries/webkitscmpy/webkitscmpy/test/contributor_unittest.py >=================================================================== >--- Tools/Scripts/libraries/webkitscmpy/webkitscmpy/test/contributor_unittest.py (revision 270400) >+++ Tools/Scripts/libraries/webkitscmpy/webkitscmpy/test/contributor_unittest.py (working copy) >@@ -29,68 +29,60 @@ from webkitscmpy import Contributor > > class TestContributor(unittest.TestCase): > def test_git_log(self): >- Contributor.clear() > contributor = Contributor.from_scm_log('Author: Jonathan Bedard <jbedard@apple.com>') > > self.assertEqual(contributor.name, 'Jonathan Bedard') > self.assertEqual(contributor.emails, ['jbedard@apple.com']) > > def test_git_svn_log(self): >- Contributor.clear() > contributor = Contributor.from_scm_log('Author: Jonathan Bedard <jbedard@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>') > > self.assertEqual(contributor.name, 'Jonathan Bedard') > self.assertEqual(contributor.emails, ['jbedard@apple.com']) > > def test_git_no_author(self): >- Contributor.clear() > contributor = Contributor.from_scm_log('Author: Automated Checkin <devnull>') > self.assertIsNone(contributor) > > def test_git_svn_no_author(self): >- Contributor.clear() > contributor = Contributor.from_scm_log('Author: (no author) <(no author)@268f45cc-cd09-0410-ab3c-d52691b4dbfc>') > self.assertIsNone(contributor) > > def test_svn_log(self): >- Contributor.clear() > contributor = Contributor.from_scm_log('r266751 | jbedard@apple.com | 2020-09-08 14:33:42 -0700 (Tue, 08 Sep 2020) | 10 lines') > > self.assertEqual(contributor.name, 'jbedard@apple.com') > self.assertEqual(contributor.emails, ['jbedard@apple.com']) > > def test_short_svn_log(self): >- Contributor.clear() > contributor = Contributor.from_scm_log('r266751 | jbedard@apple.com | 2020-09-08 14:33:42 -0700 (Tue, 08 Sep 2020) | 1 line') > > self.assertEqual(contributor.name, 'jbedard@apple.com') > self.assertEqual(contributor.emails, ['jbedard@apple.com']) > > def test_svn_patch_by_log(self): >- Contributor.clear() > contributor = Contributor.from_scm_log('Patch by Jonathan Bedard <jbedard@apple.com> on 2020-09-10') > > self.assertEqual(contributor.name, 'Jonathan Bedard') > self.assertEqual(contributor.emails, ['jbedard@apple.com']) > > def test_author_mapping(self): >- Contributor.clear() >- Contributor.from_scm_log('Author: Jonathan Bedard <jbedard@apple.com>') >- contributor = Contributor.from_scm_log('Author: Jonathan Bedard <jbedard@webkit.org>') >+ bank = Contributor.Bank() >+ Contributor.from_scm_log('Author: Jonathan Bedard <jbedard@apple.com>', bank) >+ contributor = Contributor.from_scm_log('Author: Jonathan Bedard <jbedard@webkit.org>', bank) > > self.assertEqual(contributor.name, 'Jonathan Bedard') > self.assertEqual(contributor.emails, ['jbedard@apple.com', 'jbedard@webkit.org']) > > def test_email_mapping(self): >- Contributor.clear() >- Contributor.from_scm_log('Author: Jonathan Bedard <jbedard@apple.com>') >- contributor = Contributor.from_scm_log('r266751 | jbedard@apple.com | 2020-09-08 14:33:42 -0700 (Tue, 08 Sep 2020) | 10 lines') >+ bank = Contributor.Bank() >+ Contributor.from_scm_log('Author: Jonathan Bedard <jbedard@apple.com>', bank) >+ contributor = Contributor.from_scm_log('r266751 | jbedard@apple.com | 2020-09-08 14:33:42 -0700 (Tue, 08 Sep 2020) | 10 lines', bank) > > self.assertEqual(contributor.name, 'Jonathan Bedard') > self.assertEqual(contributor.emails, ['jbedard@apple.com']) > > def test_invalid_log(self): >- Contributor.clear() > with self.assertRaises(ValueError): > Contributor.from_scm_log('Jonathan Bedard <jbedard@apple.com>') >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 217732
:
411376
|
415322
|
415323
|
415416