##// END OF EJS Templates
patch: support diff data loss detection and upgrade...
patch: support diff data loss detection and upgrade In worst case, generating diff in upgrade mode can be two times more expensive than generating it in git mode directly: we may have to regenerate the whole diff again whenever a git feature is detected. Also, the first diff attempt is completely buffered instead of being streamed. That said, even without having profiled it yet, I am convinced we can fast-path the upgrade mode if necessary were it to be used in regular diff commands, and not only in mq where avoiding data loss is worth the price.

File last commit:

r9679:a1943c2a default
r10189:e451e599 default
Show More
extensions.py
190 lines | 5.4 KiB | text/x-python | PythonLexer
Matt Mackall
Create a separate module for managing extensions
r4544 # extensions.py - extension handling for mercurial
#
Thomas Arendsen Hein
Updated copyright notices and add "and others" to "hg version"
r4635 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
Matt Mackall
Create a separate module for managing extensions
r4544 #
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
# GNU General Public License version 2, incorporated herein by reference.
Matt Mackall
Create a separate module for managing extensions
r4544
Cédric Duval
extensions: remove import rendered unnecessary by e4e22a310b62
r8896 import imp, os
Cédric Duval
extensions: move extensions listing functions from mercurial.help...
r8871 import util, cmdutil, help
from i18n import _, gettext
Matt Mackall
Create a separate module for managing extensions
r4544
_extensions = {}
Alexis S. L. Carvalho
Move cmdtable and reposetup handling out of extensions.py...
r5192 _order = []
def extensions():
for name in _order:
module = _extensions[name]
if module:
yield name, module
Matt Mackall
Create a separate module for managing extensions
r4544
def find(name):
'''return module with given extension name'''
try:
return _extensions[name]
except KeyError:
for k, v in _extensions.iteritems():
Matt Mackall
extensions: fix lookup of hgext.foo modules
r4560 if k.endswith('.' + name) or k.endswith('/' + name):
return v
Matt Mackall
Create a separate module for managing extensions
r4544 raise KeyError(name)
Alexander Solovyov
ability to load hooks from arbitrary python module
r7916 def loadpath(path, module_name):
module_name = module_name.replace('.', '_')
Alexander Solovyov
make path expanding more consistent...
r9610 path = util.expandpath(path)
Alexander Solovyov
ability to load hooks from arbitrary python module
r7916 if os.path.isdir(path):
# module/__init__.py style
Alexander Solovyov
extensions loading: don't fail if path to extension ends with a '/'
r7960 d, f = os.path.split(path.rstrip('/'))
Alexander Solovyov
ability to load hooks from arbitrary python module
r7916 fd, fpath, desc = imp.find_module(f, [d])
return imp.load_module(module_name, fd, fpath, desc)
else:
return imp.load_source(module_name, path)
Matt Mackall
Create a separate module for managing extensions
r4544 def load(ui, name, path):
Martin Geisler
extensions: load and configure extensions in well-defined phases...
r9410 # unused ui argument kept for backwards compatibility
Benoit Boissinot
Do not try to load extensions twice (issue811)
r7011 if name.startswith('hgext.') or name.startswith('hgext/'):
Bryan O'Sullivan
extensions: don't get confused by aliasing between "foo" and "hgext.foo"
r5031 shortname = name[6:]
else:
shortname = name
if shortname in _extensions:
Matt Mackall
Create a separate module for managing extensions
r4544 return
Brendan Cully
Cache extension load failures....
r5087 _extensions[shortname] = None
Matt Mackall
Create a separate module for managing extensions
r4544 if path:
# the module will be loaded in sys.modules
# choose an unique name so that it doesn't
# conflicts with other modules
Alexander Solovyov
ability to load hooks from arbitrary python module
r7916 mod = loadpath(path, 'hgext.%s' % name)
Matt Mackall
Create a separate module for managing extensions
r4544 else:
def importh(name):
mod = __import__(name)
components = name.split('.')
for comp in components[1:]:
mod = getattr(mod, comp)
return mod
try:
mod = importh("hgext.%s" % name)
except ImportError:
mod = importh(name)
Bryan O'Sullivan
extensions: don't get confused by aliasing between "foo" and "hgext.foo"
r5031 _extensions[shortname] = mod
Alexis S. L. Carvalho
Move cmdtable and reposetup handling out of extensions.py...
r5192 _order.append(shortname)
Matt Mackall
Create a separate module for managing extensions
r4544
def loadall(ui):
Matt Mackall
extensions: pull extension-aware bits out of ui
r4617 result = ui.configitems("extensions")
Martin Geisler
extensions: load and configure extensions in well-defined phases...
r9410 newindex = len(_order)
Peter Arrenbrecht
cleanup: drop enumerate() when index is not used
r7876 for (name, path) in result:
Matt Mackall
extensions: pull extension-aware bits out of ui
r4617 if path:
Steve Borho
Allow explicit disabling of extensions...
r5469 if path[0] == '!':
continue
Matt Mackall
Create a separate module for managing extensions
r4544 try:
load(ui, name, path)
Matt Mackall
error: move SignalInterrupt...
r7644 except KeyboardInterrupt:
Matt Mackall
Create a separate module for managing extensions
r4544 raise
except Exception, inst:
Jesse Glick
When failing to load an extension, show where Hg tried to load it from.
r6204 if path:
ui.warn(_("*** failed to import extension %s from %s: %s\n")
% (name, path, inst))
else:
ui.warn(_("*** failed to import extension %s: %s\n")
% (name, inst))
Matt Mackall
ui: print_exc() -> traceback()
r8206 if ui.traceback():
Matt Mackall
Create a separate module for managing extensions
r4544 return 1
Martin Geisler
extensions: load and configure extensions in well-defined phases...
r9410 for name in _order[newindex:]:
uisetup = getattr(_extensions[name], 'uisetup', None)
if uisetup:
uisetup(ui)
Yuya Nishihara
extensions: changed to call extsetup() from extensions.loadall()...
r9660 for name in _order[newindex:]:
extsetup = getattr(_extensions[name], 'extsetup', None)
if extsetup:
try:
extsetup(ui)
except TypeError:
if extsetup.func_code.co_argcount != 0:
raise
extsetup() # old extsetup with no ui argument
Matt Mackall
extensions: add wrapping functions
r7215 def wrapcommand(table, command, wrapper):
aliases, entry = cmdutil.findcmd(command, table)
for alias, e in table.iteritems():
if e is entry:
key = alias
break
origfn = entry[0]
def wrap(*args, **kwargs):
Matt Mackall
dispatch: generalize signature checking for extension command wrapping
r7388 return util.checksignature(wrapper)(
util.checksignature(origfn), *args, **kwargs)
Matt Mackall
extensions: add wrapping functions
r7215
wrap.__doc__ = getattr(origfn, '__doc__')
Dirkjan Ochtman
extensions: copy __module__ for wrapped commands
r7373 wrap.__module__ = getattr(origfn, '__module__')
Matt Mackall
extensions: add wrapping functions
r7215
newentry = list(entry)
newentry[0] = wrap
table[key] = tuple(newentry)
return entry
def wrapfunction(container, funcname, wrapper):
def wrap(*args, **kwargs):
return wrapper(origfn, *args, **kwargs)
origfn = getattr(container, funcname)
setattr(container, funcname, wrap)
return origfn
Cédric Duval
extensions: move extensions listing functions from mercurial.help...
r8871
def disabled():
'''find disabled extensions from hgext
returns a dict of {name: desc}, and the max name length'''
Dirkjan Ochtman
extensions: simplify by selecting primary hgext
r8872
import hgext
extpath = os.path.dirname(os.path.abspath(hgext.__file__))
Cédric Duval
extensions: catch OSError when hgext is not accessible (issue1708)...
r8964 try: # might not be a filesystem path
files = os.listdir(extpath)
except OSError:
return None, 0
Cédric Duval
extensions: move extensions listing functions from mercurial.help...
r8871 exts = {}
maxlength = 0
Cédric Duval
extensions: catch OSError when hgext is not accessible (issue1708)...
r8964 for e in files:
Cédric Duval
extensions: move extensions listing functions from mercurial.help...
r8871
Dirkjan Ochtman
extensions: simplify by selecting primary hgext
r8872 if e.endswith('.py'):
name = e.rsplit('.', 1)[0]
path = os.path.join(extpath, e)
else:
name = e
path = os.path.join(extpath, e, '__init__.py')
Cédric Duval
extensions: check for path existence only when necessary
r8877 if not os.path.exists(path):
continue
Dirkjan Ochtman
extensions: simplify by selecting primary hgext
r8872
Cédric Duval
extensions: use _order to determine if an extension is enabled
r8878 if name in exts or name in _order or name == '__init__':
Dirkjan Ochtman
extensions: simplify by selecting primary hgext
r8872 continue
Cédric Duval
extensions: move extensions listing functions from mercurial.help...
r8871
Dirkjan Ochtman
extensions: simplify by selecting primary hgext
r8872 try:
file = open(path)
except IOError:
continue
else:
doc = help.moduledoc(file)
file.close()
Cédric Duval
extensions: move extensions listing functions from mercurial.help...
r8871
Dirkjan Ochtman
extensions: simplify by selecting primary hgext
r8872 if doc: # extracting localized synopsis
exts[name] = gettext(doc).splitlines()[0]
else:
exts[name] = _('(no help text available)')
if len(name) > maxlength:
maxlength = len(name)
Cédric Duval
extensions: move extensions listing functions from mercurial.help...
r8871
return exts, maxlength
def enabled():
'''return a dict of {name: desc} of extensions, and the max name length'''
exts = {}
maxlength = 0
for ename, ext in extensions():
doc = (gettext(ext.__doc__) or _('(no help text available)'))
ename = ename.split('.')[-1]
maxlength = max(len(ename), maxlength)
Nicolas Dumazet
for calls expecting bool args, pass bool instead of int...
r9136 exts[ename] = doc.splitlines()[0].strip()
Cédric Duval
extensions: move extensions listing functions from mercurial.help...
r8871
return exts, maxlength