← Back to team overview

ubuntu-bots team mailing list archive

[Merge] lp:~3v1n0/ubuntu-bots/gitlab-support into lp:ubuntu-bots

 

Marco Trevisan (Treviño) has proposed merging lp:~3v1n0/ubuntu-bots/gitlab-support into lp:ubuntu-bots with lp:~3v1n0/ubuntu-bots/github-support as a prerequisite.

Commit message:
Bugtracker: add support for Gitlab issues and merge requests

Requested reviews:
  Ubuntu IRC Bots (ubuntu-bots)

For more details, see:
https://code.launchpad.net/~3v1n0/ubuntu-bots/gitlab-support/+merge/342164
-- 
Your team Ubuntu IRC Bots is requested to review the proposed merge of lp:~3v1n0/ubuntu-bots/gitlab-support into lp:ubuntu-bots.
=== modified file 'Bugtracker/plugin.py'
--- Bugtracker/plugin.py	2018-03-27 01:43:37 +0000
+++ Bugtracker/plugin.py	2018-03-27 01:43:37 +0000
@@ -419,7 +419,7 @@
                         irc.reply(makeClean(r), prefixNick=False)
 
     def turlSnarfer(self, irc, msg, match):
-        r"(?P<tracker>https?://\S*?)/(?:Bugs/0*|str.php\?L|show_bug.cgi\?id=|bugreport.cgi\?bug=|(?:bugs|\+bug)/|ticket/|tracker/|\S*aid=|bug=|issues/|pull/)?(?P<bug>\d+)(?P<sfurl>&group_id=\d+&at_id=\d+)?"
+        r"(?P<tracker>https?://\S*?)/(?:Bugs/0*|str.php\?L|show_bug.cgi\?id=|bugreport.cgi\?bug=|(?:bugs|\+bug)/|ticket/|tracker/|\S*aid=|bug=|issues/|pull/|merge_requests/)?(?P<bug>\d+)(?P<sfurl>&group_id=\d+&at_id=\d+)?"
         channel = ircutils.isChannel(msg.args[0]) and msg.args[0] or None
         if not self.registryValue('bugSnarfer', channel):
             return
@@ -1128,8 +1128,8 @@
             if is_pull_request:
                 id = u'(Pull request) {}'.format(id)
 
-            # extinfo = "(comments: {}, reactions: {})" % (issue.comments, len(issue.get_reactions()))
-            extinfo = "(comments: {})".format(issue.comments)
+            # extinfo = '(comments: {}, reactions: {})'.format(issue.comments, len(issue.get_reactions()))
+            extinfo = u'(comments: {})'.format(issue.comments)
 
             return [(id, self.repo.name, issue.title, labels, issue.state, assignee, issue.html_url, extinfo)]
         except Exception as e:
@@ -1139,6 +1139,105 @@
             raise BugtrackerError, s
 
 
