76 |
76 |
77 def hook(self, name, throw=False, **args): |
77 def hook(self, name, throw=False, **args): |
78 def callhook(hname, funcname): |
78 def callhook(hname, funcname): |
79 '''call python hook. hook is callable object, looked up as |
79 '''call python hook. hook is callable object, looked up as |
80 name in python module. if callable returns "true", hook |
80 name in python module. if callable returns "true", hook |
81 passes, else fails. if hook raises exception, treated as |
81 fails, else passes. if hook raises exception, treated as |
82 hook failure. exception propagates if throw is "true".''' |
82 hook failure. exception propagates if throw is "true". |
|
83 |
|
84 reason for "true" meaning "hook failed" is so that |
|
85 unmodified commands (e.g. mercurial.commands.update) can |
|
86 be run as hooks without wrappers to convert return values.''' |
83 |
87 |
84 self.ui.note(_("calling hook %s: %s\n") % (hname, funcname)) |
88 self.ui.note(_("calling hook %s: %s\n") % (hname, funcname)) |
85 d = funcname.rfind('.') |
89 d = funcname.rfind('.') |
86 if d == -1: |
90 if d == -1: |
87 raise util.Abort(_('%s hook is invalid ("%s" not in a module)') |
91 raise util.Abort(_('%s hook is invalid ("%s" not in a module)') |
117 '%s\n') % (hname, exc)) |
121 '%s\n') % (hname, exc)) |
118 if throw: |
122 if throw: |
119 raise |
123 raise |
120 if self.ui.traceback: |
124 if self.ui.traceback: |
121 traceback.print_exc() |
125 traceback.print_exc() |
122 return False |
126 return True |
123 if not r: |
127 if r: |
124 if throw: |
128 if throw: |
125 raise util.Abort(_('%s hook failed') % hname) |
129 raise util.Abort(_('%s hook failed') % hname) |
126 self.ui.warn(_('error: %s hook failed\n') % hname) |
130 self.ui.warn(_('warning: %s hook failed\n') % hname) |
127 return r |
131 return r |
128 |
132 |
129 def runhook(name, cmd): |
133 def runhook(name, cmd): |
130 self.ui.note(_("running hook %s: %s\n") % (name, cmd)) |
134 self.ui.note(_("running hook %s: %s\n") % (name, cmd)) |
131 env = dict([('HG_' + k.upper(), v) for k, v in args.iteritems()] + |
135 env = dict([('HG_' + k.upper(), v) for k, v in args.iteritems()] + |
133 r = util.system(cmd, environ=env, cwd=self.root) |
137 r = util.system(cmd, environ=env, cwd=self.root) |
134 if r: |
138 if r: |
135 desc, r = util.explain_exit(r) |
139 desc, r = util.explain_exit(r) |
136 if throw: |
140 if throw: |
137 raise util.Abort(_('%s hook %s') % (name, desc)) |
141 raise util.Abort(_('%s hook %s') % (name, desc)) |
138 self.ui.warn(_('error: %s hook %s\n') % (name, desc)) |
142 self.ui.warn(_('warning: %s hook %s\n') % (name, desc)) |
139 return False |
143 return r |
140 return True |
144 |
141 |
145 r = False |
142 r = True |
|
143 hooks = [(hname, cmd) for hname, cmd in self.ui.configitems("hooks") |
146 hooks = [(hname, cmd) for hname, cmd in self.ui.configitems("hooks") |
144 if hname.split(".", 1)[0] == name and cmd] |
147 if hname.split(".", 1)[0] == name and cmd] |
145 hooks.sort() |
148 hooks.sort() |
146 for hname, cmd in hooks: |
149 for hname, cmd in hooks: |
147 if cmd.startswith('python:'): |
150 if cmd.startswith('python:'): |
148 r = callhook(hname, cmd[7:].strip()) and r |
151 r = callhook(hname, cmd[7:].strip()) or r |
149 else: |
152 else: |
150 r = runhook(hname, cmd) and r |
153 r = runhook(hname, cmd) or r |
151 return r |
154 return r |
152 |
155 |
153 def tags(self): |
156 def tags(self): |
154 '''return a mapping of tag to node''' |
157 '''return a mapping of tag to node''' |
155 if not self.tagscache: |
158 if not self.tagscache: |