From 24741a1f032666dc2df447f1c1ea8de67f443984 Mon Sep 17 00:00:00 2001 From: Jude N Date: Wed, 17 Apr 2019 23:52:51 -0400 Subject: [PATCH] Removed the jokes / added the reviewer name to the single +1 response. --- README.md | 17 ++++++- plugins/marge.py | 119 +++++++++----------------------------------- setup.py | 2 + tests/test_marge.py | 36 +++++--------- 4 files changed, 54 insertions(+), 120 deletions(-) diff --git a/README.md b/README.md index 70720da..38dd0c1 100644 --- a/README.md +++ b/README.md @@ -1 +1,16 @@ -Marge: I remind you about outstanding Gitlab merge requests \ No newline at end of file +Marge: I remind you about outstanding Gitlab merge requests + +Development Notes: +``` +> python3 -m venv ./env +> source ./env/bin/activate +> python setup.py develop +> python setup.py test +``` + +Deployment Notes: +Errbot plugs aren't distributed as eggs. +Instead copy the contents of the .plugin directory to a 'Marge' directory under your Errnbot plugins directory. + +TODO Notes: +- Port from pyapi-gitlab to python-gitlab diff --git a/plugins/marge.py b/plugins/marge.py index e81e00a..86b66ec 100755 --- a/plugins/marge.py +++ b/plugins/marge.py @@ -1,9 +1,7 @@ """ Margebot: A Errbot Plugin for Gitlab MR reminders """ -import re from datetime import datetime, timezone -from time import sleep from dateutil import parser from dateutil.tz import tzutc from dateutil.relativedelta import relativedelta @@ -31,7 +29,6 @@ def addprojecthook_extra(self, project_id, url, push=False, issues=False, merge_ if request.status_code == 201: return request.json() return False - gitlab.Gitlab.addprojecthook_extra = addprojecthook_extra @@ -50,10 +47,21 @@ def editprojecthook_extra(self, project_id, hook_id, url, push=False, issues=Fal request = requests.put("{0}/{1}/hooks/{2}".format(self.projects_url, project_id, hook_id), headers=self.headers, data=data, verify=self.verify_ssl) return request.status_code == 200 - gitlab.Gitlab.editprojecthook_extra = editprojecthook_extra +def getawardemoji(self, project_id, mr_iid): + """ + Give me the thumbs + """ + url = "{0}/{1}/merge_requests/{2}/award_emoji".format(self.projects_url, project_id, mr_iid) + request = requests.get(url, headers=self.headers, verify=self.verify_ssl) + if request.status_code == 200: + return request.json() + return False +gitlab.Gitlab.getawardemoji = getawardemoji + + def deltastr(any_delta): """ Output a datetime delta in the format "x days, y hours, z minutes ago" @@ -203,6 +211,7 @@ class Marge(BotPlugin, CrontabMixin): open_mrs = self['OPEN_MRS'] + # jn: iid references in this block used to be mr_id if (target_project_id, iid, rooms) not in open_mrs: for a_room in rooms.split(','): if self.config: @@ -253,21 +262,8 @@ class Marge(BotPlugin, CrontabMixin): else: authored = False - # getapprovals is only available in GitLab 8.9 EE or greater - # (not the open source CE version) - # approvals = self.gitlab.getapprovals(a_mr['id']) - # approved = "" - # for approved in approvals['approved_by']: - # approved += "," + approvals['user']['name'] - - # See https://gitlab.com/gitlab-org/gitlab-ce/issues/35498 - # awards = GET /projects/:id/merge_requests/:merge_request_iid/award_emoji - # for an award in awards: - # if name==??? and award_type==???: - # approved += "," + award["user"]["username"] - - upvotes = a_mr['upvotes'] msg = "{} (opened {})".format(a_mr['web_url'], str_open_since) + upvotes = a_mr['upvotes'] if upvotes >= 2: msg += ": Has 2+ upvotes and could be merged in now" if warning != "": @@ -276,10 +272,17 @@ class Marge(BotPlugin, CrontabMixin): msg += "." elif upvotes == 1: + award_emoji = self.gitlab.getawardemoji(a_mr['target_project_id'], a_mr['iid']) + self.log.info("award_emoji: {}".format(award_emoji)) + already_approved = "someone" + for an_emoji in award_emoji: + if an_emoji["name"] == "thumbsup": + already_approved = an_emoji["user"]["username"] + if authored: - msg += ": Your MR is waiting for another upvote" + msg += ": Your MR has been approved by " + already_approved + " and is waiting for another upvote" else: - msg += ": Waiting for another upvote" + msg += ": Approved by " + already_approved + " and waiting for another upvote" if warning != "": msg += " but {}.".format(warning) else: @@ -539,81 +542,7 @@ class Marge(BotPlugin, CrontabMixin): # pragma pylint: disable=unused-argument - @botcmd() - def xyzzy(self, msg, args): - """ - Don't call this command... - """ - yield "/me whispers \"All open MRs have been merged into master.\"" - sleep(5) - yield "(just kidding)" - - @re_botcmd(pattern=r"I blame marge(bot)?", prefixed=False, flags=re.IGNORECASE) - def dont_blame_margebot(self, msg, match): - """ - margebot is innocent. - """ - yield u"(\u300D\uFF9F\uFF9B\uFF9F)\uFF63NOOOooooo say it ain't so." - - @re_botcmd(pattern=r"\u0028\u256F\u00B0\u25A1\u00B0\uFF09\u256F\uFE35\u0020\u253B(\u2501+)\u253B", prefixed=False) - def deflipped(self, msg, match): - """ - Unflip a properly sized table - """ - table_len = len(match.group(1)) - deflip_table = u"\u252c" + (u"\u2500" * table_len) + u"\u252c \u30ce( \u309c-\u309c\u30ce)" - # yield u"\u252c\u2500\u2500\u252c \u30ce( \u309c-\u309c\u30ce)" - yield deflip_table - - @re_botcmd(pattern=r"good bot", prefixed=False, flags=re.IGNORECASE) - def best_bot(self, msg, match): - """ - margebot is the best. - """ - yield "Best bot" - - @re_botcmd(pattern=r"magfest", prefixed=False, flags=re.IGNORECASE) - def margefest(self, msg, args): - """ - margefest4ever - """ - return "More like MargeFest, amirite ?" - -# ha the dev-infra room sez koji sooooooooooooooooooooooooooooooooooooooooooo much -# @re_botcmd(pattern=r"k+o+j+i+", prefixed=False, flags=re.IGNORECASE) -# def koji(self, msg, args): -# """ -# More like daikaiju, amirite ? -# """ -# return "More like kaiju, amirite ?" - - @re_botcmd(pattern=r"peruvian chicken", prefixed=False, flags=re.IGNORECASE) - def booruvian(self, msg, args): - """ - They put hard boiled eggs in their tamales too. - """ - return "More like Booruvian chicken, amirite ?" - - @re_botcmd(pattern=r"booruvian chicken", prefixed=False, flags=re.IGNORECASE) - def booihoohooruvian(self, msg, args): - """ - That chicken I do not like. - """ - return "More like Boohoohooruvian chicken, amirite ?" - - @re_botcmd(pattern=r"margebot sucks", prefixed=False, flags=re.IGNORECASE) - def new_agenda_item(self, msg, args): - """ - Bring it up with the committee - """ - return "Bring it up with the Margebot steering committee." - - @re_botcmd(pattern=r"jackie", prefixed=False, flags=re.IGNORECASE) - def jackie(self, msg, args): - """ - Who dat ? - """ - return "I don't know any Jackies. I'm calling security." + # Check Chucklebot for the chuckles @re_botcmd(pattern=r".*", prefixed=True) def catchall(self, msg, args): diff --git a/setup.py b/setup.py index 35f5db5..5d091a5 100644 --- a/setup.py +++ b/setup.py @@ -56,6 +56,8 @@ setup( setup_requires=['pytest-runner'], tests_require=tests_required, + zip_safe=False, + cmdclass={ 'install': ErrbotInstallCommand, 'sdist': ErrbotSdistCommand, diff --git a/tests/test_marge.py b/tests/test_marge.py index d8b85b3..defbed9 100644 --- a/tests/test_marge.py +++ b/tests/test_marge.py @@ -14,12 +14,12 @@ import logging import json from queue import Empty -import gitlab from dateutil.relativedelta import relativedelta import pytest import requests import errbot from errbot.backends.test import testbot # pylint: disable=unused-import +import gitlab from plugins.marge import deltastr @@ -87,12 +87,22 @@ class TestMarge(object): def mock_getmergerequest(self, project, iid): return {'author': {'id': 2001}, 'created_at': 'Oct 29, 2017 2:37am', + 'iid': 1, 'merge_status': 'can_be_merged', 'state': 'opened', + 'target_project_id': 1, 'upvotes': 1, 'web_url': 'http://gitlab.example.com/sample/mr/2001', 'work_in_progress': False} monkeypatch.setattr(gitlab.Gitlab, 'getmergerequest', mock_getmergerequest) + + def mock_getawardemoji(self, project, iid): + return [{'name': 'happycat', + 'user': {'username': 'ReviewerY'}}, + {'name': 'thumbsup', + 'user': {'username': 'ReviewerX'}}] + monkeypatch.setattr(gitlab.Gitlab, 'getawardemoji', mock_getawardemoji) + return margebot_one_review @pytest.fixture @@ -249,16 +259,6 @@ class TestMarge(object): assert '!reviews' in help_message assert '!watchrepo' in help_message - def test_good_bot(self, margebot): - margebot.push_message('good bot') - assert 'Best bot' in margebot.pop_message() - -# def test_xyzzy(self, margebot): -# margebot.push_message('!xyzzy') -# assert 'All open MRs have been merged into master' in margebot.pop_message() -# time.sleep(6) -# assert 'just kidding' in margebot.pop_message() - def test_webstatus(self, margebot): margebot.push_message('!webstatus') assert 'margebot/' in margebot.pop_message() @@ -379,7 +379,7 @@ class TestMarge(object): output = margebot.pop_message() assert 'These MRs need some attention' in output assert 'http://gitlab.example.com/sample/mr/2001' in output - assert 'Waiting for another upvote.' in output + assert 'Approved by ReviewerX and waiting for another upvote.' in output def test_get_one_mergable_mr(self, margebot, one_mergable_review, gitlab): one_mergable_review.push_message('!reviews') @@ -407,18 +407,6 @@ class TestMarge(object): assert 'These MRs need some attention' in output assert 'http://gitlab.example.com/sample/mr/2001 (opened' in output - def test_dont_blame_margebot(self, margebot): - margebot.push_message('I blame margebot') - assert "say it ain't so" in margebot.pop_message() - - def test_margefest(self, margebot): - margebot.push_message('magfest') - assert 'MargeFest' in margebot.pop_message() - - def test_margebot_sucks(self, margebot): - margebot.push_message('margebot sucks') - assert 'steering committee' in margebot.pop_message() - def test_margebot_unknown_command(self, margebot): margebot.push_message('Margebot, alacazam') with pytest.raises(Empty): -- 2.39.2