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

FUJIWARA Katsunori foozy at lares.dti.ne.jp
Tue Mar 8 09:08:23 EST 2016


# HG changeset patch
# User FUJIWARA Katsunori <foozy at lares.dti.ne.jp>
# Date 1457445893 -32400
#      Tue Mar 08 23:04:53 2016 +0900
# Node ID 5055652b94dcc6c536a9b1029caa4d1c1e5ddaec
# Parent  85cba1c5c22c842209588d8da99da174ff4313cd
dispatch: make loading extra information from extension extensible

This patch makes loading extra information from extension module at
dispatching extensible. Factoring 'loadcmdtable()' outo commands.py is
a part of generalization of loading extra information.

This extensibility 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 actual loading module of it, even if it isn't used at runtime
(for example, extensions don't always define revset predicate)

diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -7147,3 +7147,12 @@ def version_(ui):
             for i, name in enumerate(names):
                 ui.write("  %-*s  %s  %s\n" %
                          (maxnamelen, name, place[i], vers[i]))
+
+def loadcmdtable(ui, name, cmdtable):
+    """Load command functions from specified 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)
diff --git a/mercurial/dispatch.py b/mercurial/dispatch.py
--- a/mercurial/dispatch.py
+++ b/mercurial/dispatch.py
@@ -743,6 +743,17 @@ def _checkshellalias(lui, ui, args, prec
                                   [], {})
 
 _loaded = set()
+
+# 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, extensionname,
+#   extraobj) arguments
+extraloaders = [
+    ('cmdtable', commands, 'loadcmdtable'),
+]
+
 def _dispatch(req):
     args = req.args
     ui = req.ui
@@ -772,12 +783,10 @@ def _dispatch(req):
     # (uisetup and extsetup are handled in extensions.loadall)
 
     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:
+            extraobj = getattr(module, objname, None)
+            if extraobj is not None:
+                getattr(loadermod, loadername)(ui, name, extraobj)
         _loaded.add(name)
 
     # (reposetup is handled in hg.repository)


More information about the Mercurial-devel mailing list