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