Example #1
0
    def _assign_bug_to_last_patch_attacher(self, bug_id):
        committers = CommitterList()
        bug = self._tool.bugs.fetch_bug(bug_id)
        if not bug.is_unassigned():
            assigned_to_email = bug.assigned_to_email()
            _log.info(u"Bug %s is already assigned to %s (%s)." % (bug_id, assigned_to_email, committers.committer_by_email(assigned_to_email)))
            return

        reviewed_patches = bug.reviewed_patches()
        if not reviewed_patches:
            _log.info("Bug %s has no non-obsolete patches, ignoring." % bug_id)
            return

        # We only need to do anything with this bug if one of the r+'d patches does not have a valid committer (cq+ set).
        if self._patches_have_commiters(reviewed_patches):
            _log.info("All reviewed patches on bug %s already have commit-queue+, ignoring." % bug_id)
            return

        latest_patch = reviewed_patches[-1]
        attacher_email = latest_patch.attacher_email()
        committer = committers.committer_by_email(attacher_email)
        if not committer:
            _log.info("Attacher %s is not a committer.  Bug %s likely needs commit-queue+." % (attacher_email, bug_id))
            return

        reassign_message = u"Attachment %s was posted by a committer and has review+, assigning to %s for commit." % (latest_patch.id(), committer.full_name)
        self._tool.bugs.reassign_bug(bug_id, committer.bugzilla_email(), reassign_message)
Example #2
0
    def _assign_bug_to_last_patch_attacher(self, bug_id):
        committers = CommitterList()
        bug = self._tool.bugs.fetch_bug(bug_id)
        if not bug.is_unassigned():
            assigned_to_email = bug.assigned_to_email()
            log("Bug %s is already assigned to %s (%s)." % (bug_id, assigned_to_email, committers.committer_by_email(assigned_to_email)))
            return

        reviewed_patches = bug.reviewed_patches()
        if not reviewed_patches:
            log("Bug %s has no non-obsolete patches, ignoring." % bug_id)
            return

        # We only need to do anything with this bug if one of the r+'d patches does not have a valid committer (cq+ set).
        if self._patches_have_commiters(reviewed_patches):
            log("All reviewed patches on bug %s already have commit-queue+, ignoring." % bug_id)
            return

        latest_patch = reviewed_patches[-1]
        attacher_email = latest_patch.attacher_email()
        committer = committers.committer_by_email(attacher_email)
        if not committer:
            log("Attacher %s is not a committer.  Bug %s likely needs commit-queue+." % (attacher_email, bug_id))
            return

        reassign_message = "Attachment %s was posted by a committer and has review+, assigning to %s for commit." % (latest_patch.id(), committer.full_name)
        self._tool.bugs.reassign_bug(bug_id, committer.bugzilla_email(), reassign_message)
 def _assert_fuzz_match(self, text, name_of_expected_contributor, expected_distance):
     committers = CommitterList()
     contributors, distance = committers.contributors_by_fuzzy_match(text)
     if type(name_of_expected_contributor) is list:
         expected_names = name_of_expected_contributor
     else:
         expected_names = [name_of_expected_contributor] if name_of_expected_contributor else []
     self.assertEqual(([contributor.full_name for contributor in contributors], distance), (expected_names, expected_distance))
Example #4
0
 def _assert_fuzz_match(self, text, name_of_expected_contributor, expected_distance):
     committers = CommitterList()
     contributors, distance = committers.contributors_by_fuzzy_match(text)
     if type(name_of_expected_contributor) is list:
         expected_names = name_of_expected_contributor
     else:
         expected_names = [name_of_expected_contributor] if name_of_expected_contributor else []
     self.assertEqual(([contributor.full_name for contributor in contributors], distance), (expected_names, expected_distance))
Example #5
0
 def __init__(self, options=None):
     options = options or []
     options += [
         make_option("--max-commit-age", action="store", dest="max_commit_age", type="int", default=9, help="Specify maximum commit age to consider (in months)."),
     ]
     options = sorted(options, cmp=lambda a, b: cmp(a._long_opts, b._long_opts))
     super(AbstractCommitLogCommand, self).__init__(options=options)
     # FIXME: This should probably be on the tool somewhere.
     self._committer_list = CommitterList()
Example #6
0
    def __init__(self):
        options = [
            make_option("--committer-minimum", action="store", dest="committer_minimum", type="int", default=10, help="Specify minimum patch count for Committer nominations."),
            make_option("--reviewer-minimum", action="store", dest="reviewer_minimum", type="int", default=80, help="Specify minimum patch count for Reviewer nominations."),
            make_option("--max-commit-age", action="store", dest="max_commit_age", type="int", default=9, help="Specify max commit age to consider for nominations (in months)."),
            make_option("--show-commits", action="store_true", dest="show_commits", default=False, help="Show commit history with nomination suggestions."),
        ]

        AbstractDeclarativeCommand.__init__(self, options=options)
        # FIXME: This should probably be on the tool somewhere.
        self._committer_list = CommitterList()
Example #7
0
    def test_commit_info_creation(self):
        author = Committer("Author", "*****@*****.**")
        committer = Committer("Committer", "*****@*****.**")
        reviewer = Reviewer("Reviewer", "*****@*****.**")
        committer_list = CommitterList(committers=[author, committer],
                                       reviewers=[reviewer])

        changelog_data = {
            "bug_id": 1234,
            "author_name": "Committer",
            "author_email": "*****@*****.**",
            "author": author,
            "reviewer_text": "Reviewer",
            "reviewer": reviewer,
        }
        commit = CommitInfo(123, "*****@*****.**", changelog_data,
                            committer_list)

        self.assertEqual(commit.revision(), 123)
        self.assertEqual(commit.bug_id(), 1234)
        self.assertEqual(commit.author_name(), "Committer")
        self.assertEqual(commit.author_email(), "*****@*****.**")
        self.assertEqual(commit.author(), author)
        self.assertEqual(commit.reviewer_text(), "Reviewer")
        self.assertEqual(commit.reviewer(), reviewer)
        self.assertEqual(commit.committer(), committer)
        self.assertEqual(commit.committer_email(), "*****@*****.**")
        self.assertEqual(commit.responsible_parties(),
                         set([author, committer, reviewer]))
Example #8
0
 def execute(self, nick, args, tool, sheriff):
     if not args:
         return self.usage(nick)
     search_string = unicode(" ".join(args))
     # FIXME: We should get the ContributorList off the tool somewhere.
     contributors = CommitterList().contributors_by_search_string(
         search_string)
     if not contributors:
         return unicode(
             "%s: Sorry, I don't know any contributors matching '%s'.") % (
                 nick, search_string)
     if len(contributors) > 5:
         return unicode(
             "%s: More than 5 contributors match '%s', could you be more specific?"
         ) % (nick, search_string)
     if len(contributors) == 1:
         contributor = contributors[0]
         if not contributor.irc_nicknames:
             return unicode("%s: %s hasn't told me their nick. Boo hoo :-("
                            ) % (nick, contributor)
         return unicode("%s: %s is %s. Why do you ask?") % (
             nick, search_string, self._full_record_and_nick(contributor))
     contributor_nicks = map(self._full_record_and_nick, contributors)
     contributors_string = join_with_separators(contributor_nicks,
                                                only_two_separator=" or ",
                                                last_separator=', or ')
     return unicode("%s: I'm not sure who you mean?  %s could be '%s'.") % (
         nick, contributors_string, search_string)
