comparison mercurial/localrepo.py @ 2221:05b6c13f43c6

reverse sense of return value from python hooks. old scheme (False/None/0/'' == fail) made coding style unnatural, did not allow use of mercurial commands as hooks. new scheme (False/None/0 == pass) is pythonic, does not require peculiar "return True" at ends of hooks, allows hooks like this: [hooks] # update working dir after push into this repo changegroup.update = python:mercurial.commands.update
author Vadim Gelfer <vadim.gelfer@gmail.com>
date Mon, 08 May 2006 10:59:58 -0700
parents b67fcd91dd1b
children c9e264b115e6
comparison
equal deleted inserted replaced
2220:6d3cc2a982f3 2221:05b6c13f43c6
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: