[PATCH] Add hgrc support for specification of extension directories

Jonathan S. Shapiro shap at eros-os.com
Fri Aug 31 13:35:04 CDT 2007


# HG changeset patch
# User Jonathan S. Shapiro <shap at eros-os.com>
# Date 1188585076 14400
# Node ID c36b3419c3d6b97f09d316cca05d82f1153d1a54
# Parent  9085dc8f7de9c2642e1ee690bfc1780b6b2f1a42
Add hgrc support for specification of extension directories

This patch introduces a new section [extpaths] in hgrc that can be
used to specify additional directories from which extension modules
should be loaded. The mechanism is needed for third party packagers of
extensions to install them in a sensible way. It solves the problem of
(e.g.) forest, which initially needed to be packaged separately but
will probably be incorporated into core. The problem is that when it
is incorporated, any existing third-party packaging of the same
extension will have the wrong effect. By packaging it in a directory
of its own, the [extpaths] section can be used to search the
packager-specified directory AFTER hgext is checked.

diff -r 9085dc8f7de9 -r c36b3419c3d6 mercurial/extensions.py
--- a/mercurial/extensions.py	Fri Aug 31 12:56:42 2007 -0400
+++ b/mercurial/extensions.py	Fri Aug 31 14:31:16 2007 -0400
@@ -11,6 +11,7 @@ from i18n import _
 
 _extensions = {}
 _order = []
+_extpaths = None
 
 def extensions():
     for name in _order:
@@ -27,6 +28,16 @@ def find(name):
             if k.endswith('.' + name) or k.endswith('/' + name):
                 return v
         raise KeyError(name)
+
+def load_extpaths(ui):
+    global _extpaths
+    _extpaths = []
+    extpath_items = ui.configitems("extpaths")
+    for i, (name,path) in enumerate(extpath_items):
+        if path:
+            _extpaths.append(path)
+        else:
+            ui.warn(_("*** Malformed extpath entry %s ignored\n") % name)
 
 def load(ui, name, path):
     if name.startswith('hgext.'):
@@ -50,7 +61,20 @@ def load(ui, name, path):
             mod = imp.load_source(module_name, path)
     else:
         def importh(name):
-            mod = __import__(name)
+            if _extpaths == None:
+                load_extpaths(ui)
+        
+            # Want to respect any paths provided in an extpaths
+            # section. To do that, we Need to munge sys.path for
+            # __import__ to work, but do not want that to escape into
+            # the rest of mercurial.
+            keep_sys_path = sys.path
+            try:
+                sys.path = sys.path + _extpaths
+                mod = __import__(name)
+            finally:
+                sys.path = keep_sys_path
+                
             components = name.split('.')
             for comp in components[1:]:
                 mod = getattr(mod, comp)


More information about the Mercurial-devel mailing list