diff mercurial/extensions.py @ 32342:e5fbf9687600

extensions: prohibit registration of command without using @command (API) Detect the problem earlier for better error indication. I'm tired of teaching users that the mq extension is not guilty but the third-party extension is. https://bitbucket.org/tortoisehg/thg/issues?q=%27norepo%27
author Yuya Nishihara <yuya@tcha.org>
date Sat, 13 May 2017 15:41:50 +0900
parents b88d879e468a
children d47d7d3bd07b
line wrap: on
line diff
--- a/mercurial/extensions.py	Sun May 14 15:46:45 2017 +0900
+++ b/mercurial/extensions.py	Sat May 13 15:41:50 2017 +0900
@@ -118,6 +118,20 @@
     if ui.debugflag:
         ui.traceback()
 
+# attributes set by registrar.command
+_cmdfuncattrs = ('norepo', 'optionalrepo', 'inferrepo')
+
+def _validatecmdtable(cmdtable):
+    """Check if extension commands have required attributes"""
+    for c, e in cmdtable.iteritems():
+        f = e[0]
+        missing = [a for a in _cmdfuncattrs if not util.safehasattr(f, a)]
+        if not missing:
+            continue
+        raise error.ProgrammingError(
+            'missing attributes: %s' % ', '.join(missing),
+            hint="use @command decorator to register '%s'" % c)
+
 def load(ui, name, path):
     if name.startswith('hgext.') or name.startswith('hgext/'):
         shortname = name[6:]
@@ -139,6 +153,7 @@
         ui.warn(_('(third party extension %s requires version %s or newer '
                   'of Mercurial; disabling)\n') % (shortname, minver))
         return
+    _validatecmdtable(getattr(mod, 'cmdtable', {}))
 
     _extensions[shortname] = mod
     _order.append(shortname)