##// END OF EJS Templates
bugzilla: allow change comment to mark bugs fixed...
bugzilla: allow change comment to mark bugs fixed Add a second regular expression used when scanning change comments. Bugs matched by this new regular expression have the bug comments and optionally hours updated as with the first regular expression, but they are also marked as fixed. The bug status and resolution to set to mark a bug as fixed can be configured. By default status is set to RESOLVED and resolution to FIXED, the default Bugzilla settings. For example, a change comment containing 'Fixes 1234 h1.5' will be added to bug 1234, the bug will have its working time increased by 1.65 hours, and the bug will be marked RESOLVED/FIXED. Change comments may contain both bug update and fix instructions. If the same bug ID occurs in both, the last instruction found takes precedence. The patch adds new bug states 'bug_status' and 'resolution' and actions to update them to the XMLRPC and XMLRPC/email access methods. XMLRPC does not support marking bugs as fixed when used with Bugzilla versions prior to 4.0. When used with an earlier Bugzilla version, a warning is issued and only comment and hours updated.

File last commit:

r12063:516b000f default
r16223:ac4fd323 default
Show More
client.py
172 lines | 5.8 KiB | text/x-python | PythonLexer
Bryan O'Sullivan
Add inotify extension
r6239 # client.py - inotify status client
#
# Copyright 2006, 2007, 2008 Bryan O'Sullivan <bos@serpentine.com>
# Copyright 2007, 2008 Brendan Cully <brendan@kublai.com>
Nicolas Dumazet
inotify: modular architecture for inotify clients...
r8551 # Copyright 2009 Nicolas Dumazet <nicdumz@gmail.com>
Bryan O'Sullivan
Add inotify extension
r6239 #
Martin Geisler
updated license to be explicit about GPL version 2
r8225 # This software may be used and distributed according to the terms of the
Matt Mackall
Update license to GPLv2+
r10263 # GNU General Public License version 2 or any later version.
Bryan O'Sullivan
Add inotify extension
r6239
Martin Geisler
i18n: import _ instead of gettext
r7225 from mercurial.i18n import _
Nicolas Dumazet
inotify: Separate query sending logic from Server starting....
r8552 import common, server
import errno, os, socket, struct
Matt Mackall
many, many trivial check-code fixups
r10282 class QueryFailed(Exception):
pass
Nicolas Dumazet
inotify: Separate query sending logic from Server starting....
r8552
def start_server(function):
"""
Decorator.
Tries to call function, if it fails, try to (re)start inotify server.
Raise QueryFailed if something went wrong
"""
def decorated_function(self, *args):
try:
return function(self, *args)
except (OSError, socket.error), err:
autostart = self.ui.configbool('inotify', 'autostart', True)
Renato Cunha
removed exception args indexing (not supported by py3k)...
r11567 if err.args[0] == errno.ECONNREFUSED:
Nicolas Dumazet
inotify: improve error messages...
r9900 self.ui.warn(_('inotify-client: found dead inotify server '
'socket; removing it\n'))
Nicolas Dumazet
inotify: client: no repo use
r9351 os.unlink(os.path.join(self.root, '.hg', 'inotify.sock'))
Renato Cunha
removed exception args indexing (not supported by py3k)...
r11567 if err.args[0] in (errno.ECONNREFUSED, errno.ENOENT) and autostart:
Nicolas Dumazet
inotify: Separate query sending logic from Server starting....
r8552 try:
try:
Nicolas Dumazet
inotify: use cmdutil.service instead of local daemonizing code
r9514 server.start(self.ui, self.dirstate, self.root,
dict(daemon=True, daemon_pipefds=''))
Nicolas Dumazet
inotify: Separate query sending logic from Server starting....
r8552 except server.AlreadyStartedException, inst:
# another process may have started its own
# inotify server while this one was starting.
self.ui.debug(str(inst))
except Exception, inst:
Nicolas Dumazet
inotify: improve error messages...
r9900 self.ui.warn(_('inotify-client: could not start inotify '
'server: %s\n') % inst)
Nicolas Dumazet
inotify: Separate query sending logic from Server starting....
r8552 else:
try:
return function(self, *args)
except socket.error, err:
Nicolas Dumazet
inotify: improve error messages...
r9900 self.ui.warn(_('inotify-client: could not talk to new '
Renato Cunha
removed exception args indexing (not supported by py3k)...
r11567 'inotify server: %s\n') % err.args[-1])
elif err.args[0] in (errno.ECONNREFUSED, errno.ENOENT):
Nicolas Dumazet
inotify: Separate query sending logic from Server starting....
r8552 # silently ignore normal errors if autostart is False
Martin Geisler
do not attempt to translate ui.debug output
r9467 self.ui.debug('(inotify server not running)\n')
Nicolas Dumazet
inotify: Separate query sending logic from Server starting....
r8552 else:
Nicolas Dumazet
inotify: improve error messages...
r9900 self.ui.warn(_('inotify-client: failed to contact inotify '
Renato Cunha
removed exception args indexing (not supported by py3k)...
r11567 'server: %s\n') % err.args[-1])
Nicolas Dumazet
inotify: Separate query sending logic from Server starting....
r8552
self.ui.traceback()
raise QueryFailed('inotify query failed')
return decorated_function
Bryan O'Sullivan
Add inotify extension
r6239
Nicolas Dumazet
inotify: modular architecture for inotify clients...
r8551 class client(object):
def __init__(self, ui, repo):
self.ui = ui
Nicolas Dumazet
inotify: client: no repo use
r9351 self.dirstate = repo.dirstate
self.root = repo.root
Nicolas Dumazet
inotify: modular architecture for inotify clients...
r8551 self.sock = socket.socket(socket.AF_UNIX)
def _connect(self):
Nicolas Dumazet
inotify: client: no repo use
r9351 sockpath = os.path.join(self.root, '.hg', 'inotify.sock')
Nicolas Dumazet
inotify: modular architecture for inotify clients...
r8551 try:
self.sock.connect(sockpath)
except socket.error, err:
Renato Cunha
removed exception args indexing (not supported by py3k)...
r11567 if err.args[0] == "AF_UNIX path too long":
Nicolas Dumazet
inotify: modular architecture for inotify clients...
r8551 sockpath = os.readlink(sockpath)
self.sock.connect(sockpath)
else:
raise
Bryan O'Sullivan
Add inotify extension
r6239
Nicolas Dumazet
inotify: change protocol so that different query types can be supported.
r8553 def _send(self, type, data):
Nicolas Dumazet
inotify: modular architecture for inotify clients...
r8551 """Sends protocol version number, and the data"""
Nicolas Dumazet
inotify: change protocol so that different query types can be supported.
r8553 self.sock.sendall(chr(common.version) + type + data)
Nicolas Dumazet
inotify: modular architecture for inotify clients...
r8551
self.sock.shutdown(socket.SHUT_WR)
Bryan O'Sullivan
Add inotify extension
r6239
Nicolas Dumazet
inotify: change protocol so that different query types can be supported.
r8553 def _receive(self, type):
Nicolas Dumazet
inotify: modular architecture for inotify clients...
r8551 """
Read data, check version number, extract headers,
and returns a tuple (data descriptor, header)
Nicolas Dumazet
inotify: Separate query sending logic from Server starting....
r8552 Raises QueryFailed on error
Nicolas Dumazet
inotify: modular architecture for inotify clients...
r8551 """
cs = common.recvcs(self.sock)
Nicolas Dumazet
inotify: raise QueryFailed when the server crash...
r8788 try:
version = ord(cs.read(1))
except TypeError:
# empty answer, assume the server crashed
Nicolas Dumazet
inotify: improve error messages...
r9900 self.ui.warn(_('inotify-client: received empty answer from inotify '
'server'))
Nicolas Dumazet
inotify: raise QueryFailed when the server crash...
r8788 raise QueryFailed('server crashed')
Nicolas Dumazet
inotify: modular architecture for inotify clients...
r8551 if version != common.version:
self.ui.warn(_('(inotify: received response from incompatible '
'server version %d)\n') % version)
Nicolas Dumazet
inotify: Separate query sending logic from Server starting....
r8552 raise QueryFailed('incompatible server version')
Bryan O'Sullivan
Add inotify extension
r6239
Nicolas Dumazet
inotify: change protocol so that different query types can be supported.
r8553 readtype = cs.read(4)
if readtype != type:
self.ui.warn(_('(inotify: received \'%s\' response when expecting'
' \'%s\')\n') % (readtype, type))
raise QueryFailed('wrong response type')
Nicolas Dumazet
inotify: modular architecture for inotify clients...
r8551 hdrfmt = common.resphdrfmts[type]
hdrsize = common.resphdrsizes[type]
try:
resphdr = struct.unpack(hdrfmt, cs.read(hdrsize))
except struct.error:
Nicolas Dumazet
inotify: Separate query sending logic from Server starting....
r8552 raise QueryFailed('unable to retrieve query response headers')
Bryan O'Sullivan
Add inotify extension
r6239
Nicolas Dumazet
inotify: modular architecture for inotify clients...
r8551 return cs, resphdr
Nicolas Dumazet
inotify: change protocol so that different query types can be supported.
r8553 def query(self, type, req):
Nicolas Dumazet
inotify: modular architecture for inotify clients...
r8551 self._connect()
Bryan O'Sullivan
Add inotify extension
r6239
Nicolas Dumazet
inotify: change protocol so that different query types can be supported.
r8553 self._send(type, req)
Nicolas Dumazet
inotify: modular architecture for inotify clients...
r8551
Nicolas Dumazet
inotify: change protocol so that different query types can be supported.
r8553 return self._receive(type)
Nicolas Dumazet
inotify: modular architecture for inotify clients...
r8551
Nicolas Dumazet
inotify: Separate query sending logic from Server starting....
r8552 @start_server
Nicolas Dumazet
inotify: modular architecture for inotify clients...
r8551 def statusquery(self, names, match, ignored, clean, unknown=True):
Bryan O'Sullivan
Add inotify extension
r6239
Nicolas Dumazet
inotify: modular architecture for inotify clients...
r8551 def genquery():
for n in names:
yield n
states = 'almrx!'
if ignored:
raise ValueError('this is insanity')
Matt Mackall
many, many trivial check-code fixups
r10282 if clean:
states += 'c'
if unknown:
states += '?'
Nicolas Dumazet
inotify: modular architecture for inotify clients...
r8551 yield states
req = '\0'.join(genquery())
Bryan O'Sullivan
Add inotify extension
r6239
Nicolas Dumazet
inotify: change protocol so that different query types can be supported.
r8553 cs, resphdr = self.query('STAT', req)
Nicolas Dumazet
inotify: modular architecture for inotify clients...
r8551
def readnames(nbytes):
if nbytes:
names = cs.read(nbytes)
if names:
return filter(match, names.split('\0'))
return []
Greg Ward
inotify: make inotifydirstate.status() returns a tuple of lists....
r11628 results = tuple(map(readnames, resphdr[:-1]))
Nicolas Dumazet
inotify: mark directories visited during lookup (issue1844)...
r9854
if names:
nbytes = resphdr[-1]
vdirs = cs.read(nbytes)
if vdirs:
for vdir in vdirs.split('\0'):
match.dir(vdir)
return results
Nicolas Dumazet
inotify: modular architecture for inotify clients...
r8551
Nicolas Dumazet
inotify: introduce debuginotify, which lists which paths are under watch
r8555 @start_server
def debugquery(self):
cs, resphdr = self.query('DBUG', '')
nbytes = resphdr[0]
names = cs.read(nbytes)
return names.split('\0')