Show More
@@ -13,7 +13,7 b' that refer to bugs by Bugzilla ID are se' | |||
|
13 | 13 | the Mercurial template mechanism. |
|
14 | 14 | |
|
15 | 15 | The bug references can optionally include an update for Bugzilla of the |
|
16 | hours spent working on the bug. | |
|
16 | hours spent working on the bug. Bugs can also be marked fixed. | |
|
17 | 17 | |
|
18 | 18 | Three basic modes of access to Bugzilla are provided: |
|
19 | 19 | |
@@ -39,7 +39,7 b' Access via XMLRPC needs a Bugzilla usern' | |||
|
39 | 39 | in the configuration. Comments are added under that username. Since the |
|
40 | 40 | configuration must be readable by all Mercurial users, it is recommended |
|
41 | 41 | that the rights of that user are restricted in Bugzilla to the minimum |
|
42 | necessary to add comments. | |
|
42 | necessary to add comments. Marking bugs fixed requires Bugzilla 4.0 and later. | |
|
43 | 43 | |
|
44 | 44 | Access via XMLRPC/email uses XMLRPC to query Bugzilla, but sends |
|
45 | 45 | email to the Bugzilla email interface to submit comments to bugs. |
@@ -47,7 +47,8 b' The From: address in the email is set to' | |||
|
47 | 47 | user, so the comment appears to come from the Mercurial user. In the event |
|
48 | 48 | that the Mercurial user email is not recognised by Bugzilla as a Bugzilla |
|
49 | 49 | user, the email associated with the Bugzilla username used to log into |
|
50 | Bugzilla is used instead as the source of the comment. | |
|
50 | Bugzilla is used instead as the source of the comment. Marking bugs fixed | |
|
51 | works on all supported Bugzilla versions. | |
|
51 | 52 | |
|
52 | 53 | Configuration items common to all access modes: |
|
53 | 54 | |
@@ -63,7 +64,7 b' bugzilla.version' | |||
|
63 | 64 | including 2.18. |
|
64 | 65 | |
|
65 | 66 | bugzilla.regexp |
|
66 | Regular expression to match bug IDs in changeset commit message. | |
|
67 | Regular expression to match bug IDs for update in changeset commit message. | |
|
67 | 68 | It must contain one "()" named group ``<ids>`` containing the bug |
|
68 | 69 | IDs separated by non-digit characters. It may also contain |
|
69 | 70 | a named group ``<hours>`` with a floating-point number giving the |
@@ -74,6 +75,24 b' bugzilla.regexp' | |||
|
74 | 75 | variations thereof, followed by an hours number prefixed by ``h`` or |
|
75 | 76 | ``hours``, e.g. ``hours 1.5``. Matching is case insensitive. |
|
76 | 77 | |
|
78 | bugzilla.fixregexp | |
|
79 | Regular expression to match bug IDs for marking fixed in changeset | |
|
80 | commit message. This must contain a "()" named group ``<ids>` containing | |
|
81 | the bug IDs separated by non-digit characters. It may also contain | |
|
82 | a named group ``<hours>`` with a floating-point number giving the | |
|
83 | hours worked on the bug. If no named groups are present, the first | |
|
84 | "()" group is assumed to contain the bug IDs, and work time is not | |
|
85 | updated. The default expression matches ``Fixes 1234``, ``Fixes bug 1234``, | |
|
86 | ``Fixes bugs 1234,5678``, ``Fixes 1234 and 5678`` and | |
|
87 | variations thereof, followed by an hours number prefixed by ``h`` or | |
|
88 | ``hours``, e.g. ``hours 1.5``. Matching is case insensitive. | |
|
89 | ||
|
90 | bugzilla.fixstatus | |
|
91 | The status to set a bug to when marking fixed. Default ``RESOLVED``. | |
|
92 | ||
|
93 | bugzilla.fixresolution | |
|
94 | The resolution to set a bug to when marking fixed. Default ``FIXED``. | |
|
95 | ||
|
77 | 96 | bugzilla.style |
|
78 | 97 | The style file to use when formatting comments. |
|
79 | 98 | |
@@ -285,6 +304,7 b' class bzaccess(object):' | |||
|
285 | 304 | # updates to bug state. Recognised dict keys are: |
|
286 | 305 | # |
|
287 | 306 | # 'hours': Value, float containing work hours to be updated. |
|
307 | # 'fix': If key present, bug is to be marked fixed. Value ignored. | |
|
288 | 308 | |
|
289 | 309 | def filter_real_bug_ids(self, bugs): |
|
290 | 310 | '''remove bug IDs that do not exist in Bugzilla from bugs.''' |
@@ -587,6 +607,10 b' class bzxmlrpc(bzaccess):' | |||
|
587 | 607 | user = self.ui.config('bugzilla', 'user', 'bugs') |
|
588 | 608 | passwd = self.ui.config('bugzilla', 'password') |
|
589 | 609 | |
|
610 | self.fixstatus = self.ui.config('bugzilla', 'fixstatus', 'RESOLVED') | |
|
611 | self.fixresolution = self.ui.config('bugzilla', 'fixresolution', | |
|
612 | 'FIXED') | |
|
613 | ||
|
590 | 614 | self.bzproxy = xmlrpclib.ServerProxy(bzweb, self.transport(bzweb)) |
|
591 | 615 | self.bzproxy.User.login(dict(login=user, password=passwd)) |
|
592 | 616 | |
@@ -618,10 +642,23 b' class bzxmlrpc(bzaccess):' | |||
|
618 | 642 | del bugs[id] |
|
619 | 643 | |
|
620 | 644 | def updatebug(self, bugid, newstate, text, committer): |
|
621 | args = dict(id=bugid, comment=text) | |
|
645 | args = {} | |
|
622 | 646 | if 'hours' in newstate: |
|
623 | 647 | args['work_time'] = newstate['hours'] |
|
624 | self.bzproxy.Bug.add_comment(args) | |
|
648 | ||
|
649 | if self.bzvermajor >= 4: | |
|
650 | args['ids'] = [bugid] | |
|
651 | args['comment'] = {'body' : text} | |
|
652 | args['status'] = self.fixstatus | |
|
653 | args['resolution'] = self.fixresolution | |
|
654 | self.bzproxy.Bug.update(args) | |
|
655 | else: | |
|
656 | if 'fix' in newstate: | |
|
657 | self.ui.warn(_("Bugzilla/XMLRPC needs Bugzilla 4.0 or later " | |
|
658 | "to mark bugs fixed\n")) | |
|
659 | args['id'] = bugid | |
|
660 | args['comment'] = text | |
|
661 | self.bzproxy.Bug.add_comment(args) | |
|
625 | 662 | |
|
626 | 663 | class bzxmlrpcemail(bzxmlrpc): |
|
627 | 664 | """Read data from Bugzilla via XMLRPC, send updates via email. |
@@ -631,8 +668,9 b' class bzxmlrpcemail(bzxmlrpc):' | |||
|
631 | 668 | 2. Bug statuses or other fields not accessible via XMLRPC can |
|
632 | 669 | potentially be updated. |
|
633 | 670 | |
|
634 | Currently all status updates recognised can be done via XMLRPC, so | |
|
635 | item 1 is the only actual advantage. | |
|
671 | There is no XMLRPC function to change bug status before Bugzilla | |
|
672 | 4.0, so bugs cannot be marked fixed via XMLRPC before Bugzilla 4.0. | |
|
673 | But bugs can be marked fixed via email from 3.4 onwards. | |
|
636 | 674 | """ |
|
637 | 675 | |
|
638 | 676 | def __init__(self, ui): |
@@ -680,6 +718,9 b' class bzxmlrpcemail(bzxmlrpc):' | |||
|
680 | 718 | cmds = [] |
|
681 | 719 | if 'hours' in newstate: |
|
682 | 720 | cmds.append(self.makecommandline("work_time", newstate['hours'])) |
|
721 | if 'fix' in newstate: | |
|
722 | cmds.append(self.makecommandline("bug_status", self.fixstatus)) | |
|
723 | cmds.append(self.makecommandline("resolution", self.fixresolution)) | |
|
683 | 724 | self.send_bug_modify_email(bugid, cmds, text, committer) |
|
684 | 725 | |
|
685 | 726 | class bugzilla(object): |
@@ -697,6 +738,11 b' class bugzilla(object):' | |||
|
697 | 738 | r'(?P<ids>(?:\d+\s*(?:,?\s*(?:and)?)?\s*)+)' |
|
698 | 739 | r'\.?\s*(?:h(?:ours?)?\s*(?P<hours>\d*(?:\.\d+)?))?') |
|
699 | 740 | |
|
741 | _default_fix_re = (r'fix(?:es)?\s*(?:bugs?\s*)?,?\s*' | |
|
742 | r'(?:nos?\.?|num(?:ber)?s?)?\s*' | |
|
743 | r'(?P<ids>(?:#?\d+\s*(?:,?\s*(?:and)?)?\s*)+)' | |
|
744 | r'\.?\s*(?:h(?:ours?)?\s*(?P<hours>\d*(?:\.\d+)?))?') | |
|
745 | ||
|
700 | 746 | _bz = None |
|
701 | 747 | |
|
702 | 748 | def __init__(self, ui, repo): |
@@ -721,6 +767,7 b' class bugzilla(object):' | |||
|
721 | 767 | return getattr(self.bz(), key) |
|
722 | 768 | |
|
723 | 769 | _bug_re = None |
|
770 | _fix_re = None | |
|
724 | 771 | _split_re = None |
|
725 | 772 | |
|
726 | 773 | def find_bugs(self, ctx): |
@@ -732,18 +779,39 b' class bugzilla(object):' | |||
|
732 | 779 | ''' |
|
733 | 780 | if bugzilla._bug_re is None: |
|
734 | 781 | bugzilla._bug_re = re.compile( |
|
735 |
self.ui.config('bugzilla', 'regexp', |
|
|
736 | re.IGNORECASE) | |
|
782 | self.ui.config('bugzilla', 'regexp', | |
|
783 | bugzilla._default_bug_re), re.IGNORECASE) | |
|
784 | bugzilla._fix_re = re.compile( | |
|
785 | self.ui.config('bugzilla', 'fixregexp', | |
|
786 | bugzilla._default_fix_re), re.IGNORECASE) | |
|
737 | 787 | bugzilla._split_re = re.compile(r'\D+') |
|
738 | 788 | start = 0 |
|
739 | 789 | hours = 0.0 |
|
740 | 790 | bugs = {} |
|
791 | bugmatch = bugzilla._bug_re.search(ctx.description(), start) | |
|
792 | fixmatch = bugzilla._fix_re.search(ctx.description(), start) | |
|
741 | 793 | while True: |
|
742 | 794 | bugattribs = {} |
|
743 | m = bugzilla._bug_re.search(ctx.description(), start) | |
|
744 | if not m: | |
|
795 | if not bugmatch and not fixmatch: | |
|
745 | 796 | break |
|
797 | if not bugmatch: | |
|
798 | m = fixmatch | |
|
799 | elif not fixmatch: | |
|
800 | m = bugmatch | |
|
801 | else: | |
|
802 | if bugmatch.start() < fixmatch.start(): | |
|
803 | m = bugmatch | |
|
804 | else: | |
|
805 | m = fixmatch | |
|
746 | 806 | start = m.end() |
|
807 | if m is bugmatch: | |
|
808 | bugmatch = bugzilla._bug_re.search(ctx.description(), start) | |
|
809 | if 'fix' in bugattribs: | |
|
810 | del bugattribs['fix'] | |
|
811 | else: | |
|
812 | fixmatch = bugzilla._fix_re.search(ctx.description(), start) | |
|
813 | bugattribs['fix'] = None | |
|
814 | ||
|
747 | 815 | try: |
|
748 | 816 | ids = m.group('ids') |
|
749 | 817 | except IndexError: |
General Comments 0
You need to be logged in to leave comments.
Login now