Show More
@@ -12,7 +12,8 This hook extension adds comments on bug | |||||
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 bug references can optionally include an update for Bugzilla of the | |
|
16 | hours spent working on the bug. | |||
16 |
|
17 | |||
17 | Three basic modes of access to Bugzilla are provided: |
|
18 | Three basic modes of access to Bugzilla are provided: | |
18 |
|
19 | |||
@@ -32,7 +33,7 permission to read Bugzilla configuratio | |||||
32 | MySQL user and password to have full access rights to the Bugzilla |
|
33 | MySQL user and password to have full access rights to the Bugzilla | |
33 | database. For these reasons this access mode is now considered |
|
34 | database. For these reasons this access mode is now considered | |
34 | deprecated, and will not be updated for new Bugzilla versions going |
|
35 | deprecated, and will not be updated for new Bugzilla versions going | |
35 | forward. |
|
36 | forward. Only adding comments is supported in this access mode. | |
36 |
|
37 | |||
37 | Access via XMLRPC needs a Bugzilla username and password to be specified |
|
38 | Access via XMLRPC needs a Bugzilla username and password to be specified | |
38 | in the configuration. Comments are added under that username. Since the |
|
39 | in the configuration. Comments are added under that username. Since the | |
@@ -63,10 +64,15 bugzilla.version | |||||
63 |
|
64 | |||
64 | bugzilla.regexp |
|
65 | bugzilla.regexp | |
65 | Regular expression to match bug IDs in changeset commit message. |
|
66 | Regular expression to match bug IDs in changeset commit message. | |
66 | Must contain one "()" group. The default expression matches ``Bug |
|
67 | It must contain one "()" named group ``<ids>`` containing the bug | |
67 | 1234``, ``Bug no. 1234``, ``Bug number 1234``, ``Bugs 1234,5678``, |
|
68 | IDs separated by non-digit characters. It may also contain | |
68 | ``Bug 1234 and 5678`` and variations thereof. Matching is case |
|
69 | a named group ``<hours>`` with a floating-point number giving the | |
69 | insensitive. |
|
70 | hours worked on the bug. If no named groups are present, the first | |
|
71 | "()" group is assumed to contain the bug IDs, and work time is not | |||
|
72 | updated. The default expression matches ``Bug 1234``, ``Bug no. 1234``, | |||
|
73 | ``Bug number 1234``, ``Bugs 1234,5678``, ``Bug 1234 and 5678`` and | |||
|
74 | variations thereof, followed by an hours number prefixed by ``h`` or | |||
|
75 | ``hours``, e.g. ``hours 1.5``. Matching is case insensitive. | |||
70 |
|
76 | |||
71 | bugzilla.style |
|
77 | bugzilla.style | |
72 | The style file to use when formatting comments. |
|
78 | The style file to use when formatting comments. | |
@@ -276,8 +282,10 class bzaccess(object): | |||||
276 | # Methods to be implemented by access classes. |
|
282 | # Methods to be implemented by access classes. | |
277 | # |
|
283 | # | |
278 | # 'bugs' is a dict keyed on bug id, where values are a dict holding |
|
284 | # 'bugs' is a dict keyed on bug id, where values are a dict holding | |
279 |
# updates to bug state. |
|
285 | # updates to bug state. Recognised dict keys are: | |
280 | # will change soon. |
|
286 | # | |
|
287 | # 'hours': Value, float containing work hours to be updated. | |||
|
288 | ||||
281 | def filter_real_bug_ids(self, bugs): |
|
289 | def filter_real_bug_ids(self, bugs): | |
282 | '''remove bug IDs that do not exist in Bugzilla from bugs.''' |
|
290 | '''remove bug IDs that do not exist in Bugzilla from bugs.''' | |
283 | pass |
|
291 | pass | |
@@ -449,6 +457,9 class bzmysql(bzaccess): | |||||
449 |
|
457 | |||
450 | Try adding comment as committer of changeset, otherwise as |
|
458 | Try adding comment as committer of changeset, otherwise as | |
451 | default bugzilla user.''' |
|
459 | default bugzilla user.''' | |
|
460 | if len(newstate) > 0: | |||
|
461 | self.ui.warn(_("Bugzilla/MySQL cannot update bug state\n")) | |||
|
462 | ||||
452 | (user, userid) = self.get_bugzilla_user(committer) |
|
463 | (user, userid) = self.get_bugzilla_user(committer) | |
453 | now = time.strftime('%Y-%m-%d %H:%M:%S') |
|
464 | now = time.strftime('%Y-%m-%d %H:%M:%S') | |
454 | self.run('''insert into longdescs |
|
465 | self.run('''insert into longdescs | |
@@ -608,6 +619,8 class bzxmlrpc(bzaccess): | |||||
608 |
|
619 | |||
609 | def updatebug(self, bugid, newstate, text, committer): |
|
620 | def updatebug(self, bugid, newstate, text, committer): | |
610 | args = dict(id=bugid, comment=text) |
|
621 | args = dict(id=bugid, comment=text) | |
|
622 | if 'hours' in newstate: | |||
|
623 | args['work_time'] = newstate['hours'] | |||
611 | self.bzproxy.Bug.add_comment(args) |
|
624 | self.bzproxy.Bug.add_comment(args) | |
612 |
|
625 | |||
613 | class bzxmlrpcemail(bzxmlrpc): |
|
626 | class bzxmlrpcemail(bzxmlrpc): | |
@@ -615,8 +628,11 class bzxmlrpcemail(bzxmlrpc): | |||||
615 |
|
628 | |||
616 | Advantages of sending updates via email: |
|
629 | Advantages of sending updates via email: | |
617 | 1. Comments can be added as any user, not just logged in user. |
|
630 | 1. Comments can be added as any user, not just logged in user. | |
618 |
2. Bug statuses |
|
631 | 2. Bug statuses or other fields not accessible via XMLRPC can | |
619 | be updated. This is not currently used. |
|
632 | potentially be updated. | |
|
633 | ||||
|
634 | Currently all status updates recognised can be done via XMLRPC, so | |||
|
635 | item 1 is the only actual advantage. | |||
620 | """ |
|
636 | """ | |
621 |
|
637 | |||
622 | def __init__(self, ui): |
|
638 | def __init__(self, ui): | |
@@ -661,7 +677,10 class bzxmlrpcemail(bzxmlrpc): | |||||
661 | sendmail(user, bzemail, msg.as_string()) |
|
677 | sendmail(user, bzemail, msg.as_string()) | |
662 |
|
678 | |||
663 | def updatebug(self, bugid, newstate, text, committer): |
|
679 | def updatebug(self, bugid, newstate, text, committer): | |
664 | self.send_bug_modify_email(bugid, [], text, committer) |
|
680 | cmds = [] | |
|
681 | if 'hours' in newstate: | |||
|
682 | cmds.append(self.makecommandline("work_time", newstate['hours'])) | |||
|
683 | self.send_bug_modify_email(bugid, cmds, text, committer) | |||
665 |
|
684 | |||
666 | class bugzilla(object): |
|
685 | class bugzilla(object): | |
667 | # supported versions of bugzilla. different versions have |
|
686 | # supported versions of bugzilla. different versions have | |
@@ -675,7 +694,8 class bugzilla(object): | |||||
675 | } |
|
694 | } | |
676 |
|
695 | |||
677 | _default_bug_re = (r'bugs?\s*,?\s*(?:#|nos?\.?|num(?:ber)?s?)?\s*' |
|
696 | _default_bug_re = (r'bugs?\s*,?\s*(?:#|nos?\.?|num(?:ber)?s?)?\s*' | |
678 |
r'((?:\d+\s*(?:,?\s*(?:and)?)?\s*)+)' |
|
697 | r'(?P<ids>(?:\d+\s*(?:,?\s*(?:and)?)?\s*)+)' | |
|
698 | r'\.?\s*(?:h(?:ours?)?\s*(?P<hours>\d*(?:\.\d+)?))?') | |||
679 |
|
699 | |||
680 | _bz = None |
|
700 | _bz = None | |
681 |
|
701 | |||
@@ -716,16 +736,32 class bugzilla(object): | |||||
716 | re.IGNORECASE) |
|
736 | re.IGNORECASE) | |
717 | bugzilla._split_re = re.compile(r'\D+') |
|
737 | bugzilla._split_re = re.compile(r'\D+') | |
718 | start = 0 |
|
738 | start = 0 | |
|
739 | hours = 0.0 | |||
719 | bugs = {} |
|
740 | bugs = {} | |
720 | while True: |
|
741 | while True: | |
|
742 | bugattribs = {} | |||
721 | m = bugzilla._bug_re.search(ctx.description(), start) |
|
743 | m = bugzilla._bug_re.search(ctx.description(), start) | |
722 | if not m: |
|
744 | if not m: | |
723 | break |
|
745 | break | |
724 | start = m.end() |
|
746 | start = m.end() | |
725 | for id in bugzilla._split_re.split(m.group(1)): |
|
747 | try: | |
|
748 | ids = m.group('ids') | |||
|
749 | except IndexError: | |||
|
750 | ids = m.group(1) | |||
|
751 | try: | |||
|
752 | hours = float(m.group('hours')) | |||
|
753 | bugattribs['hours'] = hours | |||
|
754 | except IndexError: | |||
|
755 | pass | |||
|
756 | except TypeError: | |||
|
757 | pass | |||
|
758 | except ValueError: | |||
|
759 | self.ui.status(_("%s: invalid hours\n") % m.group('hours')) | |||
|
760 | ||||
|
761 | for id in bugzilla._split_re.split(ids): | |||
726 | if not id: |
|
762 | if not id: | |
727 | continue |
|
763 | continue | |
728 |
bugs[int(id)] = |
|
764 | bugs[int(id)] = bugattribs | |
729 | if bugs: |
|
765 | if bugs: | |
730 | self.filter_real_bug_ids(bugs) |
|
766 | self.filter_real_bug_ids(bugs) | |
731 | if bugs: |
|
767 | if bugs: |
General Comments 0
You need to be logged in to leave comments.
Login now