"""
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
if request.status_code == 201:
return request.json()
return False
-
gitlab.Gitlab.addprojecthook_extra = addprojecthook_extra
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"
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:
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 != "":
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:
# 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):
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
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
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/<rooms>' in margebot.pop_message()
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')
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):