[PATCH 1 of 5] dispatch: make loading extra information from extension extensible

FUJIWARA Katsunori foozy at lares.dti.ne.jp
Tue Jan 5 05:48:34 CST 2016


# HG changeset patch
# User FUJIWARA Katsunori <foozy at lares.dti.ne.jp>
# Date 1451994203 -32400
#      Tue Jan 05 20:43:23 2016 +0900
# Node ID e526fa5df73b5263d164bd339251481050755720
# Parent  b8405d739149cdd6d8d9bd5e3dd2ad8487b1f09a
dispatch: make loading extra information from extension extensible

This patch makes loading extra information from extension module at
dispatching extensible. This assumes registration of new function like
below, for example:

  - revset predicate
  - fileset predicate
  - template keyword
  - template filter
  - template function
  - internal merge tool
  - web command

This patch requires not loader function itself but container module
and the name of it, because listing loader function directly up
implies loading module of it, even if it isn't used at runtime.

diff --git a/mercurial/dispatch.py b/mercurial/dispatch.py
--- a/mercurial/dispatch.py
+++ b/mercurial/dispatch.py
@@ -749,6 +749,24 @@ def _checkshellalias(lui, ui, args, prec
     restorecommands()
 
 _loaded = set()
+
+def _loadcmdtable(ui, name, 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)
+
+# list of (objname, loadermod, loadername) tuple:
+# - objname is the name of an object in extension module, from which
+#   extra information is loaded
+# - loadermod is the module where loader is placed
+# - loadername is the name of the function, which takes (ui, objname,
+#   obj) arguments
+extraloaders = [
+    ('cmdtable', None, None), # this is just a place holder for 'cmdtable'
+]
+
 def _dispatch(req):
     args = req.args
     ui = req.ui
@@ -777,13 +795,14 @@ def _dispatch(req):
 
     # (uisetup and extsetup are handled in extensions.loadall)
 
+    loadercache = {'cmdtable': _loadcmdtable}
     for name, module in exts:
-        cmdtable = getattr(module, '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)
+        for objname, loadermod, loadername in extraloaders:
+            if util.safehasattr(module, objname):
+                if objname not in loadercache:
+                    loadercache[objname] = getattr(loadermod, loadername)
+                loader = loadercache[objname]
+                loader(ui, name, getattr(module, objname))
         _loaded.add(name)
 
     # (reposetup is handled in hg.repository)


More information about the Mercurial-devel mailing list