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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3386 - (hide annotations) (download)
Sat Jan 4 13:50:49 2014 UTC (10 years, 3 months ago) by colin
File size: 7041 byte(s)
mgagit: Attempt to write out a last-modified file for cgit.

This means the Last Modified column in cgit will show the date of the last commit
not the date of the last push (which can be completely unrelated, especially when
doing rebases or forced pushes and fixups etc.)

Note: If we stop using rsync for replication then this can be removed and replaced
with a different hook on the receiving side.
1 colin 3359 #!/usr/bin/python
2 colin 3354
3     import sys
4     import os
5     import re
6    
7 colin 3358 LIBDIR = '<%= @gitolite_commonhooksdir %>'
8 colin 3354 sys.path.insert(0, LIBDIR)
9    
10     import git_multimail
11    
12 colin 3380 import xmlrpclib
13     from cookielib import CookieJar, LWPCookieJar
14     from bugz.bugzilla import BugzillaProxy
15    
16 colin 3354 # When editing this list, remember to edit the same list in
17     # modules/cgit/templates/filter.commit-links.sh
18     BUG_REFS = {
19     'Mageia': { 're': re.compile('mga#([0-9]+)'), 'replace': 'https://bugs.mageia.org/show_bug.cgi?id=%s' },
20     'Red Hat': { 're': re.compile('rhbz#([0-9]+)'), 'replace': 'https://bugzilla.redhat.com/show_bug.cgi?id=%s' },
21     'Free Desktop': { 're': re.compile('fdo#([0-9]+)'), 'replace': 'https://bugs.freedesktop.org/show_bug.cgi?id=%s' },
22     'KDE': { 're': re.compile('(?:bko|kde)#([0-9]+)'), 'replace': 'https://bugs.kde.org/show_bug.cgi?id=%s' },
23     'GNOME': { 're': re.compile('(?:bgo|gnome)#([0-9]+)'), 'replace': 'https://bugzilla.gnome.org/show_bug.cgi?id=%s' },
24     'Launchpad': { 're': re.compile('lp#([0-9]+)'), 'replace': 'https://launchpad.net/bugs/%s' },
25     }
26    
27     COMMIT_RE = re.compile('^commit ([a-f0-9]{40})')
28     COMMIT_REPLACE = 'http://gitweb.mageia.org/%s/commit/?id=%s'
29    
30 colin 3380 MAGEIA_BUGZILLA_URL = 'https://bugs.mageia.org/xmlrpc.cgi'
31     MAGEIA_BUGZILLA_PASSWORD_FILE = '.gitzilla-password'
32     MAGEIA_BUGZILLA_COOKIE_FILE = '.gitzilla-cookie'
33 colin 3354
34    
35     git_multimail.FOOTER_TEMPLATE = """\
36    
37     -- \n\
38     Mageia Git Monkeys.
39     """
40     git_multimail.REVISION_FOOTER_TEMPLATE = git_multimail.FOOTER_TEMPLATE
41    
42     # Override the Environment class to generate an apporpriate short name which is
43     # used in git links and as an email prefix
44     class LinksEnvironment(git_multimail.Environment):
45 colin 3359 REPO_NAME_RE = re.compile(r'^/git/(?P<name>.+?)(?:\.git)?$')
46 colin 3354
47     def get_repo_shortname(self):
48     """Use the last part of the repo path, with ".git" stripped off if present."""
49    
50     basename = os.path.abspath(self.get_repo_path())
51     m = self.REPO_NAME_RE.match(basename)
52     if m:
53     return m.group('name')
54     else:
55     return basename
56    
57     git_multimail.Environment = LinksEnvironment
58    
59     # Override the Reviesion class to inject gitweb/cgit links and any referenced
60     # bug URLs
61     class LinksRevision(git_multimail.Revision):
62 colin 3380 bz = None
63    
64     def bugzilla_init(self):
65     if self.bz is None:
66     cookie_file = os.path.join(os.environ['HOME'], MAGEIA_BUGZILLA_COOKIE_FILE)
67     self.cookiejar = LWPCookieJar(cookie_file)
68     try:
69     self.cookiejar.load()
70     except IOError:
71     pass
72    
73     self.bz = BugzillaProxy(MAGEIA_BUGZILLA_URL, cookiejar=self.cookiejar)
74     return self.bz
75    
76     def bugzilla_login(self):
77     params = {
78     'login': 'bot',
79     'password': open(os.path.join(os.environ['HOME'], MAGEIA_BUGZILLA_PASSWORD_FILE), 'r').readline().rstrip(),
80     'remember': True
81     }
82     self.bz.User.login(params)
83     self.cookiejar.save()
84     os.chmod(self.cookiejar.filename, 0600)
85    
86     def bugzilla_call(self, method, *args):
87     """Attempt to call method with args. Log in if authentication is required.
88     """
89     try:
90     return method(*args)
91     except xmlrpclib.Fault, fault:
92     # Fault code 410 means login required
93     if fault.faultCode == 410:
94     self.bugzilla_login()
95     return method(*args)
96     raise
97    
98 colin 3354 def generate_email_body(self, push):
99     """Show this revision."""
100    
101     output = git_multimail.read_git_lines(
102     ['log'] + self.environment.commitlogopts + ['-1', self.rev.sha1],
103     keepends=True,
104     )
105     bugs = {}
106     commit = None
107     idx = 0
108     for line in output:
109     idx+=1
110     if line == "---\n":
111     if commit and COMMIT_REPLACE:
112     output.insert(idx, "\n")
113     output.insert(idx, " %s\n" % (COMMIT_REPLACE % (self.environment.get_repo_shortname(), commit)))
114     output.insert(idx, " Commit Link:\n")
115     idx+=3
116     if bugs:
117     output.insert(idx, " Bug links:\n")
118     idx+=1
119     for tracker,bugnos in bugs.items():
120     output.insert(idx, " %s\n" % tracker)
121     idx+=1
122     for bugno in bugnos:
123     output.insert(idx, " %s\n" % (BUG_REFS[tracker]['replace'] % bugno))
124     idx+=1
125     output.insert(idx, "\n")
126     idx+=1
127 colin 3380
128     # Attempt to modify bugzilla
129     if "Mageia" in bugs:
130     try:
131     bz = self.bugzilla_init()
132    
133     # Mask email address
134 colin 3382 comment = None
135     # Suppress the "Bug links:" section if only one bug
136     # is referenced
137     if len(bugs) == 1 and len(bugs['Mageia']) == 1:
138     comment = output[0:idx-4]
139     else:
140     comment = output[0:idx]
141 colin 3380 comment[1] = re.sub(r'^(Author: [^@]*)@.*(>)?', r'\1@...>', comment[1])
142     comment = "".join(comment)
143    
144     params = {}
145     params['ids'] = bugs['Mageia']
146     params['comment'] = { 'body': comment }
147     self.bugzilla_call(bz.Bug.update, params)
148     print "Updated bugzilla bugs: %s" % ", ".join(bugs['Mageia'])
149     except:
150     print "Unable to post to bugzilla bugs: %s :(" % ", ".join(bugs['Mageia'])
151     pass
152    
153 colin 3354 break
154     m = COMMIT_RE.search(line)
155     if m:
156     commit = m.group(1);
157     for tracker in BUG_REFS.keys():
158 colin 3384 foundbugs = BUG_REFS[tracker]['re'].findall(line)
159     if len(foundbugs):
160 colin 3354 if not tracker in bugs:
161 colin 3384 bugs[tracker] = foundbugs
162     else:
163     bugs[tracker] = list(set(bugs[tracker] + foundbugs))
164 colin 3354
165     return output
166    
167     git_multimail.Revision = LinksRevision
168    
169     if __name__ == '__main__':
170 colin 3386 # Attempt to write a last-updated file for cgit cosmetics
171     try:
172     git_dir = git_multimail.get_git_dir()
173     infowebdir = os.path.join(git_dir, 'info', 'web')
174     if not os.path.exists(infowebdir):
175     os.makedirs(infowebdir)
176     lastupdated = git_multimail.read_git_output(
177     ['for-each-ref', '--sort=-committerdate', "--format='%(committerdate:iso8601)'", '--count=1', 'refs/heads'],
178     )
179     open(os.path.join(infowebdir, 'last-modified'), 'w').write(lastupdated).close()
180     except IOError:
181     pass
182    
183 colin 3354 git_multimail.main(sys.argv[1:])

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.30