ability to load hooks from arbitrary python module
authorAlexander Solovyov <piranha@piranha.org.ua>
Fri, 27 Mar 2009 01:28:09 +0200
changeset 7916 f779e1996e23
parent 7915 fba93bbbca02
child 7917 5a5396f49420
ability to load hooks from arbitrary python module
doc/hgrc.5.txt
mercurial/extensions.py
mercurial/hook.py
--- a/doc/hgrc.5.txt	Sun Mar 29 19:06:56 2009 +0200
+++ b/doc/hgrc.5.txt	Fri Mar 27 01:28:09 2009 +0200
@@ -475,6 +475,7 @@
   The syntax for Python hooks is as follows:
 
     hookname = python:modulename.submodule.callable
+    hookname = python:/path/to/python/module.py:callable
 
   Python hooks are run within the Mercurial process. Each hook is
   called with at least three keyword arguments: a ui object (keyword
--- a/mercurial/extensions.py	Sun Mar 29 19:06:56 2009 +0200
+++ b/mercurial/extensions.py	Fri Mar 27 01:28:09 2009 +0200
@@ -28,6 +28,17 @@
                 return v
         raise KeyError(name)
 
+def loadpath(path, module_name):
+    module_name = module_name.replace('.', '_')
+    path = os.path.expanduser(path)
+    if os.path.isdir(path):
+        # module/__init__.py style
+        d, f = os.path.split(path)
+        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)
+
 def load(ui, name, path):
     if name.startswith('hgext.') or name.startswith('hgext/'):
         shortname = name[6:]
@@ -40,14 +51,7 @@
         # the module will be loaded in sys.modules
         # choose an unique name so that it doesn't
         # conflicts with other modules
-        module_name = "hgext_%s" % name.replace('.', '_')
-        if os.path.isdir(path):
-            # module/__init__.py style
-            d, f = os.path.split(path)
-            fd, fpath, desc = imp.find_module(f, [d])
-            mod = imp.load_module(module_name, fd, fpath, desc)
-        else:
-            mod = imp.load_source(module_name, path)
+        mod = loadpath(path, 'hgext.%s' % name)
     else:
         def importh(name):
             mod = __import__(name)
@@ -72,7 +76,6 @@
         if path:
             if path[0] == '!':
                 continue
-            path = os.path.expanduser(path)
         try:
             load(ui, name, path)
         except KeyboardInterrupt:
--- a/mercurial/hook.py	Sun Mar 29 19:06:56 2009 +0200
+++ b/mercurial/hook.py	Fri Mar 27 01:28:09 2009 +0200
@@ -7,6 +7,7 @@
 
 from i18n import _
 import util, os, sys
+from mercurial import extensions
 
 def _pythonhook(ui, repo, name, hname, funcname, args, throw):
     '''call python hook. hook is callable object, looked up as
@@ -109,8 +110,13 @@
             if callable(cmd):
                 r = _pythonhook(ui, repo, name, hname, cmd, args, throw) or r
             elif cmd.startswith('python:'):
-                r = _pythonhook(ui, repo, name, hname, cmd[7:].strip(),
-                                args, throw) or r
+                if cmd.count(':') == 2:
+                    path, cmd = cmd[7:].split(':')
+                    mod = extensions.loadpath(path, 'hgkook.%s' % hname)
+                    hookfn = getattr(mod, cmd)
+                else:
+                    hookfn = cmd[7:].strip()
+                r = _pythonhook(ui, repo, name, hname, hookfn, args, throw) or r
             else:
                 r = _exthook(ui, repo, hname, cmd, args, throw) or r
     finally: