Mercurial > hg
changeset 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 |
files | mercurial/extensions.py tests/test-extension.t |
diffstat | 2 files changed, 49 insertions(+), 0 deletions(-) [+] |
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)
--- a/tests/test-extension.t Sun May 14 15:46:45 2017 +0900 +++ b/tests/test-extension.t Sat May 13 15:41:50 2017 +0900 @@ -1534,6 +1534,40 @@ $ cd .. +Prohibit registration of commands that don't use @command (issue5137) + + $ hg init deprecated + $ cd deprecated + + $ cat <<EOF > deprecatedcmd.py + > def deprecatedcmd(repo, ui): + > pass + > cmdtable = { + > 'deprecatedcmd': (deprecatedcmd, [], ''), + > } + > EOF + $ cat <<EOF > .hg/hgrc + > [extensions] + > deprecatedcmd = `pwd`/deprecatedcmd.py + > mq = ! + > hgext.mq = ! + > hgext/mq = ! + > EOF + + $ hg deprecatedcmd > /dev/null + *** failed to import extension deprecatedcmd from $TESTTMP/deprecated/deprecatedcmd.py: missing attributes: norepo, optionalrepo, inferrepo + *** (use @command decorator to register 'deprecatedcmd') + hg: unknown command 'deprecatedcmd' + [255] + + the extension shouldn't be loaded at all so the mq works: + + $ hg qseries --config extensions.mq= > /dev/null + *** failed to import extension deprecatedcmd from $TESTTMP/deprecated/deprecatedcmd.py: missing attributes: norepo, optionalrepo, inferrepo + *** (use @command decorator to register 'deprecatedcmd') + + $ cd .. + Test synopsis and docstring extending $ hg init exthelp