Mercurial > hg
annotate mercurial/extensions.py @ 8676:acd69fc201a5
walk: we always have a badfn
author | Matt Mackall <mpm@selenic.com> |
---|---|
date | Sun, 31 May 2009 17:54:18 -0500 |
parents | 46293a0c7e9f |
children | 20a25042fadc |
rev | line source |
---|---|
4544
930ed513c864
Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
1 # extensions.py - extension handling for mercurial |
930ed513c864
Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
2 # |
4635
63b9d2deed48
Updated copyright notices and add "and others" to "hg version"
Thomas Arendsen Hein <thomas@intevation.de>
parents:
4633
diff
changeset
|
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com> |
4544
930ed513c864
Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
4 # |
8225
46293a0c7e9f
updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents:
8206
diff
changeset
|
5 # This software may be used and distributed according to the terms of the |
46293a0c7e9f
updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents:
8206
diff
changeset
|
6 # GNU General Public License version 2, incorporated herein by reference. |
4544
930ed513c864
Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
7 |
4569
622d8ed78b47
extensions: load modules in module/__init__.py form.
Brendan Cully <brendan@kublai.com>
parents:
4558
diff
changeset
|
8 import imp, os |
7215
0ab5f21c390b
extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents:
7011
diff
changeset
|
9 import util, cmdutil |
4544
930ed513c864
Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
10 from i18n import _ |
930ed513c864
Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
11 |
930ed513c864
Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
12 _extensions = {} |
5192
60acf1432ee0
Move cmdtable and reposetup handling out of extensions.py
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
5152
diff
changeset
|
13 _order = [] |
60acf1432ee0
Move cmdtable and reposetup handling out of extensions.py
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
5152
diff
changeset
|
14 |
60acf1432ee0
Move cmdtable and reposetup handling out of extensions.py
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
5152
diff
changeset
|
15 def extensions(): |
60acf1432ee0
Move cmdtable and reposetup handling out of extensions.py
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
5152
diff
changeset
|
16 for name in _order: |
60acf1432ee0
Move cmdtable and reposetup handling out of extensions.py
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
5152
diff
changeset
|
17 module = _extensions[name] |
60acf1432ee0
Move cmdtable and reposetup handling out of extensions.py
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
5152
diff
changeset
|
18 if module: |
60acf1432ee0
Move cmdtable and reposetup handling out of extensions.py
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
5152
diff
changeset
|
19 yield name, module |
4544
930ed513c864
Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
20 |
930ed513c864
Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
21 def find(name): |
930ed513c864
Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
22 '''return module with given extension name''' |
930ed513c864
Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
23 try: |
930ed513c864
Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
24 return _extensions[name] |
930ed513c864
Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
25 except KeyError: |
930ed513c864
Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
26 for k, v in _extensions.iteritems(): |
4560
3daed3680554
extensions: fix lookup of hgext.foo modules
Matt Mackall <mpm@selenic.com>
parents:
4558
diff
changeset
|
27 if k.endswith('.' + name) or k.endswith('/' + name): |
3daed3680554
extensions: fix lookup of hgext.foo modules
Matt Mackall <mpm@selenic.com>
parents:
4558
diff
changeset
|
28 return v |
4544
930ed513c864
Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
29 raise KeyError(name) |
930ed513c864
Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
30 |
7916
f779e1996e23
ability to load hooks from arbitrary python module
Alexander Solovyov <piranha@piranha.org.ua>
parents:
7876
diff
changeset
|
31 def loadpath(path, module_name): |
f779e1996e23
ability to load hooks from arbitrary python module
Alexander Solovyov <piranha@piranha.org.ua>
parents:
7876
diff
changeset
|
32 module_name = module_name.replace('.', '_') |
f779e1996e23
ability to load hooks from arbitrary python module
Alexander Solovyov <piranha@piranha.org.ua>
parents:
7876
diff
changeset
|
33 path = os.path.expanduser(path) |
f779e1996e23
ability to load hooks from arbitrary python module
Alexander Solovyov <piranha@piranha.org.ua>
parents:
7876
diff
changeset
|
34 if os.path.isdir(path): |
f779e1996e23
ability to load hooks from arbitrary python module
Alexander Solovyov <piranha@piranha.org.ua>
parents:
7876
diff
changeset
|
35 # module/__init__.py style |
7960
5c794e7331e7
extensions loading: don't fail if path to extension ends with a '/'
Alexander Solovyov <piranha@piranha.org.ua>
parents:
7916
diff
changeset
|
36 d, f = os.path.split(path.rstrip('/')) |
7916
f779e1996e23
ability to load hooks from arbitrary python module
Alexander Solovyov <piranha@piranha.org.ua>
parents:
7876
diff
changeset
|
37 fd, fpath, desc = imp.find_module(f, [d]) |
f779e1996e23
ability to load hooks from arbitrary python module
Alexander Solovyov <piranha@piranha.org.ua>
parents:
7876
diff
changeset
|
38 return imp.load_module(module_name, fd, fpath, desc) |
f779e1996e23
ability to load hooks from arbitrary python module
Alexander Solovyov <piranha@piranha.org.ua>
parents:
7876
diff
changeset
|
39 else: |
f779e1996e23
ability to load hooks from arbitrary python module
Alexander Solovyov <piranha@piranha.org.ua>
parents:
7876
diff
changeset
|
40 return imp.load_source(module_name, path) |
f779e1996e23
ability to load hooks from arbitrary python module
Alexander Solovyov <piranha@piranha.org.ua>
parents:
7876
diff
changeset
|
41 |
4544
930ed513c864
Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
42 def load(ui, name, path): |
7011
7da76778dbd7
Do not try to load extensions twice (issue811)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
6212
diff
changeset
|
43 if name.startswith('hgext.') or name.startswith('hgext/'): |
5031
af0995261f02
extensions: don't get confused by aliasing between "foo" and "hgext.foo"
Bryan O'Sullivan <bos@serpentine.com>
parents:
4818
diff
changeset
|
44 shortname = name[6:] |
af0995261f02
extensions: don't get confused by aliasing between "foo" and "hgext.foo"
Bryan O'Sullivan <bos@serpentine.com>
parents:
4818
diff
changeset
|
45 else: |
af0995261f02
extensions: don't get confused by aliasing between "foo" and "hgext.foo"
Bryan O'Sullivan <bos@serpentine.com>
parents:
4818
diff
changeset
|
46 shortname = name |
af0995261f02
extensions: don't get confused by aliasing between "foo" and "hgext.foo"
Bryan O'Sullivan <bos@serpentine.com>
parents:
4818
diff
changeset
|
47 if shortname in _extensions: |
4544
930ed513c864
Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
48 return |
5087
b3cc62268a91
Cache extension load failures.
Brendan Cully <brendan@kublai.com>
parents:
4635
diff
changeset
|
49 _extensions[shortname] = None |
4544
930ed513c864
Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
50 if path: |
930ed513c864
Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
51 # the module will be loaded in sys.modules |
930ed513c864
Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
52 # choose an unique name so that it doesn't |
930ed513c864
Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
53 # conflicts with other modules |
7916
f779e1996e23
ability to load hooks from arbitrary python module
Alexander Solovyov <piranha@piranha.org.ua>
parents:
7876
diff
changeset
|
54 mod = loadpath(path, 'hgext.%s' % name) |
4544
930ed513c864
Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
55 else: |
930ed513c864
Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
56 def importh(name): |
930ed513c864
Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
57 mod = __import__(name) |
930ed513c864
Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
58 components = name.split('.') |
930ed513c864
Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
59 for comp in components[1:]: |
930ed513c864
Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
60 mod = getattr(mod, comp) |
930ed513c864
Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
61 return mod |
930ed513c864
Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
62 try: |
930ed513c864
Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
63 mod = importh("hgext.%s" % name) |
930ed513c864
Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
64 except ImportError: |
930ed513c864
Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
65 mod = importh(name) |
5031
af0995261f02
extensions: don't get confused by aliasing between "foo" and "hgext.foo"
Bryan O'Sullivan <bos@serpentine.com>
parents:
4818
diff
changeset
|
66 _extensions[shortname] = mod |
5192
60acf1432ee0
Move cmdtable and reposetup handling out of extensions.py
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
5152
diff
changeset
|
67 _order.append(shortname) |
4544
930ed513c864
Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
68 |
930ed513c864
Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
69 uisetup = getattr(mod, 'uisetup', None) |
930ed513c864
Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
70 if uisetup: |
930ed513c864
Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
71 uisetup(ui) |
930ed513c864
Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
72 |
930ed513c864
Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
73 def loadall(ui): |
4617
669e76b7df24
extensions: pull extension-aware bits out of ui
Matt Mackall <mpm@selenic.com>
parents:
4582
diff
changeset
|
74 result = ui.configitems("extensions") |
7876
53c72ba36c2b
cleanup: drop enumerate() when index is not used
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
7644
diff
changeset
|
75 for (name, path) in result: |
4617
669e76b7df24
extensions: pull extension-aware bits out of ui
Matt Mackall <mpm@selenic.com>
parents:
4582
diff
changeset
|
76 if path: |
5469
b12432b1c2c7
Allow explicit disabling of extensions
Steve Borho <steve@borho.org>
parents:
5192
diff
changeset
|
77 if path[0] == '!': |
b12432b1c2c7
Allow explicit disabling of extensions
Steve Borho <steve@borho.org>
parents:
5192
diff
changeset
|
78 continue |
4544
930ed513c864
Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
79 try: |
930ed513c864
Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
80 load(ui, name, path) |
7644
182b7114d35a
error: move SignalInterrupt
Matt Mackall <mpm@selenic.com>
parents:
7388
diff
changeset
|
81 except KeyboardInterrupt: |
4544
930ed513c864
Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
82 raise |
930ed513c864
Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
83 except Exception, inst: |
6204
f8a86ea7521b
When failing to load an extension, show where Hg tried to load it from.
Jesse Glick <jesse.glick@sun.com>
parents:
5469
diff
changeset
|
84 if path: |
f8a86ea7521b
When failing to load an extension, show where Hg tried to load it from.
Jesse Glick <jesse.glick@sun.com>
parents:
5469
diff
changeset
|
85 ui.warn(_("*** failed to import extension %s from %s: %s\n") |
f8a86ea7521b
When failing to load an extension, show where Hg tried to load it from.
Jesse Glick <jesse.glick@sun.com>
parents:
5469
diff
changeset
|
86 % (name, path, inst)) |
f8a86ea7521b
When failing to load an extension, show where Hg tried to load it from.
Jesse Glick <jesse.glick@sun.com>
parents:
5469
diff
changeset
|
87 else: |
f8a86ea7521b
When failing to load an extension, show where Hg tried to load it from.
Jesse Glick <jesse.glick@sun.com>
parents:
5469
diff
changeset
|
88 ui.warn(_("*** failed to import extension %s: %s\n") |
f8a86ea7521b
When failing to load an extension, show where Hg tried to load it from.
Jesse Glick <jesse.glick@sun.com>
parents:
5469
diff
changeset
|
89 % (name, inst)) |
8206
cce63ef1045b
ui: print_exc() -> traceback()
Matt Mackall <mpm@selenic.com>
parents:
7960
diff
changeset
|
90 if ui.traceback(): |
4544
930ed513c864
Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
91 return 1 |
930ed513c864
Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
92 |
7215
0ab5f21c390b
extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents:
7011
diff
changeset
|
93 def wrapcommand(table, command, wrapper): |
0ab5f21c390b
extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents:
7011
diff
changeset
|
94 aliases, entry = cmdutil.findcmd(command, table) |
0ab5f21c390b
extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents:
7011
diff
changeset
|
95 for alias, e in table.iteritems(): |
0ab5f21c390b
extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents:
7011
diff
changeset
|
96 if e is entry: |
0ab5f21c390b
extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents:
7011
diff
changeset
|
97 key = alias |
0ab5f21c390b
extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents:
7011
diff
changeset
|
98 break |
0ab5f21c390b
extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents:
7011
diff
changeset
|
99 |
0ab5f21c390b
extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents:
7011
diff
changeset
|
100 origfn = entry[0] |
0ab5f21c390b
extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents:
7011
diff
changeset
|
101 def wrap(*args, **kwargs): |
7388
5751631246de
dispatch: generalize signature checking for extension command wrapping
Matt Mackall <mpm@selenic.com>
parents:
7373
diff
changeset
|
102 return util.checksignature(wrapper)( |
5751631246de
dispatch: generalize signature checking for extension command wrapping
Matt Mackall <mpm@selenic.com>
parents:
7373
diff
changeset
|
103 util.checksignature(origfn), *args, **kwargs) |
7215
0ab5f21c390b
extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents:
7011
diff
changeset
|
104 |
0ab5f21c390b
extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents:
7011
diff
changeset
|
105 wrap.__doc__ = getattr(origfn, '__doc__') |
7373
d9e9dd2b00fb
extensions: copy __module__ for wrapped commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
7215
diff
changeset
|
106 wrap.__module__ = getattr(origfn, '__module__') |
7215
0ab5f21c390b
extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents:
7011
diff
changeset
|
107 |
0ab5f21c390b
extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents:
7011
diff
changeset
|
108 newentry = list(entry) |
0ab5f21c390b
extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents:
7011
diff
changeset
|
109 newentry[0] = wrap |
0ab5f21c390b
extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents:
7011
diff
changeset
|
110 table[key] = tuple(newentry) |
0ab5f21c390b
extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents:
7011
diff
changeset
|
111 return entry |
0ab5f21c390b
extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents:
7011
diff
changeset
|
112 |
0ab5f21c390b
extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents:
7011
diff
changeset
|
113 def wrapfunction(container, funcname, wrapper): |
0ab5f21c390b
extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents:
7011
diff
changeset
|
114 def wrap(*args, **kwargs): |
0ab5f21c390b
extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents:
7011
diff
changeset
|
115 return wrapper(origfn, *args, **kwargs) |
0ab5f21c390b
extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents:
7011
diff
changeset
|
116 |
0ab5f21c390b
extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents:
7011
diff
changeset
|
117 origfn = getattr(container, funcname) |
0ab5f21c390b
extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents:
7011
diff
changeset
|
118 setattr(container, funcname, wrap) |
0ab5f21c390b
extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents:
7011
diff
changeset
|
119 return origfn |