Example #9
0
 def execute(self, nick, args, tool, sheriff):
     if len(args) != 1:
         return "%s: Usage: whois SEARCH_STRING" % nick
     search_string = args[0]
     # FIXME: We should get the ContributorList off the tool somewhere.
     contributors = CommitterList().contributors_by_search_string(
         search_string)
     if not contributors:
         return "%s: Sorry, I don't know any contributors matching '%s'." % (
             nick, search_string)
     if len(contributors) > 5:
         return "%s: More than 5 contributors match '%s', could you be more specific?" % (
             nick, search_string)
     if len(contributors) == 1:
         contributor = contributors[0]
         if not contributor.irc_nicknames:
             return "%s: %s hasn't told me their nick. Boo hoo :-(" % (
                 nick, contributor)
         if contributor.emails and search_string.lower() not in map(
                 lambda email: email.lower(), contributor.emails):
             formattedEmails = ', '.join(contributor.emails)
             return "%s: %s is %s (%s). Why do you ask?" % (
                 nick, search_string,
                 self._nick_or_full_record(contributor), formattedEmails)
         else:
             return "%s: %s is %s. Why do you ask?" % (
                 nick, search_string,
                 self._nick_or_full_record(contributor))
     contributor_nicks = map(self._nick_or_full_record, contributors)
     contributors_string = join_with_separators(contributor_nicks,
                                                only_two_separator=" or ",
                                                last_separator=', or ')
     return "%s: I'm not sure who you mean?  %s could be '%s'." % (
         nick, contributors_string, search_string)
Example #10
0
    def __init__(self, revision, committer_email, changelog_data, committer_list=None):
        self._revision = revision
        self._committer_email = committer_email
        self._changelog_data = changelog_data

        # Derived values:
        self._committer = (committer_list or CommitterList()).committer_by_email(committer_email)
Example #11
0
    def test_commit_queue_flag(self):
        bugzilla = Bugzilla()

        bugzilla.committers = CommitterList(reviewers=[Reviewer("WebKit Reviewer", "*****@*****.**")],
            committers=[Committer("WebKit Committer", "*****@*****.**")],
            contributors=[Contributor("WebKit Contributor", "*****@*****.**")])

        def assert_commit_queue_flag(mark_for_landing, mark_for_commit_queue, expected, username=None):
            bugzilla.username = username
            capture = OutputCapture()
            capture.capture_output()
            try:
                self.assertEqual(bugzilla._commit_queue_flag(mark_for_landing=mark_for_landing, mark_for_commit_queue=mark_for_commit_queue), expected)
            finally:
                capture.restore_output()

        assert_commit_queue_flag(mark_for_landing=False, mark_for_commit_queue=False, expected='X', username='******')
        assert_commit_queue_flag(mark_for_landing=False, mark_for_commit_queue=True, expected='?', username='******')
        assert_commit_queue_flag(mark_for_landing=False, mark_for_commit_queue=True, expected='?', username='******')
        assert_commit_queue_flag(mark_for_landing=True, mark_for_commit_queue=True, expected='?', username='******')

        assert_commit_queue_flag(mark_for_landing=False, mark_for_commit_queue=False, expected='X', username='******')
        assert_commit_queue_flag(mark_for_landing=False, mark_for_commit_queue=True, expected='?', username='******')
        assert_commit_queue_flag(mark_for_landing=True, mark_for_commit_queue=False, expected='?', username='******')
        assert_commit_queue_flag(mark_for_landing=True, mark_for_commit_queue=True, expected='?', username='******')

        assert_commit_queue_flag(mark_for_landing=False, mark_for_commit_queue=False, expected='X', username='******')
        assert_commit_queue_flag(mark_for_landing=False, mark_for_commit_queue=True, expected='?', username='******')
        assert_commit_queue_flag(mark_for_landing=True, mark_for_commit_queue=False, expected='+', username='******')
        assert_commit_queue_flag(mark_for_landing=True, mark_for_commit_queue=True, expected='+', username='******')

        assert_commit_queue_flag(mark_for_landing=False, mark_for_commit_queue=False, expected='X', username='******')
        assert_commit_queue_flag(mark_for_landing=False, mark_for_commit_queue=True, expected='?', username='******')
        assert_commit_queue_flag(mark_for_landing=True, mark_for_commit_queue=False, expected='+', username='******')
        assert_commit_queue_flag(mark_for_landing=True, mark_for_commit_queue=True, expected='+', username='******')
Example #12
0
class MockCheckout(object):

    _committer_list = CommitterList()

    def commit_info_for_revision(self, svn_revision):
        return CommitInfo(svn_revision, "*****@*****.**", {
            "bug_id": 42,
            "author_name": "Adam Barth",
            "author_email": "*****@*****.**",
            "author": self._committer_list.committer_by_email("*****@*****.**"),
            "reviewer_text": "Darin Adler",
            "reviewer": self._committer_list.committer_by_name("Darin Adler"),
        })

    def bug_id_for_revision(self, svn_revision):
        return 12345

    def modified_changelogs(self, git_commit, squash):
        # Ideally we'd return something more interesting here.  The problem is
        # that LandDiff will try to actually read the patch from disk!
        return []

    def commit_message_for_this_commit(self, git_commit, squash):
        commit_message = Mock()
        commit_message.message = lambda:"This is a fake commit message that is at least 50 characters."
        return commit_message

    def apply_patch(self, patch, force=False):
        pass

    def apply_reverse_diff(self, revision):
        pass
Example #13
0
    def _summarize_commit_log(self, commit_log,
                              committer_list=CommitterList()):
        for contributor in committer_list.contributors():
            if not contributor.irc_nicknames:
                continue
            name_with_nick = "%s (%s)" % (contributor.full_name,
                                          contributor.irc_nicknames[0])
            if contributor.full_name in commit_log:
                commit_log = commit_log.replace(contributor.full_name,
                                                name_with_nick)
                for email in contributor.emails:
                    commit_log = commit_log.replace(' <' + email + '>', '')
            else:
                for email in contributor.emails:
                    commit_log = commit_log.replace(' %s ' % email,
                                                    ' %s ' % name_with_nick)

        patch_by = self._patch_by_regex.search(commit_log)
        commit_log = self._patch_by_regex.sub('', commit_log, count=1)

        revert = self._revert_regex.search(commit_log)
        commit_log = self._revert_regex.sub('', commit_log, count=1)

        requested_by = self._requested_by_regex.search(commit_log)

        commit_log = self._bugzilla_url_regex.sub(
            r'https://webkit.org/b/\g<id>', commit_log)
        commit_log = self._trac_url_regex.sub(
            r'https://trac.webkit.org/r\g<revision>', commit_log)

        lines = commit_log.split('\n')[1:-2]  # Ignore lines with ----------.

        firstline = re.match(
            r'^(?P<revision>r\d+) \| (?P<email>[^\|]+) \| (?P<timestamp>[^|]+) \| [^\n]+',
            lines[0])
        assert firstline

        author = firstline.group('email')
        if patch_by:
            author = patch_by.group('author')

        linkified_revision = 'https://trac.webkit.org/%s' % firstline.group(
            'revision')
        lines[0] = '%s by %s' % (linkified_revision, author)

        if revert:
            if requested_by:
                author = requested_by.group('author')
                contributor = committer_list.contributor_by_irc_nickname(
                    author)
                if contributor:
                    author = "%s (%s)" % (contributor.full_name,
                                          contributor.irc_nicknames[0])
                return '%s reverted %s in %s : %s' % (
                    author, revert.group('revisions'), linkified_revision,
                    requested_by.group('reason'))
            lines[0] = '%s reverted %s in %s' % (
                author, revert.group('revisions'), linkified_revision)

        return ' '.join(list(filter(lambda line: len(line), lines))[0:4])
