changeset 4544:930ed513c864

Create a separate module for managing extensions
author Matt Mackall <mpm@selenic.com>
date Mon, 11 Jun 2007 21:09:23 -0500
parents 6b4e8a75d5fc
children aea8fd7fb5e2
files mercurial/commands.py mercurial/extensions.py
diffstat 2 files changed, 74 insertions(+), 64 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -8,8 +8,8 @@
 import demandimport; demandimport.enable()
 from node import *
 from i18n import _
-import bisect, os, re, sys, signal, imp, urllib, pdb, shlex, stat
-import fancyopts, ui, hg, util, lock, revlog, bundlerepo
+import bisect, os, re, sys, signal, urllib, pdb, shlex, stat
+import fancyopts, ui, hg, util, lock, revlog, bundlerepo, extensions
 import difflib, patch, time, help, mdiff, tempfile
 import traceback, errno, version, atexit, socket
 import archival, changegroup, cmdutil, hgweb.server, sshserver
@@ -1371,7 +1371,7 @@ def help_(ui, name=None, with_version=Fa
 
     def helpext(name):
         try:
-            mod = findext(name)
+            mod = extensions.find(name)
         except KeyError:
             raise UnknownCommand(name)
 
@@ -3137,65 +3137,6 @@ def parseconfig(config):
             raise util.Abort(_('malformed --config option: %s') % cfg)
     return parsed
 
-external = {}
-
-def findext(name):
-    '''return module with given extension name'''
-    try:
-        return sys.modules[external[name]]
-    except KeyError:
-        for k, v in external.iteritems():
-            if k.endswith('.' + name) or k.endswith('/' + name) or v == name:
-                return sys.modules[v]
-        raise KeyError(name)
-
-def load_extension(ui, name, load):
-    if name in external:
-        return
-    if load:
-        # 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('.', '_')
-        mod = imp.load_source(module_name, load)
-    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)
-    external[name] = mod.__name__
-
-    uisetup = getattr(mod, 'uisetup', None)
-    if uisetup:
-        uisetup(ui)
-    reposetup = getattr(mod, 'reposetup', None)
-    if reposetup:
-        hg.repo_setup_hooks.append(reposetup)
-    cmdtable = getattr(mod, 'cmdtable', {})
-    overrides = [cmd for cmd in cmdtable if cmd in table]
-    if overrides:
-        ui.warn(_("extension '%s' overrides commands: %s\n")
-                % (name, " ".join(overrides)))
-    table.update(cmdtable)
-
-def load_extensions(ui):
-    for name, load in ui.extensions():
-        try:
-            load_extension(ui, name, load)
-        except (util.SignalInterrupt, KeyboardInterrupt):
-            raise
-        except Exception, inst:
-            ui.warn(_("*** failed to import extension %s: %s\n") %
-                    (name, inst))
-            if ui.print_exc():
-                return 1
-
 def catchterm(*args):
     raise util.SignalInterrupt
 
@@ -3210,8 +3151,8 @@ def dispatch(args):
         sys.stderr.write(_("abort: %s\n") % inst)
         return -1
 
-    load_extensions(u)
-    u.addreadhook(load_extensions)
+    extensions.loadall(u)
+    u.addreadhook(extensions.loadall)
 
     try:
         cmd, func, args, options, cmdoptions = parse(u, args)
new file mode 100644
--- /dev/null
+++ b/mercurial/extensions.py
@@ -0,0 +1,69 @@
+# extensions.py - extension handling for mercurial
+#
+# Copyright 2005, 2006 Matt Mackall <mpm@selenic.com>
+#
+# This software may be used and distributed according to the terms
+# of the GNU General Public License, incorporated herein by reference.
+
+import imp, commands, hg, util
+from i18n import _
+
+_extensions = {}
+
+def find(name):
+    '''return module with given extension name'''
+    try:
+        return _extensions[name]
+    except KeyError:
+        for k, v in _extensions.iteritems():
+            if k.endswith('.' + name) or k.endswith('/' + name) or v == name:
+                return sys.modules[v]
+        raise KeyError(name)
+
+def load(ui, name, path):
+    if name in _extensions:
+        return
+    if path:
+        # 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('.', '_')
+        mod = imp.load_source(module_name, path)
+    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)
+    _extensions[name] = mod
+
+    uisetup = getattr(mod, 'uisetup', None)
+    if uisetup:
+        uisetup(ui)
+    reposetup = getattr(mod, 'reposetup', None)
+    if reposetup:
+        hg.repo_setup_hooks.append(reposetup)
+    cmdtable = getattr(mod, 'cmdtable', {})
+    overrides = [cmd for cmd in cmdtable if cmd in commands.table]
+    if overrides:
+        ui.warn(_("extension '%s' overrides commands: %s\n")
+                % (name, " ".join(overrides)))
+    commands.table.update(cmdtable)
+
+def loadall(ui):
+    for name, path in ui.extensions():
+        try:
+            load(ui, name, path)
+        except (util.SignalInterrupt, KeyboardInterrupt):
+            raise
+        except Exception, inst:
+            ui.warn(_("*** failed to import extension %s: %s\n") %
+                    (name, inst))
+            if ui.print_exc():
+                return 1
+