Mercurial > public > mercurial-scm > hg-stable
annotate mercurial/hook.py @ 38488:e9e61fbac787
hooks: allow Unix style environment variables on external Windows hooks
This will help making common hooks between Windows and non-Windows platforms.
Having to build the shellenviron dict here and in procutil.system() is a bit
unfortunate, but the only other option is to fix up the command inside
procutil.system(). It seems more important that the note about the hook being
run reflects what is actually run.
The patch from last summer added the hooks on the command line, but it looks
like HG_ARGS has since learned about --config args, and the output was just
confusing. Therefore, it's now loaded from a file in the histedit test for
clarity.
author | Matt Harbison <matt_harbison@yahoo.com> |
---|---|
date | Sun, 02 Jul 2017 00:32:09 -0400 |
parents | 242eb5132203 |
children | 72286f9e324f |
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 | 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, |
32665
c032e137e494
py3: convert exception to bytes to pass into ui.warn()
Pulkit Goyal <7895pulkit@gmail.com>
parents:
32637
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, |
30528
20a42325fdef
py3: use pycompat.getcwd() instead of os.getcwd()
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30482
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 ) |
37122
d4a2e0d5d042
procutil: bulk-replace util.std* to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
36849
diff
changeset
|
22 from .utils import ( |
d4a2e0d5d042
procutil: bulk-replace util.std* to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
36849
diff
changeset
|
23 procutil, |
37751
483de34f23b1
hook: use stringutil.pprint instead of reinventing it
Augie Fackler <augie@google.com>
parents:
37463
diff
changeset
|
24 stringutil, |
37122
d4a2e0d5d042
procutil: bulk-replace util.std* to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
36849
diff
changeset
|
25 ) |
4622
fff50306e6dd
hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
26 |
38074
242eb5132203
filemerge: support specifying a python function to custom merge-tools
hindlemail <tom_hindle@sil.org>
parents:
37986
diff
changeset
|
27 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
|
28 '''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
|
29 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
|
30 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
|
31 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
|
32 |
fff50306e6dd
hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
33 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
|
34 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
|
35 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
|
36 |
21797
b009dd135aa0
hook: restore use of callable() since it was readded in Python 3.2
Augie Fackler <raf@durin42.com>
parents:
20548
diff
changeset
|
37 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
|
38 obj = funcname |
32637
4b426ae96ff2
py3: ensure that we don't concat bytes and str and the end result is bytes
Pulkit Goyal <7895pulkit@gmail.com>
parents:
31752
diff
changeset
|
39 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
|
40 else: |
4622
fff50306e6dd
hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
41 d = funcname.rfind('.') |
fff50306e6dd
hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
42 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
|
43 raise error.HookLoadError( |
28106
cedbe8723d99
hook: even fewer parentheses for load errors
Siddharth Agarwal <sid0@fb.com>
parents:
28080
diff
changeset
|
44 _('%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
|
45 % (hname, funcname)) |
4622
fff50306e6dd
hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
46 modname = funcname[:d] |
10103
37679dbf2ee3
hook: fix bug (reuse of variable) introduced in 872d49dd577a
Sune Foldager <cryo@cyanite.org>
parents:
9851
diff
changeset
|
47 oldpaths = sys.path |
37123
a8a902d7176e
procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
37122
diff
changeset
|
48 if procutil.mainfrozen(): |
9332
872d49dd577a
hook: fix full path imports on Windows (issue1779)
Steve Borho <steve@borho.org>
parents:
8366
diff
changeset
|
49 # 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
|
50 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
|
51 if modpath and modfile: |
37679dbf2ee3
hook: fix bug (reuse of variable) introduced in 872d49dd577a
Sune Foldager <cryo@cyanite.org>
parents:
9851
diff
changeset
|
52 sys.path = sys.path[:] + [modpath] |
37679dbf2ee3
hook: fix bug (reuse of variable) introduced in 872d49dd577a
Sune Foldager <cryo@cyanite.org>
parents:
9851
diff
changeset
|
53 modname = modfile |
25328
2cfb0bbf83a1
hooks: replace if-try-finally with a "with" statement
Jordi Guti?rrez Hermoso <jordigh@octave.org>
parents:
25184
diff
changeset
|
54 with demandimport.deactivated(): |
4622
fff50306e6dd
hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
55 try: |
36146
c4146cf4dd20
py3: use system strings when calling __import__
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35366
diff
changeset
|
56 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
|
57 except (ImportError, SyntaxError): |
28078
2058e1a894f2
hook: use sys.exc_info rather than the deprecated equivalents
Siddharth Agarwal <sid0@fb.com>
parents:
27228
diff
changeset
|
58 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
|
59 try: |
2cfb0bbf83a1
hooks: replace if-try-finally with a "with" statement
Jordi Guti?rrez Hermoso <jordigh@octave.org>
parents:
25184
diff
changeset
|
60 # extensions are loaded with hgext_ prefix |
36146
c4146cf4dd20
py3: use system strings when calling __import__
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35366
diff
changeset
|
61 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
|
62 except (ImportError, SyntaxError): |
28078
2058e1a894f2
hook: use sys.exc_info rather than the deprecated equivalents
Siddharth Agarwal <sid0@fb.com>
parents:
27228
diff
changeset
|
63 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
|
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 first 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(e1) |
2cfb0bbf83a1
hooks: replace if-try-finally with a "with" statement
Jordi Guti?rrez Hermoso <jordigh@octave.org>
parents:
25184
diff
changeset
|
68 if ui.tracebackflag: |
2cfb0bbf83a1
hooks: replace if-try-finally with a "with" statement
Jordi Guti?rrez Hermoso <jordigh@octave.org>
parents:
25184
diff
changeset
|
69 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
|
70 'attempt:\n')) |
2cfb0bbf83a1
hooks: replace if-try-finally with a "with" statement
Jordi Guti?rrez Hermoso <jordigh@octave.org>
parents:
25184
diff
changeset
|
71 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
|
72 |
37b818cad146
hook: for python hook ImportErrors, add note to run with --traceback
Siddharth Agarwal <sid0@fb.com>
parents:
28079
diff
changeset
|
73 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
|
74 tracebackhint = _( |
37b818cad146
hook: for python hook ImportErrors, add note to run with --traceback
Siddharth Agarwal <sid0@fb.com>
parents:
28079
diff
changeset
|
75 '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
|
76 else: |
37b818cad146
hook: for python hook ImportErrors, add note to run with --traceback
Siddharth Agarwal <sid0@fb.com>
parents:
28079
diff
changeset
|
77 tracebackhint = None |
26692
8d1cfd77b64f
hook: raise a separate exception for when loading a hook fails
Siddharth Agarwal <sid0@fb.com>
parents:
26587
diff
changeset
|
78 raise error.HookLoadError( |
28079
0c9e914029be
hook: fewer parentheses for hook load errors
Siddharth Agarwal <sid0@fb.com>
parents:
28078
diff
changeset
|
79 _('%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
|
80 (hname, modname), hint=tracebackhint) |
9332
872d49dd577a
hook: fix full path imports on Windows (issue1779)
Steve Borho <steve@borho.org>
parents:
8366
diff
changeset
|
81 sys.path = oldpaths |
4622
fff50306e6dd
hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
82 try: |
fff50306e6dd
hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
83 for p in funcname.split('.')[1:]: |
fff50306e6dd
hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
84 obj = getattr(obj, p) |
7280
810ca383da9c
remove unused variables
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
6762
diff
changeset
|
85 except AttributeError: |
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 defined') |
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)) |
21797
b009dd135aa0
hook: restore use of callable() since it was readded in Python 3.2
Augie Fackler <raf@durin42.com>
parents:
20548
diff
changeset
|
89 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
|
90 raise error.HookLoadError( |
28079
0c9e914029be
hook: fewer parentheses for hook load errors
Siddharth Agarwal <sid0@fb.com>
parents:
28078
diff
changeset
|
91 _('%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
|
92 % (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
|
93 |
9d9f8ccffead
hooks: move logging of hook name to after we have found the hook
Mads Kiilerich <madski@unity3d.com>
parents:
20422
diff
changeset
|
94 ui.note(_("calling hook %s: %s\n") % (hname, funcname)) |
30995
22fbca1d11ed
mercurial: switch to util.timer for all interval timings
Simon Farnsworth <simonfar@fb.com>
parents:
30528
diff
changeset
|
95 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
|
96 |
4622
fff50306e6dd
hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
97 try: |
35366
056a9c8813aa
py3: handle keyword arguments correctly in hook.py
Pulkit Goyal <7895pulkit@gmail.com>
parents:
34687
diff
changeset
|
98 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
|
99 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
|
100 if isinstance(exc, error.Abort): |
25084
7046c7e7fcb4
hooks: use try/except/finally
Matt Mackall <mpm@selenic.com>
parents:
24716
diff
changeset
|
101 ui.warn(_('error: %s hook failed: %s\n') % |
7046c7e7fcb4
hooks: use try/except/finally
Matt Mackall <mpm@selenic.com>
parents:
24716
diff
changeset
|
102 (hname, exc.args[0])) |
7046c7e7fcb4
hooks: use try/except/finally
Matt Mackall <mpm@selenic.com>
parents:
24716
diff
changeset
|
103 else: |
7046c7e7fcb4
hooks: use try/except/finally
Matt Mackall <mpm@selenic.com>
parents:
24716
diff
changeset
|
104 ui.warn(_('error: %s hook raised an exception: ' |
32665
c032e137e494
py3: convert exception to bytes to pass into ui.warn()
Pulkit Goyal <7895pulkit@gmail.com>
parents:
32637
diff
changeset
|
105 '%s\n') % (hname, encoding.strtolocal(str(exc)))) |
25084
7046c7e7fcb4
hooks: use try/except/finally
Matt Mackall <mpm@selenic.com>
parents:
24716
diff
changeset
|
106 if throw: |
4622
fff50306e6dd
hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
107 raise |
28108
2a71d9483199
hook: for python hook exceptions, add note to run with --traceback
Siddharth Agarwal <sid0@fb.com>
parents:
28106
diff
changeset
|
108 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
|
109 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
|
110 ui.traceback() |
26739
8429369eeb85
hook: for python hooks, also return whether an exception was raised
Siddharth Agarwal <sid0@fb.com>
parents:
26738
diff
changeset
|
111 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
|
112 finally: |
30995
22fbca1d11ed
mercurial: switch to util.timer for all interval timings
Simon Farnsworth <simonfar@fb.com>
parents:
30528
diff
changeset
|
113 duration = util.timer() - starttime |
18691
4f485bd68f1d
blackbox: do not translate the log messages
Durham Goode <durham@fb.com>
parents:
18671
diff
changeset
|
114 ui.log('pythonhook', 'pythonhook-%s: %s finished in %0.2f seconds\n', |
31747
f243b7fbeba5
hook: use "htype" as variable name in _pythonhook
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
31215
diff
changeset
|
115 htype, funcname, duration) |
4622
fff50306e6dd
hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
116 if r: |
fff50306e6dd
hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
117 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
|
118 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
|
119 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
|
120 return r, False |
4622
fff50306e6dd
hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
121 |
31751
0fa30fbccc34
hook: provide hook type information to external hook
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
31750
diff
changeset
|
122 def _exthook(ui, repo, htype, name, cmd, args, throw): |
30995
22fbca1d11ed
mercurial: switch to util.timer for all interval timings
Simon Farnsworth <simonfar@fb.com>
parents:
30528
diff
changeset
|
123 starttime = util.timer() |
7787
b8d750daadde
Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents:
7644
diff
changeset
|
124 env = {} |
26751
520defbc0335
hook: centralize passing HG_PENDING to external hook process
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
26739
diff
changeset
|
125 |
520defbc0335
hook: centralize passing HG_PENDING to external hook process
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
26739
diff
changeset
|
126 # 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
|
127 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
|
128 tr = repo.currenttransaction() |
10695f8f3323
dirstate: don't write repo.currenttransaction to repo.dirstate if repo
Sietse Brouwer <sbbrouwer@gmail.com>
parents:
26861
diff
changeset
|
129 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
|
130 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
|
131 env['HG_PENDING'] = repo.root |
31751
0fa30fbccc34
hook: provide hook type information to external hook
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
31750
diff
changeset
|
132 env['HG_HOOKTYPE'] = htype |
31752
aff7b32b3c05
hook: add hook name information to external hook
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
31751
diff
changeset
|
133 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
|
134 |
7787
b8d750daadde
Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents:
7644
diff
changeset
|
135 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
|
136 if callable(v): |
7787
b8d750daadde
Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents:
7644
diff
changeset
|
137 v = v() |
37752
63b7415e37a5
hook: also use pprint on lists for stable output on py2/3
Augie Fackler <augie@google.com>
parents:
37751
diff
changeset
|
138 if isinstance(v, (dict, list)): |
37986
32bc3815efae
stringutil: flip the default of pprint() to bprefix=False
Yuya Nishihara <yuya@tcha.org>
parents:
37752
diff
changeset
|
139 v = stringutil.pprint(v) |
7787
b8d750daadde
Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents:
7644
diff
changeset
|
140 env['HG_' + k.upper()] = v |
b8d750daadde
Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents:
7644
diff
changeset
|
141 |
38488
e9e61fbac787
hooks: allow Unix style environment variables on external Windows hooks
Matt Harbison <matt_harbison@yahoo.com>
parents:
38074
diff
changeset
|
142 if pycompat.iswindows: |
e9e61fbac787
hooks: allow Unix style environment variables on external Windows hooks
Matt Harbison <matt_harbison@yahoo.com>
parents:
38074
diff
changeset
|
143 environ = procutil.shellenviron(env) |
e9e61fbac787
hooks: allow Unix style environment variables on external Windows hooks
Matt Harbison <matt_harbison@yahoo.com>
parents:
38074
diff
changeset
|
144 cmd = util.platform.shelltocmdexe(cmd, environ) |
e9e61fbac787
hooks: allow Unix style environment variables on external Windows hooks
Matt Harbison <matt_harbison@yahoo.com>
parents:
38074
diff
changeset
|
145 |
e9e61fbac787
hooks: allow Unix style environment variables on external Windows hooks
Matt Harbison <matt_harbison@yahoo.com>
parents:
38074
diff
changeset
|
146 ui.note(_("running hook %s: %s\n") % (name, cmd)) |
e9e61fbac787
hooks: allow Unix style environment variables on external Windows hooks
Matt Harbison <matt_harbison@yahoo.com>
parents:
38074
diff
changeset
|
147 |
5869
2c565b9598b8
hooks: fix pre- and post- hooks specified in .hg/hgrc
Matt Mackall <mpm@selenic.com>
parents:
5833
diff
changeset
|
148 if repo: |
2c565b9598b8
hooks: fix pre- and post- hooks specified in .hg/hgrc
Matt Mackall <mpm@selenic.com>
parents:
5833
diff
changeset
|
149 cwd = repo.root |
2c565b9598b8
hooks: fix pre- and post- hooks specified in .hg/hgrc
Matt Mackall <mpm@selenic.com>
parents:
5833
diff
changeset
|
150 else: |
30528
20a42325fdef
py3: use pycompat.getcwd() instead of os.getcwd()
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30482
diff
changeset
|
151 cwd = pycompat.getcwd() |
31215
a48c6ac5c13a
hook: give exthooks tags for blocking time
Simon Farnsworth <simonfar@fb.com>
parents:
30995
diff
changeset
|
152 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
|
153 |
30995
22fbca1d11ed
mercurial: switch to util.timer for all interval timings
Simon Farnsworth <simonfar@fb.com>
parents:
30528
diff
changeset
|
154 duration = util.timer() - starttime |
18691
4f485bd68f1d
blackbox: do not translate the log messages
Durham Goode <durham@fb.com>
parents:
18671
diff
changeset
|
155 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
|
156 name, cmd, duration) |
4622
fff50306e6dd
hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
157 if r: |
37463
bbd240f81ac5
procutil: make explainexit() simply return a message (API)
Yuya Nishihara <yuya@tcha.org>
parents:
37123
diff
changeset
|
158 desc = procutil.explainexit(r) |
4622
fff50306e6dd
hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
159 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
|
160 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
|
161 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
|
162 return r |
fff50306e6dd
hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
163 |
28938
ea1fec3e9aba
hook: report untrusted hooks as failure (issue5110) (BC)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
28937
diff
changeset
|
164 # 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
|
165 _fromuntrusted = object() |
ea1fec3e9aba
hook: report untrusted hooks as failure (issue5110) (BC)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
28937
diff
changeset
|
166 |
15896
30c34fde40cc
hooks: prioritize run order of hooks
Matt Zuba <matt.zuba@goodwillaz.org>
parents:
15512
diff
changeset
|
167 def _allhooks(ui): |
28937
3112c5e18835
hook: split config reading further
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
28936
diff
changeset
|
168 """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
|
169 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
|
170 # 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
|
171 # 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
|
172 # 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
|
173 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
|
174 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
|
175 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
|
176 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
|
177 (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
|
178 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
|
179 # (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
|
180 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
|
181 |
28938
ea1fec3e9aba
hook: report untrusted hooks as failure (issue5110) (BC)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
28937
diff
changeset
|
182 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
|
183 """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
|
184 hooks = {} |
28938
ea1fec3e9aba
hook: report untrusted hooks as failure (issue5110) (BC)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
28937
diff
changeset
|
185 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
|
186 if not name.startswith('priority'): |
30c34fde40cc
hooks: prioritize run order of hooks
Matt Zuba <matt.zuba@goodwillaz.org>
parents:
15512
diff
changeset
|
187 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
|
188 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
|
189 return hooks |
15896
30c34fde40cc
hooks: prioritize run order of hooks
Matt Zuba <matt.zuba@goodwillaz.org>
parents:
15512
diff
changeset
|
190 |
5833
323b9c55b328
hook: redirect stdout to stderr for ssh and http servers
Matt Mackall <mpm@selenic.com>
parents:
4622
diff
changeset
|
191 _redirect = False |
323b9c55b328
hook: redirect stdout to stderr for ssh and http servers
Matt Mackall <mpm@selenic.com>
parents:
4622
diff
changeset
|
192 def redirect(state): |
6266
9f76df0edb7d
hook.py: fix redirections introduced by 323b9c55b328
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
5869
diff
changeset
|
193 global _redirect |
5833
323b9c55b328
hook: redirect stdout to stderr for ssh and http servers
Matt Mackall <mpm@selenic.com>
parents:
4622
diff
changeset
|
194 _redirect = state |
323b9c55b328
hook: redirect stdout to stderr for ssh and http servers
Matt Mackall <mpm@selenic.com>
parents:
4622
diff
changeset
|
195 |
34687
e79b6300d97c
hook: add a 'hashook' function to test for hook existence
Boris Feld <boris.feld@octobus.net>
parents:
32915
diff
changeset
|
196 def hashook(ui, htype): |
e79b6300d97c
hook: add a 'hashook' function to test for hook existence
Boris Feld <boris.feld@octobus.net>
parents:
32915
diff
changeset
|
197 """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:
32915
diff
changeset
|
198 if not ui.callhooks: |
e79b6300d97c
hook: add a 'hashook' function to test for hook existence
Boris Feld <boris.feld@octobus.net>
parents:
32915
diff
changeset
|
199 return False |
e79b6300d97c
hook: add a 'hashook' function to test for hook existence
Boris Feld <boris.feld@octobus.net>
parents:
32915
diff
changeset
|
200 for hname, cmd in _allhooks(ui): |
e79b6300d97c
hook: add a 'hashook' function to test for hook existence
Boris Feld <boris.feld@octobus.net>
parents:
32915
diff
changeset
|
201 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:
32915
diff
changeset
|
202 return True |
e79b6300d97c
hook: add a 'hashook' function to test for hook existence
Boris Feld <boris.feld@octobus.net>
parents:
32915
diff
changeset
|
203 return False |
e79b6300d97c
hook: add a 'hashook' function to test for hook existence
Boris Feld <boris.feld@octobus.net>
parents:
32915
diff
changeset
|
204 |
31750
33504b54863e
hook: use 'htype' in 'hook'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
31749
diff
changeset
|
205 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
|
206 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
|
207 return False |
15d4d475de9e
ui: add a variable to control whether hooks should be called
Idan Kamara <idankk86@gmail.com>
parents:
15896
diff
changeset
|
208 |
26737
a930d66a04af
hook: factor out determination of hooks from running them
Siddharth Agarwal <sid0@fb.com>
parents:
26692
diff
changeset
|
209 hooks = [] |
a930d66a04af
hook: factor out determination of hooks from running them
Siddharth Agarwal <sid0@fb.com>
parents:
26692
diff
changeset
|
210 for hname, cmd in _allhooks(ui): |
31750
33504b54863e
hook: use 'htype' in 'hook'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
31749
diff
changeset
|
211 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
|
212 hooks.append((hname, cmd)) |
a930d66a04af
hook: factor out determination of hooks from running them
Siddharth Agarwal <sid0@fb.com>
parents:
26692
diff
changeset
|
213 |
31750
33504b54863e
hook: use 'htype' in 'hook'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
31749
diff
changeset
|
214 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
|
215 r = False |
9abc2c921bbd
hook.runhooks: return a dict of result values
Siddharth Agarwal <sid0@fb.com>
parents:
26737
diff
changeset
|
216 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
|
217 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
|
218 return r |
26737
a930d66a04af
hook: factor out determination of hooks from running them
Siddharth Agarwal <sid0@fb.com>
parents:
26692
diff
changeset
|
219 |
31749
5678496659e9
hook: use 'htype' in 'runhooks'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
31748
diff
changeset
|
220 def runhooks(ui, repo, htype, hooks, throw=False, **args): |
32915
799db2af824c
py3: convert keys of kwargs back to bytes using pycompat.byteskwargs()
Pulkit Goyal <7895pulkit@gmail.com>
parents:
32665
diff
changeset
|
221 args = pycompat.byteskwargs(args) |
26738
9abc2c921bbd
hook.runhooks: return a dict of result values
Siddharth Agarwal <sid0@fb.com>
parents:
26737
diff
changeset
|
222 res = {} |
9658
852b1f3032d2
hook: only redirect stdout if it and stderr are valid files
Sune Foldager <cryo@cyanite.org>
parents:
9332
diff
changeset
|
223 oldstdout = -1 |
5833
323b9c55b328
hook: redirect stdout to stderr for ssh and http servers
Matt Mackall <mpm@selenic.com>
parents:
4622
diff
changeset
|
224 |
7416
196b05a548d0
hooks: restore io correctly on exception
Jesse Long <jesse@virtualpostman.co.za>
parents:
7280
diff
changeset
|
225 try: |
26737
a930d66a04af
hook: factor out determination of hooks from running them
Siddharth Agarwal <sid0@fb.com>
parents:
26692
diff
changeset
|
226 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
|
227 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
|
228 try: |
37122
d4a2e0d5d042
procutil: bulk-replace util.std* to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
36849
diff
changeset
|
229 stdoutno = procutil.stdout.fileno() |
d4a2e0d5d042
procutil: bulk-replace util.std* to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
36849
diff
changeset
|
230 stderrno = procutil.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
|
231 # 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
|
232 if stdoutno >= 0 and stderrno >= 0: |
37122
d4a2e0d5d042
procutil: bulk-replace util.std* to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
36849
diff
changeset
|
233 procutil.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
|
234 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
|
235 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
|
236 except (OSError, AttributeError): |
2c63896783e3
hooks: be even more forgiven of non-fd descriptors (issue3711)
Matt Mackall <mpm@selenic.com>
parents:
17963
diff
changeset
|
237 # 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
|
238 pass |
6180dcb29ec5
hooks: delay I/O redirection until we actually run a hook (issue3711)
Matt Mackall <mpm@selenic.com>
parents:
17428
diff
changeset
|
239 |
28938
ea1fec3e9aba
hook: report untrusted hooks as failure (issue5110) (BC)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
28937
diff
changeset
|
240 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
|
241 if throw: |
ea1fec3e9aba
hook: report untrusted hooks as failure (issue5110) (BC)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
28937
diff
changeset
|
242 raise error.HookAbort( |
31748
f610c3220eec
hook: fix name used in untrusted message
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
31747
diff
changeset
|
243 _('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
|
244 hint = _("see 'hg help config.trusted'")) |
31748
f610c3220eec
hook: fix name used in untrusted message
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
31747
diff
changeset
|
245 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
|
246 r = 1 |
ea1fec3e9aba
hook: report untrusted hooks as failure (issue5110) (BC)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
28937
diff
changeset
|
247 raised = False |
ea1fec3e9aba
hook: report untrusted hooks as failure (issue5110) (BC)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
28937
diff
changeset
|
248 elif callable(cmd): |
38074
242eb5132203
filemerge: support specifying a python function to custom merge-tools
hindlemail <tom_hindle@sil.org>
parents:
37986
diff
changeset
|
249 r, raised = pythonhook(ui, repo, htype, hname, cmd, args, |
31749
5678496659e9
hook: use 'htype' in 'runhooks'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
31748
diff
changeset
|
250 throw) |
7416
196b05a548d0
hooks: restore io correctly on exception
Jesse Long <jesse@virtualpostman.co.za>
parents:
7280
diff
changeset
|
251 elif cmd.startswith('python:'): |
9332
872d49dd577a
hook: fix full path imports on Windows (issue1779)
Steve Borho <steve@borho.org>
parents:
8366
diff
changeset
|
252 if cmd.count(':') >= 2: |
872d49dd577a
hook: fix full path imports on Windows (issue1779)
Steve Borho <steve@borho.org>
parents:
8366
diff
changeset
|
253 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
|
254 path = util.expandpath(path) |
13119
ecf7d6e0eef0
hook: fix import path handling for repo=None
Matt Mackall <mpm@selenic.com>
parents:
13118
diff
changeset
|
255 if repo: |
ecf7d6e0eef0
hook: fix import path handling for repo=None
Matt Mackall <mpm@selenic.com>
parents:
13118
diff
changeset
|
256 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
|
257 try: |
1b2b727a885f
hooks: print out more information when loading a python hook fails
Simon Heimberg <simohe@besonet.ch>
parents:
17048
diff
changeset
|
258 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
|
259 except Exception: |
1b2b727a885f
hooks: print out more information when loading a python hook fails
Simon Heimberg <simohe@besonet.ch>
parents:
17048
diff
changeset
|
260 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
|
261 raise |
7916
f779e1996e23
ability to load hooks from arbitrary python module
Alexander Solovyov <piranha@piranha.org.ua>
parents:
7787
diff
changeset
|
262 hookfn = getattr(mod, cmd) |
f779e1996e23
ability to load hooks from arbitrary python module
Alexander Solovyov <piranha@piranha.org.ua>
parents:
7787
diff
changeset
|
263 else: |
f779e1996e23
ability to load hooks from arbitrary python module
Alexander Solovyov <piranha@piranha.org.ua>
parents:
7787
diff
changeset
|
264 hookfn = cmd[7:].strip() |
38074
242eb5132203
filemerge: support specifying a python function to custom merge-tools
hindlemail <tom_hindle@sil.org>
parents:
37986
diff
changeset
|
265 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
|
266 throw) |
7416
196b05a548d0
hooks: restore io correctly on exception
Jesse Long <jesse@virtualpostman.co.za>
parents:
7280
diff
changeset
|
267 else: |
31751
0fa30fbccc34
hook: provide hook type information to external hook
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
31750
diff
changeset
|
268 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
|
269 raised = False |
26738
9abc2c921bbd
hook.runhooks: return a dict of result values
Siddharth Agarwal <sid0@fb.com>
parents:
26737
diff
changeset
|
270 |
26739
8429369eeb85
hook: for python hooks, also return whether an exception was raised
Siddharth Agarwal <sid0@fb.com>
parents:
26738
diff
changeset
|
271 res[hname] = r, raised |
36849
9c636ec1ef37
hook: ensure stderr is flushed when an exception is raised, for test stability
Matt Harbison <matt_harbison@yahoo.com>
parents:
36146
diff
changeset
|
272 finally: |
9c636ec1ef37
hook: ensure stderr is flushed when an exception is raised, for test stability
Matt Harbison <matt_harbison@yahoo.com>
parents:
36146
diff
changeset
|
273 # The stderr is fully buffered on Windows when connected to a pipe. |
9c636ec1ef37
hook: ensure stderr is flushed when an exception is raised, for test stability
Matt Harbison <matt_harbison@yahoo.com>
parents:
36146
diff
changeset
|
274 # A forcible flush is required to make small stderr data in the |
9c636ec1ef37
hook: ensure stderr is flushed when an exception is raised, for test stability
Matt Harbison <matt_harbison@yahoo.com>
parents:
36146
diff
changeset
|
275 # remote side available to the client immediately. |
37122
d4a2e0d5d042
procutil: bulk-replace util.std* to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
36849
diff
changeset
|
276 procutil.stderr.flush() |
24716
2abbf4750915
hook: forcibly flush stderr for Windows test stability
Matt Harbison <matt_harbison@yahoo.com>
parents:
23426
diff
changeset
|
277 |
9658
852b1f3032d2
hook: only redirect stdout if it and stderr are valid files
Sune Foldager <cryo@cyanite.org>
parents:
9332
diff
changeset
|
278 if _redirect and oldstdout >= 0: |
37122
d4a2e0d5d042
procutil: bulk-replace util.std* to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
36849
diff
changeset
|
279 procutil.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
|
280 os.dup2(oldstdout, stdoutno) |
7416
196b05a548d0
hooks: restore io correctly on exception
Jesse Long <jesse@virtualpostman.co.za>
parents:
7280
diff
changeset
|
281 os.close(oldstdout) |
6266
9f76df0edb7d
hook.py: fix redirections introduced by 323b9c55b328
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
5869
diff
changeset
|
282 |
26738
9abc2c921bbd
hook.runhooks: return a dict of result values
Siddharth Agarwal <sid0@fb.com>
parents:
26737
diff
changeset
|
283 return res |