# HG changeset patch # User Alexis S. L. Carvalho # Date 1171000108 7200 # Node ID 961ccb615cf7b6280a1cb51091c51efbb4a7a563 # Parent 3fef134832d895b87fcf1a4c55b601fd0b086735 Handle functions as the value of a hooks. config variable This should make it easier for extensions to add a hook when they're loaded. diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py --- a/mercurial/localrepo.py +++ b/mercurial/localrepo.py @@ -142,32 +142,34 @@ class localrepository(repo.repository): 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 @@ class localrepository(repo.repository): 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 diff --git a/tests/test-hook b/tests/test-hook --- a/tests/test-hook +++ b/tests/test-hook @@ -183,4 +183,24 @@ echo 'commit.abort = python:hooktests.ab echo a >> a hg --traceback commit -A -m a 2>&1 | grep '^Traceback' +cd .. +hg init c +cd c + +cat > hookext.py <> .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 diff --git a/tests/test-hook.out b/tests/test-hook.out --- a/tests/test-hook.out +++ b/tests/test-hook.out @@ -138,3 +138,7 @@ added 1 changesets with 1 changes to 1 f (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: +Automatically installed hook