Handle functions as the value of a hooks.<name> config variable
This should make it easier for extensions to add a hook when
they're loaded.
--- a/mercurial/localrepo.py Fri Feb 09 03:48:26 2007 -0200
+++ b/mercurial/localrepo.py Fri Feb 09 03:48:28 2007 -0200
@@ -142,32 +142,34 @@
be run as hooks without wrappers to convert return values.'''
self.ui.note(_("calling hook %s: %s\n") % (hname, funcname))
- d = funcname.rfind('.')
- if d == -1:
- raise util.Abort(_('%s hook is invalid ("%s" not in a module)')
- % (hname, funcname))
- modname = funcname[:d]
- try:
- obj = __import__(modname)
- except ImportError:
+ obj = funcname
+ if not callable(obj):
+ d = funcname.rfind('.')
+ if d == -1:
+ raise util.Abort(_('%s hook is invalid ("%s" not in '
+ 'a module)') % (hname, funcname))
+ modname = funcname[:d]
try:
- # extensions are loaded with hgext_ prefix
- obj = __import__("hgext_%s" % modname)
+ obj = __import__(modname)
except ImportError:
+ try:
+ # extensions are loaded with hgext_ prefix
+ obj = __import__("hgext_%s" % modname)
+ except ImportError:
+ raise util.Abort(_('%s hook is invalid '
+ '(import of "%s" failed)') %
+ (hname, modname))
+ try:
+ for p in funcname.split('.')[1:]:
+ obj = getattr(obj, p)
+ except AttributeError, err:
raise util.Abort(_('%s hook is invalid '
- '(import of "%s" failed)') %
- (hname, modname))
- try:
- for p in funcname.split('.')[1:]:
- obj = getattr(obj, p)
- except AttributeError, err:
- raise util.Abort(_('%s hook is invalid '
- '("%s" is not defined)') %
- (hname, funcname))
- if not callable(obj):
- raise util.Abort(_('%s hook is invalid '
- '("%s" is not callable)') %
- (hname, funcname))
+ '("%s" is not defined)') %
+ (hname, funcname))
+ if not callable(obj):
+ raise util.Abort(_('%s hook is invalid '
+ '("%s" is not callable)') %
+ (hname, funcname))
try:
r = obj(ui=self.ui, repo=self, hooktype=name, **args)
except (KeyboardInterrupt, util.SignalInterrupt):
@@ -205,7 +207,9 @@
if hname.split(".", 1)[0] == name and cmd]
hooks.sort()
for hname, cmd in hooks:
- if cmd.startswith('python:'):
+ if callable(cmd):
+ r = callhook(hname, cmd) or r
+ elif cmd.startswith('python:'):
r = callhook(hname, cmd[7:].strip()) or r
else:
r = runhook(hname, cmd) or r
--- a/tests/test-hook Fri Feb 09 03:48:26 2007 -0200
+++ b/tests/test-hook Fri Feb 09 03:48:28 2007 -0200
@@ -183,4 +183,24 @@
echo a >> a
hg --traceback commit -A -m a 2>&1 | grep '^Traceback'
+cd ..
+hg init c
+cd c
+
+cat > hookext.py <<EOF
+def autohook(**args):
+ print "Automatically installed hook"
+
+def reposetup(ui, repo):
+ repo.ui.setconfig("hooks", "commit.auto", autohook)
+EOF
+echo '[extensions]' >> .hg/hgrc
+echo 'hookext = hookext.py' >> .hg/hgrc
+
+touch foo
+hg add foo
+hg ci -m 'add foo'
+echo >> foo
+hg ci --debug -m 'change foo' | sed -e 's/ at .*>/>/'
+
exit 0
--- a/tests/test-hook.out Fri Feb 09 03:48:26 2007 -0200
+++ b/tests/test-hook.out Fri Feb 09 03:48:28 2007 -0200
@@ -138,3 +138,7 @@
(run 'hg update' to get a working copy)
# make sure --traceback works
Traceback (most recent call last):
+Automatically installed hook
+foo
+calling hook commit.auto: <function autohook>
+Automatically installed hook