/[adm]/puppet/deployment/mgagit/templates/git-post-receive-hook
ViewVC logotype

Contents of /puppet/deployment/mgagit/templates/git-post-receive-hook

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3461 - (show annotations) (download)
Sun Apr 27 12:20:34 2014 UTC (9 years, 11 months ago) by colin
File size: 10503 byte(s)
mgagit: Add new mail headers to the i18n mails.
1 #!/usr/bin/python
2
3 import sys
4 import os
5 import re
6
7 LIBDIR = '<%= @gitolite_commonhooksdir %>'
8 sys.path.insert(0, LIBDIR)
9
10 import git_multimail
11
12 import xmlrpclib
13 from cookielib import LWPCookieJar
14 from bugz.bugzilla import BugzillaProxy
15
16 import urllib2
17
18 # When editing this list, remember to edit the same list in
19 # modules/cgit/templates/filter.commit-links.sh
20 BUG_REFS = {
21 'Mageia': { 're': re.compile('mga#([0-9]+)'), 'replace': 'https://bugs.mageia.org/show_bug.cgi?id=%s' },
22 'Red Hat': { 're': re.compile('rhbz#([0-9]+)'), 'replace': 'https://bugzilla.redhat.com/show_bug.cgi?id=%s' },
23 'Free Desktop': { 're': re.compile('fdo#([0-9]+)'), 'replace': 'https://bugs.freedesktop.org/show_bug.cgi?id=%s' },
24 'KDE': { 're': re.compile('(?:bko|kde)#([0-9]+)'), 'replace': 'https://bugs.kde.org/show_bug.cgi?id=%s' },
25 'GNOME': { 're': re.compile('(?:bgo|gnome)#([0-9]+)'), 'replace': 'https://bugzilla.gnome.org/show_bug.cgi?id=%s' },
26 'Launchpad': { 're': re.compile('lp#([0-9]+)'), 'replace': 'https://launchpad.net/bugs/%s' },
27 }
28
29 COMMIT_RE = re.compile('^commit ([a-f0-9]{40})')
30 COMMIT_REPLACE = 'http://gitweb.mageia.org/%s/commit/?id=%s'
31
32 MAGEIA_BUGZILLA_URL = 'https://bugs.mageia.org/xmlrpc.cgi'
33 MAGEIA_BUGZILLA_PASSWORD_FILE = '.gitzilla-password'
34 MAGEIA_BUGZILLA_COOKIE_FILE = '.gitzilla-cookie'
35
36
37 git_multimail.FOOTER_TEMPLATE = """\
38
39 -- \n\
40 Mageia Git Monkeys.
41 """
42 git_multimail.REVISION_FOOTER_TEMPLATE = git_multimail.FOOTER_TEMPLATE
43
44 I18N_REVISION_HEADER_TEMPLATE = """\
45 Date: %(send_date)s
46 To: %(recipients)s
47 Subject: %(emailprefix)s%(oneline)s
48 MIME-Version: 1.0
49 Content-Type: text/plain; charset=%(charset)s
50 Content-Transfer-Encoding: 8bit
51 From: %(fromaddr)s
52 Reply-To: %(reply_to)s
53 In-Reply-To: %(reply_to_msgid)s
54 References: %(reply_to_msgid)s
55 X-Git-Host: %(fqdn)s
56 X-Git-Repo: %(repo_shortname)s
57 X-Git-Refname: %(refname)s
58 X-Git-Reftype: %(refname_type)s
59 X-Git-Rev: %(rev)s
60 Auto-Submitted: auto-generated
61 """
62
63
64 REPO_NAME_RE = re.compile(r'^/git/(?P<name>.+?)(?:\.git)?$')
65 def repo_shortname():
66 basename = os.path.abspath(git_multimail.get_git_dir())
67 m = REPO_NAME_RE.match(basename)
68 if m:
69 return m.group('name')
70 else:
71 return basename
72
73
74 # Override the Environment class to generate an apporpriate short name which is
75 # used in git links and as an email prefix
76 class MageiaEnvironment(git_multimail.Environment):
77 def get_repo_shortname(self):
78 return repo_shortname()
79 git_multimail.Environment = MageiaEnvironment
80
81
82 # Override the Reviesion class to inject gitweb/cgit links and any referenced
83 # bug URLs
84 class MageiaLinksRevision(git_multimail.Revision):
85 bz = None
86
87 def bugzilla_init(self):
88 if self.bz is None:
89 cookie_file = os.path.join(os.environ['HOME'], MAGEIA_BUGZILLA_COOKIE_FILE)
90 self.cookiejar = LWPCookieJar(cookie_file)
91 try:
92 self.cookiejar.load()
93 except IOError:
94 pass
95
96 self.bz = BugzillaProxy(MAGEIA_BUGZILLA_URL, cookiejar=self.cookiejar)
97 return self.bz
98
99 def bugzilla_login(self):
100 params = {
101 'login': 'bot',
102 'password': open(os.path.join(os.environ['HOME'], MAGEIA_BUGZILLA_PASSWORD_FILE), 'r').readline().rstrip(),
103 'remember': True
104 }
105 self.bz.User.login(params)
106 self.cookiejar.save()
107 os.chmod(self.cookiejar.filename, 0600)
108
109 def bugzilla_call(self, method, *args):
110 """Attempt to call method with args. Log in if authentication is required.
111 """
112 try:
113 return method(*args)
114 except xmlrpclib.Fault, fault:
115 # Fault code 410 means login required
116 if fault.faultCode == 410:
117 self.bugzilla_login()
118 return method(*args)
119 raise
120
121 def generate_email_body(self, push):
122 """Show this revision."""
123
124 output = git_multimail.read_git_lines(
125 ['log'] + self.environment.commitlogopts + ['-1', self.rev.sha1],
126 keepends=True,
127 )
128 bugs = {}
129 commit = None
130 idx = 0
131 for line in output:
132 idx += 1
133 if line == "---\n":
134 if commit and COMMIT_REPLACE:
135 output.insert(idx, "\n")
136 output.insert(idx, " %s\n" % (COMMIT_REPLACE % (self.environment.get_repo_shortname(), commit)))
137 output.insert(idx, " Commit Link:\n")
138 idx += 3
139 if bugs:
140 output.insert(idx, " Bug links:\n")
141 idx += 1
142 for tracker, bugnos in bugs.items():
143 output.insert(idx, " %s\n" % tracker)
144 idx += 1
145 for bugno in bugnos:
146 output.insert(idx, " %s\n" % (BUG_REFS[tracker]['replace'] % bugno))
147 idx += 1
148 output.insert(idx, "\n")
149 idx += 1
150
151 # Attempt to modify bugzilla
152 if "Mageia" in bugs:
153 try:
154 bz = self.bugzilla_init()
155
156 # Mask email address
157 comment = None
158 # Suppress the "Bug links:" section if only one bug
159 # is referenced
160 if len(bugs) == 1 and len(bugs['Mageia']) == 1:
161 comment = output[0:idx-4]
162 else:
163 comment = output[0:idx]
164 comment[1] = re.sub(r'^(Author: [^@]*)@.*(>)?', r'\1@...>', comment[1])
165 comment = "".join(comment)
166
167 params = {}
168 params['ids'] = bugs['Mageia']
169 params['comment'] = { 'body': comment }
170 self.bugzilla_call(bz.Bug.update, params)
171 print "Updated bugzilla bugs: %s" % ", ".join(bugs['Mageia'])
172 except:
173 print "Unable to post to bugzilla bugs: %s :(" % ", ".join(bugs['Mageia'])
174 pass
175
176 break
177 m = COMMIT_RE.search(line)
178 if m:
179 commit = m.group(1)
180 for tracker in BUG_REFS.keys():
181 foundbugs = BUG_REFS[tracker]['re'].findall(line)
182 if len(foundbugs):
183 if not tracker in bugs:
184 bugs[tracker] = foundbugs
185 else:
186 bugs[tracker] = list(set(bugs[tracker] + foundbugs))
187
188 return output
189
190 # Override the Revision class to inject gitweb/cgit links and any referenced
191 # bug URLs
192 class MageiaI18NRevision(git_multimail.Revision):
193 """A Change consisting of a single git commit."""
194
195 def __init__(self, reference_change, rev, num, tot):
196 git_multimail.Change.__init__(self, reference_change.environment)
197 self.reference_change = reference_change
198 self.rev = rev
199 self.change_type = self.reference_change.change_type
200 self.refname = self.reference_change.refname
201 self.num = num
202 self.tot = tot
203 self.author = git_multimail.read_git_output(['log', '--no-walk', '--format=%aN <%aE>', self.rev.sha1])
204 self.recipients = False
205 self.output = []
206
207
208 i18n_folders = []
209 # Check files and find i18n folders
210 for line in git_multimail.read_git_lines(['ls-tree', '-rd', self.rev.sha1]):
211 (modetypesha1, name) = line.split("\t", 1)
212 if name.endswith("/.tx"):
213 i18n_folders.append(os.path.dirname(name))
214
215 if len(i18n_folders):
216 self.output = git_multimail.read_git_lines(
217 ['log', '-C', '--stat', '-p', '--no-walk', self.rev.sha1, '--'] + i18n_folders,
218 keepends=True,
219 )
220 if len(self.output):
221 # We have some output so lets send the mail...
222 self.recipients = 'i18n-reports@ml.mageia.org'
223
224 def generate_email_body(self, push):
225 """Show this revision."""
226
227 return self.output
228
229
230
231 if __name__ == '__main__':
232 # Attempt to write a last-updated file for cgit cosmetics
233 try:
234 git_dir = git_multimail.get_git_dir()
235 infowebdir = os.path.join(git_dir, 'info', 'web')
236 if not os.path.exists(infowebdir):
237 os.makedirs(infowebdir)
238 lastupdated = git_multimail.read_git_output(
239 ['for-each-ref', '--sort=-committerdate', "--format=%(committerdate:iso8601)", '--count=1', 'refs/heads'],
240 )
241 modfile = open(os.path.join(infowebdir, 'last-modified'), 'w')
242 modfile.write(lastupdated)
243 modfile.close()
244 except Exception:
245 pass
246
247 try:
248 req = urllib2.Request('http://alamut.mageia.org:8000', repo_shortname() + '.git')
249 req.add_header('Content-Type', 'x-git/repo')
250 fp = urllib2.urlopen(req, timeout=5)
251 if (fp):
252 fp.close()
253 except Exception:
254 pass
255
256
257 config = git_multimail.Config('multimailhook')
258
259 try:
260 environment = git_multimail.choose_environment(
261 config, osenv=os.environ,
262 )
263
264 mailer = git_multimail.choose_mailer(config, environment)
265 # For testing...
266 #mailer = git_multimail.OutputMailer(sys.stdout)
267
268 changes = []
269 for line in sys.stdin:
270 (oldrev, newrev, refname) = line.strip().split(' ', 2)
271 changes.append(
272 git_multimail.ReferenceChange.create(environment, oldrev, newrev, refname)
273 )
274 push = git_multimail.Push(changes)
275
276
277 # First pass - regular commit mails
278 git_multimail.Revision = MageiaLinksRevision
279 push.send_emails(mailer, body_filter=environment.filter_body)
280
281 # Second pass - i18n commit mails
282 git_multimail.REVISION_HEADER_TEMPLATE = I18N_REVISION_HEADER_TEMPLATE
283 git_multimail.Revision = MageiaI18NRevision
284 # Don't send the summary email, so nuke the change recipients
285 for change in push.changes:
286 change.recipients = False
287 push.send_emails(mailer, body_filter=environment.filter_body)
288
289 except git_multimail.ConfigurationException, e:
290 sys.exit(str(e))

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.30