[PATCH 5 of 5] bugzilla: add modified XMLRPC mode that uses email to send bug comments

Jim Hague jim.hague at acm.org
Wed Mar 30 08:54:21 UTC 2011


# HG changeset patch
# User Jim Hague <jim.hague at acm.org>
# Date 1301474985 -3600
# Node ID ec46d053942c31e0d0a8584b13cb471efc326887
# Parent  6d54c75879341f8c4d376a898c899d1b586caded
bugzilla: add modified XMLRPC mode that uses email to send bug comments.

If Bugzilla has its email interface configured, an email can be used
to update bugs. If the From: address in the email matches a valid user
email, Bugzillas make the update as that user. So comments attached to a
bug appear under the name of the user making the change, and the user
does not receive email about the change, exactly as if they had made
the change via the web interface.

So add a modified XMLRPC mode that uses email to modify bugs. The format
of the mails is documented in the Bugzilla email_in.pl specification.
Briefly, initial non-blank lines in the message body starting
'@<field> = <value> modify bug fields. A blank line signals the end of
the command lines, and the rest of the message is used as bug comment.

Invoke the same Mercurial user to Bugzilla user email mapping
currently used in the MySQL mode.

All other processing - checking the bug numbers, checking user ids, etc.
continues to be done via XMLRPC.

diff --git a/hgext/bugzilla.py b/hgext/bugzilla.py
--- a/hgext/bugzilla.py
+++ b/hgext/bugzilla.py
@@ -14,9 +14,12 @@
 
 The hook does not change bug status.
 
-Two basic modes of access to Bugzilla are provided:
+Three basic modes of access to Bugzilla are provided:
 
-1. Access via the Bugzilla XMLRPC interface (requires Bugzilla 3.4 or later).
+1. Access via the Bugzilla XMLRPC interface. Requires Bugzilla 3.4 or later.
+
+2. Check data via the Bugzilla XMLRPC interface and submit bug change
+   via email to Bugzilla email interface. Requires Bugzilla 3.4 or later.
 
 2. Writing directly to the Bugzilla database. Only Bugzilla installations
    using MySQL are supported. Requires Python MySQLdb.
@@ -37,15 +40,24 @@
 that the rights of that user are restricted in Bugzilla to the minimum
 necessary to add comments.
 
-Configuration items common to both access modes:
+Access via XMLRPC/email behaves uses XMLRPC to query Bugzilla, but sends
+email to the Bugzilla email interface to submit comments to bugs.
+The From: address in the email is set to the email address of the Mercurial
+user, so the comment appears to come from the Mercurial user. In the event
+that the Mercurial user email is not recognised by Bugzilla as a Bugzilla
+user, the Bugzilla username and password used to log into Bugzilla are
+used instead as the source of the comment.
+
+Configuration items common to all access modes:
 
 [bugzilla]
 version
   This access type to use. Values recognised are:
-  xmlrpc  Bugzilla XMLRPC interface.
-  3.0     MySQL access, Bugzilla 3.0 and later.
-  2.18    MySQL access, Bugzilla 2.18 and up to but not including 3.0.
-  2.16    MySQL access, Bugzilla 2.16 and up to but not including 2.18.
+  xmlrpc       Bugzilla XMLRPC interface.
+  xmlrpc+email Bugzilla XMLRPC and email interfaces.
+  3.0          MySQL access, Bugzilla 3.0 and later.
+  2.18         MySQL access, Bugzilla 2.18 and up to but not including 3.0.
+  2.16         MySQL access, Bugzilla 2.16 and up to but not including 2.18.
 
 regexp
   Regular expression to match bug IDs in changeset commit message.
@@ -80,6 +92,18 @@
   Base URL for browsing Mercurial repositories. Referenced from
   templates as {hgweb}.
 
+Configuration items common to XMLRPC+email and MySQL access modes:
+
+usermap
+  Path of file containing Mercurial committer email to Bugzilla user email
+  mappings. If specified, the file should contain one mapping per
+  line, "committer"="Bugzilla user". See also the [usermap] section.
+
+[usermap]
+The [usermap] section is used to specify mappings of Mercurial
+committer email to Bugzilla user email. See also [bugzilla].usermap.
+Contains entries of the form "committer"="Bugzilla user".
+
 XMLRPC access mode configuration:
 
 [bugzilla]
@@ -93,6 +117,16 @@
 password
   The password for Bugzilla login.
 
+XMLRPC+email access mode uses the XMLRPC access mode configuration items,
+and also:
+
+[bugzilla]
+bzemail
+  The Bugzilla email address.
+
+In addition, the Mercurial email settings must be configured. See the
+documentation for 'hgrc', sections '[email]' and '[smtp]'.
+
 MySQL access mode configuration:
 
 [bugzilla]
@@ -127,16 +161,6 @@
   from 2.18 it is "cd %(bzdir)s && perl -T contrib/sendbugmail.pl
   %(id)s %(user)s".
 
