[PATCH 2 of 2] Treat extension load paths as relative to the defining hgrc

Jesse Glick Jesse.Glick at Sun.COM
Sun Jan 27 12:46:58 CST 2008


# HG changeset patch
# User Jesse Glick <jesse.glick at sun.com>
# Date 1201458613 18000
# Node ID d33016d9de57905a50c843759afbebc1584980f5
# Parent  67fa45ab91165524776db508e5b789ffdc371ae9
Treat extension load paths as relative to the defining hgrc.

When a custom extension is mandated for use on a particular project, it is most
convenient to physically associate the extension's source code with the project,
perhaps even keeping it inside the project, and define the extension in the
repository's .hg/hgrc. This is awkward to set up when custom extensions must be
loaded from absolute paths, since moving the repository then implies that its
hgrc must be updated as well. It is most natural to treat relative paths as
being relative to the defining configuration file, as is already done for the
[paths] section.

diff --git a/mercurial/dispatch.py b/mercurial/dispatch.py
--- a/mercurial/dispatch.py
+++ b/mercurial/dispatch.py
@@ -260,7 +260,7 @@ def _dispatch(ui, args):
     if path:
         try:
             lui = _ui.ui(parentui=ui)
-            lui.readconfig(os.path.join(path, ".hg", "hgrc"))
+            lui.readconfig(os.path.join(path, ".hg", "hgrc"), root=path)
         except IOError:
             pass
 
@@ -269,7 +269,7 @@ def _dispatch(ui, args):
     if rpath:
         path = lui.expandpath(rpath[-1])
         lui = _ui.ui(parentui=ui)
-        lui.readconfig(os.path.join(path, ".hg", "hgrc"))
+        lui.readconfig(os.path.join(path, ".hg", "hgrc"), root=path)
 
     extensions.loadall(lui)
     for name, module in extensions.extensions():
diff --git a/mercurial/ui.py b/mercurial/ui.py
--- a/mercurial/ui.py
+++ b/mercurial/ui.py
@@ -192,20 +192,22 @@ class ui(object):
 
     def fixconfig(self, section=None, name=None, value=None, root=None):
         # translate paths relative to root (or home) into absolute paths
-        if section is None or section == 'paths':
+        pathsections = ['paths', 'extensions']
+        if section is None or section in pathsections:
             if root is None:
                 root = os.getcwd()
-            items = section and [(name, value)] or []
             for cdata in self.cdata, self.ucdata, self.overlay:
                 if not cdata: continue
-                if not items and cdata.has_section('paths'):
-                    pathsitems = cdata.items('paths')
+                def absolutize(s, n, v):
+                    if v and "://" not in v and v[0] != '!' and not os.path.isabs(v):
+                        cdata.set(s, n, os.path.normpath(os.path.join(root, v)))
+                if section:
+                    absolutize(section, name, value)
                 else:
-                    pathsitems = items
-                for n, path in pathsitems:
-                    if path and "://" not in path and not os.path.isabs(path):
-                        cdata.set("paths", n,
-                                  os.path.normpath(os.path.join(root, path)))
+                    for s in pathsections:
+                        if cdata.has_section(s):
+                            for n, v in cdata.items(s):
+                                absolutize(s, n, v)
 
         # update verbosity/interactive/report_untrusted settings
         if section is None or section == 'ui':
diff --git a/tests/test-extension b/tests/test-extension
--- a/tests/test-extension
+++ b/tests/test-extension
@@ -80,3 +80,10 @@ hg help debugextension
 hg help debugextension
 hg --debug help debugextension
 echo 'debugextension = !' >> $HGRCPATH
+
+echo > $HGRCPATH
+hg init rel
+echo '[extensions]' >> rel/.hg/hgrc
+echo 'foobar = ../foobar.py' >> rel/.hg/hgrc
+hg --cwd rel foo
+hg -R rel foo
diff --git a/tests/test-extension.out b/tests/test-extension.out
--- a/tests/test-extension.out
+++ b/tests/test-extension.out
@@ -49,3 +49,13 @@ global options:
     --profile         print command execution profile
     --version         output version information and exit
  -h --help            display help and exit
+uisetup called
+ui.parentui isnot None
+reposetup called for rel
+ui == repo.ui
+Foo
+uisetup called
+ui.parentui isnot None
+reposetup called for rel
+ui == repo.ui
+Foo


More information about the Mercurial-devel mailing list