##// END OF EJS Templates
hgcia: Set default value of strip to -1 (issue2891)...
Cédric Krier -
r14850:a95242af stable
parent child Browse files
Show More
@@ -1,272 +1,279 b''
1 1 # Copyright (C) 2007-8 Brendan Cully <brendan@kublai.com>
2 2 #
3 3 # This software may be used and distributed according to the terms of the
4 4 # GNU General Public License version 2 or any later version.
5 5
6 6 """hooks for integrating with the CIA.vc notification service
7 7
8 8 This is meant to be run as a changegroup or incoming hook. To
9 9 configure it, set the following options in your hgrc::
10 10
11 11 [cia]
12 12 # your registered CIA user name
13 13 user = foo
14 14 # the name of the project in CIA
15 15 project = foo
16 16 # the module (subproject) (optional)
17 17 #module = foo
18 18 # Append a diffstat to the log message (optional)
19 19 #diffstat = False
20 20 # Template to use for log messages (optional)
21 21 #template = {desc}\\n{baseurl}{webroot}/rev/{node}-- {diffstat}
22 22 # Style to use (optional)
23 23 #style = foo
24 24 # The URL of the CIA notification service (optional)
25 25 # You can use mailto: URLs to send by email, eg
26 26 # mailto:cia@cia.vc
27 27 # Make sure to set email.from if you do this.
28 28 #url = http://cia.vc/
29 29 # print message instead of sending it (optional)
30 30 #test = False
31 31 # number of slashes to strip for url paths
32 32 #strip = 0
33 33
34 34 [hooks]
35 35 # one of these:
36 36 changegroup.cia = python:hgcia.hook
37 37 #incoming.cia = python:hgcia.hook
38 38
39 39 [web]
40 40 # If you want hyperlinks (optional)
41 41 baseurl = http://server/path/to/repo
42 42 """
43 43
44 44 from mercurial.i18n import _
45 45 from mercurial.node import bin, short
46 46 from mercurial import cmdutil, patch, templater, util, mail
47 47 import email.Parser
48 48
49 49 import xmlrpclib
50 50 from xml.sax import saxutils
51 51
52 52 socket_timeout = 30 # seconds
53 53 try:
54 54 # set a timeout for the socket so you don't have to wait so looooong
55 55 # when cia.vc is having problems. requires python >= 2.3:
56 56 import socket
57 57 socket.setdefaulttimeout(socket_timeout)
58 58 except:
59 59 pass
60 60
61 61 HGCIA_VERSION = '0.1'
62 62 HGCIA_URL = 'http://hg.kublai.com/mercurial/hgcia'
63 63
64 64
65 65 class ciamsg(object):
66 66 """ A CIA message """
67 67 def __init__(self, cia, ctx):
68 68 self.cia = cia
69 69 self.ctx = ctx
70 70 self.url = self.cia.url
71 71 if self.url:
72 72 self.url += self.cia.root
73 73
74 74 def fileelem(self, path, uri, action):
75 75 if uri:
76 76 uri = ' uri=%s' % saxutils.quoteattr(uri)
77 77 return '<file%s action=%s>%s</file>' % (
78 78 uri, saxutils.quoteattr(action), saxutils.escape(path))
79 79
80 80 def fileelems(self):
81 81 n = self.ctx.node()
82 82 f = self.cia.repo.status(self.ctx.p1().node(), n)
83 83 url = self.url or ''
84 if url and url[-1] == '/':
85 url = url[:-1]
84 86 elems = []
85 87 for path in f[0]:
86 88 uri = '%s/diff/%s/%s' % (url, short(n), path)
87 89 elems.append(self.fileelem(path, url and uri, 'modify'))
88 90 for path in f[1]:
89 91 # TODO: copy/rename ?
90 92 uri = '%s/file/%s/%s' % (url, short(n), path)
91 93 elems.append(self.fileelem(path, url and uri, 'add'))
92 94 for path in f[2]:
93 95 elems.append(self.fileelem(path, '', 'remove'))
94 96
95 97 return '\n'.join(elems)
96 98
97 99 def sourceelem(self, project, module=None, branch=None):
98 100 msg = ['<source>', '<project>%s</project>' % saxutils.escape(project)]
99 101 if module:
100 102 msg.append('<module>%s</module>' % saxutils.escape(module))
101 103 if branch:
102 104 msg.append('<branch>%s</branch>' % saxutils.escape(branch))
103 105 msg.append('</source>')
104 106
105 107 return '\n'.join(msg)
106 108
107 109 def diffstat(self):
108 110 class patchbuf(object):
109 111 def __init__(self):
110 112 self.lines = []
111 113 # diffstat is stupid
112 114 self.name = 'cia'
113 115 def write(self, data):
114 116 self.lines.append(data)
115 117 def close(self):
116 118 pass
117 119
118 120 n = self.ctx.node()
119 121 pbuf = patchbuf()
120 122 cmdutil.export(self.cia.repo, [n], fp=pbuf)
121 123 return patch.diffstat(pbuf.lines) or ''
122 124
123 125 def logmsg(self):
124 126 diffstat = self.cia.diffstat and self.diffstat() or ''
125 127 self.cia.ui.pushbuffer()
126 128 self.cia.templater.show(self.ctx, changes=self.ctx.changeset(),
127 129 baseurl=self.cia.ui.config('web', 'baseurl'),
128 130 url=self.url, diffstat=diffstat,
129 131 webroot=self.cia.root)
130 132 return self.cia.ui.popbuffer()
131 133
132 134 def xml(self):
133 135 n = short(self.ctx.node())
134 136 src = self.sourceelem(self.cia.project, module=self.cia.module,
135 137 branch=self.ctx.branch())
136 138 # unix timestamp
137 139 dt = self.ctx.date()
138 140 timestamp = dt[0]
139 141
140 142 author = saxutils.escape(self.ctx.user())
141 143 rev = '%d:%s' % (self.ctx.rev(), n)
142 144 log = saxutils.escape(self.logmsg())
143 145
144 url = self.url and '<url>%s/rev/%s</url>' % (saxutils.escape(self.url),
145 n) or ''
146 url = self.url
147 if url and url[-1] == '/':
148 url = url[:-1]
149 url = url and '<url>%s/rev/%s</url>' % (saxutils.escape(url), n) or ''
146 150
147 151 msg = """
148 152 <message>
149 153 <generator>
150 154 <name>Mercurial (hgcia)</name>
151 155 <version>%s</version>
152 156 <url>%s</url>
153 157 <user>%s</user>
154 158 </generator>
155 159 %s
156 160 <body>
157 161 <commit>
158 162 <author>%s</author>
159 163 <version>%s</version>
160 164 <log>%s</log>
161 165 %s
162 166 <files>%s</files>
163 167 </commit>
164 168 </body>
165 169 <timestamp>%d</timestamp>
166 170 </message>
167 171 """ % \
168 172 (HGCIA_VERSION, saxutils.escape(HGCIA_URL),
169 173 saxutils.escape(self.cia.user), src, author, rev, log, url,
170 174 self.fileelems(), timestamp)
171 175
172 176 return msg
173 177
174 178
175 179 class hgcia(object):
176 180 """ CIA notification class """
177 181
178 182 deftemplate = '{desc}'
179 183 dstemplate = '{desc}\n-- \n{diffstat}'
180 184
181 185 def __init__(self, ui, repo):
182 186 self.ui = ui
183 187 self.repo = repo
184 188
185 189 self.ciaurl = self.ui.config('cia', 'url', 'http://cia.vc')
186 190 self.user = self.ui.config('cia', 'user')
187 191 self.project = self.ui.config('cia', 'project')
188 192 self.module = self.ui.config('cia', 'module')
189 193 self.diffstat = self.ui.configbool('cia', 'diffstat')
190 194 self.emailfrom = self.ui.config('email', 'from')
191 195 self.dryrun = self.ui.configbool('cia', 'test')
192 196 self.url = self.ui.config('web', 'baseurl')
193 self.stripcount = int(self.ui.config('cia', 'strip', 0))
197 # Default to -1 for backward compatibility
198 self.stripcount = int(self.ui.config('cia', 'strip', -1))
194 199 self.root = self.strip(self.repo.root)
195 200
196 201 style = self.ui.config('cia', 'style')
197 202 template = self.ui.config('cia', 'template')
198 203 if not template:
199 204 template = self.diffstat and self.dstemplate or self.deftemplate
200 205 template = templater.parsestring(template, quoted=False)
201 206 t = cmdutil.changeset_templater(self.ui, self.repo, False, None,
202 207 style, False)
203 208 t.use_template(template)
204 209 self.templater = t
205 210
206 211 def strip(self, path):
207 212 '''strip leading slashes from local path, turn into web-safe path.'''
208 213
209 214 path = util.pconvert(path)
210 215 count = self.stripcount
216 if count < 0:
217 return ''
211 218 while count > 0:
212 219 c = path.find('/')
213 220 if c == -1:
214 221 break
215 222 path = path[c + 1:]
216 223 count -= 1
217 224 return path
218 225
219 226 def sendrpc(self, msg):
220 227 srv = xmlrpclib.Server(self.ciaurl)
221 228 res = srv.hub.deliver(msg)
222 229 if res is not True and res != 'queued.':
223 230 raise util.Abort(_('%s returned an error: %s') %
224 231 (self.ciaurl, res))
225 232
226 233 def sendemail(self, address, data):
227 234 p = email.Parser.Parser()
228 235 msg = p.parsestr(data)
229 236 msg['Date'] = util.datestr(format="%a, %d %b %Y %H:%M:%S %1%2")
230 237 msg['To'] = address
231 238 msg['From'] = self.emailfrom
232 239 msg['Subject'] = 'DeliverXML'
233 240 msg['Content-type'] = 'text/xml'
234 241 msgtext = msg.as_string()
235 242
236 243 self.ui.status(_('hgcia: sending update to %s\n') % address)
237 244 mail.sendmail(self.ui, util.email(self.emailfrom),
238 245 [address], msgtext)
239 246
240 247
241 248 def hook(ui, repo, hooktype, node=None, url=None, **kwargs):
242 249 """ send CIA notification """
243 250 def sendmsg(cia, ctx):
244 251 msg = ciamsg(cia, ctx).xml()
245 252 if cia.dryrun:
246 253 ui.write(msg)
247 254 elif cia.ciaurl.startswith('mailto:'):
248 255 if not cia.emailfrom:
249 256 raise util.Abort(_('email.from must be defined when '
250 257 'sending by email'))
251 258 cia.sendemail(cia.ciaurl[7:], msg)
252 259 else:
253 260 cia.sendrpc(msg)
254 261
255 262 n = bin(node)
256 263 cia = hgcia(ui, repo)
257 264 if not cia.user:
258 265 ui.debug('cia: no user specified')
259 266 return
260 267 if not cia.project:
261 268 ui.debug('cia: no project specified')
262 269 return
263 270 if hooktype == 'changegroup':
264 271 start = repo.changelog.rev(n)
265 272 end = len(repo.changelog)
266 273 for rev in xrange(start, end):
267 274 n = repo.changelog.node(rev)
268 275 ctx = repo.changectx(n)
269 276 sendmsg(cia, ctx)
270 277 else:
271 278 ctx = repo.changectx(n)
272 279 sendmsg(cia, ctx)
@@ -1,54 +1,92 b''
1 1 Test the CIA extension
2 2
3 3 $ cat >> $HGRCPATH <<EOF
4 4 > [extensions]
5 5 > hgcia=
6 6 >
7 7 > [hooks]
8 8 > changegroup.cia = python:hgext.hgcia.hook
9 9 >
10 10 > [web]
11 11 > baseurl = http://hgserver/
12 12 >
13 13 > [cia]
14 14 > user = testuser
15 15 > project = testproject
16 16 > test = True
17 17 > EOF
18 18
19 19 $ hg init src
20 20 $ hg init cia
21 21 $ cd src
22 22 $ echo foo > foo
23 23 $ hg ci -Amfoo
24 24 adding foo
25 25 $ hg push ../cia
26 26 pushing to ../cia
27 27 searching for changes
28 28 adding changesets
29 29 adding manifests
30 30 adding file changes
31 31 added 1 changesets with 1 changes to 1 files
32 32
33 33 <message>
34 34 <generator>
35 35 <name>Mercurial (hgcia)</name>
36 36 <version>0.1</version>
37 37 <url>http://hg.kublai.com/mercurial/hgcia</url>
38 38 <user>testuser</user>
39 39 </generator>
40 40 <source>
41 41 <project>testproject</project>
42 42 <branch>default</branch>
43 43 </source>
44 44 <body>
45 45 <commit>
46 46 <author>test</author>
47 47 <version>0:e63c23eaa88a</version>
48 48 <log>foo</log>
49 <url>http://hgserver/$TESTTMP/cia/rev/e63c23eaa88a</url>
50 <files><file uri="http://hgserver/$TESTTMP/cia/file/e63c23eaa88a/foo" action="add">foo</file></files>
49 <url>http://hgserver/rev/e63c23eaa88a</url>
50 <files><file uri="http://hgserver/file/e63c23eaa88a/foo" action="add">foo</file></files>
51 51 </commit>
52 52 </body>
53 53 <timestamp>0</timestamp>
54 54 </message>
55
56 $ cat >> $HGRCPATH <<EOF
57 > strip = 0
58 > EOF
59
60 $ echo bar > bar
61 $ hg ci -Ambar
62 adding bar
63 $ hg push ../cia
64 pushing to ../cia
65 searching for changes
66 adding changesets
67 adding manifests
68 adding file changes
69 added 1 changesets with 1 changes to 1 files
70
71 <message>
72 <generator>
73 <name>Mercurial (hgcia)</name>
74 <version>0.1</version>
75 <url>http://hg.kublai.com/mercurial/hgcia</url>
76 <user>testuser</user>
77 </generator>
78 <source>
79 <project>testproject</project>
80 <branch>default</branch>
81 </source>
82 <body>
83 <commit>
84 <author>test</author>
85 <version>1:c0c7cf58edc5</version>
86 <log>bar</log>
87 <url>http://hgserver/$TESTTMP/cia/rev/c0c7cf58edc5</url>
88 <files><file uri="http://hgserver/$TESTTMP/cia/file/c0c7cf58edc5/bar" action="add">bar</file></files>
89 </commit>
90 </body>
91 <timestamp>0</timestamp>
92 </message>
General Comments 0
You need to be logged in to leave comments. Login now