Example #14
0
    def test_commit_queue_flag(self):
        bugzilla = Bugzilla()

        bugzilla.committers = CommitterList(
            reviewers=[Reviewer("WebKit Reviewer", "*****@*****.**")],
            committers=[Committer("WebKit Committer", "*****@*****.**")],
            contributors=[
                Contributor("WebKit Contributor", "*****@*****.**")
            ])

        def assert_commit_queue_flag(commit_flag, expected, username=None):
            bugzilla.username = username
            with OutputCapture():
                self.assertEqual(bugzilla._commit_queue_flag(commit_flag),
                                 expected)

        assert_commit_queue_flag(commit_flag=CommitQueueFlag.mark_for_nothing,
                                 expected='X',
                                 username='******')
        assert_commit_queue_flag(
            commit_flag=CommitQueueFlag.mark_for_commit_queue,
            expected='?',
            username='******')
        assert_commit_queue_flag(commit_flag=CommitQueueFlag.mark_for_landing,
                                 expected='?',
                                 username='******')

        assert_commit_queue_flag(commit_flag=CommitQueueFlag.mark_for_nothing,
                                 expected='X',
                                 username='******')
        assert_commit_queue_flag(
            commit_flag=CommitQueueFlag.mark_for_commit_queue,
            expected='?',
            username='******')
        assert_commit_queue_flag(commit_flag=CommitQueueFlag.mark_for_landing,
                                 expected='?',
                                 username='******')

        assert_commit_queue_flag(commit_flag=CommitQueueFlag.mark_for_nothing,
                                 expected='X',
                                 username='******')
        assert_commit_queue_flag(
            commit_flag=CommitQueueFlag.mark_for_commit_queue,
            expected='?',
            username='******')
        assert_commit_queue_flag(commit_flag=CommitQueueFlag.mark_for_landing,
                                 expected='+',
                                 username='******')

        assert_commit_queue_flag(commit_flag=CommitQueueFlag.mark_for_nothing,
                                 expected='X',
                                 username='******')
        assert_commit_queue_flag(
            commit_flag=CommitQueueFlag.mark_for_commit_queue,
            expected='?',
            username='******')
        assert_commit_queue_flag(commit_flag=CommitQueueFlag.mark_for_landing,
                                 expected='+',
                                 username='******')
Example #15
0
class MockCheckout(object):

    # FIXME: This should move onto the Host object, and we should use a MockCommitterList for tests.
    _committer_list = CommitterList()

    def commit_info_for_revision(self, svn_revision):
        # The real Checkout would probably throw an exception, but this is the only way tests have to get None back at the moment.
        if not svn_revision:
            return None
        return CommitInfo(
            svn_revision, "*****@*****.**", {
                "bug_id":
                50000,
                "author_name":
                "Adam Barth",
                "author_email":
                "*****@*****.**",
                "author":
                self._committer_list.contributor_by_email("*****@*****.**"),
                "reviewer_text":
                "Darin Adler",
                "reviewer":
                self._committer_list.committer_by_name("Darin Adler"),
                "changed_files": [
                    "path/to/file",
                    "another/file",
                ],
            })

    def is_path_to_changelog(self, path):
        # FIXME: This should self._filesystem.basename.
        return os.path.basename(path) == "ChangeLog"

    def bug_id_for_revision(self, svn_revision):
        return 12345

    def recent_commit_infos_for_files(self, paths):
        return [self.commit_info_for_revision(32)]

    def modified_changelogs(self, git_commit, changed_files=None):
        # Ideally we'd return something more interesting here.  The problem is
        # that LandDiff will try to actually read the patch from disk!
        return []

    def commit_message_for_this_commit(self, git_commit, changed_files=None):
        return MockCommitMessage()

    def chromium_deps(self):
        return MockDEPS()

    def apply_patch(self, patch):
        pass

    def apply_reverse_diffs(self, revision):
        pass

    def suggested_reviewers(self, git_commit, changed_files=None):
        # FIXME: We should use a shared mock commiter list.
        return [_mock_reviewers[0]]
Example #16
0
 def __init__(self,
              contents,
              committer_list=CommitterList(),
              revision=None):
     self._contents = contents
     self._committer_list = committer_list
     self._revision = revision
     self._parse_entry()
    def _validate(self, watch_list):
        cc_definitions_set = self._rule_definitions_as_set(watch_list.cc_rules)
        messages_definitions_set = self._rule_definitions_as_set(watch_list.message_rules)
        self._verify_all_definitions_are_used(watch_list, cc_definitions_set.union(messages_definitions_set))

        self._validate_definitions(cc_definitions_set, self._CC_RULES, watch_list)
        self._validate_definitions(messages_definitions_set, self._MESSAGE_RULES, watch_list)

        accounts = CommitterList()
        for cc_rule in watch_list.cc_rules:
            # Copy the instructions since we'll be remove items from the original list and
            # modifying a list while iterating through it leads to undefined behavior.
            intructions_copy = cc_rule.instructions()[:]
            for email in intructions_copy:
                if not accounts.contributor_by_email(email):
                    cc_rule.remove_instruction(email)
                    self._log_error("The email alias %s which is in the watchlist is not listed as a contributor in committers.py" % email)
                    continue
 def __init__(self, options=None):
     options = options or []
     options += [
         make_option("--max-commit-age", action="store", dest="max_commit_age", type="int", default=9, help="Specify maximum commit age to consider (in months)."),
     ]
     options = sorted(options, cmp=lambda a, b: cmp(a._long_opts, b._long_opts))
     super(AbstractCommitLogCommand, self).__init__(options=options)
     # FIXME: This should probably be on the tool somewhere.
     self._committer_list = CommitterList()
 def execute(self, nick, args, tool, sheriff):
     if len(args) != 1:
         return "%s: Usage: BUGZILLA_EMAIL" % nick
     email = args[0]
     committer = CommitterList().committer_by_email(email)
     if not committer:
         return "%s: Sorry, I don't know %s. Maybe you could introduce me?" % (nick, email)
     if not committer.irc_nickname:
         return "%s: %s hasn't told me their nick. Boo hoo :-(" % (nick, email)
     return "%s: %s is %s. Why do you ask?" % (nick, email, committer.irc_nickname)
Example #20
0
    def _needs_commit_queue(patch):
        if patch.commit_queue() == "+": # If it's already cq+, ignore the patch.
            log("%s already has cq=%s" % (patch.id(), patch.commit_queue()))
            return False

        # We only need to worry about patches from contributers who are not yet committers.
        committer_record = CommitterList().committer_by_email(patch.attacher_email())
        if committer_record:
            log("%s committer = %s" % (patch.id(), committer_record))
        return not committer_record
Example #21
0
 def check(self, lines):
     super(ContributorsChecker, self).check(lines)
     canonicalized = CommitterList().as_json()
     actual = FileSystem().read_text_file(self._file_path)
     diff = self._unidiff_output(actual, canonicalized)
     if diff:
         self._handle_style_error(
             0, 'json/syntax', 5,
             'contributors.json differs from the canonical format. Use "validate-committer-lists --canonicalize" to reformat it.'
         )
         print diff
Example #22
0
 def execute(self, options, args, tool):
     committers = CommitterList()
     for bug_id in tool.bugs.queries.fetch_bug_ids_from_pending_commit_list():
         bug = self._tool.bugs.fetch_bug(bug_id)
         patches = bug.patches(include_obsolete=True)
         for patch in patches:
             flags_to_clear = self._flags_to_clear_on_patch(patch)
             if not flags_to_clear:
                 continue
             message = u"Cleared %s from obsolete attachment %s so that this bug does not appear in http://webkit.org/pending-commit." % (flags_to_clear, patch.id())
             self._tool.bugs.obsolete_attachment(patch.id(), message)
