Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Side by Side Diff: sitescripts/hg/bin/update_issues.py

Issue 29336790: Issue 3674 - Add a hg hook that references commits in issues (Closed)
Patch Set: Address comments Created Feb. 22, 2016, 8:04 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 #!/usr/bin/env python
2
3 # This file is part of Adblock Plus <https://adblockplus.org/>,
4 # Copyright (C) 2006-2016 Eyeo GmbH
5 #
6 # Adblock Plus is free software: you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License version 3 as
8 # published by the Free Software Foundation.
9 #
10 # Adblock Plus is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>.
17
18 """
19 This module implements a changegroup (or pretxnchangegroup) hook that inspects
20 all commit messages and checks if issues from the Adblock Plus issue tracker are
21 being referenced. If there are, it updates them with the respective changeset
22 URLs.
23 """
24
25 import posixpath
26 import re
27 import xmlrpclib
28
29 from sitescripts.utils import get_config, get_template
30
31 def _generate_comments(repository_name, changes_by_issue):
32 comments = {}
33 template = get_template("hg/template/issue_commit_comment.tmpl")
Wladimir Palant 2016/02/23 10:41:31 I think you need autoescape=False here.
Felix Dahlke 2016/02/23 16:22:59 Done.
34 for issue_id, changes in changes_by_issue.iteritems():
35 comments[issue_id] = template.render({"repository_name": repository_name,
36 "changes": changes})
37 return comments
38
39 def _post_comment(issue_id, comment):
40 issue_id = int(issue_id)
41 url = get_config().get("hg", "trac_xmlrpc_url")
42 server = xmlrpclib.ServerProxy(url)
43 attributes = server.ticket.get(issue_id)[3]
44 server.ticket.update(issue_id, comment,
45 {"_ts": attributes["_ts"], "action": "leave"}, True)
46
47 def hook(ui, repo, node, **kwargs):
48 first_change = repo[node]
49 issue_number_regex = re.compile(r"\bissue\s+(\d+)\b", re.I)
50 noissue_regex = re.compile(r"noissue\b", re.I)
Wladimir Palant 2016/02/23 10:41:31 This should be \bnoissue\b (make sure that the wor
Felix Dahlke 2016/02/23 16:22:59 I'm using match() so the message has to start with
Wladimir Palant 2016/02/23 21:33:23 We agreed a while ago that we shouldn't be using m
Felix Dahlke 2016/02/23 21:40:58 Fair enough. Tried to be smart, but this comment t
Wladimir Palant 2016/02/24 10:13:49 Yes, particularly with the regexp and re.match() n
51 changes_by_issue = {}
52 for revision in xrange(first_change.rev(), len(repo)):
53 change = repo[revision]
54 description = change.description()
55 issue_ids = issue_number_regex.findall(description)
56 if issue_ids:
57 for issue_id in issue_ids:
58 changes_by_issue.setdefault(issue_id, []).append(change)
59 elif not noissue_regex.match(description):
60 # We should just reject all changes when one of them has an invalid
61 # commit message format, see: https://issues.adblockplus.org/ticket/3679
Wladimir Palant 2016/02/23 10:41:31 Is that a TODO comment? Maybe it should actually s
Felix Dahlke 2016/02/23 16:22:59 Well it's referencing an issue, I normally do just
62 ui.warn("warning: invalid commit message format in changeset %s\n" %
63 change)
64
65 repository_name = posixpath.split(repo.url())[1]
66 comments = _generate_comments(repository_name, changes_by_issue)
67
68 issue_url_template = get_config().get("hg", "issue_url_template")
69 for issue_id, comment in comments.iteritems():
70 try:
71 _post_comment(issue_id, comment)
72 ui.status("updating %s\n" % issue_url_template.format(id=issue_id))
73 except:
74 ui.warn("warning: failed to update %s\n" %
75 issue_url_template.format(id=issue_id))
OLDNEW

Powered by Google App Engine
This is Rietveld