/[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 3448 - (show annotations) (download)
Mon Apr 21 19:47:51 2014 UTC (10 years ago) by colin
File size: 10462 byte(s)
mgagit: Send a second email about any i18n changes to the i18n-reports ML.

After sending the original email, we send a second email to i18n-reports
detailing any i18n changes.

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

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.30