Example #23
0
    def _validate(self, watch_list):
        cc_definitions_set = self._rule_definitions_as_set(watch_list.cc_rules)
        messages_definitions_set = self._rule_definitions_as_set(
            watch_list.message_rules)
        self._verify_all_definitions_are_used(
            watch_list, cc_definitions_set.union(messages_definitions_set))

        self._validate_definitions(cc_definitions_set, self._CC_RULES,
                                   watch_list)
        self._validate_definitions(messages_definitions_set,
                                   self._MESSAGE_RULES, watch_list)

        accounts = CommitterList()
        for cc_rule in watch_list.cc_rules:
            # Copy the instructions since we'll be remove items from the original list and
            # modifying a list while iterating through it leads to undefined behavior.
            intructions_copy = cc_rule.instructions()[:]
            for email in intructions_copy:
                if not accounts.contributor_by_email(email):
                    cc_rule.remove_instruction(email)
                    self._log_error(
                        "The email alias %s which is in the watchlist is not listed as a contributor in contributors.json"
                        % email)
                    continue
Example #24
0
    def __init__(self,
                 revision,
                 committer_email,
                 changelog_data,
                 committer_list=CommitterList()):
        self._revision = revision
        self._committer_email = committer_email
        self._bug_id = changelog_data["bug_id"]
        self._author_name = changelog_data["author_name"]
        self._author_email = changelog_data["author_email"]
        self._author = changelog_data["author"]
        self._reviewer_text = changelog_data["reviewer_text"]
        self._reviewer = changelog_data["reviewer"]

        # Derived values:
        self._committer = committer_list.committer_by_email(committer_email)
Example #25
0
class MockCheckout(object):

    _committer_list = CommitterList()

    def commit_info_for_revision(self, svn_revision):
        # The real Checkout would probably throw an exception, but this is the only way tests have to get None back at the moment.
        if not svn_revision:
            return None
        return CommitInfo(svn_revision, "*****@*****.**", {
            "bug_id": 42,
            "author_name": "Adam Barth",
            "author_email": "*****@*****.**",
            "author": self._committer_list.committer_by_email("*****@*****.**"),
            "reviewer_text": "Darin Adler",
            "reviewer": self._committer_list.committer_by_name("Darin Adler"),
        })

    def bug_id_for_revision(self, svn_revision):
        return 12345

    def recent_commit_infos_for_files(self, paths):
        return [self.commit_info_for_revision(32)]

    def modified_changelogs(self, git_commit, changed_files=None):
        # Ideally we'd return something more interesting here.  The problem is
        # that LandDiff will try to actually read the patch from disk!
        return []

    def commit_message_for_this_commit(self, git_commit, changed_files=None):
        commit_message = Mock()
        commit_message.message = lambda:"This is a fake commit message that is at least 50 characters."
        return commit_message

    def chromium_deps(self):
        return MockDEPS()

    def apply_patch(self, patch, force=False):
        pass

    def apply_reverse_diffs(self, revision):
        pass

    def suggested_reviewers(self, git_commit, changed_files=None):
        return [_mock_reviewer]
Example #26
0
 def _expand_irc_nickname(self, nick):
     contributor = CommitterList().contributor_by_irc_nickname(nick)
     if contributor:
         return str(contributor)
     return nick
class AbstractCommitLogCommand(Command):
    _leading_indent_regexp = re.compile(r"^[ ]{4}", re.MULTILINE)
    _reviewed_by_regexp = re.compile(ChangeLogEntry.reviewed_by_regexp, re.MULTILINE)
    _patch_by_regexp = re.compile(r'^Patch by (?P<name>.+?)\s+<(?P<email>[^<>]+)> on (?P<date>\d{4}-\d{2}-\d{2})$', re.MULTILINE)
    _committer_regexp = re.compile(r'^Author: (?P<email>\S+)\s+<[^>]+>$', re.MULTILINE)
    _date_regexp = re.compile(r'^Date:   (?P<date>\d{4}-\d{2}-\d{2}) (?P<time>\d{2}:\d{2}:\d{2}) [\+\-]\d{4}$', re.MULTILINE)
    _revision_regexp = re.compile(r'^git-svn-id: http://svn.webkit.org/repository/webkit/trunk@(?P<svnid>\d+) (?P<gitid>[0-9a-f\-]{36})$', re.MULTILINE)

    def __init__(self, options=None):
        options = options or []
        options += [
            make_option("--max-commit-age", action="store", dest="max_commit_age", type="int", default=9, help="Specify maximum commit age to consider (in months)."),
        ]
        options = sorted(options, cmp=lambda a, b: cmp(a._long_opts, b._long_opts))
        super(AbstractCommitLogCommand, self).__init__(options=options)
        # FIXME: This should probably be on the tool somewhere.
        self._committer_list = CommitterList()

    def _init_options(self, options):
        self.verbose = options.verbose
        self.max_commit_age = options.max_commit_age

    # FIXME: This should move to scm.py
    def _recent_commit_messages(self):
        git_log = self._tool.executive.run_command(['git', 'log', '--date=iso', '--since="%s months ago"' % self.max_commit_age])
        messages = re.compile(r"^commit \w{40}$", re.MULTILINE).split(git_log)[1:]  # Ignore the first message which will be empty.
        for message in messages:
            # Unindent all the lines
            (message, _) = self._leading_indent_regexp.subn("", message)
            yield message.lstrip()  # Remove any leading newlines from the log message.

    def _author_name_from_email(self, email):
        contributor = self._committer_list.contributor_by_email(email)
        return contributor.full_name if contributor else None

    def _contributor_from_email(self, email):
        contributor = self._committer_list.contributor_by_email(email)
        return contributor if contributor else None

    def _parse_commit_message(self, commit_message):
        committer_match = self._committer_regexp.search(commit_message)
        if not committer_match:
            raise CommitLogError

        committer_email = committer_match.group('email')
        if not committer_email:
            raise CommitLogError

        committer = self._contributor_from_email(committer_email)
        if not committer:
            raise CommitLogError

        commit_date_match = self._date_regexp.search(commit_message)
        if not commit_date_match:
            raise CommitLogError
        commit_date = commit_date_match.group('date')

        revision_match = self._revision_regexp.search(commit_message)
        if not revision_match:
            raise CommitLogError
        revision = revision_match.group('svnid')

        # Look for "Patch by" line first, which is used for non-committer contributors;
        # otherwise, use committer info determined above.
        author_match = self._patch_by_regexp.search(commit_message)
        if not author_match:
            author_match = committer_match

        author_email = author_match.group('email')
        if not author_email:
            author_email = committer_email

        author_name = author_match.group('name') if 'name' in author_match.groupdict() else None
        if not author_name:
            author_name = self._author_name_from_email(author_email)
        if not author_name:
            raise CommitLogError

        contributor = self._contributor_from_email(author_email)
        if contributor and author_name != contributor.full_name and contributor.full_name:
            author_name = contributor.full_name

        reviewer_match = self._reviewed_by_regexp.search(commit_message)
        if not reviewer_match:
            raise CommitLogMissingReviewer
        reviewers = reviewer_match.group('reviewer')

        return {
            'committer': committer,
            'commit_date': commit_date,
            'revision': revision,
            'author_email': author_email,
            'author_name': author_name,
            'contributor': contributor,
            'reviewers': reviewers,
        }
