##// END OF EJS Templates
extensions: list up only enabled extensions, if "ui" is specified...
extensions: list up only enabled extensions, if "ui" is specified Before this patch, "extensions.extensions()" always lists up all loaded extensions. So, commands handling multiple repositories at a time like below enable extensions unexpectedly. - clone from or push to localhost: extensions enabled only in the source are enabled also in the destination - pull from localhost: extensions enabled only in the destination are enabled also in the source - recursive execution in subrepo tree: extensions enabled only in the parent or some of siblings in the tree are enabled also in others In addition to it, extensions disabled locally may be enabled unexpectedly. This patch checks whether each of extensions should be listed up or not, if "ui" is specified to "extensions.extensions()", and invokes "reposetup()" of each extensions only for repositories enabling it.

File last commit:

r19143:3cb94685 default
r19777:6f72e7d2 default
Show More
client.py
173 lines | 5.9 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'):
Siddharth Agarwal
match: make explicitdir and traversedir None by default...
r19143 if match.explicitdir:
match.explicitdir(vdir)
Nicolas Dumazet
inotify: mark directories visited during lookup (issue1844)...
r9854
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')