##// END OF EJS Templates
dispatch: fix typo in debug message
Wagner Bruna -
r13430:ed720c7c stable
parent child Browse files
Show More
@@ -1,653 +1,653 b''
1 # dispatch.py - command dispatching for mercurial
1 # dispatch.py - command dispatching for mercurial
2 #
2 #
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 from i18n import _
8 from i18n import _
9 import os, sys, atexit, signal, pdb, socket, errno, shlex, time, traceback, re
9 import os, sys, atexit, signal, pdb, socket, errno, shlex, time, traceback, re
10 import util, commands, hg, fancyopts, extensions, hook, error
10 import util, commands, hg, fancyopts, extensions, hook, error
11 import cmdutil, encoding
11 import cmdutil, encoding
12 import ui as uimod
12 import ui as uimod
13
13
14 def run():
14 def run():
15 "run the command in sys.argv"
15 "run the command in sys.argv"
16 sys.exit(dispatch(sys.argv[1:]))
16 sys.exit(dispatch(sys.argv[1:]))
17
17
18 def dispatch(args):
18 def dispatch(args):
19 "run the command specified in args"
19 "run the command specified in args"
20 try:
20 try:
21 u = uimod.ui()
21 u = uimod.ui()
22 if '--traceback' in args:
22 if '--traceback' in args:
23 u.setconfig('ui', 'traceback', 'on')
23 u.setconfig('ui', 'traceback', 'on')
24 except util.Abort, inst:
24 except util.Abort, inst:
25 sys.stderr.write(_("abort: %s\n") % inst)
25 sys.stderr.write(_("abort: %s\n") % inst)
26 if inst.hint:
26 if inst.hint:
27 sys.stderr.write(_("(%s)\n") % inst.hint)
27 sys.stderr.write(_("(%s)\n") % inst.hint)
28 return -1
28 return -1
29 except error.ParseError, inst:
29 except error.ParseError, inst:
30 if len(inst.args) > 1:
30 if len(inst.args) > 1:
31 sys.stderr.write(_("hg: parse error at %s: %s\n") %
31 sys.stderr.write(_("hg: parse error at %s: %s\n") %
32 (inst.args[1], inst.args[0]))
32 (inst.args[1], inst.args[0]))
33 else:
33 else:
34 sys.stderr.write(_("hg: parse error: %s\n") % inst.args[0])
34 sys.stderr.write(_("hg: parse error: %s\n") % inst.args[0])
35 return -1
35 return -1
36 return _runcatch(u, args)
36 return _runcatch(u, args)
37
37
38 def _runcatch(ui, args):
38 def _runcatch(ui, args):
39 def catchterm(*args):
39 def catchterm(*args):
40 raise error.SignalInterrupt
40 raise error.SignalInterrupt
41
41
42 try:
42 try:
43 for name in 'SIGBREAK', 'SIGHUP', 'SIGTERM':
43 for name in 'SIGBREAK', 'SIGHUP', 'SIGTERM':
44 num = getattr(signal, name, None)
44 num = getattr(signal, name, None)
45 if num:
45 if num:
46 signal.signal(num, catchterm)
46 signal.signal(num, catchterm)
47 except ValueError:
47 except ValueError:
48 pass # happens if called in a thread
48 pass # happens if called in a thread
49
49
50 try:
50 try:
51 try:
51 try:
52 # enter the debugger before command execution
52 # enter the debugger before command execution
53 if '--debugger' in args:
53 if '--debugger' in args:
54 ui.warn(_("entering debugger - "
54 ui.warn(_("entering debugger - "
55 "type c to continue starting hg or h for help\n"))
55 "type c to continue starting hg or h for help\n"))
56 pdb.set_trace()
56 pdb.set_trace()
57 try:
57 try:
58 return _dispatch(ui, args)
58 return _dispatch(ui, args)
59 finally:
59 finally:
60 ui.flush()
60 ui.flush()
61 except:
61 except:
62 # enter the debugger when we hit an exception
62 # enter the debugger when we hit an exception
63 if '--debugger' in args:
63 if '--debugger' in args:
64 traceback.print_exc()
64 traceback.print_exc()
65 pdb.post_mortem(sys.exc_info()[2])
65 pdb.post_mortem(sys.exc_info()[2])
66 ui.traceback()
66 ui.traceback()
67 raise
67 raise
68
68
69 # Global exception handling, alphabetically
69 # Global exception handling, alphabetically
70 # Mercurial-specific first, followed by built-in and library exceptions
70 # Mercurial-specific first, followed by built-in and library exceptions
71 except error.AmbiguousCommand, inst:
71 except error.AmbiguousCommand, inst:
72 ui.warn(_("hg: command '%s' is ambiguous:\n %s\n") %
72 ui.warn(_("hg: command '%s' is ambiguous:\n %s\n") %
73 (inst.args[0], " ".join(inst.args[1])))
73 (inst.args[0], " ".join(inst.args[1])))
74 except error.ParseError, inst:
74 except error.ParseError, inst:
75 if len(inst.args) > 1:
75 if len(inst.args) > 1:
76 ui.warn(_("hg: parse error at %s: %s\n") %
76 ui.warn(_("hg: parse error at %s: %s\n") %
77 (inst.args[1], inst.args[0]))
77 (inst.args[1], inst.args[0]))
78 else:
78 else:
79 ui.warn(_("hg: parse error: %s\n") % inst.args[0])
79 ui.warn(_("hg: parse error: %s\n") % inst.args[0])
80 return -1
80 return -1
81 except error.LockHeld, inst:
81 except error.LockHeld, inst:
82 if inst.errno == errno.ETIMEDOUT:
82 if inst.errno == errno.ETIMEDOUT:
83 reason = _('timed out waiting for lock held by %s') % inst.locker
83 reason = _('timed out waiting for lock held by %s') % inst.locker
84 else:
84 else:
85 reason = _('lock held by %s') % inst.locker
85 reason = _('lock held by %s') % inst.locker
86 ui.warn(_("abort: %s: %s\n") % (inst.desc or inst.filename, reason))
86 ui.warn(_("abort: %s: %s\n") % (inst.desc or inst.filename, reason))
87 except error.LockUnavailable, inst:
87 except error.LockUnavailable, inst:
88 ui.warn(_("abort: could not lock %s: %s\n") %
88 ui.warn(_("abort: could not lock %s: %s\n") %
89 (inst.desc or inst.filename, inst.strerror))
89 (inst.desc or inst.filename, inst.strerror))
90 except error.CommandError, inst:
90 except error.CommandError, inst:
91 if inst.args[0]:
91 if inst.args[0]:
92 ui.warn(_("hg %s: %s\n") % (inst.args[0], inst.args[1]))
92 ui.warn(_("hg %s: %s\n") % (inst.args[0], inst.args[1]))
93 commands.help_(ui, inst.args[0])
93 commands.help_(ui, inst.args[0])
94 else:
94 else:
95 ui.warn(_("hg: %s\n") % inst.args[1])
95 ui.warn(_("hg: %s\n") % inst.args[1])
96 commands.help_(ui, 'shortlist')
96 commands.help_(ui, 'shortlist')
97 except error.RepoError, inst:
97 except error.RepoError, inst:
98 ui.warn(_("abort: %s!\n") % inst)
98 ui.warn(_("abort: %s!\n") % inst)
99 except error.ResponseError, inst:
99 except error.ResponseError, inst:
100 ui.warn(_("abort: %s") % inst.args[0])
100 ui.warn(_("abort: %s") % inst.args[0])
101 if not isinstance(inst.args[1], basestring):
101 if not isinstance(inst.args[1], basestring):
102 ui.warn(" %r\n" % (inst.args[1],))
102 ui.warn(" %r\n" % (inst.args[1],))
103 elif not inst.args[1]:
103 elif not inst.args[1]:
104 ui.warn(_(" empty string\n"))
104 ui.warn(_(" empty string\n"))
105 else:
105 else:
106 ui.warn("\n%r\n" % util.ellipsis(inst.args[1]))
106 ui.warn("\n%r\n" % util.ellipsis(inst.args[1]))
107 except error.RevlogError, inst:
107 except error.RevlogError, inst:
108 ui.warn(_("abort: %s!\n") % inst)
108 ui.warn(_("abort: %s!\n") % inst)
109 except error.SignalInterrupt:
109 except error.SignalInterrupt:
110 ui.warn(_("killed!\n"))
110 ui.warn(_("killed!\n"))
111 except error.UnknownCommand, inst:
111 except error.UnknownCommand, inst:
112 ui.warn(_("hg: unknown command '%s'\n") % inst.args[0])
112 ui.warn(_("hg: unknown command '%s'\n") % inst.args[0])
113 try:
113 try:
114 # check if the command is in a disabled extension
114 # check if the command is in a disabled extension
115 # (but don't check for extensions themselves)
115 # (but don't check for extensions themselves)
116 commands.help_(ui, inst.args[0], unknowncmd=True)
116 commands.help_(ui, inst.args[0], unknowncmd=True)
117 except error.UnknownCommand:
117 except error.UnknownCommand:
118 commands.help_(ui, 'shortlist')
118 commands.help_(ui, 'shortlist')
119 except util.Abort, inst:
119 except util.Abort, inst:
120 ui.warn(_("abort: %s\n") % inst)
120 ui.warn(_("abort: %s\n") % inst)
121 if inst.hint:
121 if inst.hint:
122 ui.warn(_("(%s)\n") % inst.hint)
122 ui.warn(_("(%s)\n") % inst.hint)
123 except ImportError, inst:
123 except ImportError, inst:
124 ui.warn(_("abort: %s!\n") % inst)
124 ui.warn(_("abort: %s!\n") % inst)
125 m = str(inst).split()[-1]
125 m = str(inst).split()[-1]
126 if m in "mpatch bdiff".split():
126 if m in "mpatch bdiff".split():
127 ui.warn(_("(did you forget to compile extensions?)\n"))
127 ui.warn(_("(did you forget to compile extensions?)\n"))
128 elif m in "zlib".split():
128 elif m in "zlib".split():
129 ui.warn(_("(is your Python install correct?)\n"))
129 ui.warn(_("(is your Python install correct?)\n"))
130 except IOError, inst:
130 except IOError, inst:
131 if hasattr(inst, "code"):
131 if hasattr(inst, "code"):
132 ui.warn(_("abort: %s\n") % inst)
132 ui.warn(_("abort: %s\n") % inst)
133 elif hasattr(inst, "reason"):
133 elif hasattr(inst, "reason"):
134 try: # usually it is in the form (errno, strerror)
134 try: # usually it is in the form (errno, strerror)
135 reason = inst.reason.args[1]
135 reason = inst.reason.args[1]
136 except: # it might be anything, for example a string
136 except: # it might be anything, for example a string
137 reason = inst.reason
137 reason = inst.reason
138 ui.warn(_("abort: error: %s\n") % reason)
138 ui.warn(_("abort: error: %s\n") % reason)
139 elif hasattr(inst, "args") and inst.args[0] == errno.EPIPE:
139 elif hasattr(inst, "args") and inst.args[0] == errno.EPIPE:
140 if ui.debugflag:
140 if ui.debugflag:
141 ui.warn(_("broken pipe\n"))
141 ui.warn(_("broken pipe\n"))
142 elif getattr(inst, "strerror", None):
142 elif getattr(inst, "strerror", None):
143 if getattr(inst, "filename", None):
143 if getattr(inst, "filename", None):
144 ui.warn(_("abort: %s: %s\n") % (inst.strerror, inst.filename))
144 ui.warn(_("abort: %s: %s\n") % (inst.strerror, inst.filename))
145 else:
145 else:
146 ui.warn(_("abort: %s\n") % inst.strerror)
146 ui.warn(_("abort: %s\n") % inst.strerror)
147 else:
147 else:
148 raise
148 raise
149 except OSError, inst:
149 except OSError, inst:
150 if getattr(inst, "filename", None):
150 if getattr(inst, "filename", None):
151 ui.warn(_("abort: %s: %s\n") % (inst.strerror, inst.filename))
151 ui.warn(_("abort: %s: %s\n") % (inst.strerror, inst.filename))
152 else:
152 else:
153 ui.warn(_("abort: %s\n") % inst.strerror)
153 ui.warn(_("abort: %s\n") % inst.strerror)
154 except KeyboardInterrupt:
154 except KeyboardInterrupt:
155 try:
155 try:
156 ui.warn(_("interrupted!\n"))
156 ui.warn(_("interrupted!\n"))
157 except IOError, inst:
157 except IOError, inst:
158 if inst.errno == errno.EPIPE:
158 if inst.errno == errno.EPIPE:
159 if ui.debugflag:
159 if ui.debugflag:
160 ui.warn(_("\nbroken pipe\n"))
160 ui.warn(_("\nbroken pipe\n"))
161 else:
161 else:
162 raise
162 raise
163 except MemoryError:
163 except MemoryError:
164 ui.warn(_("abort: out of memory\n"))
164 ui.warn(_("abort: out of memory\n"))
165 except SystemExit, inst:
165 except SystemExit, inst:
166 # Commands shouldn't sys.exit directly, but give a return code.
166 # Commands shouldn't sys.exit directly, but give a return code.
167 # Just in case catch this and and pass exit code to caller.
167 # Just in case catch this and and pass exit code to caller.
168 return inst.code
168 return inst.code
169 except socket.error, inst:
169 except socket.error, inst:
170 ui.warn(_("abort: %s\n") % inst.args[-1])
170 ui.warn(_("abort: %s\n") % inst.args[-1])
171 except:
171 except:
172 ui.warn(_("** unknown exception encountered,"
172 ui.warn(_("** unknown exception encountered,"
173 " please report by visiting\n"))
173 " please report by visiting\n"))
174 ui.warn(_("** http://mercurial.selenic.com/wiki/BugTracker\n"))
174 ui.warn(_("** http://mercurial.selenic.com/wiki/BugTracker\n"))
175 ui.warn(_("** Python %s\n") % sys.version.replace('\n', ''))
175 ui.warn(_("** Python %s\n") % sys.version.replace('\n', ''))
176 ui.warn(_("** Mercurial Distributed SCM (version %s)\n")
176 ui.warn(_("** Mercurial Distributed SCM (version %s)\n")
177 % util.version())
177 % util.version())
178 ui.warn(_("** Extensions loaded: %s\n")
178 ui.warn(_("** Extensions loaded: %s\n")
179 % ", ".join([x[0] for x in extensions.extensions()]))
179 % ", ".join([x[0] for x in extensions.extensions()]))
180 raise
180 raise
181
181
182 return -1
182 return -1
183
183
184 def aliasargs(fn):
184 def aliasargs(fn):
185 if hasattr(fn, 'args'):
185 if hasattr(fn, 'args'):
186 return fn.args
186 return fn.args
187 return []
187 return []
188
188
189 class cmdalias(object):
189 class cmdalias(object):
190 def __init__(self, name, definition, cmdtable):
190 def __init__(self, name, definition, cmdtable):
191 self.name = self.cmd = name
191 self.name = self.cmd = name
192 self.cmdname = ''
192 self.cmdname = ''
193 self.definition = definition
193 self.definition = definition
194 self.args = []
194 self.args = []
195 self.opts = []
195 self.opts = []
196 self.help = ''
196 self.help = ''
197 self.norepo = True
197 self.norepo = True
198 self.badalias = False
198 self.badalias = False
199
199
200 try:
200 try:
201 aliases, entry = cmdutil.findcmd(self.name, cmdtable)
201 aliases, entry = cmdutil.findcmd(self.name, cmdtable)
202 for alias, e in cmdtable.iteritems():
202 for alias, e in cmdtable.iteritems():
203 if e is entry:
203 if e is entry:
204 self.cmd = alias
204 self.cmd = alias
205 break
205 break
206 self.shadows = True
206 self.shadows = True
207 except error.UnknownCommand:
207 except error.UnknownCommand:
208 self.shadows = False
208 self.shadows = False
209
209
210 if not self.definition:
210 if not self.definition:
211 def fn(ui, *args):
211 def fn(ui, *args):
212 ui.warn(_("no definition for alias '%s'\n") % self.name)
212 ui.warn(_("no definition for alias '%s'\n") % self.name)
213 return 1
213 return 1
214 self.fn = fn
214 self.fn = fn
215 self.badalias = True
215 self.badalias = True
216
216
217 return
217 return
218
218
219 if self.definition.startswith('!'):
219 if self.definition.startswith('!'):
220 self.shell = True
220 self.shell = True
221 def fn(ui, *args):
221 def fn(ui, *args):
222 env = {'HG_ARGS': ' '.join((self.name,) + args)}
222 env = {'HG_ARGS': ' '.join((self.name,) + args)}
223 def _checkvar(m):
223 def _checkvar(m):
224 if m.groups()[0] == '$':
224 if m.groups()[0] == '$':
225 return m.group()
225 return m.group()
226 elif int(m.groups()[0]) <= len(args):
226 elif int(m.groups()[0]) <= len(args):
227 return m.group()
227 return m.group()
228 else:
228 else:
229 ui.debug(_("No argument found for substitution"
229 ui.debug(_("No argument found for substitution "
230 "of %i variable in alias '%s' definition.")
230 "of %i variable in alias '%s' definition.")
231 % (int(m.groups()[0]), self.name))
231 % (int(m.groups()[0]), self.name))
232 return ''
232 return ''
233 cmd = re.sub(r'\$(\d+|\$)', _checkvar, self.definition[1:])
233 cmd = re.sub(r'\$(\d+|\$)', _checkvar, self.definition[1:])
234 replace = dict((str(i + 1), arg) for i, arg in enumerate(args))
234 replace = dict((str(i + 1), arg) for i, arg in enumerate(args))
235 replace['0'] = self.name
235 replace['0'] = self.name
236 replace['@'] = ' '.join(args)
236 replace['@'] = ' '.join(args)
237 cmd = util.interpolate(r'\$', replace, cmd, escape_prefix=True)
237 cmd = util.interpolate(r'\$', replace, cmd, escape_prefix=True)
238 return util.system(cmd, environ=env)
238 return util.system(cmd, environ=env)
239 self.fn = fn
239 self.fn = fn
240 return
240 return
241
241
242 args = shlex.split(self.definition)
242 args = shlex.split(self.definition)
243 self.cmdname = cmd = args.pop(0)
243 self.cmdname = cmd = args.pop(0)
244 args = map(util.expandpath, args)
244 args = map(util.expandpath, args)
245
245
246 for invalidarg in ("--cwd", "-R", "--repository", "--repo"):
246 for invalidarg in ("--cwd", "-R", "--repository", "--repo"):
247 if _earlygetopt([invalidarg], args):
247 if _earlygetopt([invalidarg], args):
248 def fn(ui, *args):
248 def fn(ui, *args):
249 ui.warn(_("error in definition for alias '%s': %s may only "
249 ui.warn(_("error in definition for alias '%s': %s may only "
250 "be given on the command line\n")
250 "be given on the command line\n")
251 % (self.name, invalidarg))
251 % (self.name, invalidarg))
252 return 1
252 return 1
253
253
254 self.fn = fn
254 self.fn = fn
255 self.badalias = True
255 self.badalias = True
256 return
256 return
257
257
258 try:
258 try:
259 tableentry = cmdutil.findcmd(cmd, cmdtable, False)[1]
259 tableentry = cmdutil.findcmd(cmd, cmdtable, False)[1]
260 if len(tableentry) > 2:
260 if len(tableentry) > 2:
261 self.fn, self.opts, self.help = tableentry
261 self.fn, self.opts, self.help = tableentry
262 else:
262 else:
263 self.fn, self.opts = tableentry
263 self.fn, self.opts = tableentry
264
264
265 self.args = aliasargs(self.fn) + args
265 self.args = aliasargs(self.fn) + args
266 if cmd not in commands.norepo.split(' '):
266 if cmd not in commands.norepo.split(' '):
267 self.norepo = False
267 self.norepo = False
268 if self.help.startswith("hg " + cmd):
268 if self.help.startswith("hg " + cmd):
269 # drop prefix in old-style help lines so hg shows the alias
269 # drop prefix in old-style help lines so hg shows the alias
270 self.help = self.help[4 + len(cmd):]
270 self.help = self.help[4 + len(cmd):]
271 self.__doc__ = self.fn.__doc__
271 self.__doc__ = self.fn.__doc__
272
272
273 except error.UnknownCommand:
273 except error.UnknownCommand:
274 def fn(ui, *args):
274 def fn(ui, *args):
275 ui.warn(_("alias '%s' resolves to unknown command '%s'\n") \
275 ui.warn(_("alias '%s' resolves to unknown command '%s'\n") \
276 % (self.name, cmd))
276 % (self.name, cmd))
277 try:
277 try:
278 # check if the command is in a disabled extension
278 # check if the command is in a disabled extension
279 commands.help_(ui, cmd, unknowncmd=True)
279 commands.help_(ui, cmd, unknowncmd=True)
280 except error.UnknownCommand:
280 except error.UnknownCommand:
281 pass
281 pass
282 return 1
282 return 1
283 self.fn = fn
283 self.fn = fn
284 self.badalias = True
284 self.badalias = True
285 except error.AmbiguousCommand:
285 except error.AmbiguousCommand:
286 def fn(ui, *args):
286 def fn(ui, *args):
287 ui.warn(_("alias '%s' resolves to ambiguous command '%s'\n") \
287 ui.warn(_("alias '%s' resolves to ambiguous command '%s'\n") \
288 % (self.name, cmd))
288 % (self.name, cmd))
289 return 1
289 return 1
290 self.fn = fn
290 self.fn = fn
291 self.badalias = True
291 self.badalias = True
292
292
293 def __call__(self, ui, *args, **opts):
293 def __call__(self, ui, *args, **opts):
294 if self.shadows:
294 if self.shadows:
295 ui.debug("alias '%s' shadows command '%s'\n" %
295 ui.debug("alias '%s' shadows command '%s'\n" %
296 (self.name, self.cmdname))
296 (self.name, self.cmdname))
297
297
298 if hasattr(self, 'shell'):
298 if hasattr(self, 'shell'):
299 return self.fn(ui, *args, **opts)
299 return self.fn(ui, *args, **opts)
300 else:
300 else:
301 try:
301 try:
302 util.checksignature(self.fn)(ui, *args, **opts)
302 util.checksignature(self.fn)(ui, *args, **opts)
303 except error.SignatureError:
303 except error.SignatureError:
304 args = ' '.join([self.cmdname] + self.args)
304 args = ' '.join([self.cmdname] + self.args)
305 ui.debug("alias '%s' expands to '%s'\n" % (self.name, args))
305 ui.debug("alias '%s' expands to '%s'\n" % (self.name, args))
306 raise
306 raise
307
307
308 def addaliases(ui, cmdtable):
308 def addaliases(ui, cmdtable):
309 # aliases are processed after extensions have been loaded, so they
309 # aliases are processed after extensions have been loaded, so they
310 # may use extension commands. Aliases can also use other alias definitions,
310 # may use extension commands. Aliases can also use other alias definitions,
311 # but only if they have been defined prior to the current definition.
311 # but only if they have been defined prior to the current definition.
312 for alias, definition in ui.configitems('alias'):
312 for alias, definition in ui.configitems('alias'):
313 aliasdef = cmdalias(alias, definition, cmdtable)
313 aliasdef = cmdalias(alias, definition, cmdtable)
314 cmdtable[aliasdef.cmd] = (aliasdef, aliasdef.opts, aliasdef.help)
314 cmdtable[aliasdef.cmd] = (aliasdef, aliasdef.opts, aliasdef.help)
315 if aliasdef.norepo:
315 if aliasdef.norepo:
316 commands.norepo += ' %s' % alias
316 commands.norepo += ' %s' % alias
317
317
318 def _parse(ui, args):
318 def _parse(ui, args):
319 options = {}
319 options = {}
320 cmdoptions = {}
320 cmdoptions = {}
321
321
322 try:
322 try:
323 args = fancyopts.fancyopts(args, commands.globalopts, options)
323 args = fancyopts.fancyopts(args, commands.globalopts, options)
324 except fancyopts.getopt.GetoptError, inst:
324 except fancyopts.getopt.GetoptError, inst:
325 raise error.CommandError(None, inst)
325 raise error.CommandError(None, inst)
326
326
327 if args:
327 if args:
328 cmd, args = args[0], args[1:]
328 cmd, args = args[0], args[1:]
329 aliases, entry = cmdutil.findcmd(cmd, commands.table,
329 aliases, entry = cmdutil.findcmd(cmd, commands.table,
330 ui.config("ui", "strict"))
330 ui.config("ui", "strict"))
331 cmd = aliases[0]
331 cmd = aliases[0]
332 args = aliasargs(entry[0]) + args
332 args = aliasargs(entry[0]) + args
333 defaults = ui.config("defaults", cmd)
333 defaults = ui.config("defaults", cmd)
334 if defaults:
334 if defaults:
335 args = map(util.expandpath, shlex.split(defaults)) + args
335 args = map(util.expandpath, shlex.split(defaults)) + args
336 c = list(entry[1])
336 c = list(entry[1])
337 else:
337 else:
338 cmd = None
338 cmd = None
339 c = []
339 c = []
340
340
341 # combine global options into local
341 # combine global options into local
342 for o in commands.globalopts:
342 for o in commands.globalopts:
343 c.append((o[0], o[1], options[o[1]], o[3]))
343 c.append((o[0], o[1], options[o[1]], o[3]))
344
344
345 try:
345 try:
346 args = fancyopts.fancyopts(args, c, cmdoptions, True)
346 args = fancyopts.fancyopts(args, c, cmdoptions, True)
347 except fancyopts.getopt.GetoptError, inst:
347 except fancyopts.getopt.GetoptError, inst:
348 raise error.CommandError(cmd, inst)
348 raise error.CommandError(cmd, inst)
349
349
350 # separate global options back out
350 # separate global options back out
351 for o in commands.globalopts:
351 for o in commands.globalopts:
352 n = o[1]
352 n = o[1]
353 options[n] = cmdoptions[n]
353 options[n] = cmdoptions[n]
354 del cmdoptions[n]
354 del cmdoptions[n]
355
355
356 return (cmd, cmd and entry[0] or None, args, options, cmdoptions)
356 return (cmd, cmd and entry[0] or None, args, options, cmdoptions)
357
357
358 def _parseconfig(ui, config):
358 def _parseconfig(ui, config):
359 """parse the --config options from the command line"""
359 """parse the --config options from the command line"""
360 for cfg in config:
360 for cfg in config:
361 try:
361 try:
362 name, value = cfg.split('=', 1)
362 name, value = cfg.split('=', 1)
363 section, name = name.split('.', 1)
363 section, name = name.split('.', 1)
364 if not section or not name:
364 if not section or not name:
365 raise IndexError
365 raise IndexError
366 ui.setconfig(section, name, value)
366 ui.setconfig(section, name, value)
367 except (IndexError, ValueError):
367 except (IndexError, ValueError):
368 raise util.Abort(_('malformed --config option: %r '
368 raise util.Abort(_('malformed --config option: %r '
369 '(use --config section.name=value)') % cfg)
369 '(use --config section.name=value)') % cfg)
370
370
371 def _earlygetopt(aliases, args):
371 def _earlygetopt(aliases, args):
372 """Return list of values for an option (or aliases).
372 """Return list of values for an option (or aliases).
373
373
374 The values are listed in the order they appear in args.
374 The values are listed in the order they appear in args.
375 The options and values are removed from args.
375 The options and values are removed from args.
376 """
376 """
377 try:
377 try:
378 argcount = args.index("--")
378 argcount = args.index("--")
379 except ValueError:
379 except ValueError:
380 argcount = len(args)
380 argcount = len(args)
381 shortopts = [opt for opt in aliases if len(opt) == 2]
381 shortopts = [opt for opt in aliases if len(opt) == 2]
382 values = []
382 values = []
383 pos = 0
383 pos = 0
384 while pos < argcount:
384 while pos < argcount:
385 if args[pos] in aliases:
385 if args[pos] in aliases:
386 if pos + 1 >= argcount:
386 if pos + 1 >= argcount:
387 # ignore and let getopt report an error if there is no value
387 # ignore and let getopt report an error if there is no value
388 break
388 break
389 del args[pos]
389 del args[pos]
390 values.append(args.pop(pos))
390 values.append(args.pop(pos))
391 argcount -= 2
391 argcount -= 2
392 elif args[pos][:2] in shortopts:
392 elif args[pos][:2] in shortopts:
393 # short option can have no following space, e.g. hg log -Rfoo
393 # short option can have no following space, e.g. hg log -Rfoo
394 values.append(args.pop(pos)[2:])
394 values.append(args.pop(pos)[2:])
395 argcount -= 1
395 argcount -= 1
396 else:
396 else:
397 pos += 1
397 pos += 1
398 return values
398 return values
399
399
400 def runcommand(lui, repo, cmd, fullargs, ui, options, d, cmdpats, cmdoptions):
400 def runcommand(lui, repo, cmd, fullargs, ui, options, d, cmdpats, cmdoptions):
401 # run pre-hook, and abort if it fails
401 # run pre-hook, and abort if it fails
402 ret = hook.hook(lui, repo, "pre-%s" % cmd, False, args=" ".join(fullargs),
402 ret = hook.hook(lui, repo, "pre-%s" % cmd, False, args=" ".join(fullargs),
403 pats=cmdpats, opts=cmdoptions)
403 pats=cmdpats, opts=cmdoptions)
404 if ret:
404 if ret:
405 return ret
405 return ret
406 ret = _runcommand(ui, options, cmd, d)
406 ret = _runcommand(ui, options, cmd, d)
407 # run post-hook, passing command result
407 # run post-hook, passing command result
408 hook.hook(lui, repo, "post-%s" % cmd, False, args=" ".join(fullargs),
408 hook.hook(lui, repo, "post-%s" % cmd, False, args=" ".join(fullargs),
409 result=ret, pats=cmdpats, opts=cmdoptions)
409 result=ret, pats=cmdpats, opts=cmdoptions)
410 return ret
410 return ret
411
411
412 def _getlocal(ui, rpath):
412 def _getlocal(ui, rpath):
413 """Return (path, local ui object) for the given target path.
413 """Return (path, local ui object) for the given target path.
414
414
415 Takes paths in [cwd]/.hg/hgrc into account."
415 Takes paths in [cwd]/.hg/hgrc into account."
416 """
416 """
417 try:
417 try:
418 wd = os.getcwd()
418 wd = os.getcwd()
419 except OSError, e:
419 except OSError, e:
420 raise util.Abort(_("error getting current working directory: %s") %
420 raise util.Abort(_("error getting current working directory: %s") %
421 e.strerror)
421 e.strerror)
422 path = cmdutil.findrepo(wd) or ""
422 path = cmdutil.findrepo(wd) or ""
423 if not path:
423 if not path:
424 lui = ui
424 lui = ui
425 else:
425 else:
426 lui = ui.copy()
426 lui = ui.copy()
427 lui.readconfig(os.path.join(path, ".hg", "hgrc"), path)
427 lui.readconfig(os.path.join(path, ".hg", "hgrc"), path)
428
428
429 if rpath:
429 if rpath:
430 path = lui.expandpath(rpath[-1])
430 path = lui.expandpath(rpath[-1])
431 lui = ui.copy()
431 lui = ui.copy()
432 lui.readconfig(os.path.join(path, ".hg", "hgrc"), path)
432 lui.readconfig(os.path.join(path, ".hg", "hgrc"), path)
433
433
434 return path, lui
434 return path, lui
435
435
436 def _checkshellalias(ui, args):
436 def _checkshellalias(ui, args):
437 cwd = os.getcwd()
437 cwd = os.getcwd()
438 norepo = commands.norepo
438 norepo = commands.norepo
439 options = {}
439 options = {}
440
440
441 try:
441 try:
442 args = fancyopts.fancyopts(args, commands.globalopts, options)
442 args = fancyopts.fancyopts(args, commands.globalopts, options)
443 except fancyopts.getopt.GetoptError:
443 except fancyopts.getopt.GetoptError:
444 return
444 return
445
445
446 if not args:
446 if not args:
447 return
447 return
448
448
449 _parseconfig(ui, options['config'])
449 _parseconfig(ui, options['config'])
450 if options['cwd']:
450 if options['cwd']:
451 os.chdir(options['cwd'])
451 os.chdir(options['cwd'])
452
452
453 path, lui = _getlocal(ui, [options['repository']])
453 path, lui = _getlocal(ui, [options['repository']])
454
454
455 cmdtable = commands.table.copy()
455 cmdtable = commands.table.copy()
456 addaliases(lui, cmdtable)
456 addaliases(lui, cmdtable)
457
457
458 cmd = args[0]
458 cmd = args[0]
459 try:
459 try:
460 aliases, entry = cmdutil.findcmd(cmd, cmdtable, lui.config("ui", "strict"))
460 aliases, entry = cmdutil.findcmd(cmd, cmdtable, lui.config("ui", "strict"))
461 except (error.AmbiguousCommand, error.UnknownCommand):
461 except (error.AmbiguousCommand, error.UnknownCommand):
462 commands.norepo = norepo
462 commands.norepo = norepo
463 os.chdir(cwd)
463 os.chdir(cwd)
464 return
464 return
465
465
466 cmd = aliases[0]
466 cmd = aliases[0]
467 fn = entry[0]
467 fn = entry[0]
468
468
469 if cmd and hasattr(fn, 'shell'):
469 if cmd and hasattr(fn, 'shell'):
470 d = lambda: fn(ui, *args[1:])
470 d = lambda: fn(ui, *args[1:])
471 return lambda: runcommand(lui, None, cmd, args[:1], ui, options, d, [], {})
471 return lambda: runcommand(lui, None, cmd, args[:1], ui, options, d, [], {})
472
472
473 commands.norepo = norepo
473 commands.norepo = norepo
474 os.chdir(cwd)
474 os.chdir(cwd)
475
475
476 _loaded = set()
476 _loaded = set()
477 def _dispatch(ui, args):
477 def _dispatch(ui, args):
478 shellaliasfn = _checkshellalias(ui, args)
478 shellaliasfn = _checkshellalias(ui, args)
479 if shellaliasfn:
479 if shellaliasfn:
480 return shellaliasfn()
480 return shellaliasfn()
481
481
482 # read --config before doing anything else
482 # read --config before doing anything else
483 # (e.g. to change trust settings for reading .hg/hgrc)
483 # (e.g. to change trust settings for reading .hg/hgrc)
484 _parseconfig(ui, _earlygetopt(['--config'], args))
484 _parseconfig(ui, _earlygetopt(['--config'], args))
485
485
486 # check for cwd
486 # check for cwd
487 cwd = _earlygetopt(['--cwd'], args)
487 cwd = _earlygetopt(['--cwd'], args)
488 if cwd:
488 if cwd:
489 os.chdir(cwd[-1])
489 os.chdir(cwd[-1])
490
490
491 rpath = _earlygetopt(["-R", "--repository", "--repo"], args)
491 rpath = _earlygetopt(["-R", "--repository", "--repo"], args)
492 path, lui = _getlocal(ui, rpath)
492 path, lui = _getlocal(ui, rpath)
493
493
494 # Configure extensions in phases: uisetup, extsetup, cmdtable, and
494 # Configure extensions in phases: uisetup, extsetup, cmdtable, and
495 # reposetup. Programs like TortoiseHg will call _dispatch several
495 # reposetup. Programs like TortoiseHg will call _dispatch several
496 # times so we keep track of configured extensions in _loaded.
496 # times so we keep track of configured extensions in _loaded.
497 extensions.loadall(lui)
497 extensions.loadall(lui)
498 exts = [ext for ext in extensions.extensions() if ext[0] not in _loaded]
498 exts = [ext for ext in extensions.extensions() if ext[0] not in _loaded]
499 # Propagate any changes to lui.__class__ by extensions
499 # Propagate any changes to lui.__class__ by extensions
500 ui.__class__ = lui.__class__
500 ui.__class__ = lui.__class__
501
501
502 # (uisetup and extsetup are handled in extensions.loadall)
502 # (uisetup and extsetup are handled in extensions.loadall)
503
503
504 for name, module in exts:
504 for name, module in exts:
505 cmdtable = getattr(module, 'cmdtable', {})
505 cmdtable = getattr(module, 'cmdtable', {})
506 overrides = [cmd for cmd in cmdtable if cmd in commands.table]
506 overrides = [cmd for cmd in cmdtable if cmd in commands.table]
507 if overrides:
507 if overrides:
508 ui.warn(_("extension '%s' overrides commands: %s\n")
508 ui.warn(_("extension '%s' overrides commands: %s\n")
509 % (name, " ".join(overrides)))
509 % (name, " ".join(overrides)))
510 commands.table.update(cmdtable)
510 commands.table.update(cmdtable)
511 _loaded.add(name)
511 _loaded.add(name)
512
512
513 # (reposetup is handled in hg.repository)
513 # (reposetup is handled in hg.repository)
514
514
515 addaliases(lui, commands.table)
515 addaliases(lui, commands.table)
516
516
517 # check for fallback encoding
517 # check for fallback encoding
518 fallback = lui.config('ui', 'fallbackencoding')
518 fallback = lui.config('ui', 'fallbackencoding')
519 if fallback:
519 if fallback:
520 encoding.fallbackencoding = fallback
520 encoding.fallbackencoding = fallback
521
521
522 fullargs = args
522 fullargs = args
523 cmd, func, args, options, cmdoptions = _parse(lui, args)
523 cmd, func, args, options, cmdoptions = _parse(lui, args)
524
524
525 if options["config"]:
525 if options["config"]:
526 raise util.Abort(_("option --config may not be abbreviated!"))
526 raise util.Abort(_("option --config may not be abbreviated!"))
527 if options["cwd"]:
527 if options["cwd"]:
528 raise util.Abort(_("option --cwd may not be abbreviated!"))
528 raise util.Abort(_("option --cwd may not be abbreviated!"))
529 if options["repository"]:
529 if options["repository"]:
530 raise util.Abort(_(
530 raise util.Abort(_(
531 "Option -R has to be separated from other options (e.g. not -qR) "
531 "Option -R has to be separated from other options (e.g. not -qR) "
532 "and --repository may only be abbreviated as --repo!"))
532 "and --repository may only be abbreviated as --repo!"))
533
533
534 if options["encoding"]:
534 if options["encoding"]:
535 encoding.encoding = options["encoding"]
535 encoding.encoding = options["encoding"]
536 if options["encodingmode"]:
536 if options["encodingmode"]:
537 encoding.encodingmode = options["encodingmode"]
537 encoding.encodingmode = options["encodingmode"]
538 if options["time"]:
538 if options["time"]:
539 def get_times():
539 def get_times():
540 t = os.times()
540 t = os.times()
541 if t[4] == 0.0: # Windows leaves this as zero, so use time.clock()
541 if t[4] == 0.0: # Windows leaves this as zero, so use time.clock()
542 t = (t[0], t[1], t[2], t[3], time.clock())
542 t = (t[0], t[1], t[2], t[3], time.clock())
543 return t
543 return t
544 s = get_times()
544 s = get_times()
545 def print_time():
545 def print_time():
546 t = get_times()
546 t = get_times()
547 ui.warn(_("Time: real %.3f secs (user %.3f+%.3f sys %.3f+%.3f)\n") %
547 ui.warn(_("Time: real %.3f secs (user %.3f+%.3f sys %.3f+%.3f)\n") %
548 (t[4]-s[4], t[0]-s[0], t[2]-s[2], t[1]-s[1], t[3]-s[3]))
548 (t[4]-s[4], t[0]-s[0], t[2]-s[2], t[1]-s[1], t[3]-s[3]))
549 atexit.register(print_time)
549 atexit.register(print_time)
550
550
551 if options['verbose'] or options['debug'] or options['quiet']:
551 if options['verbose'] or options['debug'] or options['quiet']:
552 ui.setconfig('ui', 'verbose', str(bool(options['verbose'])))
552 ui.setconfig('ui', 'verbose', str(bool(options['verbose'])))
553 ui.setconfig('ui', 'debug', str(bool(options['debug'])))
553 ui.setconfig('ui', 'debug', str(bool(options['debug'])))
554 ui.setconfig('ui', 'quiet', str(bool(options['quiet'])))
554 ui.setconfig('ui', 'quiet', str(bool(options['quiet'])))
555 if options['traceback']:
555 if options['traceback']:
556 ui.setconfig('ui', 'traceback', 'on')
556 ui.setconfig('ui', 'traceback', 'on')
557 if options['noninteractive']:
557 if options['noninteractive']:
558 ui.setconfig('ui', 'interactive', 'off')
558 ui.setconfig('ui', 'interactive', 'off')
559
559
560 if cmdoptions.get('insecure', False):
560 if cmdoptions.get('insecure', False):
561 ui.setconfig('web', 'cacerts', '')
561 ui.setconfig('web', 'cacerts', '')
562
562
563 if options['help']:
563 if options['help']:
564 return commands.help_(ui, cmd, options['version'])
564 return commands.help_(ui, cmd, options['version'])
565 elif options['version']:
565 elif options['version']:
566 return commands.version_(ui)
566 return commands.version_(ui)
567 elif not cmd:
567 elif not cmd:
568 return commands.help_(ui, 'shortlist')
568 return commands.help_(ui, 'shortlist')
569
569
570 repo = None
570 repo = None
571 cmdpats = args[:]
571 cmdpats = args[:]
572 if cmd not in commands.norepo.split():
572 if cmd not in commands.norepo.split():
573 try:
573 try:
574 repo = hg.repository(ui, path=path)
574 repo = hg.repository(ui, path=path)
575 ui = repo.ui
575 ui = repo.ui
576 if not repo.local():
576 if not repo.local():
577 raise util.Abort(_("repository '%s' is not local") % path)
577 raise util.Abort(_("repository '%s' is not local") % path)
578 ui.setconfig("bundle", "mainreporoot", repo.root)
578 ui.setconfig("bundle", "mainreporoot", repo.root)
579 except error.RepoError:
579 except error.RepoError:
580 if cmd not in commands.optionalrepo.split():
580 if cmd not in commands.optionalrepo.split():
581 if args and not path: # try to infer -R from command args
581 if args and not path: # try to infer -R from command args
582 repos = map(cmdutil.findrepo, args)
582 repos = map(cmdutil.findrepo, args)
583 guess = repos[0]
583 guess = repos[0]
584 if guess and repos.count(guess) == len(repos):
584 if guess and repos.count(guess) == len(repos):
585 return _dispatch(ui, ['--repository', guess] + fullargs)
585 return _dispatch(ui, ['--repository', guess] + fullargs)
586 if not path:
586 if not path:
587 raise error.RepoError(_("There is no Mercurial repository"
587 raise error.RepoError(_("There is no Mercurial repository"
588 " here (.hg not found)"))
588 " here (.hg not found)"))
589 raise
589 raise
590 args.insert(0, repo)
590 args.insert(0, repo)
591 elif rpath:
591 elif rpath:
592 ui.warn(_("warning: --repository ignored\n"))
592 ui.warn(_("warning: --repository ignored\n"))
593
593
594 msg = ' '.join(' ' in a and repr(a) or a for a in fullargs)
594 msg = ' '.join(' ' in a and repr(a) or a for a in fullargs)
595 ui.log("command", msg + "\n")
595 ui.log("command", msg + "\n")
596 d = lambda: util.checksignature(func)(ui, *args, **cmdoptions)
596 d = lambda: util.checksignature(func)(ui, *args, **cmdoptions)
597 try:
597 try:
598 return runcommand(lui, repo, cmd, fullargs, ui, options, d,
598 return runcommand(lui, repo, cmd, fullargs, ui, options, d,
599 cmdpats, cmdoptions)
599 cmdpats, cmdoptions)
600 finally:
600 finally:
601 if repo:
601 if repo:
602 repo.close()
602 repo.close()
603
603
604 def _runcommand(ui, options, cmd, cmdfunc):
604 def _runcommand(ui, options, cmd, cmdfunc):
605 def checkargs():
605 def checkargs():
606 try:
606 try:
607 return cmdfunc()
607 return cmdfunc()
608 except error.SignatureError:
608 except error.SignatureError:
609 raise error.CommandError(cmd, _("invalid arguments"))
609 raise error.CommandError(cmd, _("invalid arguments"))
610
610
611 if options['profile']:
611 if options['profile']:
612 format = ui.config('profiling', 'format', default='text')
612 format = ui.config('profiling', 'format', default='text')
613
613
614 if not format in ['text', 'kcachegrind']:
614 if not format in ['text', 'kcachegrind']:
615 ui.warn(_("unrecognized profiling format '%s'"
615 ui.warn(_("unrecognized profiling format '%s'"
616 " - Ignored\n") % format)
616 " - Ignored\n") % format)
617 format = 'text'
617 format = 'text'
618
618
619 output = ui.config('profiling', 'output')
619 output = ui.config('profiling', 'output')
620
620
621 if output:
621 if output:
622 path = ui.expandpath(output)
622 path = ui.expandpath(output)
623 ostream = open(path, 'wb')
623 ostream = open(path, 'wb')
624 else:
624 else:
625 ostream = sys.stderr
625 ostream = sys.stderr
626
626
627 try:
627 try:
628 from mercurial import lsprof
628 from mercurial import lsprof
629 except ImportError:
629 except ImportError:
630 raise util.Abort(_(
630 raise util.Abort(_(
631 'lsprof not available - install from '
631 'lsprof not available - install from '
632 'http://codespeak.net/svn/user/arigo/hack/misc/lsprof/'))
632 'http://codespeak.net/svn/user/arigo/hack/misc/lsprof/'))
633 p = lsprof.Profiler()
633 p = lsprof.Profiler()
634 p.enable(subcalls=True)
634 p.enable(subcalls=True)
635 try:
635 try:
636 return checkargs()
636 return checkargs()
637 finally:
637 finally:
638 p.disable()
638 p.disable()
639
639
640 if format == 'kcachegrind':
640 if format == 'kcachegrind':
641 import lsprofcalltree
641 import lsprofcalltree
642 calltree = lsprofcalltree.KCacheGrind(p)
642 calltree = lsprofcalltree.KCacheGrind(p)
643 calltree.output(ostream)
643 calltree.output(ostream)
644 else:
644 else:
645 # format == 'text'
645 # format == 'text'
646 stats = lsprof.Stats(p.getstats())
646 stats = lsprof.Stats(p.getstats())
647 stats.sort()
647 stats.sort()
648 stats.pprint(top=10, file=ostream, climit=5)
648 stats.pprint(top=10, file=ostream, climit=5)
649
649
650 if output:
650 if output:
651 ostream.close()
651 ostream.close()
652 else:
652 else:
653 return checkargs()
653 return checkargs()
General Comments 0
You need to be logged in to leave comments. Login now