Example #28
0
class SuggestNominations(AbstractDeclarativeCommand):
    name = "suggest-nominations"
    help_text = "Suggest contributors for committer/reviewer nominations"

    def __init__(self):
        options = [
            make_option("--committer-minimum", action="store", dest="committer_minimum", type="int", default=10, help="Specify minimum patch count for Committer nominations."),
            make_option("--reviewer-minimum", action="store", dest="reviewer_minimum", type="int", default=80, help="Specify minimum patch count for Reviewer nominations."),
            make_option("--max-commit-age", action="store", dest="max_commit_age", type="int", default=9, help="Specify max commit age to consider for nominations (in months)."),
            make_option("--show-commits", action="store_true", dest="show_commits", default=False, help="Show commit history with nomination suggestions."),
        ]

        AbstractDeclarativeCommand.__init__(self, options=options)
        # FIXME: This should probably be on the tool somewhere.
        self._committer_list = CommitterList()

    _counters_by_name = {}
    _counters_by_email = {}

    def _init_options(self, options):
        self.committer_minimum = options.committer_minimum
        self.reviewer_minimum = options.reviewer_minimum
        self.max_commit_age = options.max_commit_age
        self.show_commits = options.show_commits
        self.verbose = options.verbose

    # FIXME: This should move to scm.py
    def _recent_commit_messages(self):
        git_log = self._tool.executive.run_command(['git', 'log', '--since="%s months ago"' % self.max_commit_age])
        match_git_svn_id = re.compile(r"\n\n    git-svn-id:.*\n", re.MULTILINE)
        match_get_log_lines = re.compile(r"^\S.*\n", re.MULTILINE)
        match_leading_indent = re.compile(r"^[ ]{4}", re.MULTILINE)

        messages = re.split(r"commit \w{40}", git_log)[1:]  # Ignore the first message which will be empty.
        for message in messages:
            # Remove any lines from git and unindent all the lines
            (message, _) = match_git_svn_id.subn("", message)
            (message, _) = match_get_log_lines.subn("", message)
            (message, _) = match_leading_indent.subn("", message)
            yield message.lstrip()  # Remove any leading newlines from the log message.

    # e.g. Patch by Eric Seidel <*****@*****.**> on 2011-09-15
    patch_by_regexp = r'^Patch by (?P<name>.+?)\s+<(?P<email>[^<>]+)> on (?P<date>\d{4}-\d{2}-\d{2})$'

    def _count_recent_patches(self):
        # This entire block could be written as a map/reduce over the messages.
        for message in self._recent_commit_messages():
            # FIXME: This should use ChangeLogEntry to do the entire parse instead
            # of grabbing at its regexps.
            dateline_match = re.match(ChangeLogEntry.date_line_regexp, message, re.MULTILINE)
            if not dateline_match:
                # Modern commit messages don't just dump the ChangeLog entry, but rather
                # have a special Patch by line for non-committers.
                dateline_match = re.search(self.patch_by_regexp, message, re.MULTILINE)
                if not dateline_match:
                    continue

            author_email = dateline_match.group("email")
            if not author_email:
                continue

            # We only care about reviewed patches, so make sure it has a valid reviewer line.
            reviewer_match = re.search(ChangeLogEntry.reviewed_by_regexp, message, re.MULTILINE)
            # We might also want to validate the reviewer name against the committer list.
            if not reviewer_match or not reviewer_match.group("reviewer"):
                continue

            author_name = dateline_match.group("name")
            if not author_name:
                continue

            if re.search("([^a-zA-Z]and[^a-zA-Z])|(,)|(@)", author_name):
                # This entry seems to have multiple reviewers, or invalid characters, so reject it.
                continue

            svn_id_match = re.search(ChangeLogEntry.svn_id_regexp, message, re.MULTILINE)
            if svn_id_match:
                svn_id = svn_id_match.group("svnid")
            if not svn_id_match or not svn_id:
                svn_id = "unknown"
            commit_date = dateline_match.group("date")

            # See if we already have a contributor with this name or email
            counter_by_name = self._counters_by_name.get(author_name)
            counter_by_email = self._counters_by_email.get(author_email)
            if counter_by_name:
                if counter_by_email:
                    if counter_by_name != counter_by_email:
                        # Merge these two counters  This is for the case where we had
                        # John Smith ([email protected]) and Jonathan Smith ([email protected])
                        # and just found a John Smith ([email protected]).  Now we know the
                        # two names are the same person
                        counter_by_name['names'] |= counter_by_email['names']
                        counter_by_name['emails'] |= counter_by_email['emails']
                        counter_by_name['count'] += counter_by_email.get('count', 0)
                        self._counters_by_email[author_email] = counter_by_name
                else:
                    # Add email to the existing counter
                    self._counters_by_email[author_email] = counter_by_name
                    counter_by_name['emails'] |= set([author_email])
            else:
                if counter_by_email:
                    # Add name to the existing counter
                    self._counters_by_name[author_name] = counter_by_email
                    counter_by_email['names'] |= set([author_name])
                else:
                    # Create new counter
                    new_counter = {'names': set([author_name]), 'emails': set([author_email]), 'latest_name': author_name, 'latest_email': author_email, 'commits': ""}
                    self._counters_by_name[author_name] = new_counter
                    self._counters_by_email[author_email] = new_counter

            assert(self._counters_by_name[author_name] == self._counters_by_email[author_email])
            counter = self._counters_by_name[author_name]
            counter['count'] = counter.get('count', 0) + 1

            if svn_id.isdigit():
                svn_id = "http://trac.webkit.org/changeset/" + svn_id
            counter['commits'] += "  commit: %s on %s by %s (%s)\n" % (svn_id, commit_date, author_name, author_email)

        return self._counters_by_email

    def _collect_nominations(self, counters_by_email):
        nominations = []
        for author_email, counter in counters_by_email.items():
            if author_email != counter['latest_email']:
                continue
            roles = []

            contributor = self._committer_list.contributor_by_email(author_email)

            author_name = counter['latest_name']
            patch_count = counter['count']

            if patch_count >= self.committer_minimum and (not contributor or not contributor.can_commit):
                roles.append("committer")
            if patch_count >= self.reviewer_minimum  and (not contributor or not contributor.can_review):
                roles.append("reviewer")
            if roles:
                nominations.append({
                    'roles': roles,
                    'author_name': author_name,
                    'author_email': author_email,
                    'patch_count': patch_count,
                })
        return nominations

    def _print_nominations(self, nominations):
        def nomination_cmp(a_nomination, b_nomination):
            roles_result = cmp(a_nomination['roles'], b_nomination['roles'])
            if roles_result:
                return -roles_result
            count_result = cmp(a_nomination['patch_count'], b_nomination['patch_count'])
            if count_result:
                return -count_result
            return cmp(a_nomination['author_name'], b_nomination['author_name'])

        for nomination in sorted(nominations, nomination_cmp):
            # This is a little bit of a hack, but its convienent to just pass the nomination dictionary to the formating operator.
            nomination['roles_string'] = join_with_separators(nomination['roles']).upper()
            print "%(roles_string)s: %(author_name)s (%(author_email)s) has %(patch_count)s reviewed patches" % nomination
            counter = self._counters_by_email[nomination['author_email']]

            if self.show_commits:
                print counter['commits']

    def _print_counts(self, counters_by_email):
        def counter_cmp(a_tuple, b_tuple):
            # split the tuples
            # the second element is the "counter" structure
            _, a_counter = a_tuple
            _, b_counter = b_tuple

            count_result = cmp(a_counter['count'], b_counter['count'])
            if count_result:
                return -count_result
            return cmp(a_counter['latest_name'].lower(), b_counter['latest_name'].lower())

        for author_email, counter in sorted(counters_by_email.items(), counter_cmp):
            if author_email != counter['latest_email']:
                continue
            contributor = self._committer_list.contributor_by_email(author_email)
            author_name = counter['latest_name']
            patch_count = counter['count']
            counter['names'] = counter['names'] - set([author_name])
            counter['emails'] = counter['emails'] - set([author_email])

            alias_list = []
            for alias in counter['names']:
                alias_list.append(alias)
            for alias in counter['emails']:
                alias_list.append(alias)
            if alias_list:
                print "CONTRIBUTOR: %s (%s) has %d reviewed patches %s" % (author_name, author_email, patch_count, "(aliases: " + ", ".join(alias_list) + ")")
            else:
                print "CONTRIBUTOR: %s (%s) has %d reviewed patches" % (author_name, author_email, patch_count)
        return

    def execute(self, options, args, tool):
        self._init_options(options)
        patch_counts = self._count_recent_patches()
        nominations = self._collect_nominations(patch_counts)
        self._print_nominations(nominations)
        if self.verbose:
            self._print_counts(patch_counts)
Example #29
0
    def test_committer_lookup(self):
        committer = Committer('Test One', '*****@*****.**', 'one')
        reviewer = Reviewer(
            'Test Two', ['*****@*****.**', '*****@*****.**', '*****@*****.**'])
        contributor = Contributor('Test Three', ['*****@*****.**'], 'three')
        contributor_with_two_nicknames = Contributor('Other Four',
                                                     ['*****@*****.**'],
                                                     ['four', 'otherfour'])
        committer_list = CommitterList(
            committers=[committer],
            reviewers=[reviewer],
            contributors=[contributor, contributor_with_two_nicknames])

        # Test valid committer, reviewer and contributor lookup
        self.assertEqual(committer_list.committer_by_email('*****@*****.**'),
                         committer)
        self.assertEqual(committer_list.reviewer_by_email('*****@*****.**'),
                         reviewer)
        self.assertEqual(committer_list.committer_by_email('*****@*****.**'),
                         reviewer)
        self.assertEqual(committer_list.committer_by_email('*****@*****.**'),
                         reviewer)
        self.assertEqual(committer_list.reviewer_by_email('*****@*****.**'),
                         reviewer)
        self.assertEqual(committer_list.contributor_by_email('*****@*****.**'),
                         contributor)

        # Test valid committer, reviewer and contributor lookup
        self.assertEqual(committer_list.committer_by_name("Test One"),
                         committer)
        self.assertEqual(committer_list.committer_by_name("Test Two"),
                         reviewer)
        self.assertEqual(committer_list.committer_by_name("Test Three"), None)
        self.assertEqual(committer_list.contributor_by_name("Test Three"),
                         contributor)

        # Test that the first email is assumed to be the Bugzilla email address (for now)
        self.assertEqual(
            committer_list.committer_by_email('*****@*****.**').bugzilla_email(),
            '*****@*****.**')

        # Test that a known committer is not returned during reviewer lookup
        self.assertEqual(committer_list.reviewer_by_email('*****@*****.**'),
                         None)
        self.assertEqual(committer_list.reviewer_by_email('*****@*****.**'),
                         None)
        # and likewise that a known contributor is not returned for committer lookup.
        self.assertEqual(committer_list.committer_by_email('*****@*****.**'),
                         None)

        # Test that unknown email address fail both committer and reviewer lookup
        self.assertEqual(committer_list.committer_by_email('*****@*****.**'),
                         None)
        self.assertEqual(committer_list.reviewer_by_email('*****@*****.**'), None)

        # Test that emails returns a list.
        self.assertEqual(committer.emails, ['*****@*****.**'])

        self.assertEqual(committer.irc_nicknames, ['one'])
        self.assertEqual(committer_list.contributor_by_irc_nickname('one'),
                         committer)
        self.assertEqual(committer_list.contributor_by_irc_nickname('three'),
                         contributor)
        self.assertEqual(committer_list.contributor_by_irc_nickname('four'),
                         contributor_with_two_nicknames)
        self.assertEqual(
            committer_list.contributor_by_irc_nickname('otherfour'),
            contributor_with_two_nicknames)

        # Test that the lists returned are are we expect them.
        self.assertEqual(
            committer_list.contributors(),
            [contributor, contributor_with_two_nicknames, committer, reviewer])
        self.assertEqual(committer_list.committers(), [committer, reviewer])
        self.assertEqual(committer_list.reviewers(), [reviewer])

        self.assertEqual(committer_list.contributors_by_search_string('test'),
                         [contributor, committer, reviewer])
        self.assertEqual(committer_list.contributors_by_search_string('rad'),
                         [reviewer])
        self.assertEqual(committer_list.contributors_by_search_string('Two'),
                         [reviewer])
Example #30
0
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

from .commitinfo import CommitInfo

# FIXME: These imports are wrong, we should use a shared MockCommittersList.
from webkitpy.common.config.committers import CommitterList
from webkitpy.common.net.bugzilla.bugzilla_mock import _mock_reviewers
from webkitpy.common.system.filesystem_mock import MockFileSystem


class MockCommitMessage(object):
    def message(self):
        return "This is a fake commit message that is at least 50 characters."


committer_list = CommitterList()

