Mercurial > hg
annotate mercurial/hook.py @ 18650:de0bd4bfc6d7
merge: run _forgetremoved after manifestmerge
_forgetremoved can trigger manifest construction, but we only want it to
happen after manifestmerge, so that our attempt to read the manifests in the
right order in an upcoming patch actually works.
author | Siddharth Agarwal <sid0@fb.com> |
---|---|
date | Sun, 10 Feb 2013 12:16:46 +0000 |
parents | d7c28954d901 |
children | 1c305128e5b9 |
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 |
fff50306e6dd
hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
8 from i18n import _ |
8312
b87a50b7125c
separate import lines from mercurial and general python modules
Simon Heimberg <simohe@besonet.ch>
parents:
8225
diff
changeset
|
9 import os, sys |
18111
d7c28954d901
hook: disable demandimport before importing hooks
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
17964
diff
changeset
|
10 import extensions, util, demandimport |
4622
fff50306e6dd
hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
11 |
fff50306e6dd
hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
12 def _pythonhook(ui, repo, name, hname, funcname, args, throw): |
fff50306e6dd
hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
13 '''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
|
14 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
|
15 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
|
16 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
|
17 |
fff50306e6dd
hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
18 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
|
19 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
|
20 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
|
21 |
fff50306e6dd
hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
22 ui.note(_("calling hook %s: %s\n") % (hname, funcname)) |
fff50306e6dd
hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
23 obj = funcname |
14943
d3bb825ddae3
globally: use safehasattr(x, '__call__') instead of hasattr(x, '__call__')
Augie Fackler <durin42@gmail.com>
parents:
14941
diff
changeset
|
24 if not util.safehasattr(obj, '__call__'): |
4622
fff50306e6dd
hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
25 d = funcname.rfind('.') |
fff50306e6dd
hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
26 if d == -1: |
fff50306e6dd
hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
27 raise util.Abort(_('%s hook is invalid ("%s" not in ' |
fff50306e6dd
hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
28 'a module)') % (hname, funcname)) |
fff50306e6dd
hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
29 modname = funcname[:d] |
10103
37679dbf2ee3
hook: fix bug (reuse of variable) introduced in 872d49dd577a
Sune Foldager <cryo@cyanite.org>
parents:
9851
diff
changeset
|
30 oldpaths = sys.path |
14941
4a28cb4df1f8
windows: check util.mainfrozen() instead of ad-hoc checks everywhere
Augie Fackler <durin42@gmail.com>
parents:
14916
diff
changeset
|
31 if util.mainfrozen(): |
9332
872d49dd577a
hook: fix full path imports on Windows (issue1779)
Steve Borho <steve@borho.org>
parents:
8366
diff
changeset
|
32 # 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
|
33 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
|
34 if modpath and modfile: |
37679dbf2ee3
hook: fix bug (reuse of variable) introduced in 872d49dd577a
Sune Foldager <cryo@cyanite.org>
parents:
9851
diff
changeset
|
35 sys.path = sys.path[:] + [modpath] |
37679dbf2ee3
hook: fix bug (reuse of variable) introduced in 872d49dd577a
Sune Foldager <cryo@cyanite.org>
parents:
9851
diff
changeset
|
36 modname = modfile |
4622
fff50306e6dd
hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
37 try: |
18111
d7c28954d901
hook: disable demandimport before importing hooks
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
17964
diff
changeset
|
38 demandimport.disable() |
4622
fff50306e6dd
hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
39 obj = __import__(modname) |
18111
d7c28954d901
hook: disable demandimport before importing hooks
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
17964
diff
changeset
|
40 demandimport.enable() |
4622
fff50306e6dd
hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
41 except ImportError: |
9851
9e7b2c49d25d
Make it possible to debug failed hook imports via use of --traceback
Bryan O'Sullivan <bos@serpentine.com>
parents:
9658
diff
changeset
|
42 e1 = sys.exc_type, sys.exc_value, sys.exc_traceback |
4622
fff50306e6dd
hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
43 try: |
fff50306e6dd
hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
44 # extensions are loaded with hgext_ prefix |
fff50306e6dd
hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
45 obj = __import__("hgext_%s" % modname) |
18111
d7c28954d901
hook: disable demandimport before importing hooks
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
17964
diff
changeset
|
46 demandimport.enable() |
4622
fff50306e6dd
hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
47 except ImportError: |
18111
d7c28954d901
hook: disable demandimport before importing hooks
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
17964
diff
changeset
|
48 demandimport.enable() |
9851
9e7b2c49d25d
Make it possible to debug failed hook imports via use of --traceback
Bryan O'Sullivan <bos@serpentine.com>
parents:
9658
diff
changeset
|
49 e2 = sys.exc_type, sys.exc_value, sys.exc_traceback |
9e7b2c49d25d
Make it possible to debug failed hook imports via use of --traceback
Bryan O'Sullivan <bos@serpentine.com>
parents:
9658
diff
changeset
|
50 if ui.tracebackflag: |
9e7b2c49d25d
Make it possible to debug failed hook imports via use of --traceback
Bryan O'Sullivan <bos@serpentine.com>
parents:
9658
diff
changeset
|
51 ui.warn(_('exception from first failed import attempt:\n')) |
9e7b2c49d25d
Make it possible to debug failed hook imports via use of --traceback
Bryan O'Sullivan <bos@serpentine.com>
parents:
9658
diff
changeset
|
52 ui.traceback(e1) |
9e7b2c49d25d
Make it possible to debug failed hook imports via use of --traceback
Bryan O'Sullivan <bos@serpentine.com>
parents:
9658
diff
changeset
|
53 if ui.tracebackflag: |
9e7b2c49d25d
Make it possible to debug failed hook imports via use of --traceback
Bryan O'Sullivan <bos@serpentine.com>
parents:
9658
diff
changeset
|
54 ui.warn(_('exception from second failed import attempt:\n')) |
9e7b2c49d25d
Make it possible to debug failed hook imports via use of --traceback
Bryan O'Sullivan <bos@serpentine.com>
parents:
9658
diff
changeset
|
55 ui.traceback(e2) |
4622
fff50306e6dd
hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
56 raise util.Abort(_('%s hook is invalid ' |
fff50306e6dd
hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
57 '(import of "%s" failed)') % |
fff50306e6dd
hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
58 (hname, modname)) |
9332
872d49dd577a
hook: fix full path imports on Windows (issue1779)
Steve Borho <steve@borho.org>
parents:
8366
diff
changeset
|
59 sys.path = oldpaths |
4622
fff50306e6dd
hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
60 try: |
fff50306e6dd
hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
61 for p in funcname.split('.')[1:]: |
fff50306e6dd
hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
62 obj = getattr(obj, p) |
7280
810ca383da9c
remove unused variables
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
6762
diff
changeset
|
63 except AttributeError: |
4622
fff50306e6dd
hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
64 raise util.Abort(_('%s hook is invalid ' |
fff50306e6dd
hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
65 '("%s" is not defined)') % |
fff50306e6dd
hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
66 (hname, funcname)) |
14943
d3bb825ddae3
globally: use safehasattr(x, '__call__') instead of hasattr(x, '__call__')
Augie Fackler <durin42@gmail.com>
parents:
14941
diff
changeset
|
67 if not util.safehasattr(obj, '__call__'): |
4622
fff50306e6dd
hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
68 raise util.Abort(_('%s hook is invalid ' |
fff50306e6dd
hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
69 '("%s" is not callable)') % |
fff50306e6dd
hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
70 (hname, funcname)) |
fff50306e6dd
hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
71 try: |
14916
58f97dcbd550
hooks: use python 2.4 compatible exception handling
Lee Cantey <lcantey@gmail.com>
parents:
14889
diff
changeset
|
72 try: |
17251
98166640b356
help: fix some instances of 'the the'
Mads Kiilerich <mads@kiilerich.com>
parents:
17217
diff
changeset
|
73 # redirect IO descriptors to the ui descriptors so hooks |
14916
58f97dcbd550
hooks: use python 2.4 compatible exception handling
Lee Cantey <lcantey@gmail.com>
parents:
14889
diff
changeset
|
74 # that write directly to these don't mess up the command |
58f97dcbd550
hooks: use python 2.4 compatible exception handling
Lee Cantey <lcantey@gmail.com>
parents:
14889
diff
changeset
|
75 # protocol when running through the command server |
58f97dcbd550
hooks: use python 2.4 compatible exception handling
Lee Cantey <lcantey@gmail.com>
parents:
14889
diff
changeset
|
76 old = sys.stdout, sys.stderr, sys.stdin |
58f97dcbd550
hooks: use python 2.4 compatible exception handling
Lee Cantey <lcantey@gmail.com>
parents:
14889
diff
changeset
|
77 sys.stdout, sys.stderr, sys.stdin = ui.fout, ui.ferr, ui.fin |
14889
a59058fd074a
hooks: redirect stdout/err/in to the ui descriptors when calling python hooks
Idan Kamara <idankk86@gmail.com>
parents:
14711
diff
changeset
|
78 |
14916
58f97dcbd550
hooks: use python 2.4 compatible exception handling
Lee Cantey <lcantey@gmail.com>
parents:
14889
diff
changeset
|
79 r = obj(ui=ui, repo=repo, hooktype=name, **args) |
58f97dcbd550
hooks: use python 2.4 compatible exception handling
Lee Cantey <lcantey@gmail.com>
parents:
14889
diff
changeset
|
80 except KeyboardInterrupt: |
4622
fff50306e6dd
hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
81 raise |
14916
58f97dcbd550
hooks: use python 2.4 compatible exception handling
Lee Cantey <lcantey@gmail.com>
parents:
14889
diff
changeset
|
82 except Exception, exc: |
58f97dcbd550
hooks: use python 2.4 compatible exception handling
Lee Cantey <lcantey@gmail.com>
parents:
14889
diff
changeset
|
83 if isinstance(exc, util.Abort): |
58f97dcbd550
hooks: use python 2.4 compatible exception handling
Lee Cantey <lcantey@gmail.com>
parents:
14889
diff
changeset
|
84 ui.warn(_('error: %s hook failed: %s\n') % |
58f97dcbd550
hooks: use python 2.4 compatible exception handling
Lee Cantey <lcantey@gmail.com>
parents:
14889
diff
changeset
|
85 (hname, exc.args[0])) |
58f97dcbd550
hooks: use python 2.4 compatible exception handling
Lee Cantey <lcantey@gmail.com>
parents:
14889
diff
changeset
|
86 else: |
58f97dcbd550
hooks: use python 2.4 compatible exception handling
Lee Cantey <lcantey@gmail.com>
parents:
14889
diff
changeset
|
87 ui.warn(_('error: %s hook raised an exception: ' |
58f97dcbd550
hooks: use python 2.4 compatible exception handling
Lee Cantey <lcantey@gmail.com>
parents:
14889
diff
changeset
|
88 '%s\n') % (hname, exc)) |
58f97dcbd550
hooks: use python 2.4 compatible exception handling
Lee Cantey <lcantey@gmail.com>
parents:
14889
diff
changeset
|
89 if throw: |
58f97dcbd550
hooks: use python 2.4 compatible exception handling
Lee Cantey <lcantey@gmail.com>
parents:
14889
diff
changeset
|
90 raise |
58f97dcbd550
hooks: use python 2.4 compatible exception handling
Lee Cantey <lcantey@gmail.com>
parents:
14889
diff
changeset
|
91 ui.traceback() |
58f97dcbd550
hooks: use python 2.4 compatible exception handling
Lee Cantey <lcantey@gmail.com>
parents:
14889
diff
changeset
|
92 return 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
|
93 finally: |
a59058fd074a
hooks: redirect stdout/err/in to the ui descriptors when calling python hooks
Idan Kamara <idankk86@gmail.com>
parents:
14711
diff
changeset
|
94 sys.stdout, sys.stderr, sys.stdin = old |
4622
fff50306e6dd
hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
95 if r: |
fff50306e6dd
hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
96 if throw: |
fff50306e6dd
hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
97 raise util.Abort(_('%s hook failed') % hname) |
fff50306e6dd
hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
98 ui.warn(_('warning: %s hook failed\n') % hname) |
fff50306e6dd
hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
99 return r |
fff50306e6dd
hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
100 |
fff50306e6dd
hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
101 def _exthook(ui, repo, name, cmd, args, throw): |
fff50306e6dd
hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
102 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
|
103 |
b8d750daadde
Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents:
7644
diff
changeset
|
104 env = {} |
b8d750daadde
Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents:
7644
diff
changeset
|
105 for k, v in args.iteritems(): |
14943
d3bb825ddae3
globally: use safehasattr(x, '__call__') instead of hasattr(x, '__call__')
Augie Fackler <durin42@gmail.com>
parents:
14941
diff
changeset
|
106 if util.safehasattr(v, '__call__'): |
7787
b8d750daadde
Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents:
7644
diff
changeset
|
107 v = v() |
13207
1775382ff833
hooks: sort any dictionaries set in the environment
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
13119
diff
changeset
|
108 if isinstance(v, dict): |
1775382ff833
hooks: sort any dictionaries set in the environment
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
13119
diff
changeset
|
109 # 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
|
110 # implementations |
1775382ff833
hooks: sort any dictionaries set in the environment
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
13119
diff
changeset
|
111 v = ('{' + |
1775382ff833
hooks: sort any dictionaries set in the environment
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
13119
diff
changeset
|
112 ', '.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
|
113 '}') |
7787
b8d750daadde
Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents:
7644
diff
changeset
|
114 env['HG_' + k.upper()] = v |
b8d750daadde
Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents:
7644
diff
changeset
|
115 |
5869
2c565b9598b8
hooks: fix pre- and post- hooks specified in .hg/hgrc
Matt Mackall <mpm@selenic.com>
parents:
5833
diff
changeset
|
116 if repo: |
2c565b9598b8
hooks: fix pre- and post- hooks specified in .hg/hgrc
Matt Mackall <mpm@selenic.com>
parents:
5833
diff
changeset
|
117 cwd = repo.root |
2c565b9598b8
hooks: fix pre- and post- hooks specified in .hg/hgrc
Matt Mackall <mpm@selenic.com>
parents:
5833
diff
changeset
|
118 else: |
2c565b9598b8
hooks: fix pre- and post- hooks specified in .hg/hgrc
Matt Mackall <mpm@selenic.com>
parents:
5833
diff
changeset
|
119 cwd = os.getcwd() |
11469
c37f35d7f2f5
http: deliver hook output to client
Maxim Khitrov <mkhitrov@gmail.com>
parents:
10263
diff
changeset
|
120 if 'HG_URL' in env and env['HG_URL'].startswith('remote:http'): |
c37f35d7f2f5
http: deliver hook output to client
Maxim Khitrov <mkhitrov@gmail.com>
parents:
10263
diff
changeset
|
121 r = util.system(cmd, environ=env, cwd=cwd, out=ui) |
c37f35d7f2f5
http: deliver hook output to client
Maxim Khitrov <mkhitrov@gmail.com>
parents:
10263
diff
changeset
|
122 else: |
14711
ac70f8d5987c
hook: write hook output to ui fout descriptor
Idan Kamara <idankk86@gmail.com>
parents:
14234
diff
changeset
|
123 r = util.system(cmd, environ=env, cwd=cwd, out=ui.fout) |
4622
fff50306e6dd
hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
124 if r: |
14234
600e64004eb5
rename explain_exit to explainexit
Adrian Buehlmann <adrian@cadifra.com>
parents:
13207
diff
changeset
|
125 desc, r = util.explainexit(r) |
4622
fff50306e6dd
hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
126 if throw: |
fff50306e6dd
hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
127 raise util.Abort(_('%s hook %s') % (name, desc)) |
fff50306e6dd
hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
128 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
|
129 return r |
fff50306e6dd
hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
130 |
15896
30c34fde40cc
hooks: prioritize run order of hooks
Matt Zuba <matt.zuba@goodwillaz.org>
parents:
15512
diff
changeset
|
131 def _allhooks(ui): |
30c34fde40cc
hooks: prioritize run order of hooks
Matt Zuba <matt.zuba@goodwillaz.org>
parents:
15512
diff
changeset
|
132 hooks = [] |
30c34fde40cc
hooks: prioritize run order of hooks
Matt Zuba <matt.zuba@goodwillaz.org>
parents:
15512
diff
changeset
|
133 for name, cmd in ui.configitems('hooks'): |
30c34fde40cc
hooks: prioritize run order of hooks
Matt Zuba <matt.zuba@goodwillaz.org>
parents:
15512
diff
changeset
|
134 if not name.startswith('priority'): |
30c34fde40cc
hooks: prioritize run order of hooks
Matt Zuba <matt.zuba@goodwillaz.org>
parents:
15512
diff
changeset
|
135 priority = ui.configint('hooks', 'priority.%s' % name, 0) |
30c34fde40cc
hooks: prioritize run order of hooks
Matt Zuba <matt.zuba@goodwillaz.org>
parents:
15512
diff
changeset
|
136 hooks.append((-priority, len(hooks), name, cmd)) |
30c34fde40cc
hooks: prioritize run order of hooks
Matt Zuba <matt.zuba@goodwillaz.org>
parents:
15512
diff
changeset
|
137 return [(k, v) for p, o, k, v in sorted(hooks)] |
30c34fde40cc
hooks: prioritize run order of hooks
Matt Zuba <matt.zuba@goodwillaz.org>
parents:
15512
diff
changeset
|
138 |
5833
323b9c55b328
hook: redirect stdout to stderr for ssh and http servers
Matt Mackall <mpm@selenic.com>
parents:
4622
diff
changeset
|
139 _redirect = False |
323b9c55b328
hook: redirect stdout to stderr for ssh and http servers
Matt Mackall <mpm@selenic.com>
parents:
4622
diff
changeset
|
140 def redirect(state): |
6266
9f76df0edb7d
hook.py: fix redirections introduced by 323b9c55b328
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
5869
diff
changeset
|
141 global _redirect |
5833
323b9c55b328
hook: redirect stdout to stderr for ssh and http servers
Matt Mackall <mpm@selenic.com>
parents:
4622
diff
changeset
|
142 _redirect = state |
323b9c55b328
hook: redirect stdout to stderr for ssh and http servers
Matt Mackall <mpm@selenic.com>
parents:
4622
diff
changeset
|
143 |
4622
fff50306e6dd
hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
144 def hook(ui, repo, name, 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
|
145 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
|
146 return False |
15d4d475de9e
ui: add a variable to control whether hooks should be called
Idan Kamara <idankk86@gmail.com>
parents:
15896
diff
changeset
|
147 |
4622
fff50306e6dd
hooks: separate hook code into a separate module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
148 r = False |
9658
852b1f3032d2
hook: only redirect stdout if it and stderr are valid files
Sune Foldager <cryo@cyanite.org>
parents:
9332
diff
changeset
|
149 oldstdout = -1 |
5833
323b9c55b328
hook: redirect stdout to stderr for ssh and http servers
Matt Mackall <mpm@selenic.com>
parents:
4622
diff
changeset
|
150 |
7416
196b05a548d0
hooks: restore io correctly on exception
Jesse Long <jesse@virtualpostman.co.za>
parents:
7280
diff
changeset
|
151 try: |
15896
30c34fde40cc
hooks: prioritize run order of hooks
Matt Zuba <matt.zuba@goodwillaz.org>
parents:
15512
diff
changeset
|
152 for hname, cmd in _allhooks(ui): |
7416
196b05a548d0
hooks: restore io correctly on exception
Jesse Long <jesse@virtualpostman.co.za>
parents:
7280
diff
changeset
|
153 if hname.split('.')[0] != name or not cmd: |
196b05a548d0
hooks: restore io correctly on exception
Jesse Long <jesse@virtualpostman.co.za>
parents:
7280
diff
changeset
|
154 continue |
17963
6180dcb29ec5
hooks: delay I/O redirection until we actually run a hook (issue3711)
Matt Mackall <mpm@selenic.com>
parents:
17428
diff
changeset
|
155 |
6180dcb29ec5
hooks: delay I/O redirection until we actually run a hook (issue3711)
Matt Mackall <mpm@selenic.com>
parents:
17428
diff
changeset
|
156 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
|
157 try: |
6180dcb29ec5
hooks: delay I/O redirection until we actually run a hook (issue3711)
Matt Mackall <mpm@selenic.com>
parents:
17428
diff
changeset
|
158 stdoutno = sys.__stdout__.fileno() |
6180dcb29ec5
hooks: delay I/O redirection until we actually run a hook (issue3711)
Matt Mackall <mpm@selenic.com>
parents:
17428
diff
changeset
|
159 stderrno = sys.__stderr__.fileno() |
6180dcb29ec5
hooks: delay I/O redirection until we actually run a hook (issue3711)
Matt Mackall <mpm@selenic.com>
parents:
17428
diff
changeset
|
160 # 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
|
161 if stdoutno >= 0 and stderrno >= 0: |
6180dcb29ec5
hooks: delay I/O redirection until we actually run a hook (issue3711)
Matt Mackall <mpm@selenic.com>
parents:
17428
diff
changeset
|
162 sys.__stdout__.flush() |
6180dcb29ec5
hooks: delay I/O redirection until we actually run a hook (issue3711)
Matt Mackall <mpm@selenic.com>
parents:
17428
diff
changeset
|
163 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
|
164 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
|
165 except (OSError, AttributeError): |
2c63896783e3
hooks: be even more forgiven of non-fd descriptors (issue3711)
Matt Mackall <mpm@selenic.com>
parents:
17963
diff
changeset
|
166 # 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
|
167 pass |
6180dcb29ec5
hooks: delay I/O redirection until we actually run a hook (issue3711)
Matt Mackall <mpm@selenic.com>
parents:
17428
diff
changeset
|
168 |
14943
d3bb825ddae3
globally: use safehasattr(x, '__call__') instead of hasattr(x, '__call__')
Augie Fackler <durin42@gmail.com>
parents:
14941
diff
changeset
|
169 if util.safehasattr(cmd, '__call__'): |
7416
196b05a548d0
hooks: restore io correctly on exception
Jesse Long <jesse@virtualpostman.co.za>
parents:
7280
diff
changeset
|
170 r = _pythonhook(ui, repo, name, hname, cmd, args, throw) or r |
196b05a548d0
hooks: restore io correctly on exception
Jesse Long <jesse@virtualpostman.co.za>
parents:
7280
diff
changeset
|
171 elif cmd.startswith('python:'): |
9332
872d49dd577a
hook: fix full path imports on Windows (issue1779)
Steve Borho <steve@borho.org>
parents:
8366
diff
changeset
|
172 if cmd.count(':') >= 2: |
872d49dd577a
hook: fix full path imports on Windows (issue1779)
Steve Borho <steve@borho.org>
parents:
8366
diff
changeset
|
173 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
|
174 path = util.expandpath(path) |
13119
ecf7d6e0eef0
hook: fix import path handling for repo=None
Matt Mackall <mpm@selenic.com>
parents:
13118
diff
changeset
|
175 if repo: |
ecf7d6e0eef0
hook: fix import path handling for repo=None
Matt Mackall <mpm@selenic.com>
parents:
13118
diff
changeset
|
176 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
|
177 try: |
1b2b727a885f
hooks: print out more information when loading a python hook fails
Simon Heimberg <simohe@besonet.ch>
parents:
17048
diff
changeset
|
178 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
|
179 except Exception: |
1b2b727a885f
hooks: print out more information when loading a python hook fails
Simon Heimberg <simohe@besonet.ch>
parents:
17048
diff
changeset
|
180 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
|
181 raise |
7916
f779e1996e23
ability to load hooks from arbitrary python module
Alexander Solovyov <piranha@piranha.org.ua>
parents:
7787
diff
changeset
|
182 hookfn = getattr(mod, cmd) |
f779e1996e23
ability to load hooks from arbitrary python module
Alexander Solovyov <piranha@piranha.org.ua>
parents:
7787
diff
changeset
|
183 else: |
f779e1996e23
ability to load hooks from arbitrary python module
Alexander Solovyov <piranha@piranha.org.ua>
parents:
7787
diff
changeset
|
184 hookfn = cmd[7:].strip() |
f779e1996e23
ability to load hooks from arbitrary python module
Alexander Solovyov <piranha@piranha.org.ua>
parents:
7787
diff
changeset
|
185 r = _pythonhook(ui, repo, name, hname, hookfn, args, throw) or r |
7416
196b05a548d0
hooks: restore io correctly on exception
Jesse Long <jesse@virtualpostman.co.za>
parents:
7280
diff
changeset
|
186 else: |
196b05a548d0
hooks: restore io correctly on exception
Jesse Long <jesse@virtualpostman.co.za>
parents:
7280
diff
changeset
|
187 r = _exthook(ui, repo, hname, cmd, args, throw) or r |
196b05a548d0
hooks: restore io correctly on exception
Jesse Long <jesse@virtualpostman.co.za>
parents:
7280
diff
changeset
|
188 finally: |
9658
852b1f3032d2
hook: only redirect stdout if it and stderr are valid files
Sune Foldager <cryo@cyanite.org>
parents:
9332
diff
changeset
|
189 if _redirect and oldstdout >= 0: |
852b1f3032d2
hook: only redirect stdout if it and stderr are valid files
Sune Foldager <cryo@cyanite.org>
parents:
9332
diff
changeset
|
190 os.dup2(oldstdout, stdoutno) |
7416
196b05a548d0
hooks: restore io correctly on exception
Jesse Long <jesse@virtualpostman.co.za>
parents:
7280
diff
changeset
|
191 os.close(oldstdout) |
6266
9f76df0edb7d
hook.py: fix redirections introduced by 323b9c55b328
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
5869
diff
changeset
|
192 |
9f76df0edb7d
hook.py: fix redirections introduced by 323b9c55b328
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
5869
diff
changeset
|
193 return r |