+class Gitlab(IBugtracker):
+    _GL_TOKENS = {'gitlab.com': None,
+                  'gitlab.gnome.org': None}
+    _gl = {}
+
+    def __init__(self, *args, **kwargs):
+        IBugtracker.__init__(self, *args, **kwargs)
+
+        self.gl = None
+        self.project = None
+        self.merge_requests = False
+
+        hostname = self.url.split('://', 1)[1].split('/', 1)[0]
+
+        if not hostname in Gitlab._gl.keys():
+            if not hostname in Gitlab._GL_TOKENS.keys() or not Gitlab._GL_TOKENS[hostname]:
+                self.log.error("No access token for gitlab host {}".format(hostname))
+                return
+
+            try: # We need python-gitlab
+                import gitlab
+                from distutils.version import LooseVersion
+
+                if LooseVersion(gitlab.__version__) < LooseVersion('1.0.0'):
+                    self.log.exception("gitlab version must be 1.0.0 or newer")
+
+                Gitlab._gl[hostname] = gitlab.Gitlab(self.url, private_token=Gitlab._GL_TOKENS[hostname])
+            except ImportError:
+                self.log.error("Please install python-github")
+
+        self.gl = Gitlab._gl[hostname]
+
+    def has_multiple_trackers(self):
+        return True
+
+    def get_tracker(self, url):
+        if not self.gl:
+            return
+        if not url:
+            self.log.info("Impossible to get tracker for an empty url")
+            return
+
+        try:
+            url = url.replace('http://', 'https://', 1)
+            if url.startswith(self.url):
+                projectmatch = re.search("([^/]+/[^/]+)/(issues|merge_requests)/\d+", url)
+
+                if projectmatch:
+                    project_full_name = projectmatch.group(1)
+                    project = self.gl.projects.get(project_full_name)
+                    merge_request = projectmatch.group(2) == u'merge_requests'
+
+                    if not merge_request and not project.issues_enabled:
+                        s = u'Project {} has no issues'.format(project_full_name)
+                        self.log.error(s)
+                        return
+                    elif merge_request and not project.merge_requests_enabled:
+                        s = u'Project {} has no merge requests'.format(project_full_name)
+                        self.log.error(s)
+                        return
+
+                    gl = Gitlab(project_full_name.replace('/', '-'), project.web_url, project.name)
+                    gl.project = project
+                    gl.merge_requests = merge_request
+                    return gl
+
+        except Exception as e:
+            s = u'{}: Impossible to get tracker for {}: {}'.format(
+                self.description, url, e)
+            self.log.exception(s)
+
+    def get_bug(self, id):
+        if not self.gl or not self.project:
+            self.log.info("Gitlab or project not initialized")
+            return []
+
+        try:
+            if self.merge_requests:
+                issue = self.project.mergerequests.get(id)
+                id = u'(Merge request) {}'.format(id)
+            else:
+                issue = self.project.issues.get(id)
+
+            assignee = None
+            labels = u', '.join([l for l in issue.labels])
+
+            if issue.assignee:
+                assignee = u'{} ({})'.format(issue.assignee.username, issue.assignee['name'])
+
+            extinfo = u'(comments: {})'.format(issue.user_notes_count)
+
+            return [(id, self.project.path, issue.title, labels, issue.state, assignee, issue.web_url, extinfo)]
+        except Exception as e:
+            s = u'{}: Impossible to get infos for {} issue {}: {}'.format(
+                self.description, self.project.path_with_namespace, id, e)
+            self.log.exception(s)
+            raise BugtrackerError, s
+
+
 # Introspection is quite cool
 defined_bugtrackers = {}
 v = vars()
@@ -1150,6 +1249,7 @@
 registerBugtracker('ubuntu', 'https://launchpad.net', 'Ubuntu', 'launchpad')
 registerBugtracker('gnome', 'http://bugzilla.gnome.org', 'Gnome', 'bugzilla')
 registerBugtracker('gnome2', 'http://bugs.gnome.org', 'Gnome', 'bugzilla')
+registerBugtracker('gnome3', 'https://gitlab.gnome.org', 'Gnome', 'gitlab')
 registerBugtracker('kde', 'http://bugs.kde.org', 'KDE', 'bugzilla')
 registerBugtracker('ximian', 'http://bugzilla.ximian.com', 'Ximian', 'bugzilla')
 registerBugtracker('freedesktop', 'http://bugzilla.freedesktop.org', 'Freedesktop', 'bugzilla')
@@ -1168,5 +1268,7 @@
 registerBugtracker('ubottu', 'https://launchpad.net', 'Ubottu', 'launchpad')
 registerBugtracker('sourceforge', 'http://sourceforge.net/tracker/', 'Sourceforge', 'sourceforge')
 registerBugtracker('github', 'https://github.com', 'Github', 'github')
+registerBugtracker('gitlab', 'https://gitlab.com', 'Gitlab', 'gitlab')
+
 # Don't delete this one
 Class = Bugtracker