-usermap
-  Path of file containing Mercurial committer ID to Bugzilla user ID
-  mappings. If specified, the file should contain one mapping per
-  line, "committer"="Bugzilla user". See also the [usermap] section.
-
-[usermap]
-The [usermap] section is used to specify mappings of Mercurial
-committer email to Bugzilla user email. See also [bugzilla].usermap.
-Contains entries of the form "committer"="Bugzilla user".
-
 Activating the extension::
 
     [extensions]
@@ -162,6 +186,22 @@
     [web]
     baseurl=http://my-project.org/hg
 
+XMLRPC+email example configuration. This uses the Bugzilla at
+'http://my-project.org/bugzilla', logging in as user 'bugmail at my-project.org'
+wityh password 'plugh'. It is used with a collection of Mercurial
+repositories in '/var/local/hg/repos/'. Bug comments are sent to the
+Bugzilla email address 'buzilla at my-project.org'. ::
+
+    [bugzilla]
+    user=bugmail at my-project.org
+    password=plugh
+    version=xmlrpc
+    bzemail=bugzilla at my-project.org
+
+    [web]
+    baseurl=https://dev.laicatc.com/hg
+    bugzillaurl=https://dev.laicatc.com/bugzilla
+
 MySQL example configuration. This is for a collection of Mercurial
 repositories in '/var/local/hg/repos/' used with a local Bugzilla 3.2
 installation in /opt/bugzilla-3.2. The MySQL database is on 'localhost',
@@ -185,7 +225,7 @@
     [usermap]
     user at emaildomain.com=user.name at bugzilladomain.com
 
-Both the above add a comment to the Bugzilla bug record of the form::
+All the above add a comment to the Bugzilla bug record of the form::
 
     Changeset 3b16791d6642 in repository-name.
     http://dev.domain.com/hg/repository-name/rev/3b16791d6642
@@ -195,7 +235,7 @@
 
 from mercurial.i18n import _
 from mercurial.node import short
-from mercurial import cmdutil, templater, util
+from mercurial import cmdutil, mail, templater, util
 import re, time, xmlrpclib
 
 class bzaccess(object):
@@ -520,6 +560,59 @@
     def add_comment(self, bugid, text, committer):
         self.bzproxy.Bug.add_comment(dict(id=bugid, comment=text))
 
+class bzxmlrpcemail(bzxmlrpc):
+    """Read data from Bugzilla via XMLRPC, send updates via email.
+
+    Advantages of sending updates via email:
+      1. Comments can be added as any user, not just logged in user.
+      2. Bug statuses and other fields not accessible via XMLRPC can
+        be updated. This is not currently used.
+    """
+
+    def __init__(self, ui):
+        bzxmlrpc.__init__(self, ui)
+
+        self.bzemail = self.ui.config('bugzilla', 'bzemail')
+        if not self.bzemail:
+            raise util.Abort(_("configuration 'bzemail' missing"))
+        mail.validateconfig(self.ui)
+
+    def send_bug_modify_email(self, bugid, commands, comment, committer):
+        '''send modification message to Bugzilla bug via email.
+
+        The message format is documented in the Bugzilla email_in.pl
+        specification. commands is a list of command lines, comment is the
+        comment text.
+
+        To stop users from crafting commit comments with
+        Bugzilla commands, specify the bug ID via the message body, rather
+        than the subject line, and leave a blank line after it.
+        '''
+        user = self.map_committer(committer)
+        matches = self.bzproxy.User.get(dict(match=[user]))
+        if not matches['users']:
+            user = self.ui.config('bugzilla', 'user', 'bugs')
+            matches = self.bzproxy.User.get(dict(match=[user]))
+            if not matches['users']:
+                raise util.Abort(_("default bugzilla user %s email not found") %
+                                 user)
+        user = matches['users'][0]['email']
+
+        text = "\n".join(commands) + "\n at bug_id = %d\n\n" % bugid + comment
+
+        _charsets = mail._charsets(self.ui)
+        user = mail.addressencode(self.ui, user, _charsets)
+        bzemail = mail.addressencode(self.ui, self.bzemail, _charsets)
+        msg = mail.mimeencode(self.ui, text, _charsets)
+        msg['From'] = user
+        msg['To'] = bzemail
+        msg['Subject'] = mail.headencode(self.ui, "Bug modification", _charsets)
+        sendmail = mail.connect(self.ui)
+        sendmail(user, bzemail, msg.as_string())
+
+    def add_comment(self, bugid, text, committer):
+        self.send_bug_modify_email(bugid, [], text, committer)
+
 class bugzilla(object):
     # supported versions of bugzilla. different versions have
     # different schemas.
@@ -527,7 +620,8 @@
         '2.16': bzmysql,
         '2.18': bzmysql_2_18,
         '3.0':  bzmysql_3_0,
-        'xmlrpc': bzxmlrpc
+        'xmlrpc': bzxmlrpc,
+        'xmlrpc+email': bzxmlrpcemail
         }
 
     _default_bug_re = (r'bugs?\s*,?\s*(?:#|nos?\.?|num(?:ber)?s?)?\s*'



More information about the Mercurial-devel mailing list