hgext/bugzilla.py
changeset 13802 49b5a1aaf726
parent 13801 60256f7f30c1
child 13832 9358fdeaa532
equal deleted inserted replaced
13801:60256f7f30c1 13802:49b5a1aaf726
    12 that refer to bugs by Bugzilla ID are seen. The comment is formatted using
    12 that refer to bugs by Bugzilla ID are seen. The comment is formatted using
    13 the Mercurial template mechanism.
    13 the Mercurial template mechanism.
    14 
    14 
    15 The hook does not change bug status.
    15 The hook does not change bug status.
    16 
    16 
    17 Two basic modes of access to Bugzilla are provided:
    17 Three basic modes of access to Bugzilla are provided:
    18 
    18 
    19 1. Access via the Bugzilla XMLRPC interface (requires Bugzilla 3.4 or later).
    19 1. Access via the Bugzilla XMLRPC interface. Requires Bugzilla 3.4 or later.
       
    20 
       
    21 2. Check data via the Bugzilla XMLRPC interface and submit bug change
       
    22    via email to Bugzilla email interface. Requires Bugzilla 3.4 or later.
    20 
    23 
    21 2. Writing directly to the Bugzilla database. Only Bugzilla installations
    24 2. Writing directly to the Bugzilla database. Only Bugzilla installations
    22    using MySQL are supported. Requires Python MySQLdb.
    25    using MySQL are supported. Requires Python MySQLdb.
    23 
    26 
    24 Writing directly to the database is susceptible to schema changes, and
    27 Writing directly to the database is susceptible to schema changes, and
    35 in the configuration. Comments are added under that username. Since the
    38 in the configuration. Comments are added under that username. Since the
    36 configuration must be readable by all Mercurial users, it is recommended
    39 configuration must be readable by all Mercurial users, it is recommended
    37 that the rights of that user are restricted in Bugzilla to the minimum
    40 that the rights of that user are restricted in Bugzilla to the minimum
    38 necessary to add comments.
    41 necessary to add comments.
    39 
    42 
    40 Configuration items common to both access modes:
    43 Access via XMLRPC/email behaves uses XMLRPC to query Bugzilla, but sends
       
    44 email to the Bugzilla email interface to submit comments to bugs.
       
    45 The From: address in the email is set to the email address of the Mercurial
       
    46 user, so the comment appears to come from the Mercurial user. In the event
       
    47 that the Mercurial user email is not recognised by Bugzilla as a Bugzilla
       
    48 user, the Bugzilla username and password used to log into Bugzilla are
       
    49 used instead as the source of the comment.
       
    50 
       
    51 Configuration items common to all access modes:
    41 
    52 
    42 [bugzilla]
    53 [bugzilla]
    43 version
    54 version
    44   This access type to use. Values recognised are:
    55   This access type to use. Values recognised are:
    45   xmlrpc  Bugzilla XMLRPC interface.
    56   xmlrpc       Bugzilla XMLRPC interface.
    46   3.0     MySQL access, Bugzilla 3.0 and later.
    57   xmlrpc+email Bugzilla XMLRPC and email interfaces.
    47   2.18    MySQL access, Bugzilla 2.18 and up to but not including 3.0.
    58   3.0          MySQL access, Bugzilla 3.0 and later.
    48   2.16    MySQL access, Bugzilla 2.16 and up to but not including 2.18.
    59   2.18         MySQL access, Bugzilla 2.18 and up to but not including 3.0.
       
    60   2.16         MySQL access, Bugzilla 2.16 and up to but not including 2.18.
    49 
    61 
    50 regexp
    62 regexp
    51   Regular expression to match bug IDs in changeset commit message.
    63   Regular expression to match bug IDs in changeset commit message.
    52   Must contain one "()" group. The default expression matches 'Bug
    64   Must contain one "()" group. The default expression matches 'Bug
    53   1234', 'Bug no. 1234', 'Bug number 1234', 'Bugs 1234,5678', 'Bug
    65   1234', 'Bug no. 1234', 'Bug number 1234', 'Bugs 1234,5678', 'Bug
    78 [web]
    90 [web]
    79 baseurl
    91 baseurl
    80   Base URL for browsing Mercurial repositories. Referenced from
    92   Base URL for browsing Mercurial repositories. Referenced from
    81   templates as {hgweb}.
    93   templates as {hgweb}.
    82 
    94 
       
    95 Configuration items common to XMLRPC+email and MySQL access modes:
       
    96 
       
    97 usermap
       
    98   Path of file containing Mercurial committer email to Bugzilla user email
       
    99   mappings. If specified, the file should contain one mapping per
       
   100   line, "committer"="Bugzilla user". See also the [usermap] section.
       
   101 
       
   102 [usermap]
       
   103 The [usermap] section is used to specify mappings of Mercurial
       
   104 committer email to Bugzilla user email. See also [bugzilla].usermap.
       
   105 Contains entries of the form "committer"="Bugzilla user".
       
   106 
    83 XMLRPC access mode configuration:
   107 XMLRPC access mode configuration:
    84 
   108 
    85 [bugzilla]
   109 [bugzilla]
    86 bzurl
   110 bzurl
    87   The base URL for the Bugzilla installation.
   111   The base URL for the Bugzilla installation.
    90 user
   114 user
    91   The username to use to log into Bugzilla via XMLRPC. Default 'bugs'.
   115   The username to use to log into Bugzilla via XMLRPC. Default 'bugs'.
    92 
   116 
    93 password
   117 password
    94   The password for Bugzilla login.
   118   The password for Bugzilla login.
       
   119 
       
   120 XMLRPC+email access mode uses the XMLRPC access mode configuration items,
       
   121 and also:
       
   122 
       
   123 [bugzilla]
       
   124 bzemail
       
   125   The Bugzilla email address.
       
   126 
       
   127 In addition, the Mercurial email settings must be configured. See the
       
   128 documentation for 'hgrc', sections '[email]' and '[smtp]'.
    95 
   129 
    96 MySQL access mode configuration:
   130 MySQL access mode configuration:
    97 
   131 
    98 [bugzilla]
   132 [bugzilla]
    99 host
   133 host
   125   emails. Substitutes from a map with 3 keys, 'bzdir', 'id' (bug id)
   159   emails. Substitutes from a map with 3 keys, 'bzdir', 'id' (bug id)
   126   and 'user' (committer bugzilla email). Default depends on version;
   160   and 'user' (committer bugzilla email). Default depends on version;
   127   from 2.18 it is "cd %(bzdir)s && perl -T contrib/sendbugmail.pl
   161   from 2.18 it is "cd %(bzdir)s && perl -T contrib/sendbugmail.pl
   128   %(id)s %(user)s".
   162   %(id)s %(user)s".
   129 
   163 
   130 usermap
       
   131   Path of file containing Mercurial committer ID to Bugzilla user ID
       
   132   mappings. If specified, the file should contain one mapping per
       
   133   line, "committer"="Bugzilla user". See also the [usermap] section.
       
   134 
       
   135 [usermap]
       
   136 The [usermap] section is used to specify mappings of Mercurial
       
   137 committer email to Bugzilla user email. See also [bugzilla].usermap.
       
   138 Contains entries of the form "committer"="Bugzilla user".
       
   139 
       
   140 Activating the extension::
   164 Activating the extension::
   141 
   165 
   142     [extensions]
   166     [extensions]
   143     bugzilla =
   167     bugzilla =
   144 
   168 
   159     password=plugh
   183     password=plugh
   160     version=xmlrpc
   184     version=xmlrpc
   161 
   185 
   162     [web]
   186     [web]
   163     baseurl=http://my-project.org/hg
   187     baseurl=http://my-project.org/hg
       
   188 
       
   189 XMLRPC+email example configuration. This uses the Bugzilla at
       
   190 'http://my-project.org/bugzilla', logging in as user 'bugmail@my-project.org'
       
   191 wityh password 'plugh'. It is used with a collection of Mercurial
       
   192 repositories in '/var/local/hg/repos/'. Bug comments are sent to the
       
   193 Bugzilla email address 'buzilla@my-project.org'. ::
       
   194 
       
   195     [bugzilla]
       
   196     user=bugmail@my-project.org
       
   197     password=plugh
       
   198     version=xmlrpc
       
   199     bzemail=bugzilla@my-project.org
       
   200 
       
   201     [web]
       
   202     baseurl=https://dev.laicatc.com/hg
       
   203     bugzillaurl=https://dev.laicatc.com/bugzilla
   164 
   204 
   165 MySQL example configuration. This is for a collection of Mercurial
   205 MySQL example configuration. This is for a collection of Mercurial
   166 repositories in '/var/local/hg/repos/' used with a local Bugzilla 3.2
   206 repositories in '/var/local/hg/repos/' used with a local Bugzilla 3.2
   167 installation in /opt/bugzilla-3.2. The MySQL database is on 'localhost',
   207 installation in /opt/bugzilla-3.2. The MySQL database is on 'localhost',
   168 the Bugzilla database name is 'bugs' and MySQL is accessed with MySQL
   208 the Bugzilla database name is 'bugs' and MySQL is accessed with MySQL
   183     baseurl=http://dev.domain.com/hg
   223     baseurl=http://dev.domain.com/hg
   184 
   224 
   185     [usermap]
   225     [usermap]
   186     user@emaildomain.com=user.name@bugzilladomain.com
   226     user@emaildomain.com=user.name@bugzilladomain.com
   187 
   227 
   188 Both the above add a comment to the Bugzilla bug record of the form::
   228 All the above add a comment to the Bugzilla bug record of the form::
   189 
   229 
   190     Changeset 3b16791d6642 in repository-name.
   230     Changeset 3b16791d6642 in repository-name.
   191     http://dev.domain.com/hg/repository-name/rev/3b16791d6642
   231     http://dev.domain.com/hg/repository-name/rev/3b16791d6642
   192 
   232 
   193     Changeset commit comment. Bug 1234.
   233     Changeset commit comment. Bug 1234.
   194 '''
   234 '''
   195 
   235 
   196 from mercurial.i18n import _
   236 from mercurial.i18n import _
   197 from mercurial.node import short
   237 from mercurial.node import short
   198 from mercurial import cmdutil, templater, util
   238 from mercurial import cmdutil, mail, templater, util
   199 import re, time, xmlrpclib
   239 import re, time, xmlrpclib
   200 
   240 
   201 class bzaccess(object):
   241 class bzaccess(object):
   202     '''Base class for access to Bugzilla.'''
   242     '''Base class for access to Bugzilla.'''
   203 
   243 
   518         return ids
   558         return ids
   519 
   559 
   520     def add_comment(self, bugid, text, committer):
   560     def add_comment(self, bugid, text, committer):
   521         self.bzproxy.Bug.add_comment(dict(id=bugid, comment=text))
   561         self.bzproxy.Bug.add_comment(dict(id=bugid, comment=text))
   522 
   562 
       
   563 class bzxmlrpcemail(bzxmlrpc):
       
   564     """Read data from Bugzilla via XMLRPC, send updates via email.
       
   565 
       
   566     Advantages of sending updates via email:
       
   567       1. Comments can be added as any user, not just logged in user.
       
   568       2. Bug statuses and other fields not accessible via XMLRPC can
       
   569         be updated. This is not currently used.
       
   570     """
       
   571 
       
   572     def __init__(self, ui):
       
   573         bzxmlrpc.__init__(self, ui)
       
   574 
       
   575         self.bzemail = self.ui.config('bugzilla', 'bzemail')
       
   576         if not self.bzemail:
       
   577             raise util.Abort(_("configuration 'bzemail' missing"))
       
   578         mail.validateconfig(self.ui)
       
   579 
       
   580     def send_bug_modify_email(self, bugid, commands, comment, committer):
       
   581         '''send modification message to Bugzilla bug via email.
       
   582 
       
   583         The message format is documented in the Bugzilla email_in.pl
       
   584         specification. commands is a list of command lines, comment is the
       
   585         comment text.
       
   586 
       
   587         To stop users from crafting commit comments with
       
   588         Bugzilla commands, specify the bug ID via the message body, rather
       
   589         than the subject line, and leave a blank line after it.
       
   590         '''
       
   591         user = self.map_committer(committer)
       
   592         matches = self.bzproxy.User.get(dict(match=[user]))
       
   593         if not matches['users']:
       
   594             user = self.ui.config('bugzilla', 'user', 'bugs')
       
   595             matches = self.bzproxy.User.get(dict(match=[user]))
       
   596             if not matches['users']:
       
   597                 raise util.Abort(_("default bugzilla user %s email not found") %
       
   598                                  user)
       
   599         user = matches['users'][0]['email']
       
   600 
       
   601         text = "\n".join(commands) + "\n@bug_id = %d\n\n" % bugid + comment
       
   602 
       
   603         _charsets = mail._charsets(self.ui)
       
   604         user = mail.addressencode(self.ui, user, _charsets)
       
   605         bzemail = mail.addressencode(self.ui, self.bzemail, _charsets)
       
   606         msg = mail.mimeencode(self.ui, text, _charsets)
       
   607         msg['From'] = user
       
   608         msg['To'] = bzemail
       
   609         msg['Subject'] = mail.headencode(self.ui, "Bug modification", _charsets)
       
   610         sendmail = mail.connect(self.ui)
       
   611         sendmail(user, bzemail, msg.as_string())
       
   612 
       
   613     def add_comment(self, bugid, text, committer):
       
   614         self.send_bug_modify_email(bugid, [], text, committer)
       
   615 
   523 class bugzilla(object):
   616 class bugzilla(object):
   524     # supported versions of bugzilla. different versions have
   617     # supported versions of bugzilla. different versions have
   525     # different schemas.
   618     # different schemas.
   526     _versions = {
   619     _versions = {
   527         '2.16': bzmysql,
   620         '2.16': bzmysql,
   528         '2.18': bzmysql_2_18,
   621         '2.18': bzmysql_2_18,
   529         '3.0':  bzmysql_3_0,
   622         '3.0':  bzmysql_3_0,
   530         'xmlrpc': bzxmlrpc
   623         'xmlrpc': bzxmlrpc,
       
   624         'xmlrpc+email': bzxmlrpcemail
   531         }
   625         }
   532 
   626 
   533     _default_bug_re = (r'bugs?\s*,?\s*(?:#|nos?\.?|num(?:ber)?s?)?\s*'
   627     _default_bug_re = (r'bugs?\s*,?\s*(?:#|nos?\.?|num(?:ber)?s?)?\s*'
   534                        r'((?:\d+\s*(?:,?\s*(?:and)?)?\s*)+)')
   628                        r'((?:\d+\s*(?:,?\s*(?:and)?)?\s*)+)')
   535 
   629