##// END OF EJS Templates
wireprotocol: use visibleheads as reference while unbundling (issue 3303)...
wireprotocol: use visibleheads as reference while unbundling (issue 3303) The `repo` object here is *always* local. Using `repo.heads()` ensure we will reject push if any secret changeset exists. During discovery, `visibleheads` were sent to the peer. So we can only expect it to send us `visibleheads` back. If any secret changeset exists:: visibleheads != repo.heads() This fix server side part of issue 3303 when pushing over the wire.

File last commit:

r15776:55a85a55 default
r16532:9eba72cd stable
Show More
hgcia.py
279 lines | 8.7 KiB | text/x-python | PythonLexer
Brendan Cully
Add hgcia to hgext
r7438 # Copyright (C) 2007-8 Brendan Cully <brendan@kublai.com>
Matt Mackall
Update license to GPLv2+
r10263 #
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
Brendan Cully
Add hgcia to hgext
r7438
Dirkjan Ochtman
extensions: change descriptions for hook-providing extensions...
r8935 """hooks for integrating with the CIA.vc notification service
Brendan Cully
Add hgcia to hgext
r7438
Martin Geisler
hgcia: wrap docstrings at 70 characters
r9260 This is meant to be run as a changegroup or incoming hook. To
configure it, set the following options in your hgrc::
Brendan Cully
Add hgcia to hgext
r7438
Martin Geisler
hgcia: use reST syntax for literal block
r9208 [cia]
# your registered CIA user name
user = foo
# the name of the project in CIA
project = foo
# the module (subproject) (optional)
#module = foo
# Append a diffstat to the log message (optional)
#diffstat = False
# Template to use for log messages (optional)
Cédric Krier
hgcia: Handle URL like in notify (issue2406)...
r14314 #template = {desc}\\n{baseurl}{webroot}/rev/{node}-- {diffstat}
Martin Geisler
hgcia: use reST syntax for literal block
r9208 # Style to use (optional)
#style = foo
# The URL of the CIA notification service (optional)
# You can use mailto: URLs to send by email, eg
# mailto:cia@cia.vc
# Make sure to set email.from if you do this.
#url = http://cia.vc/
# print message instead of sending it (optional)
#test = False
Cédric Krier
hgcia: Handle URL like in notify (issue2406)...
r14314 # number of slashes to strip for url paths
#strip = 0
Brendan Cully
Add hgcia to hgext
r7438
Martin Geisler
hgcia: use reST syntax for literal block
r9208 [hooks]
# one of these:
changegroup.cia = python:hgcia.hook
#incoming.cia = python:hgcia.hook
Brendan Cully
Add hgcia to hgext
r7438
Martin Geisler
hgcia: use reST syntax for literal block
r9208 [web]
# If you want hyperlinks (optional)
baseurl = http://server/path/to/repo
Brendan Cully
Add hgcia to hgext
r7438 """
from mercurial.i18n import _
Brodie Rao
hgcia/color: remove star imports...
r11750 from mercurial.node import bin, short
Brendan Cully
Add hgcia to hgext
r7438 from mercurial import cmdutil, patch, templater, util, mail
import email.Parser
import xmlrpclib
from xml.sax import saxutils
socket_timeout = 30 # seconds
try:
# set a timeout for the socket so you don't have to wait so looooong
# when cia.vc is having problems. requires python >= 2.3:
import socket
socket.setdefaulttimeout(socket_timeout)
except:
pass
HGCIA_VERSION = '0.1'
HGCIA_URL = 'http://hg.kublai.com/mercurial/hgcia'
class ciamsg(object):
""" A CIA message """
def __init__(self, cia, ctx):
self.cia = cia
self.ctx = ctx
self.url = self.cia.url
Cédric Krier
hgcia: Handle URL like in notify (issue2406)...
r14314 if self.url:
self.url += self.cia.root
Brendan Cully
Add hgcia to hgext
r7438
def fileelem(self, path, uri, action):
if uri:
uri = ' uri=%s' % saxutils.quoteattr(uri)
return '<file%s action=%s>%s</file>' % (
uri, saxutils.quoteattr(action), saxutils.escape(path))
def fileelems(self):
n = self.ctx.node()
Matt Mackall
misc: replace .parents()[0] with p1()
r13878 f = self.cia.repo.status(self.ctx.p1().node(), n)
Brendan Cully
Add hgcia to hgext
r7438 url = self.url or ''
Cédric Krier
hgcia: Set default value of strip to -1 (issue2891)...
r14850 if url and url[-1] == '/':
url = url[:-1]
Brendan Cully
Add hgcia to hgext
r7438 elems = []
for path in f[0]:
uri = '%s/diff/%s/%s' % (url, short(n), path)
elems.append(self.fileelem(path, url and uri, 'modify'))
for path in f[1]:
# TODO: copy/rename ?
uri = '%s/file/%s/%s' % (url, short(n), path)
elems.append(self.fileelem(path, url and uri, 'add'))
for path in f[2]:
elems.append(self.fileelem(path, '', 'remove'))
return '\n'.join(elems)
def sourceelem(self, project, module=None, branch=None):
msg = ['<source>', '<project>%s</project>' % saxutils.escape(project)]
if module:
msg.append('<module>%s</module>' % saxutils.escape(module))
if branch:
msg.append('<branch>%s</branch>' % saxutils.escape(branch))
msg.append('</source>')
return '\n'.join(msg)
def diffstat(self):
Benoit Boissinot
use new style classes
r8778 class patchbuf(object):
Brendan Cully
Add hgcia to hgext
r7438 def __init__(self):
self.lines = []
# diffstat is stupid
self.name = 'cia'
def write(self, data):
Matt Mackall
hgcia: fix diffstat support
r15776 self.lines += data.splitlines(True)
Brendan Cully
Add hgcia to hgext
r7438 def close(self):
pass
n = self.ctx.node()
pbuf = patchbuf()
Benoit Boissinot
patch/diff: move patch.export() to cmdutil.export()...
r10611 cmdutil.export(self.cia.repo, [n], fp=pbuf)
Brendan Cully
Add hgcia to hgext
r7438 return patch.diffstat(pbuf.lines) or ''
def logmsg(self):
diffstat = self.cia.diffstat and self.diffstat() or ''
self.cia.ui.pushbuffer()
self.cia.templater.show(self.ctx, changes=self.ctx.changeset(),
Cédric Krier
hgcia: Handle URL like in notify (issue2406)...
r14314 baseurl=self.cia.ui.config('web', 'baseurl'),
url=self.url, diffstat=diffstat,
webroot=self.cia.root)
Brendan Cully
Add hgcia to hgext
r7438 return self.cia.ui.popbuffer()
def xml(self):
n = short(self.ctx.node())
src = self.sourceelem(self.cia.project, module=self.cia.module,
branch=self.ctx.branch())
# unix timestamp
dt = self.ctx.date()
timestamp = dt[0]
author = saxutils.escape(self.ctx.user())
rev = '%d:%s' % (self.ctx.rev(), n)
log = saxutils.escape(self.logmsg())
Cédric Krier
hgcia: Set default value of strip to -1 (issue2891)...
r14850 url = self.url
if url and url[-1] == '/':
url = url[:-1]
url = url and '<url>%s/rev/%s</url>' % (saxutils.escape(url), n) or ''
Brendan Cully
Add hgcia to hgext
r7438
msg = """
<message>
<generator>
<name>Mercurial (hgcia)</name>
<version>%s</version>
<url>%s</url>
<user>%s</user>
</generator>
%s
<body>
<commit>
<author>%s</author>
<version>%s</version>
<log>%s</log>
%s
<files>%s</files>
</commit>
</body>
<timestamp>%d</timestamp>
</message>
""" % \
(HGCIA_VERSION, saxutils.escape(HGCIA_URL),
saxutils.escape(self.cia.user), src, author, rev, log, url,
self.fileelems(), timestamp)
return msg
class hgcia(object):
""" CIA notification class """
deftemplate = '{desc}'
dstemplate = '{desc}\n-- \n{diffstat}'
def __init__(self, ui, repo):
self.ui = ui
self.repo = repo
self.ciaurl = self.ui.config('cia', 'url', 'http://cia.vc')
self.user = self.ui.config('cia', 'user')
self.project = self.ui.config('cia', 'project')
self.module = self.ui.config('cia', 'module')
self.diffstat = self.ui.configbool('cia', 'diffstat')
self.emailfrom = self.ui.config('email', 'from')
self.dryrun = self.ui.configbool('cia', 'test')
self.url = self.ui.config('web', 'baseurl')
Cédric Krier
hgcia: Set default value of strip to -1 (issue2891)...
r14850 # Default to -1 for backward compatibility
self.stripcount = int(self.ui.config('cia', 'strip', -1))
Cédric Krier
hgcia: Handle URL like in notify (issue2406)...
r14314 self.root = self.strip(self.repo.root)
Brendan Cully
Add hgcia to hgext
r7438
style = self.ui.config('cia', 'style')
template = self.ui.config('cia', 'template')
if not template:
template = self.diffstat and self.dstemplate or self.deftemplate
template = templater.parsestring(template, quoted=False)
Jim Correia
add --git option to commands supporting --patch (log, incoming, history, tip)...
r7762 t = cmdutil.changeset_templater(self.ui, self.repo, False, None,
style, False)
Brendan Cully
Add hgcia to hgext
r7438 t.use_template(template)
self.templater = t
Cédric Krier
hgcia: Handle URL like in notify (issue2406)...
r14314 def strip(self, path):
'''strip leading slashes from local path, turn into web-safe path.'''
path = util.pconvert(path)
count = self.stripcount
Cédric Krier
hgcia: Set default value of strip to -1 (issue2891)...
r14850 if count < 0:
return ''
Cédric Krier
hgcia: Handle URL like in notify (issue2406)...
r14314 while count > 0:
c = path.find('/')
if c == -1:
break
path = path[c + 1:]
count -= 1
return path
Brendan Cully
Add hgcia to hgext
r7438 def sendrpc(self, msg):
srv = xmlrpclib.Server(self.ciaurl)
Brendan Cully
hgcia: report RPC errors
r10529 res = srv.hub.deliver(msg)
Georg Brandl
hgcia: accept "queued." xmlrpc return as success
r13551 if res is not True and res != 'queued.':
Brendan Cully
hgcia: report RPC errors
r10529 raise util.Abort(_('%s returned an error: %s') %
(self.ciaurl, res))
Brendan Cully
Add hgcia to hgext
r7438
def sendemail(self, address, data):
p = email.Parser.Parser()
msg = p.parsestr(data)
msg['Date'] = util.datestr(format="%a, %d %b %Y %H:%M:%S %1%2")
msg['To'] = address
msg['From'] = self.emailfrom
msg['Subject'] = 'DeliverXML'
msg['Content-type'] = 'text/xml'
Nicolas Dumazet
for calls expecting bool args, pass bool instead of int...
r9136 msgtext = msg.as_string()
Brendan Cully
Add hgcia to hgext
r7438
self.ui.status(_('hgcia: sending update to %s\n') % address)
mail.sendmail(self.ui, util.email(self.emailfrom),
[address], msgtext)
def hook(ui, repo, hooktype, node=None, url=None, **kwargs):
""" send CIA notification """
def sendmsg(cia, ctx):
msg = ciamsg(cia, ctx).xml()
if cia.dryrun:
ui.write(msg)
elif cia.ciaurl.startswith('mailto:'):
if not cia.emailfrom:
raise util.Abort(_('email.from must be defined when '
'sending by email'))
cia.sendemail(cia.ciaurl[7:], msg)
else:
cia.sendrpc(msg)
n = bin(node)
cia = hgcia(ui, repo)
if not cia.user:
Martin Geisler
do not attempt to translate ui.debug output
r9467 ui.debug('cia: no user specified')
Brendan Cully
Add hgcia to hgext
r7438 return
if not cia.project:
Martin Geisler
do not attempt to translate ui.debug output
r9467 ui.debug('cia: no project specified')
Brendan Cully
Add hgcia to hgext
r7438 return
if hooktype == 'changegroup':
start = repo.changelog.rev(n)
end = len(repo.changelog)
for rev in xrange(start, end):
n = repo.changelog.node(rev)
ctx = repo.changectx(n)
sendmsg(cia, ctx)
else:
ctx = repo.changectx(n)
sendmsg(cia, ctx)