annotate mercurial/hook.py @ 36626:6754d0c5e1b5

py3: make test-ancestors.py pass on Python 3 with C extensions # skip-blame just some b prefixes
author Yuya Nishihara <yuya@tcha.org>
date Sat, 03 Mar 2018 07:59:20 -0500
parents c4146cf4dd20
children 9c636ec1ef37
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
4622
fff50306e6dd hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
1 # hook.py - hook support for mercurial
fff50306e6dd hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
2 #
fff50306e6dd hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
3 # Copyright 2007 Matt Mackall <mpm@selenic.com>
fff50306e6dd hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
4 #
8225
46293a0c7e9f updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents: 8209
diff changeset
5 # This software may be used and distributed according to the terms of the
10263
25e572394f5c Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 10103
diff changeset
6 # GNU General Public License version 2 or any later version.
4622
fff50306e6dd hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
7
25953
d15b279ddade hook: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
8 from __future__ import absolute_import
d15b279ddade hook: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
9
d15b279ddade hook: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
10 import os
d15b279ddade hook: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
11 import sys
d15b279ddade hook: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
12
d15b279ddade hook: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
13 from .i18n import _
d15b279ddade hook: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
14 from . import (
d15b279ddade hook: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
15 demandimport,
32642
c032e137e494 py3: convert exception to bytes to pass into ui.warn()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32614
diff changeset
16 encoding,
25953
d15b279ddade hook: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
17 error,
d15b279ddade hook: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
18 extensions,
30519
20a42325fdef py3: use pycompat.getcwd() instead of os.getcwd()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30473
diff changeset
19 pycompat,
25953
d15b279ddade hook: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
20 util,
d15b279ddade hook: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
21 )
4622
fff50306e6dd hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
22
31742
f243b7fbeba5 hook: use "htype" as variable name in _pythonhook
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31205
diff changeset
23 def _pythonhook(ui, repo, htype, hname, funcname, args, throw):
4622
fff50306e6dd hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
24 '''call python hook. hook is callable object, looked up as
fff50306e6dd hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
25 name in python module. if callable returns "true", hook
fff50306e6dd hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
26 fails, else passes. if hook raises exception, treated as
fff50306e6dd hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
27 hook failure. exception propagates if throw is "true".
fff50306e6dd hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
28
fff50306e6dd hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
29 reason for "true" meaning "hook failed" is so that
fff50306e6dd hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
30 unmodified commands (e.g. mercurial.commands.update) can
fff50306e6dd hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
31 be run as hooks without wrappers to convert return values.'''
fff50306e6dd hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
32
21797
b009dd135aa0 hook: restore use of callable() since it was readded in Python 3.2
Augie Fackler <raf@durin42.com>
parents: 20548
diff changeset
33 if callable(funcname):
20548
5bd6a9fec103 hooks: for python hooks, consistently use __name__ etc as name, not the repr
Mads Kiilerich <madski@unity3d.com>
parents: 20547
diff changeset
34 obj = funcname
32614
4b426ae96ff2 py3: ensure that we don't concat bytes and str and the end result is bytes
Pulkit Goyal <7895pulkit@gmail.com>
parents: 31747
diff changeset
35 funcname = pycompat.sysbytes(obj.__module__ + r"." + obj.__name__)
20548
5bd6a9fec103 hooks: for python hooks, consistently use __name__ etc as name, not the repr
Mads Kiilerich <madski@unity3d.com>
parents: 20547
diff changeset
36 else:
4622
fff50306e6dd hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
37 d = funcname.rfind('.')
fff50306e6dd hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
38 if d == -1:
26692
8d1cfd77b64f hook: raise a separate exception for when loading a hook fails
Siddharth Agarwal <sid0@fb.com>
parents: 26587
diff changeset
39 raise error.HookLoadError(
28106
cedbe8723d99 hook: even fewer parentheses for load errors
Siddharth Agarwal <sid0@fb.com>
parents: 28080
diff changeset
40 _('%s hook is invalid: "%s" not in a module')
26692
8d1cfd77b64f hook: raise a separate exception for when loading a hook fails
Siddharth Agarwal <sid0@fb.com>
parents: 26587
diff changeset
41 % (hname, funcname))
4622
fff50306e6dd hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
42 modname = funcname[:d]
10103
37679dbf2ee3 hook: fix bug (reuse of variable) introduced in 872d49dd577a
Sune Foldager <cryo@cyanite.org>
parents: 9851
diff changeset
43 oldpaths = sys.path
14941
4a28cb4df1f8 windows: check util.mainfrozen() instead of ad-hoc checks everywhere
Augie Fackler <durin42@gmail.com>
parents: 14916
diff changeset
44 if util.mainfrozen():
9332
872d49dd577a hook: fix full path imports on Windows (issue1779)
Steve Borho <steve@borho.org>
parents: 8366
diff changeset
45 # binary installs require sys.path manipulation
10103
37679dbf2ee3 hook: fix bug (reuse of variable) introduced in 872d49dd577a
Sune Foldager <cryo@cyanite.org>
parents: 9851
diff changeset
46 modpath, modfile = os.path.split(modname)
37679dbf2ee3 hook: fix bug (reuse of variable) introduced in 872d49dd577a
Sune Foldager <cryo@cyanite.org>
parents: 9851
diff changeset
47 if modpath and modfile:
37679dbf2ee3 hook: fix bug (reuse of variable) introduced in 872d49dd577a
Sune Foldager <cryo@cyanite.org>
parents: 9851
diff changeset
48 sys.path = sys.path[:] + [modpath]
37679dbf2ee3 hook: fix bug (reuse of variable) introduced in 872d49dd577a
Sune Foldager <cryo@cyanite.org>
parents: 9851
diff changeset
49 modname = modfile
25328
2cfb0bbf83a1 hooks: replace if-try-finally with a "with" statement
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 25184
diff changeset
50 with demandimport.deactivated():
4622
fff50306e6dd hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
51 try:
36108
c4146cf4dd20 py3: use system strings when calling __import__
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35357
diff changeset
52 obj = __import__(pycompat.sysstr(modname))
28109
b892e424f88c hook: don't crash on syntax errors in python hooks
Siddharth Agarwal <sid0@fb.com>
parents: 28108
diff changeset
53 except (ImportError, SyntaxError):
28078
2058e1a894f2 hook: use sys.exc_info rather than the deprecated equivalents
Siddharth Agarwal <sid0@fb.com>
parents: 27228
diff changeset
54 e1 = sys.exc_info()
25328
2cfb0bbf83a1 hooks: replace if-try-finally with a "with" statement
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 25184
diff changeset
55 try:
2cfb0bbf83a1 hooks: replace if-try-finally with a "with" statement
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 25184
diff changeset
56 # extensions are loaded with hgext_ prefix
36108
c4146cf4dd20 py3: use system strings when calling __import__
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35357
diff changeset
57 obj = __import__(r"hgext_%s" % pycompat.sysstr(modname))
28109
b892e424f88c hook: don't crash on syntax errors in python hooks
Siddharth Agarwal <sid0@fb.com>
parents: 28108
diff changeset
58 except (ImportError, SyntaxError):
28078
2058e1a894f2 hook: use sys.exc_info rather than the deprecated equivalents
Siddharth Agarwal <sid0@fb.com>
parents: 27228
diff changeset
59 e2 = sys.exc_info()
25328
2cfb0bbf83a1 hooks: replace if-try-finally with a "with" statement
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 25184
diff changeset
60 if ui.tracebackflag:
2cfb0bbf83a1 hooks: replace if-try-finally with a "with" statement
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 25184
diff changeset
61 ui.warn(_('exception from first failed import '
2cfb0bbf83a1 hooks: replace if-try-finally with a "with" statement
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 25184
diff changeset
62 'attempt:\n'))
2cfb0bbf83a1 hooks: replace if-try-finally with a "with" statement
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 25184
diff changeset
63 ui.traceback(e1)
2cfb0bbf83a1 hooks: replace if-try-finally with a "with" statement
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 25184
diff changeset
64 if ui.tracebackflag:
2cfb0bbf83a1 hooks: replace if-try-finally with a "with" statement
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 25184
diff changeset
65 ui.warn(_('exception from second failed import '
2cfb0bbf83a1 hooks: replace if-try-finally with a "with" statement
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 25184
diff changeset
66 'attempt:\n'))
2cfb0bbf83a1 hooks: replace if-try-finally with a "with" statement
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 25184
diff changeset
67 ui.traceback(e2)
28080
37b818cad146 hook: for python hook ImportErrors, add note to run with --traceback
Siddharth Agarwal <sid0@fb.com>
parents: 28079
diff changeset
68
37b818cad146 hook: for python hook ImportErrors, add note to run with --traceback
Siddharth Agarwal <sid0@fb.com>
parents: 28079
diff changeset
69 if not ui.tracebackflag:
37b818cad146 hook: for python hook ImportErrors, add note to run with --traceback
Siddharth Agarwal <sid0@fb.com>
parents: 28079
diff changeset
70 tracebackhint = _(
37b818cad146 hook: for python hook ImportErrors, add note to run with --traceback
Siddharth Agarwal <sid0@fb.com>
parents: 28079
diff changeset
71 'run with --traceback for stack trace')
37b818cad146 hook: for python hook ImportErrors, add note to run with --traceback
Siddharth Agarwal <sid0@fb.com>
parents: 28079
diff changeset
72 else:
37b818cad146 hook: for python hook ImportErrors, add note to run with --traceback
Siddharth Agarwal <sid0@fb.com>
parents: 28079
diff changeset
73 tracebackhint = None
26692
8d1cfd77b64f hook: raise a separate exception for when loading a hook fails
Siddharth Agarwal <sid0@fb.com>
parents: 26587
diff changeset
74 raise error.HookLoadError(
28079
0c9e914029be hook: fewer parentheses for hook load errors
Siddharth Agarwal <sid0@fb.com>
parents: 28078
diff changeset
75 _('%s hook is invalid: import of "%s" failed') %
28080
37b818cad146 hook: for python hook ImportErrors, add note to run with --traceback
Siddharth Agarwal <sid0@fb.com>
parents: 28079
diff changeset
76 (hname, modname), hint=tracebackhint)
9332
872d49dd577a hook: fix full path imports on Windows (issue1779)
Steve Borho <steve@borho.org>
parents: 8366
diff changeset
77 sys.path = oldpaths
4622
fff50306e6dd hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
78 try:
fff50306e6dd hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
79 for p in funcname.split('.')[1:]:
fff50306e6dd hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
80 obj = getattr(obj, p)
7280
810ca383da9c remove unused variables
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6762
diff changeset
81 except AttributeError:
26692
8d1cfd77b64f hook: raise a separate exception for when loading a hook fails
Siddharth Agarwal <sid0@fb.com>
parents: 26587
diff changeset
82 raise error.HookLoadError(
28079
0c9e914029be hook: fewer parentheses for hook load errors
Siddharth Agarwal <sid0@fb.com>
parents: 28078
diff changeset
83 _('%s hook is invalid: "%s" is not defined')
26692
8d1cfd77b64f hook: raise a separate exception for when loading a hook fails
Siddharth Agarwal <sid0@fb.com>
parents: 26587
diff changeset
84 % (hname, funcname))
21797
b009dd135aa0 hook: restore use of callable() since it was readded in Python 3.2
Augie Fackler <raf@durin42.com>
parents: 20548
diff changeset
85 if not callable(obj):
26692
8d1cfd77b64f hook: raise a separate exception for when loading a hook fails
Siddharth Agarwal <sid0@fb.com>
parents: 26587
diff changeset
86 raise error.HookLoadError(
28079
0c9e914029be hook: fewer parentheses for hook load errors
Siddharth Agarwal <sid0@fb.com>
parents: 28078
diff changeset
87 _('%s hook is invalid: "%s" is not callable')
26692
8d1cfd77b64f hook: raise a separate exception for when loading a hook fails
Siddharth Agarwal <sid0@fb.com>
parents: 26587
diff changeset
88 % (hname, funcname))
20547
9d9f8ccffead hooks: move logging of hook name to after we have found the hook
Mads Kiilerich <madski@unity3d.com>
parents: 20422
diff changeset
89
9d9f8ccffead hooks: move logging of hook name to after we have found the hook
Mads Kiilerich <madski@unity3d.com>
parents: 20422
diff changeset
90 ui.note(_("calling hook %s: %s\n") % (hname, funcname))
30975
22fbca1d11ed mercurial: switch to util.timer for all interval timings
Simon Farnsworth <simonfar@fb.com>
parents: 30519
diff changeset
91 starttime = util.timer()
20547
9d9f8ccffead hooks: move logging of hook name to after we have found the hook
Mads Kiilerich <madski@unity3d.com>
parents: 20422
diff changeset
92
4622
fff50306e6dd hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
93 try:
35357
056a9c8813aa py3: handle keyword arguments correctly in hook.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34687
diff changeset
94 r = obj(ui=ui, repo=repo, hooktype=htype, **pycompat.strkwargs(args))
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25328
diff changeset
95 except Exception as exc:
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25953
diff changeset
96 if isinstance(exc, error.Abort):
25084
7046c7e7fcb4 hooks: use try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 24716
diff changeset
97 ui.warn(_('error: %s hook failed: %s\n') %
7046c7e7fcb4 hooks: use try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 24716
diff changeset
98 (hname, exc.args[0]))
7046c7e7fcb4 hooks: use try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 24716
diff changeset
99 else:
7046c7e7fcb4 hooks: use try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 24716
diff changeset
100 ui.warn(_('error: %s hook raised an exception: '
32642
c032e137e494 py3: convert exception to bytes to pass into ui.warn()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32614
diff changeset
101 '%s\n') % (hname, encoding.strtolocal(str(exc))))
25084
7046c7e7fcb4 hooks: use try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 24716
diff changeset
102 if throw:
4622
fff50306e6dd hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
103 raise
28108
2a71d9483199 hook: for python hook exceptions, add note to run with --traceback
Siddharth Agarwal <sid0@fb.com>
parents: 28106
diff changeset
104 if not ui.tracebackflag:
2a71d9483199 hook: for python hook exceptions, add note to run with --traceback
Siddharth Agarwal <sid0@fb.com>
parents: 28106
diff changeset
105 ui.warn(_('(run with --traceback for stack trace)\n'))
25084
7046c7e7fcb4 hooks: use try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 24716
diff changeset
106 ui.traceback()
26739
8429369eeb85 hook: for python hooks, also return whether an exception was raised
Siddharth Agarwal <sid0@fb.com>
parents: 26738
diff changeset
107 return True, True
14889
a59058fd074a hooks: redirect stdout/err/in to the ui descriptors when calling python hooks
Idan Kamara <idankk86@gmail.com>
parents: 14711
diff changeset
108 finally:
30975
22fbca1d11ed mercurial: switch to util.timer for all interval timings
Simon Farnsworth <simonfar@fb.com>
parents: 30519
diff changeset
109 duration = util.timer() - starttime
18691
4f485bd68f1d blackbox: do not translate the log messages
Durham Goode <durham@fb.com>
parents: 18671
diff changeset
110 ui.log('pythonhook', 'pythonhook-%s: %s finished in %0.2f seconds\n',
31742
f243b7fbeba5 hook: use "htype" as variable name in _pythonhook
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31205
diff changeset
111 htype, funcname, duration)
4622
fff50306e6dd hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
112 if r:
fff50306e6dd hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
113 if throw:
23415
cdbb85489c41 hook: raise a more specialized HookAbort exception when a hook fails
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21797
diff changeset
114 raise error.HookAbort(_('%s hook failed') % hname)
4622
fff50306e6dd hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
115 ui.warn(_('warning: %s hook failed\n') % hname)
26739
8429369eeb85 hook: for python hooks, also return whether an exception was raised
Siddharth Agarwal <sid0@fb.com>
parents: 26738
diff changeset
116 return r, False
4622
fff50306e6dd hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
117
31746
0fa30fbccc34 hook: provide hook type information to external hook
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31745
diff changeset
118 def _exthook(ui, repo, htype, name, cmd, args, throw):
4622
fff50306e6dd hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
119 ui.note(_("running hook %s: %s\n") % (name, cmd))
7787
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7644
diff changeset
120
30975
22fbca1d11ed mercurial: switch to util.timer for all interval timings
Simon Farnsworth <simonfar@fb.com>
parents: 30519
diff changeset
121 starttime = util.timer()
7787
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7644
diff changeset
122 env = {}
26751
520defbc0335 hook: centralize passing HG_PENDING to external hook process
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 26739
diff changeset
123
520defbc0335 hook: centralize passing HG_PENDING to external hook process
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 26739
diff changeset
124 # make in-memory changes visible to external process
27228
10695f8f3323 dirstate: don't write repo.currenttransaction to repo.dirstate if repo
Sietse Brouwer <sbbrouwer@gmail.com>
parents: 26861
diff changeset
125 if repo is not None:
10695f8f3323 dirstate: don't write repo.currenttransaction to repo.dirstate if repo
Sietse Brouwer <sbbrouwer@gmail.com>
parents: 26861
diff changeset
126 tr = repo.currenttransaction()
10695f8f3323 dirstate: don't write repo.currenttransaction to repo.dirstate if repo
Sietse Brouwer <sbbrouwer@gmail.com>
parents: 26861
diff changeset
127 repo.dirstate.write(tr)
10695f8f3323 dirstate: don't write repo.currenttransaction to repo.dirstate if repo
Sietse Brouwer <sbbrouwer@gmail.com>
parents: 26861
diff changeset
128 if tr and tr.writepending():
10695f8f3323 dirstate: don't write repo.currenttransaction to repo.dirstate if repo
Sietse Brouwer <sbbrouwer@gmail.com>
parents: 26861
diff changeset
129 env['HG_PENDING'] = repo.root
31746
0fa30fbccc34 hook: provide hook type information to external hook
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31745
diff changeset
130 env['HG_HOOKTYPE'] = htype
31747
aff7b32b3c05 hook: add hook name information to external hook
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31746
diff changeset
131 env['HG_HOOKNAME'] = name
26751
520defbc0335 hook: centralize passing HG_PENDING to external hook process
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 26739
diff changeset
132
7787
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7644
diff changeset
133 for k, v in args.iteritems():
21797
b009dd135aa0 hook: restore use of callable() since it was readded in Python 3.2
Augie Fackler <raf@durin42.com>
parents: 20548
diff changeset
134 if callable(v):
7787
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7644
diff changeset
135 v = v()
13207
1775382ff833 hooks: sort any dictionaries set in the environment
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 13119
diff changeset
136 if isinstance(v, dict):
1775382ff833 hooks: sort any dictionaries set in the environment
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 13119
diff changeset
137 # make the dictionary element order stable across Python
1775382ff833 hooks: sort any dictionaries set in the environment
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 13119
diff changeset
138 # implementations
1775382ff833 hooks: sort any dictionaries set in the environment
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 13119
diff changeset
139 v = ('{' +
1775382ff833 hooks: sort any dictionaries set in the environment
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 13119
diff changeset
140 ', '.join('%r: %r' % i for i in sorted(v.iteritems())) +
1775382ff833 hooks: sort any dictionaries set in the environment
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 13119
diff changeset
141 '}')
7787
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7644
diff changeset
142 env['HG_' + k.upper()] = v
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7644
diff changeset
143
5869
2c565b9598b8 hooks: fix pre- and post- hooks specified in .hg/hgrc
Matt Mackall <mpm@selenic.com>
parents: 5833
diff changeset
144 if repo:
2c565b9598b8 hooks: fix pre- and post- hooks specified in .hg/hgrc
Matt Mackall <mpm@selenic.com>
parents: 5833
diff changeset
145 cwd = repo.root
2c565b9598b8 hooks: fix pre- and post- hooks specified in .hg/hgrc
Matt Mackall <mpm@selenic.com>
parents: 5833
diff changeset
146 else:
30519
20a42325fdef py3: use pycompat.getcwd() instead of os.getcwd()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30473
diff changeset
147 cwd = pycompat.getcwd()
31205
a48c6ac5c13a hook: give exthooks tags for blocking time
Simon Farnsworth <simonfar@fb.com>
parents: 30975
diff changeset
148 r = ui.system(cmd, environ=env, cwd=cwd, blockedtag='exthook-%s' % (name,))
18671
1c305128e5b9 blackbox: logs python and extension hooks via ui.log()
Durham Goode <durham@fb.com>
parents: 18111
diff changeset
149
30975
22fbca1d11ed mercurial: switch to util.timer for all interval timings
Simon Farnsworth <simonfar@fb.com>
parents: 30519
diff changeset
150 duration = util.timer() - starttime
18691
4f485bd68f1d blackbox: do not translate the log messages
Durham Goode <durham@fb.com>
parents: 18671
diff changeset
151 ui.log('exthook', 'exthook-%s: %s finished in %0.2f seconds\n',
18671
1c305128e5b9 blackbox: logs python and extension hooks via ui.log()
Durham Goode <durham@fb.com>
parents: 18111
diff changeset
152 name, cmd, duration)
4622
fff50306e6dd hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
153 if r:
14234
600e64004eb5 rename explain_exit to explainexit
Adrian Buehlmann <adrian@cadifra.com>
parents: 13207
diff changeset
154 desc, r = util.explainexit(r)
4622
fff50306e6dd hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
155 if throw:
23415
cdbb85489c41 hook: raise a more specialized HookAbort exception when a hook fails
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21797
diff changeset
156 raise error.HookAbort(_('%s hook %s') % (name, desc))
4622
fff50306e6dd hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
157 ui.warn(_('warning: %s hook %s\n') % (name, desc))
fff50306e6dd hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
158 return r
fff50306e6dd hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
159
28938
ea1fec3e9aba hook: report untrusted hooks as failure (issue5110) (BC)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 28937
diff changeset
160 # represent an untrusted hook command
ea1fec3e9aba hook: report untrusted hooks as failure (issue5110) (BC)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 28937
diff changeset
161 _fromuntrusted = object()
ea1fec3e9aba hook: report untrusted hooks as failure (issue5110) (BC)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 28937
diff changeset
162
15896
30c34fde40cc hooks: prioritize run order of hooks
Matt Zuba <matt.zuba@goodwillaz.org>
parents: 15512
diff changeset
163 def _allhooks(ui):
28937
3112c5e18835 hook: split config reading further
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 28936
diff changeset
164 """return a list of (hook-id, cmd) pairs sorted by priority"""
3112c5e18835 hook: split config reading further
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 28936
diff changeset
165 hooks = _hookitems(ui)
28938
ea1fec3e9aba hook: report untrusted hooks as failure (issue5110) (BC)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 28937
diff changeset
166 # Be careful in this section, propagating the real commands from untrusted
ea1fec3e9aba hook: report untrusted hooks as failure (issue5110) (BC)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 28937
diff changeset
167 # sources would create a security vulnerability, make sure anything altered
ea1fec3e9aba hook: report untrusted hooks as failure (issue5110) (BC)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 28937
diff changeset
168 # in that section uses "_fromuntrusted" as its command.
ea1fec3e9aba hook: report untrusted hooks as failure (issue5110) (BC)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 28937
diff changeset
169 untrustedhooks = _hookitems(ui, _untrusted=True)
ea1fec3e9aba hook: report untrusted hooks as failure (issue5110) (BC)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 28937
diff changeset
170 for name, value in untrustedhooks.items():
ea1fec3e9aba hook: report untrusted hooks as failure (issue5110) (BC)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 28937
diff changeset
171 trustedvalue = hooks.get(name, (None, None, name, _fromuntrusted))
ea1fec3e9aba hook: report untrusted hooks as failure (issue5110) (BC)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 28937
diff changeset
172 if value != trustedvalue:
ea1fec3e9aba hook: report untrusted hooks as failure (issue5110) (BC)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 28937
diff changeset
173 (lp, lo, lk, lv) = trustedvalue
ea1fec3e9aba hook: report untrusted hooks as failure (issue5110) (BC)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 28937
diff changeset
174 hooks[name] = (lp, lo, lk, _fromuntrusted)
ea1fec3e9aba hook: report untrusted hooks as failure (issue5110) (BC)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 28937
diff changeset
175 # (end of the security sensitive section)
28937
3112c5e18835 hook: split config reading further
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 28936
diff changeset
176 return [(k, v) for p, o, k, v in sorted(hooks.values())]
3112c5e18835 hook: split config reading further
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 28936
diff changeset
177
28938
ea1fec3e9aba hook: report untrusted hooks as failure (issue5110) (BC)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 28937
diff changeset
178 def _hookitems(ui, _untrusted=False):
28937
3112c5e18835 hook: split config reading further
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 28936
diff changeset
179 """return all hooks items ready to be sorted"""
28936
44bd37af54e5 hook: small refactor to store hooks as dict instead of list
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 28109
diff changeset
180 hooks = {}
28938
ea1fec3e9aba hook: report untrusted hooks as failure (issue5110) (BC)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 28937
diff changeset
181 for name, cmd in ui.configitems('hooks', untrusted=_untrusted):
15896
30c34fde40cc hooks: prioritize run order of hooks
Matt Zuba <matt.zuba@goodwillaz.org>
parents: 15512
diff changeset
182 if not name.startswith('priority'):
30c34fde40cc hooks: prioritize run order of hooks
Matt Zuba <matt.zuba@goodwillaz.org>
parents: 15512
diff changeset
183 priority = ui.configint('hooks', 'priority.%s' % name, 0)
28936
44bd37af54e5 hook: small refactor to store hooks as dict instead of list
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 28109
diff changeset
184 hooks[name] = (-priority, len(hooks), name, cmd)
28937
3112c5e18835 hook: split config reading further
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 28936
diff changeset
185 return hooks
15896
30c34fde40cc hooks: prioritize run order of hooks
Matt Zuba <matt.zuba@goodwillaz.org>
parents: 15512
diff changeset
186
5833
323b9c55b328 hook: redirect stdout to stderr for ssh and http servers
Matt Mackall <mpm@selenic.com>
parents: 4622
diff changeset
187 _redirect = False
323b9c55b328 hook: redirect stdout to stderr for ssh and http servers
Matt Mackall <mpm@selenic.com>
parents: 4622
diff changeset
188 def redirect(state):
6266
9f76df0edb7d hook.py: fix redirections introduced by 323b9c55b328
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5869
diff changeset
189 global _redirect
5833
323b9c55b328 hook: redirect stdout to stderr for ssh and http servers
Matt Mackall <mpm@selenic.com>
parents: 4622
diff changeset
190 _redirect = state
323b9c55b328 hook: redirect stdout to stderr for ssh and http servers
Matt Mackall <mpm@selenic.com>
parents: 4622
diff changeset
191
34687
e79b6300d97c hook: add a 'hashook' function to test for hook existence
Boris Feld <boris.feld@octobus.net>
parents: 32897
diff changeset
192 def hashook(ui, htype):
e79b6300d97c hook: add a 'hashook' function to test for hook existence
Boris Feld <boris.feld@octobus.net>
parents: 32897
diff changeset
193 """return True if a hook is configured for 'htype'"""
e79b6300d97c hook: add a 'hashook' function to test for hook existence
Boris Feld <boris.feld@octobus.net>
parents: 32897
diff changeset
194 if not ui.callhooks:
e79b6300d97c hook: add a 'hashook' function to test for hook existence
Boris Feld <boris.feld@octobus.net>
parents: 32897
diff changeset
195 return False
e79b6300d97c hook: add a 'hashook' function to test for hook existence
Boris Feld <boris.feld@octobus.net>
parents: 32897
diff changeset
196 for hname, cmd in _allhooks(ui):
e79b6300d97c hook: add a 'hashook' function to test for hook existence
Boris Feld <boris.feld@octobus.net>
parents: 32897
diff changeset
197 if hname.split('.')[0] == htype and cmd:
e79b6300d97c hook: add a 'hashook' function to test for hook existence
Boris Feld <boris.feld@octobus.net>
parents: 32897
diff changeset
198 return True
e79b6300d97c hook: add a 'hashook' function to test for hook existence
Boris Feld <boris.feld@octobus.net>
parents: 32897
diff changeset
199 return False
e79b6300d97c hook: add a 'hashook' function to test for hook existence
Boris Feld <boris.feld@octobus.net>
parents: 32897
diff changeset
200
31745
33504b54863e hook: use 'htype' in 'hook'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31744
diff changeset
201 def hook(ui, repo, htype, throw=False, **args):
17048
15d4d475de9e ui: add a variable to control whether hooks should be called
Idan Kamara <idankk86@gmail.com>
parents: 15896
diff changeset
202 if not ui.callhooks:
15d4d475de9e ui: add a variable to control whether hooks should be called
Idan Kamara <idankk86@gmail.com>
parents: 15896
diff changeset
203 return False
15d4d475de9e ui: add a variable to control whether hooks should be called
Idan Kamara <idankk86@gmail.com>
parents: 15896
diff changeset
204
26737
a930d66a04af hook: factor out determination of hooks from running them
Siddharth Agarwal <sid0@fb.com>
parents: 26692
diff changeset
205 hooks = []
a930d66a04af hook: factor out determination of hooks from running them
Siddharth Agarwal <sid0@fb.com>
parents: 26692
diff changeset
206 for hname, cmd in _allhooks(ui):
31745
33504b54863e hook: use 'htype' in 'hook'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31744
diff changeset
207 if hname.split('.')[0] == htype and cmd:
26737
a930d66a04af hook: factor out determination of hooks from running them
Siddharth Agarwal <sid0@fb.com>
parents: 26692
diff changeset
208 hooks.append((hname, cmd))
a930d66a04af hook: factor out determination of hooks from running them
Siddharth Agarwal <sid0@fb.com>
parents: 26692
diff changeset
209
31745
33504b54863e hook: use 'htype' in 'hook'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31744
diff changeset
210 res = runhooks(ui, repo, htype, hooks, throw=throw, **args)
26738
9abc2c921bbd hook.runhooks: return a dict of result values
Siddharth Agarwal <sid0@fb.com>
parents: 26737
diff changeset
211 r = False
9abc2c921bbd hook.runhooks: return a dict of result values
Siddharth Agarwal <sid0@fb.com>
parents: 26737
diff changeset
212 for hname, cmd in hooks:
26739
8429369eeb85 hook: for python hooks, also return whether an exception was raised
Siddharth Agarwal <sid0@fb.com>
parents: 26738
diff changeset
213 r = res[hname][0] or r
26738
9abc2c921bbd hook.runhooks: return a dict of result values
Siddharth Agarwal <sid0@fb.com>
parents: 26737
diff changeset
214 return r
26737
a930d66a04af hook: factor out determination of hooks from running them
Siddharth Agarwal <sid0@fb.com>
parents: 26692
diff changeset
215
31744
5678496659e9 hook: use 'htype' in 'runhooks'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31743
diff changeset
216 def runhooks(ui, repo, htype, hooks, throw=False, **args):
32897
799db2af824c py3: convert keys of kwargs back to bytes using pycompat.byteskwargs()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32642
diff changeset
217 args = pycompat.byteskwargs(args)
26738
9abc2c921bbd hook.runhooks: return a dict of result values
Siddharth Agarwal <sid0@fb.com>
parents: 26737
diff changeset
218 res = {}
9658
852b1f3032d2 hook: only redirect stdout if it and stderr are valid files
Sune Foldager <cryo@cyanite.org>
parents: 9332
diff changeset
219 oldstdout = -1
5833
323b9c55b328 hook: redirect stdout to stderr for ssh and http servers
Matt Mackall <mpm@selenic.com>
parents: 4622
diff changeset
220
7416
196b05a548d0 hooks: restore io correctly on exception
Jesse Long <jesse@virtualpostman.co.za>
parents: 7280
diff changeset
221 try:
26737
a930d66a04af hook: factor out determination of hooks from running them
Siddharth Agarwal <sid0@fb.com>
parents: 26692
diff changeset
222 for hname, cmd in hooks:
17963
6180dcb29ec5 hooks: delay I/O redirection until we actually run a hook (issue3711)
Matt Mackall <mpm@selenic.com>
parents: 17428
diff changeset
223 if oldstdout == -1 and _redirect:
6180dcb29ec5 hooks: delay I/O redirection until we actually run a hook (issue3711)
Matt Mackall <mpm@selenic.com>
parents: 17428
diff changeset
224 try:
30473
39d13b8c101d py3: bulk replace sys.stdin/out/err by util's
Yuya Nishihara <yuya@tcha.org>
parents: 30365
diff changeset
225 stdoutno = util.stdout.fileno()
39d13b8c101d py3: bulk replace sys.stdin/out/err by util's
Yuya Nishihara <yuya@tcha.org>
parents: 30365
diff changeset
226 stderrno = util.stderr.fileno()
17963
6180dcb29ec5 hooks: delay I/O redirection until we actually run a hook (issue3711)
Matt Mackall <mpm@selenic.com>
parents: 17428
diff changeset
227 # temporarily redirect stdout to stderr, if possible
6180dcb29ec5 hooks: delay I/O redirection until we actually run a hook (issue3711)
Matt Mackall <mpm@selenic.com>
parents: 17428
diff changeset
228 if stdoutno >= 0 and stderrno >= 0:
30473
39d13b8c101d py3: bulk replace sys.stdin/out/err by util's
Yuya Nishihara <yuya@tcha.org>
parents: 30365
diff changeset
229 util.stdout.flush()
17963
6180dcb29ec5 hooks: delay I/O redirection until we actually run a hook (issue3711)
Matt Mackall <mpm@selenic.com>
parents: 17428
diff changeset
230 oldstdout = os.dup(stdoutno)
6180dcb29ec5 hooks: delay I/O redirection until we actually run a hook (issue3711)
Matt Mackall <mpm@selenic.com>
parents: 17428
diff changeset
231 os.dup2(stderrno, stdoutno)
17964
2c63896783e3 hooks: be even more forgiven of non-fd descriptors (issue3711)
Matt Mackall <mpm@selenic.com>
parents: 17963
diff changeset
232 except (OSError, AttributeError):
2c63896783e3 hooks: be even more forgiven of non-fd descriptors (issue3711)
Matt Mackall <mpm@selenic.com>
parents: 17963
diff changeset
233 # files seem to be bogus, give up on redirecting (WSGI, etc)
17963
6180dcb29ec5 hooks: delay I/O redirection until we actually run a hook (issue3711)
Matt Mackall <mpm@selenic.com>
parents: 17428
diff changeset
234 pass
6180dcb29ec5 hooks: delay I/O redirection until we actually run a hook (issue3711)
Matt Mackall <mpm@selenic.com>
parents: 17428
diff changeset
235
28938
ea1fec3e9aba hook: report untrusted hooks as failure (issue5110) (BC)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 28937
diff changeset
236 if cmd is _fromuntrusted:
ea1fec3e9aba hook: report untrusted hooks as failure (issue5110) (BC)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 28937
diff changeset
237 if throw:
ea1fec3e9aba hook: report untrusted hooks as failure (issue5110) (BC)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 28937
diff changeset
238 raise error.HookAbort(
31743
f610c3220eec hook: fix name used in untrusted message
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31742
diff changeset
239 _('untrusted hook %s not executed') % hname,
28938
ea1fec3e9aba hook: report untrusted hooks as failure (issue5110) (BC)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 28937
diff changeset
240 hint = _("see 'hg help config.trusted'"))
31743
f610c3220eec hook: fix name used in untrusted message
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31742
diff changeset
241 ui.warn(_('warning: untrusted hook %s not executed\n') % hname)
28938
ea1fec3e9aba hook: report untrusted hooks as failure (issue5110) (BC)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 28937
diff changeset
242 r = 1
ea1fec3e9aba hook: report untrusted hooks as failure (issue5110) (BC)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 28937
diff changeset
243 raised = False
ea1fec3e9aba hook: report untrusted hooks as failure (issue5110) (BC)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 28937
diff changeset
244 elif callable(cmd):
31744
5678496659e9 hook: use 'htype' in 'runhooks'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31743
diff changeset
245 r, raised = _pythonhook(ui, repo, htype, hname, cmd, args,
5678496659e9 hook: use 'htype' in 'runhooks'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31743
diff changeset
246 throw)
7416
196b05a548d0 hooks: restore io correctly on exception
Jesse Long <jesse@virtualpostman.co.za>
parents: 7280
diff changeset
247 elif cmd.startswith('python:'):
9332
872d49dd577a hook: fix full path imports on Windows (issue1779)
Steve Borho <steve@borho.org>
parents: 8366
diff changeset
248 if cmd.count(':') >= 2:
872d49dd577a hook: fix full path imports on Windows (issue1779)
Steve Borho <steve@borho.org>
parents: 8366
diff changeset
249 path, cmd = cmd[7:].rsplit(':', 1)
13118
789e0fa2fcea hook: assume relative path to hook is given from repo root
Alexander Solovyov <alexander@solovyov.net>
parents: 11469
diff changeset
250 path = util.expandpath(path)
13119
ecf7d6e0eef0 hook: fix import path handling for repo=None
Matt Mackall <mpm@selenic.com>
parents: 13118
diff changeset
251 if repo:
ecf7d6e0eef0 hook: fix import path handling for repo=None
Matt Mackall <mpm@selenic.com>
parents: 13118
diff changeset
252 path = os.path.join(repo.root, path)
17217
1b2b727a885f hooks: print out more information when loading a python hook fails
Simon Heimberg <simohe@besonet.ch>
parents: 17048
diff changeset
253 try:
1b2b727a885f hooks: print out more information when loading a python hook fails
Simon Heimberg <simohe@besonet.ch>
parents: 17048
diff changeset
254 mod = extensions.loadpath(path, 'hghook.%s' % hname)
1b2b727a885f hooks: print out more information when loading a python hook fails
Simon Heimberg <simohe@besonet.ch>
parents: 17048
diff changeset
255 except Exception:
1b2b727a885f hooks: print out more information when loading a python hook fails
Simon Heimberg <simohe@besonet.ch>
parents: 17048
diff changeset
256 ui.write(_("loading %s hook failed:\n") % hname)
1b2b727a885f hooks: print out more information when loading a python hook fails
Simon Heimberg <simohe@besonet.ch>
parents: 17048
diff changeset
257 raise
7916
f779e1996e23 ability to load hooks from arbitrary python module
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7787
diff changeset
258 hookfn = getattr(mod, cmd)
f779e1996e23 ability to load hooks from arbitrary python module
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7787
diff changeset
259 else:
f779e1996e23 ability to load hooks from arbitrary python module
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7787
diff changeset
260 hookfn = cmd[7:].strip()
31744
5678496659e9 hook: use 'htype' in 'runhooks'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31743
diff changeset
261 r, raised = _pythonhook(ui, repo, htype, hname, hookfn, args,
26739
8429369eeb85 hook: for python hooks, also return whether an exception was raised
Siddharth Agarwal <sid0@fb.com>
parents: 26738
diff changeset
262 throw)
7416
196b05a548d0 hooks: restore io correctly on exception
Jesse Long <jesse@virtualpostman.co.za>
parents: 7280
diff changeset
263 else:
31746
0fa30fbccc34 hook: provide hook type information to external hook
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31745
diff changeset
264 r = _exthook(ui, repo, htype, hname, cmd, args, throw)
26739
8429369eeb85 hook: for python hooks, also return whether an exception was raised
Siddharth Agarwal <sid0@fb.com>
parents: 26738
diff changeset
265 raised = False
26738
9abc2c921bbd hook.runhooks: return a dict of result values
Siddharth Agarwal <sid0@fb.com>
parents: 26737
diff changeset
266
26739
8429369eeb85 hook: for python hooks, also return whether an exception was raised
Siddharth Agarwal <sid0@fb.com>
parents: 26738
diff changeset
267 res[hname] = r, raised
24716
2abbf4750915 hook: forcibly flush stderr for Windows test stability
Matt Harbison <matt_harbison@yahoo.com>
parents: 23426
diff changeset
268
2abbf4750915 hook: forcibly flush stderr for Windows test stability
Matt Harbison <matt_harbison@yahoo.com>
parents: 23426
diff changeset
269 # The stderr is fully buffered on Windows when connected to a pipe.
2abbf4750915 hook: forcibly flush stderr for Windows test stability
Matt Harbison <matt_harbison@yahoo.com>
parents: 23426
diff changeset
270 # A forcible flush is required to make small stderr data in the
2abbf4750915 hook: forcibly flush stderr for Windows test stability
Matt Harbison <matt_harbison@yahoo.com>
parents: 23426
diff changeset
271 # remote side available to the client immediately.
30473
39d13b8c101d py3: bulk replace sys.stdin/out/err by util's
Yuya Nishihara <yuya@tcha.org>
parents: 30365
diff changeset
272 util.stderr.flush()
7416
196b05a548d0 hooks: restore io correctly on exception
Jesse Long <jesse@virtualpostman.co.za>
parents: 7280
diff changeset
273 finally:
9658
852b1f3032d2 hook: only redirect stdout if it and stderr are valid files
Sune Foldager <cryo@cyanite.org>
parents: 9332
diff changeset
274 if _redirect and oldstdout >= 0:
30473
39d13b8c101d py3: bulk replace sys.stdin/out/err by util's
Yuya Nishihara <yuya@tcha.org>
parents: 30365
diff changeset
275 util.stdout.flush() # write hook output to stderr fd
9658
852b1f3032d2 hook: only redirect stdout if it and stderr are valid files
Sune Foldager <cryo@cyanite.org>
parents: 9332
diff changeset
276 os.dup2(oldstdout, stdoutno)
7416
196b05a548d0 hooks: restore io correctly on exception
Jesse Long <jesse@virtualpostman.co.za>
parents: 7280
diff changeset
277 os.close(oldstdout)
6266
9f76df0edb7d hook.py: fix redirections introduced by 323b9c55b328
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5869
diff changeset
278
26738
9abc2c921bbd hook.runhooks: return a dict of result values
Siddharth Agarwal <sid0@fb.com>
parents: 26737
diff changeset
279 return res