Bugtracker: Add GitLab and Gitea as trackers.
This commit is contained in:
@ -24,7 +24,7 @@ import supybot.world as world
|
|||||||
|
|
||||||
from imp import reload
|
from imp import reload
|
||||||
|
|
||||||
__version__ = "3.0.0"
|
__version__ = "3.1.0"
|
||||||
__author__ = supybot.Author("Krytarik Raido", "krytarik", "krytarik@tuxgarage.com")
|
__author__ = supybot.Author("Krytarik Raido", "krytarik", "krytarik@tuxgarage.com")
|
||||||
__contributors__ = {
|
__contributors__ = {
|
||||||
supybot.Author("Dennis Kaarsemaker", "Seveas", "dennis@kaarsemaker.net"): ['Original Author'],
|
supybot.Author("Dennis Kaarsemaker", "Seveas", "dennis@kaarsemaker.net"): ['Original Author'],
|
||||||
|
@ -151,8 +151,8 @@ class Bugtracker(callbacks.PluginRegexp):
|
|||||||
def add(self, irc, msg, args, name, trackertype, url, description):
|
def add(self, irc, msg, args, name, trackertype, url, description):
|
||||||
"""<name> <type> <url> [<description>]
|
"""<name> <type> <url> [<description>]
|
||||||
|
|
||||||
Add a bugtracker to the list of defined bugtrackers. Currently supported
|
Add a bugtracker to the list of defined bugtrackers. Currently supported types are
|
||||||
types are Launchpad, Debbugs, Bugzilla, SourceForge, Github, Mantis, and Trac.
|
Launchpad, Debbugs, Bugzilla, SourceForge, Github, GitLab, Gitea, Mantis, and Trac.
|
||||||
<name> will be used to reference the bugtracker in all commands.
|
<name> will be used to reference the bugtracker in all commands.
|
||||||
Unambiguous abbreviations of it will also be accepted.
|
Unambiguous abbreviations of it will also be accepted.
|
||||||
<description> will be used to reference the bugtracker in the
|
<description> will be used to reference the bugtracker in the
|
||||||
@ -323,7 +323,7 @@ class Bugtracker(callbacks.PluginRegexp):
|
|||||||
irc.reply(report)
|
irc.reply(report)
|
||||||
|
|
||||||
def turlSnarfer(self, irc, msg, match):
|
def turlSnarfer(self, irc, msg, match):
|
||||||
r"(https?://)?((bugs\.debian\.org|pad\.lv)/|\S+/(show_bug\.cgi\?id=|bugreport\.cgi\?bug=|view\.php\?id=|bug=|bugs/|\+bug/|ticket/|feature-requests/|patches/|todo/|issues/|pulls?/))(?P<bug>\d+)/?"
|
r"(https?://)?((bugs\.debian\.org|pad\.lv)/|\S+/(show_bug\.cgi\?id=|bugreport\.cgi\?bug=|view\.php\?id=|bug=|bugs/|\+bug/|ticket/|feature-requests/|patches/|todo/|issues/|pulls?/|merge_requests/))(?P<bug>\d+)/?"
|
||||||
channel = msg.args[0] if ircutils.isChannel(msg.args[0]) else None
|
channel = msg.args[0] if ircutils.isChannel(msg.args[0]) else None
|
||||||
if checkAddressed(msg.args[1].strip(), channel):
|
if checkAddressed(msg.args[1].strip(), channel):
|
||||||
return
|
return
|
||||||
@ -334,13 +334,14 @@ class Bugtracker(callbacks.PluginRegexp):
|
|||||||
return
|
return
|
||||||
msg.tag('nbugs', nbugs+1)
|
msg.tag('nbugs', nbugs+1)
|
||||||
url = match.group(0)
|
url = match.group(0)
|
||||||
|
bugid = int(match.group('bug'))
|
||||||
if '://' in url:
|
if '://' in url:
|
||||||
url = url[url.rfind('://')+3:]
|
url = url[url.rfind('://')+3:]
|
||||||
try:
|
try:
|
||||||
tracker = self.get_tracker(url)
|
tracker = self.get_tracker(url, bugid)
|
||||||
if not tracker:
|
if not tracker:
|
||||||
return
|
return
|
||||||
report = self.get_bug(channel or msg.nick, tracker, int(match.group('bug')), self.registryValue('showassignee', channel),
|
report = self.get_bug(channel or msg.nick, tracker, bugid, self.registryValue('showassignee', channel),
|
||||||
self.registryValue('extended', channel), do_url=False)
|
self.registryValue('extended', channel), do_url=False)
|
||||||
except BugtrackerError as e:
|
except BugtrackerError as e:
|
||||||
irc.error(str(e))
|
irc.error(str(e))
|
||||||
@ -395,7 +396,7 @@ class Bugtracker(callbacks.PluginRegexp):
|
|||||||
irc.reply(cverr)
|
irc.reply(cverr)
|
||||||
|
|
||||||
#TODO: As we will depend on launchpadlib, we should consider using lazr.uri.URI to do URL parsing
|
#TODO: As we will depend on launchpadlib, we should consider using lazr.uri.URI to do URL parsing
|
||||||
def get_tracker(self, snarfurl):
|
def get_tracker(self, snarfurl, bugid):
|
||||||
# SourceForge short domain
|
# SourceForge short domain
|
||||||
snarfurl = snarfurl.replace('sf.net', 'sourceforge.net', 1)
|
snarfurl = snarfurl.replace('sf.net', 'sourceforge.net', 1)
|
||||||
|
|
||||||
@ -418,6 +419,10 @@ class Bugtracker(callbacks.PluginRegexp):
|
|||||||
tracker = SourceForge().get_tracker(snarfurl)
|
tracker = SourceForge().get_tracker(snarfurl)
|
||||||
elif 'github.com' in snarfurl:
|
elif 'github.com' in snarfurl:
|
||||||
tracker = GitHub().get_tracker(snarfurl)
|
tracker = GitHub().get_tracker(snarfurl)
|
||||||
|
elif re.match(r'[^\s/]+/[^\s/]+/[^\s/]+/(issues|pulls|merge_requests)', snarfurl):
|
||||||
|
tracker = GitLab().get_tracker(snarfurl, bugid)
|
||||||
|
if not tracker:
|
||||||
|
tracker = Gitea().get_tracker(snarfurl, bugid)
|
||||||
elif 'view.php' in snarfurl:
|
elif 'view.php' in snarfurl:
|
||||||
tracker = Mantis().get_tracker(snarfurl)
|
tracker = Mantis().get_tracker(snarfurl)
|
||||||
elif '/ticket/' in snarfurl:
|
elif '/ticket/' in snarfurl:
|
||||||
@ -443,9 +448,9 @@ class Bugtracker(callbacks.PluginRegexp):
|
|||||||
if duplicate and not self.is_ok(channel, tracker, bid):
|
if duplicate and not self.is_ok(channel, tracker, bid):
|
||||||
return
|
return
|
||||||
|
|
||||||
bugtype = re.match(r'.*/(feature-)?(?P<type>request|patch|todo|issue|pull|ticket)(e?s)?/[0-9]+/?$', url)
|
bugtype = re.match(r'.*/(feature-)?(?P<type>request|patch|todo|issue|pull|merge|ticket)(_requests)?(e?s)?/[0-9]+/?$', url)
|
||||||
if do_tracker and tracker.trackertype != 'github':
|
if do_tracker and tracker.trackertype not in ('github', 'gitlab', 'gitea'):
|
||||||
if re.match(r'.*/(bugs|feature-requests|patches|todo|issues|pulls?|ticket)/?$', tracker.description):
|
if re.match(r'.*/(bugs|feature-requests|patches|todo|issues|pulls?|merge_requests|ticket)/?$', tracker.description):
|
||||||
report = '%s %d' % (tracker.description, bid)
|
report = '%s %d' % (tracker.description, bid)
|
||||||
else:
|
else:
|
||||||
if bugtype:
|
if bugtype:
|
||||||
@ -855,6 +860,74 @@ class GitHub(IBugtracker):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise BugtrackerError(self.errparse % (self.description, e, url))
|
raise BugtrackerError(self.errparse % (self.description, e, url))
|
||||||
|
|
||||||
|
class GitLab(IBugtracker):
|
||||||
|
def get_tracker(self, url, id):
|
||||||
|
try:
|
||||||
|
match = re.match(r'[^\s/]+/[^\s/]+/[^\s/]+/(issues|merge_requests)', url)
|
||||||
|
name = desc = match.group(0)
|
||||||
|
url = 'https://%s' % name
|
||||||
|
bugurl = '%s/%d.json' % (url, id)
|
||||||
|
bugjson = utils.web.getUrl(bugurl)
|
||||||
|
bug = json.loads(bugjson.decode('utf-8'))
|
||||||
|
# registerBugtracker(name, url, desc, 'gitlab')
|
||||||
|
return GitLab(name, url, desc, 'gitlab')
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def get_bug(self, id):
|
||||||
|
url = "%s/%d.json" % (self.url, id)
|
||||||
|
try:
|
||||||
|
bugjson = utils.web.getUrl(url)
|
||||||
|
bug = json.loads(bugjson.decode('utf-8'))
|
||||||
|
except Exception as e:
|
||||||
|
raise BugtrackerError(self.errget % (self.description, e, url))
|
||||||
|
try:
|
||||||
|
product = '/'.join(url.split('/')[-4:-2])
|
||||||
|
status = bug['state']
|
||||||
|
if 'assignees' in bug and bug['assignees']:
|
||||||
|
assignee = bug['assignees'][0]['name']
|
||||||
|
else:
|
||||||
|
assignee = ''
|
||||||
|
return (id, product, bug['title'], '', status, assignee, "%s/%d" % (self.url, id), [], [])
|
||||||
|
except Exception as e:
|
||||||
|
raise BugtrackerError(self.errparse % (self.description, e, url))
|
||||||
|
|
||||||
|
class Gitea(IBugtracker):
|
||||||
|
def get_tracker(self, url, id):
|
||||||
|
try:
|
||||||
|
match = re.match(r'[^\s/]+/[^\s/]+/[^\s/]+/(issues|pulls)', url)
|
||||||
|
name = desc = match.group(0)
|
||||||
|
url = 'https://%s' % name
|
||||||
|
bugurl = '%s/%d' % (re.sub(r'://[^\s/]+/', r'\g<0>api/v1/repos/', url), id)
|
||||||
|
bugjson = utils.web.getUrl(bugurl)
|
||||||
|
bug = json.loads(bugjson.decode('utf-8'))
|
||||||
|
# registerBugtracker(name, url, desc, 'gitea')
|
||||||
|
return Gitea(name, url, desc, 'gitea')
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def get_bug(self, id):
|
||||||
|
url = "%s/%d" % (re.sub(r'://[^\s/]+/', r'\g<0>api/v1/repos/', self.url), id)
|
||||||
|
try:
|
||||||
|
bugjson = utils.web.getUrl(url)
|
||||||
|
bug = json.loads(bugjson.decode('utf-8'))
|
||||||
|
except Exception as e:
|
||||||
|
raise BugtrackerError(self.errget % (self.description, e, url))
|
||||||
|
try:
|
||||||
|
product = '/'.join(url.split('/')[-4:-2])
|
||||||
|
if 'merged' in bug and bug['merged']:
|
||||||
|
status = 'Merged'
|
||||||
|
else:
|
||||||
|
status = bug['state']
|
||||||
|
if bug['assignee']:
|
||||||
|
assignee = bug['assignee']['username']
|
||||||
|
else:
|
||||||
|
assignee = ''
|
||||||
|
# Issues have no 'html_url', but pulls do
|
||||||
|
return (id, product, bug['title'], '', status, assignee, "%s/%d" % (self.url, id), [], [])
|
||||||
|
except Exception as e:
|
||||||
|
raise BugtrackerError(self.errparse % (self.description, e, url))
|
||||||
|
|
||||||
class Mantis(IBugtracker):
|
class Mantis(IBugtracker):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
if not sys.version_info < (3,0):
|
if not sys.version_info < (3,0):
|
||||||
|
Reference in New Issue
Block a user