mock_revisions = {
    1:
    CommitInfo(
        852, "*****@*****.**", {
            "bug_id": 50000,
            "author_name": "Adam Barth",
            "author_email": "*****@*****.**",
            "author": committer_list.contributor_by_email("*****@*****.**"),
            "reviewer_text": "Darin Adler",
            "reviewer": committer_list.committer_by_name("Darin Adler"),
            "changed_files": [
                "path/to/file",
                "another/file",
            ],
Example #31
0
 def execute(self, options, args, tool):
     search_string = args[0]
     users = CommitterList().contributors_by_search_string(search_string)
     for user in users:
         print(user)
Example #32
0
class AbstractCommitLogCommand(Command):
    _leading_indent_regexp = re.compile(r"^[ ]{4}", re.MULTILINE)
    _reviewed_by_regexp = re.compile(ChangeLogEntry.reviewed_by_regexp, re.MULTILINE)
    _patch_by_regexp = re.compile(r'^Patch by (?P<name>.+?)\s+<(?P<email>[^<>]+)> on (?P<date>\d{4}-\d{2}-\d{2})$', re.MULTILINE)
    _committer_regexp = re.compile(r'^Author: (?P<email>\S+)\s+<[^>]+>$', re.MULTILINE)
    _date_regexp = re.compile(r'^Date:   (?P<date>\d{4}-\d{2}-\d{2}) (?P<time>\d{2}:\d{2}:\d{2}) [\+\-]\d{4}$', re.MULTILINE)
    _revision_regexp = re.compile(r'^git-svn-id: http://svn.webkit.org/repository/webkit/trunk@(?P<svnid>\d+) (?P<gitid>[0-9a-f\-]{36})$', re.MULTILINE)

    def __init__(self, options=None):
        options = options or []
        options += [
            make_option("--max-commit-age", action="store", dest="max_commit_age", type="int", default=9, help="Specify maximum commit age to consider (in months)."),
        ]
        options = sorted(options, cmp=lambda a, b: cmp(a._long_opts, b._long_opts))
        super(AbstractCommitLogCommand, self).__init__(options=options)
        # FIXME: This should probably be on the tool somewhere.
        self._committer_list = CommitterList()

    def _init_options(self, options):
        self.verbose = options.verbose
        self.max_commit_age = options.max_commit_age

    # FIXME: This should move to scm.py
    def _recent_commit_messages(self):
        git_log = self._tool.executive.run_command(['git', 'log', '--date=iso', '--since="%s months ago"' % self.max_commit_age])
        messages = re.compile(r"^commit \w{40}$", re.MULTILINE).split(git_log)[1:]  # Ignore the first message which will be empty.
        for message in messages:
            # Unindent all the lines
            (message, _) = self._leading_indent_regexp.subn("", message)
            yield message.lstrip()  # Remove any leading newlines from the log message.

    def _author_name_from_email(self, email):
        contributor = self._committer_list.contributor_by_email(email)
        return contributor.full_name if contributor else None

    def _contributor_from_email(self, email):
        contributor = self._committer_list.contributor_by_email(email)
        return contributor if contributor else None

    def _parse_commit_message(self, commit_message):
        committer_match = self._committer_regexp.search(commit_message)
        if not committer_match:
            raise CommitLogError

        committer_email = committer_match.group('email')
        if not committer_email:
            raise CommitLogError

        committer = self._contributor_from_email(committer_email)
        if not committer:
            raise CommitLogError

        commit_date_match = self._date_regexp.search(commit_message)
        if not commit_date_match:
            raise CommitLogError
        commit_date = commit_date_match.group('date')

        revision_match = self._revision_regexp.search(commit_message)
        if not revision_match:
            raise CommitLogError
        revision = revision_match.group('svnid')

        # Look for "Patch by" line first, which is used for non-committer contributors;
        # otherwise, use committer info determined above.
        author_match = self._patch_by_regexp.search(commit_message)
        if not author_match:
            author_match = committer_match

        author_email = author_match.group('email')
        if not author_email:
            author_email = committer_email

        author_name = author_match.group('name') if 'name' in author_match.groupdict() else None
        if not author_name:
            author_name = self._author_name_from_email(author_email)
        if not author_name:
            raise CommitLogError

        contributor = self._contributor_from_email(author_email)
        if contributor and author_name != contributor.full_name and contributor.full_name:
            author_name = contributor.full_name

        reviewer_match = self._reviewed_by_regexp.search(commit_message)
        if not reviewer_match:
            raise CommitLogMissingReviewer
        reviewers = reviewer_match.group('reviewer')

        return {
            'committer': committer,
            'commit_date': commit_date,
            'revision': revision,
            'author_email': author_email,
            'author_name': author_name,
            'contributor': contributor,
            'reviewers': reviewers,
        }
Example #33
0
 def __init__(self):
     self.queries = MockBugzillaQueries(self)
     # FIXME: This should move onto the Host object, and we should use a MockCommitterList
     self.committers = CommitterList(reviewers=_mock_reviewers)
     self.username = None
     self._override_patch = None
Example #34
0
 def __init__(self, contents, committer_list=CommitterList()):
     self._contents = contents
     self._committer_list = committer_list
     self._parse_entry()
Example #35
0
    def test_committer_lookup(self):
        committer = Committer('Test One', '*****@*****.**', 'one')
        reviewer = Reviewer('Test Two', ['*****@*****.**', '*****@*****.**', '*****@*****.**'])
        contributor = Contributor('Test Three', ['*****@*****.**'], 'three')
        contributor_with_two_nicknames = Contributor('Other Four', ['*****@*****.**', '*****@*****.**'], ['four', 'otherfour'])
        contributor_with_same_email_username = Contributor('Yet Another Four', ['*****@*****.**'], ['yetanotherfour'])
        committer_list = CommitterList(committers=[committer], reviewers=[reviewer],
            contributors=[contributor, contributor_with_two_nicknames, contributor_with_same_email_username])

        # Test valid committer, reviewer and contributor lookup
        self.assertEqual(committer_list.committer_by_email('*****@*****.**'), committer)
        self.assertEqual(committer_list.reviewer_by_email('*****@*****.**'), reviewer)
        self.assertEqual(committer_list.committer_by_email('*****@*****.**'), reviewer)
        self.assertEqual(committer_list.committer_by_email('*****@*****.**'), reviewer)
        self.assertEqual(committer_list.reviewer_by_email('*****@*****.**'), reviewer)
        self.assertEqual(committer_list.contributor_by_email('*****@*****.**'), contributor)

        # Test valid committer, reviewer and contributor lookup
        self.assertEqual(committer_list.committer_by_name("Test One"), committer)
        self.assertEqual(committer_list.committer_by_name("Test Two"), reviewer)
        self.assertIsNone(committer_list.committer_by_name("Test Three"))
        self.assertEqual(committer_list.contributor_by_name("Test Three"), contributor)
        self.assertEqual(committer_list.contributor_by_name("test one"), committer)
        self.assertEqual(committer_list.contributor_by_name("test two"), reviewer)
        self.assertEqual(committer_list.contributor_by_name("test three"), contributor)

        # Test that the first email is assumed to be the Bugzilla email address (for now)
        self.assertEqual(committer_list.committer_by_email('*****@*****.**').bugzilla_email(), '*****@*****.**')

        # Test that a known committer is not returned during reviewer lookup
        self.assertIsNone(committer_list.reviewer_by_email('*****@*****.**'))
        self.assertIsNone(committer_list.reviewer_by_email('*****@*****.**'))
        # and likewise that a known contributor is not returned for committer lookup.
        self.assertIsNone(committer_list.committer_by_email('*****@*****.**'))

        # Test that unknown email address fail both committer and reviewer lookup
        self.assertIsNone(committer_list.committer_by_email('*****@*****.**'))
        self.assertIsNone(committer_list.reviewer_by_email('*****@*****.**'))

        # Test that emails returns a list.
        self.assertEqual(committer.emails, ['*****@*****.**'])

        self.assertEqual(committer.irc_nicknames, ['one'])
        self.assertEqual(committer_list.contributor_by_irc_nickname('one'), committer)
        self.assertEqual(committer_list.contributor_by_irc_nickname('three'), contributor)
        self.assertEqual(committer_list.contributor_by_irc_nickname('four'), contributor_with_two_nicknames)
        self.assertEqual(committer_list.contributor_by_irc_nickname('otherfour'), contributor_with_two_nicknames)

        # Test that the lists returned are are we expect them.
        self.assertEqual(committer_list.contributors(), [contributor, contributor_with_two_nicknames, contributor_with_same_email_username, committer, reviewer])
        self.assertEqual(committer_list.committers(), [committer, reviewer])
        self.assertEqual(committer_list.reviewers(), [reviewer])

        self.assertEqual(committer_list.contributors_by_search_string('test'), [contributor, committer, reviewer])
        self.assertEqual(committer_list.contributors_by_search_string('rad'), [reviewer])
        self.assertEqual(committer_list.contributors_by_search_string('Two'), [reviewer])
        self.assertEqual(committer_list.contributors_by_search_string('otherfour'), [contributor_with_two_nicknames])
        self.assertEqual(committer_list.contributors_by_search_string('*otherfour*'), [contributor_with_two_nicknames, contributor_with_same_email_username])

        self.assertEqual(committer_list.contributors_by_email_username("one"), [committer])
        self.assertEqual(committer_list.contributors_by_email_username("four"), [])
        self.assertEqual(committer_list.contributors_by_email_username("otherfour"), [contributor_with_two_nicknames, contributor_with_same_email_username])
    def test_committer_lookup(self):
        committer = Committer('Test One', '*****@*****.**', 'one')
        reviewer = Reviewer('Test Two', ['*****@*****.**', '*****@*****.**', '*****@*****.**'])
        committer_list = CommitterList(committers=[committer], reviewers=[reviewer])

        # Test valid committer and reviewer lookup
        self.assertEqual(committer_list.committer_by_email('*****@*****.**'), committer)
        self.assertEqual(committer_list.reviewer_by_email('*****@*****.**'), reviewer)
        self.assertEqual(committer_list.committer_by_email('*****@*****.**'), reviewer)
        self.assertEqual(committer_list.committer_by_email('*****@*****.**'), reviewer)
        self.assertEqual(committer_list.reviewer_by_email('*****@*****.**'), reviewer)

        # Test valid committer and reviewer lookup
        self.assertEqual(committer_list.committer_by_name("Test One"), committer)
        self.assertEqual(committer_list.committer_by_name("Test Two"), reviewer)
        self.assertEqual(committer_list.committer_by_name("Test Three"), None)

        # Test that the first email is assumed to be the Bugzilla email address (for now)
        self.assertEqual(committer_list.committer_by_email('*****@*****.**').bugzilla_email(), '*****@*****.**')

        # Test that a known committer is not returned during reviewer lookup
        self.assertEqual(committer_list.reviewer_by_email('*****@*****.**'), None)

        # Test that unknown email address fail both committer and reviewer lookup
        self.assertEqual(committer_list.committer_by_email('*****@*****.**'), None)
        self.assertEqual(committer_list.reviewer_by_email('*****@*****.**'), None)

        # Test that emails returns a list.
        self.assertEqual(committer.emails, ['*****@*****.**'])

        self.assertEqual(committer.irc_nickname, 'one')

        # Test that committers returns committers and reviewers and reviewers() just reviewers.
        self.assertEqual(committer_list.committers(), [committer, reviewer])
        self.assertEqual(committer_list.reviewers(), [reviewer])
Example #37
0
 def __init__(self):
     Mock.__init__(self)
     self.queries = MockBugzillaQueries(self)
     self.committers = CommitterList(reviewers=[Reviewer("Foo Bar",
                                                         "*****@*****.**")])
Example #38
0
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

from .commitinfo import CommitInfo

# FIXME: These imports are wrong, we should use a shared MockCommittersList.
from webkitpy.common.config.committers import CommitterList
from webkitpy.common.net.bugzilla.bugzilla_mock import _mock_reviewers
from webkitpy.common.system.filesystem_mock import MockFileSystem


class MockCommitMessage(object):
    def message(self):
        return "This is a fake commit message that is at least 50 characters."


committer_list = CommitterList()

mock_revisions = {
    1: CommitInfo(852, "*****@*****.**", {
        "bug_id": 50000,
        "author_name": "Adam Barth",
        "author_email": "*****@*****.**",
        "author": committer_list.contributor_by_email("*****@*****.**"),
        "reviewer_text": "Darin Adler",
        "reviewer": committer_list.committer_by_name("Darin Adler"),
        "changed_files": [
            "path/to/file",
            "another/file",
        ],
        "bug_description": "Example description of bug 50000.",
    }),
Example #39
0
    def test_committer_lookup(self):
        account = Account("Test Zero", ["*****@*****.**", "*****@*****.**"], "zero")
        committer = Committer("Test One", "*****@*****.**", "one")
        reviewer = Reviewer("Test Two", ["*****@*****.**", "*****@*****.**", "*****@*****.**"])
        contributor = Contributor("Test Three", ["*****@*****.**"], "three")
        contributor_with_two_nicknames = Contributor(
            "Other Four", ["*****@*****.**", "*****@*****.**"], ["four", "otherfour"]
        )
        contributor_with_same_email_username = Contributor(
            "Yet Another Four", ["*****@*****.**"], ["yetanotherfour"]
        )
        committer_list = CommitterList(
            watchers=[account],
            committers=[committer],
            reviewers=[reviewer],
            contributors=[contributor, contributor_with_two_nicknames, contributor_with_same_email_username],
        )

        # Test valid committer, reviewer and contributor lookup
        self.assertEqual(committer_list.account_by_email("*****@*****.**"), account)
        self.assertEqual(committer_list.committer_by_email("*****@*****.**"), committer)
        self.assertEqual(committer_list.reviewer_by_email("*****@*****.**"), reviewer)
        self.assertEqual(committer_list.committer_by_email("*****@*****.**"), reviewer)
        self.assertEqual(committer_list.committer_by_email("*****@*****.**"), reviewer)
        self.assertEqual(committer_list.reviewer_by_email("*****@*****.**"), reviewer)
        self.assertEqual(committer_list.contributor_by_email("*****@*****.**"), contributor)

        # Test valid committer, reviewer and contributor lookup
        self.assertEqual(committer_list.committer_by_name("Test One"), committer)
        self.assertEqual(committer_list.committer_by_name("Test Two"), reviewer)
        self.assertEqual(committer_list.committer_by_name("Test Three"), None)
        self.assertEqual(committer_list.contributor_by_name("Test Three"), contributor)
        self.assertEqual(committer_list.contributor_by_name("test one"), committer)
        self.assertEqual(committer_list.contributor_by_name("test two"), reviewer)
        self.assertEqual(committer_list.contributor_by_name("test three"), contributor)

        # Test that the first email is assumed to be the Bugzilla email address (for now)
        self.assertEqual(committer_list.committer_by_email("*****@*****.**").bugzilla_email(), "*****@*****.**")

        # Test lookup by login email address
        self.assertEqual(committer_list.account_by_login("*****@*****.**"), account)
        self.assertEqual(committer_list.account_by_login("*****@*****.**"), None)
        self.assertEqual(committer_list.account_by_login("*****@*****.**"), committer)
        self.assertEqual(committer_list.account_by_login("*****@*****.**"), reviewer)
        self.assertEqual(committer_list.account_by_login("*****@*****.**"), None)
        self.assertEqual(committer_list.account_by_login("*****@*****.**"), None)

        # Test that a known committer is not returned during reviewer lookup
        self.assertEqual(committer_list.reviewer_by_email("*****@*****.**"), None)
        self.assertEqual(committer_list.reviewer_by_email("*****@*****.**"), None)
        # and likewise that a known contributor is not returned for committer lookup.
        self.assertEqual(committer_list.committer_by_email("*****@*****.**"), None)

        # Test that unknown email address fail both committer and reviewer lookup
        self.assertEqual(committer_list.committer_by_email("*****@*****.**"), None)
        self.assertEqual(committer_list.reviewer_by_email("*****@*****.**"), None)

        # Test that emails returns a list.
        self.assertEqual(committer.emails, ["*****@*****.**"])

        self.assertEqual(committer.irc_nicknames, ["one"])
        self.assertEqual(committer_list.contributor_by_irc_nickname("one"), committer)
        self.assertEqual(committer_list.contributor_by_irc_nickname("three"), contributor)
        self.assertEqual(committer_list.contributor_by_irc_nickname("four"), contributor_with_two_nicknames)
        self.assertEqual(committer_list.contributor_by_irc_nickname("otherfour"), contributor_with_two_nicknames)

        # Test that the lists returned are are we expect them.
        self.assertEqual(
            committer_list.contributors(),
            [contributor, contributor_with_two_nicknames, contributor_with_same_email_username, committer, reviewer],
        )
        self.assertEqual(committer_list.committers(), [committer, reviewer])
        self.assertEqual(committer_list.reviewers(), [reviewer])

        self.assertEqual(committer_list.contributors_by_search_string("test"), [contributor, committer, reviewer])
        self.assertEqual(committer_list.contributors_by_search_string("rad"), [reviewer])
        self.assertEqual(committer_list.contributors_by_search_string("Two"), [reviewer])
        self.assertEqual(committer_list.contributors_by_search_string("otherfour"), [contributor_with_two_nicknames])
        self.assertEqual(
            committer_list.contributors_by_search_string("*otherfour*"),
            [contributor_with_two_nicknames, contributor_with_same_email_username],
        )

        self.assertEqual(committer_list.contributors_by_email_username("one"), [committer])
        self.assertEqual(committer_list.contributors_by_email_username("four"), [])
        self.assertEqual(
            committer_list.contributors_by_email_username("otherfour"),
            [contributor_with_two_nicknames, contributor_with_same_email_username],
        )