##// END OF EJS Templates
i18n: unmark untranslatable string
Wagner Bruna -
r12276:0c605364 default
parent child Browse files
Show More
@@ -1,593 +1,593 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, details follow\n"))
172 ui.warn(_("** unknown exception encountered, details follow\n"))
173 ui.warn(_("** report bug details to "
173 ui.warn(_("** report bug details to "
174 "http://mercurial.selenic.com/bts/\n"))
174 "http://mercurial.selenic.com/bts/\n"))
175 ui.warn(_("** or mercurial@selenic.com\n"))
175 ui.warn(_("** or mercurial@selenic.com\n"))
176 ui.warn(_("** Python %s\n") % sys.version.replace('\n', ''))
176 ui.warn(_("** Python %s\n") % sys.version.replace('\n', ''))
177 ui.warn(_("** Mercurial Distributed SCM (version %s)\n")
177 ui.warn(_("** Mercurial Distributed SCM (version %s)\n")
178 % util.version())
178 % util.version())
179 ui.warn(_("** Extensions loaded: %s\n")
179 ui.warn(_("** Extensions loaded: %s\n")
180 % ", ".join([x[0] for x in extensions.extensions()]))
180 % ", ".join([x[0] for x in extensions.extensions()]))
181 raise
181 raise
182
182
183 return -1
183 return -1
184
184
185 def aliasargs(fn):
185 def aliasargs(fn):
186 if hasattr(fn, 'args'):
186 if hasattr(fn, 'args'):
187 return fn.args
187 return fn.args
188 return []
188 return []
189
189
190 class cmdalias(object):
190 class cmdalias(object):
191 def __init__(self, name, definition, cmdtable):
191 def __init__(self, name, definition, cmdtable):
192 self.name = self.cmd = name
192 self.name = self.cmd = name
193 self.cmdname = ''
193 self.cmdname = ''
194 self.definition = definition
194 self.definition = definition
195 self.args = []
195 self.args = []
196 self.opts = []
196 self.opts = []
197 self.help = ''
197 self.help = ''
198 self.norepo = True
198 self.norepo = True
199 self.badalias = False
199 self.badalias = False
200
200
201 try:
201 try:
202 aliases, entry = cmdutil.findcmd(self.name, cmdtable)
202 aliases, entry = cmdutil.findcmd(self.name, cmdtable)
203 for alias, e in cmdtable.iteritems():
203 for alias, e in cmdtable.iteritems():
204 if e is entry:
204 if e is entry:
205 self.cmd = alias
205 self.cmd = alias
206 break
206 break
207 self.shadows = True
207 self.shadows = True
208 except error.UnknownCommand:
208 except error.UnknownCommand:
209 self.shadows = False
209 self.shadows = False
210
210
211 if not self.definition:
211 if not self.definition:
212 def fn(ui, *args):
212 def fn(ui, *args):
213 ui.warn(_("no definition for alias '%s'\n") % self.name)
213 ui.warn(_("no definition for alias '%s'\n") % self.name)
214 return 1
214 return 1
215 self.fn = fn
215 self.fn = fn
216 self.badalias = True
216 self.badalias = True
217
217
218 return
218 return
219
219
220 if self.definition.startswith('!'):
220 if self.definition.startswith('!'):
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 int(m.groups()[0]) <= len(args):
224 if int(m.groups()[0]) <= len(args):
225 return m.group()
225 return m.group()
226 else:
226 else:
227 return ''
227 return ''
228 cmd = re.sub(r'\$(\d+)', _checkvar, self.definition[1:])
228 cmd = re.sub(r'\$(\d+)', _checkvar, self.definition[1:])
229 replace = dict((str(i + 1), arg) for i, arg in enumerate(args))
229 replace = dict((str(i + 1), arg) for i, arg in enumerate(args))
230 replace['0'] = self.name
230 replace['0'] = self.name
231 replace['@'] = ' '.join(args)
231 replace['@'] = ' '.join(args)
232 cmd = util.interpolate(r'\$', replace, cmd)
232 cmd = util.interpolate(r'\$', replace, cmd)
233 return util.system(cmd, environ=env)
233 return util.system(cmd, environ=env)
234 self.fn = fn
234 self.fn = fn
235 return
235 return
236
236
237 args = shlex.split(self.definition)
237 args = shlex.split(self.definition)
238 self.cmdname = cmd = args.pop(0)
238 self.cmdname = cmd = args.pop(0)
239 args = map(util.expandpath, args)
239 args = map(util.expandpath, args)
240
240
241 for invalidarg in ("--cwd", "-R", "--repository", "--repo"):
241 for invalidarg in ("--cwd", "-R", "--repository", "--repo"):
242 if _earlygetopt([invalidarg], args):
242 if _earlygetopt([invalidarg], args):
243 def fn(ui, *args):
243 def fn(ui, *args):
244 ui.warn(_("error in definition for alias '%s': %s may only "
244 ui.warn(_("error in definition for alias '%s': %s may only "
245 "be given on the command line\n")
245 "be given on the command line\n")
246 % (self.name, invalidarg))
246 % (self.name, invalidarg))
247 return 1
247 return 1
248
248
249 self.fn = fn
249 self.fn = fn
250 self.badalias = True
250 self.badalias = True
251 return
251 return
252
252
253 try:
253 try:
254 tableentry = cmdutil.findcmd(cmd, cmdtable, False)[1]
254 tableentry = cmdutil.findcmd(cmd, cmdtable, False)[1]
255 if len(tableentry) > 2:
255 if len(tableentry) > 2:
256 self.fn, self.opts, self.help = tableentry
256 self.fn, self.opts, self.help = tableentry
257 else:
257 else:
258 self.fn, self.opts = tableentry
258 self.fn, self.opts = tableentry
259
259
260 self.args = aliasargs(self.fn) + args
260 self.args = aliasargs(self.fn) + args
261 if cmd not in commands.norepo.split(' '):
261 if cmd not in commands.norepo.split(' '):
262 self.norepo = False
262 self.norepo = False
263 if self.help.startswith("hg " + cmd):
263 if self.help.startswith("hg " + cmd):
264 # drop prefix in old-style help lines so hg shows the alias
264 # drop prefix in old-style help lines so hg shows the alias
265 self.help = self.help[4 + len(cmd):]
265 self.help = self.help[4 + len(cmd):]
266 self.__doc__ = self.fn.__doc__
266 self.__doc__ = self.fn.__doc__
267
267
268 except error.UnknownCommand:
268 except error.UnknownCommand:
269 def fn(ui, *args):
269 def fn(ui, *args):
270 ui.warn(_("alias '%s' resolves to unknown command '%s'\n") \
270 ui.warn(_("alias '%s' resolves to unknown command '%s'\n") \
271 % (self.name, cmd))
271 % (self.name, cmd))
272 try:
272 try:
273 # check if the command is in a disabled extension
273 # check if the command is in a disabled extension
274 commands.help_(ui, cmd, unknowncmd=True)
274 commands.help_(ui, cmd, unknowncmd=True)
275 except error.UnknownCommand:
275 except error.UnknownCommand:
276 pass
276 pass
277 return 1
277 return 1
278 self.fn = fn
278 self.fn = fn
279 self.badalias = True
279 self.badalias = True
280 except error.AmbiguousCommand:
280 except error.AmbiguousCommand:
281 def fn(ui, *args):
281 def fn(ui, *args):
282 ui.warn(_("alias '%s' resolves to ambiguous command '%s'\n") \
282 ui.warn(_("alias '%s' resolves to ambiguous command '%s'\n") \
283 % (self.name, cmd))
283 % (self.name, cmd))
284 return 1
284 return 1
285 self.fn = fn
285 self.fn = fn
286 self.badalias = True
286 self.badalias = True
287
287
288 def __call__(self, ui, *args, **opts):
288 def __call__(self, ui, *args, **opts):
289 if self.shadows:
289 if self.shadows:
290 ui.debug("alias '%s' shadows command '%s'\n" %
290 ui.debug("alias '%s' shadows command '%s'\n" %
291 (self.name, self.cmdname))
291 (self.name, self.cmdname))
292
292
293 if self.definition.startswith('!'):
293 if self.definition.startswith('!'):
294 return self.fn(ui, *args, **opts)
294 return self.fn(ui, *args, **opts)
295 else:
295 else:
296 try:
296 try:
297 util.checksignature(self.fn)(ui, *args, **opts)
297 util.checksignature(self.fn)(ui, *args, **opts)
298 except error.SignatureError:
298 except error.SignatureError:
299 args = ' '.join([self.cmdname] + self.args)
299 args = ' '.join([self.cmdname] + self.args)
300 ui.debug("alias '%s' expands to '%s'\n" % (self.name, args))
300 ui.debug("alias '%s' expands to '%s'\n" % (self.name, args))
301 raise
301 raise
302
302
303 def addaliases(ui, cmdtable):
303 def addaliases(ui, cmdtable):
304 # aliases are processed after extensions have been loaded, so they
304 # aliases are processed after extensions have been loaded, so they
305 # may use extension commands. Aliases can also use other alias definitions,
305 # may use extension commands. Aliases can also use other alias definitions,
306 # but only if they have been defined prior to the current definition.
306 # but only if they have been defined prior to the current definition.
307 for alias, definition in ui.configitems('alias'):
307 for alias, definition in ui.configitems('alias'):
308 aliasdef = cmdalias(alias, definition, cmdtable)
308 aliasdef = cmdalias(alias, definition, cmdtable)
309 cmdtable[aliasdef.cmd] = (aliasdef, aliasdef.opts, aliasdef.help)
309 cmdtable[aliasdef.cmd] = (aliasdef, aliasdef.opts, aliasdef.help)
310 if aliasdef.norepo:
310 if aliasdef.norepo:
311 commands.norepo += ' %s' % alias
311 commands.norepo += ' %s' % alias
312
312
313 def _parse(ui, args):
313 def _parse(ui, args):
314 options = {}
314 options = {}
315 cmdoptions = {}
315 cmdoptions = {}
316
316
317 try:
317 try:
318 args = fancyopts.fancyopts(args, commands.globalopts, options)
318 args = fancyopts.fancyopts(args, commands.globalopts, options)
319 except fancyopts.getopt.GetoptError, inst:
319 except fancyopts.getopt.GetoptError, inst:
320 raise error.CommandError(None, inst)
320 raise error.CommandError(None, inst)
321
321
322 if args:
322 if args:
323 cmd, args = args[0], args[1:]
323 cmd, args = args[0], args[1:]
324 aliases, entry = cmdutil.findcmd(cmd, commands.table,
324 aliases, entry = cmdutil.findcmd(cmd, commands.table,
325 ui.config("ui", "strict"))
325 ui.config("ui", "strict"))
326 cmd = aliases[0]
326 cmd = aliases[0]
327 args = aliasargs(entry[0]) + args
327 args = aliasargs(entry[0]) + args
328 defaults = ui.config("defaults", cmd)
328 defaults = ui.config("defaults", cmd)
329 if defaults:
329 if defaults:
330 args = map(util.expandpath, shlex.split(defaults)) + args
330 args = map(util.expandpath, shlex.split(defaults)) + args
331 c = list(entry[1])
331 c = list(entry[1])
332 else:
332 else:
333 cmd = None
333 cmd = None
334 c = []
334 c = []
335
335
336 # combine global options into local
336 # combine global options into local
337 for o in commands.globalopts:
337 for o in commands.globalopts:
338 c.append((o[0], o[1], options[o[1]], o[3]))
338 c.append((o[0], o[1], options[o[1]], o[3]))
339
339
340 try:
340 try:
341 args = fancyopts.fancyopts(args, c, cmdoptions, True)
341 args = fancyopts.fancyopts(args, c, cmdoptions, True)
342 except fancyopts.getopt.GetoptError, inst:
342 except fancyopts.getopt.GetoptError, inst:
343 raise error.CommandError(cmd, inst)
343 raise error.CommandError(cmd, inst)
344
344
345 # separate global options back out
345 # separate global options back out
346 for o in commands.globalopts:
346 for o in commands.globalopts:
347 n = o[1]
347 n = o[1]
348 options[n] = cmdoptions[n]
348 options[n] = cmdoptions[n]
349 del cmdoptions[n]
349 del cmdoptions[n]
350
350
351 return (cmd, cmd and entry[0] or None, args, options, cmdoptions)
351 return (cmd, cmd and entry[0] or None, args, options, cmdoptions)
352
352
353 def _parseconfig(ui, config):
353 def _parseconfig(ui, config):
354 """parse the --config options from the command line"""
354 """parse the --config options from the command line"""
355 for cfg in config:
355 for cfg in config:
356 try:
356 try:
357 name, value = cfg.split('=', 1)
357 name, value = cfg.split('=', 1)
358 section, name = name.split('.', 1)
358 section, name = name.split('.', 1)
359 if not section or not name:
359 if not section or not name:
360 raise IndexError
360 raise IndexError
361 ui.setconfig(section, name, value)
361 ui.setconfig(section, name, value)
362 except (IndexError, ValueError):
362 except (IndexError, ValueError):
363 raise util.Abort(_('malformed --config option: %r '
363 raise util.Abort(_('malformed --config option: %r '
364 '(use --config section.name=value)') % cfg)
364 '(use --config section.name=value)') % cfg)
365
365
366 def _earlygetopt(aliases, args):
366 def _earlygetopt(aliases, args):
367 """Return list of values for an option (or aliases).
367 """Return list of values for an option (or aliases).
368
368
369 The values are listed in the order they appear in args.
369 The values are listed in the order they appear in args.
370 The options and values are removed from args.
370 The options and values are removed from args.
371 """
371 """
372 try:
372 try:
373 argcount = args.index("--")
373 argcount = args.index("--")
374 except ValueError:
374 except ValueError:
375 argcount = len(args)
375 argcount = len(args)
376 shortopts = [opt for opt in aliases if len(opt) == 2]
376 shortopts = [opt for opt in aliases if len(opt) == 2]
377 values = []
377 values = []
378 pos = 0
378 pos = 0
379 while pos < argcount:
379 while pos < argcount:
380 if args[pos] in aliases:
380 if args[pos] in aliases:
381 if pos + 1 >= argcount:
381 if pos + 1 >= argcount:
382 # ignore and let getopt report an error if there is no value
382 # ignore and let getopt report an error if there is no value
383 break
383 break
384 del args[pos]
384 del args[pos]
385 values.append(args.pop(pos))
385 values.append(args.pop(pos))
386 argcount -= 2
386 argcount -= 2
387 elif args[pos][:2] in shortopts:
387 elif args[pos][:2] in shortopts:
388 # short option can have no following space, e.g. hg log -Rfoo
388 # short option can have no following space, e.g. hg log -Rfoo
389 values.append(args.pop(pos)[2:])
389 values.append(args.pop(pos)[2:])
390 argcount -= 1
390 argcount -= 1
391 else:
391 else:
392 pos += 1
392 pos += 1
393 return values
393 return values
394
394
395 def runcommand(lui, repo, cmd, fullargs, ui, options, d, cmdpats, cmdoptions):
395 def runcommand(lui, repo, cmd, fullargs, ui, options, d, cmdpats, cmdoptions):
396 # run pre-hook, and abort if it fails
396 # run pre-hook, and abort if it fails
397 ret = hook.hook(lui, repo, "pre-%s" % cmd, False, args=" ".join(fullargs),
397 ret = hook.hook(lui, repo, "pre-%s" % cmd, False, args=" ".join(fullargs),
398 pats=cmdpats, opts=cmdoptions)
398 pats=cmdpats, opts=cmdoptions)
399 if ret:
399 if ret:
400 return ret
400 return ret
401 ret = _runcommand(ui, options, cmd, d)
401 ret = _runcommand(ui, options, cmd, d)
402 # run post-hook, passing command result
402 # run post-hook, passing command result
403 hook.hook(lui, repo, "post-%s" % cmd, False, args=" ".join(fullargs),
403 hook.hook(lui, repo, "post-%s" % cmd, False, args=" ".join(fullargs),
404 result=ret, pats=cmdpats, opts=cmdoptions)
404 result=ret, pats=cmdpats, opts=cmdoptions)
405 return ret
405 return ret
406
406
407 _loaded = set()
407 _loaded = set()
408 def _dispatch(ui, args):
408 def _dispatch(ui, args):
409 # read --config before doing anything else
409 # read --config before doing anything else
410 # (e.g. to change trust settings for reading .hg/hgrc)
410 # (e.g. to change trust settings for reading .hg/hgrc)
411 _parseconfig(ui, _earlygetopt(['--config'], args))
411 _parseconfig(ui, _earlygetopt(['--config'], args))
412
412
413 # check for cwd
413 # check for cwd
414 cwd = _earlygetopt(['--cwd'], args)
414 cwd = _earlygetopt(['--cwd'], args)
415 if cwd:
415 if cwd:
416 os.chdir(cwd[-1])
416 os.chdir(cwd[-1])
417
417
418 # read the local repository .hgrc into a local ui object
418 # read the local repository .hgrc into a local ui object
419 try:
419 try:
420 wd = os.getcwd()
420 wd = os.getcwd()
421 except OSError, e:
421 except OSError, e:
422 raise util.Abort(_("error getting current working directory: %s") %
422 raise util.Abort(_("error getting current working directory: %s") %
423 e.strerror)
423 e.strerror)
424 path = cmdutil.findrepo(wd) or ""
424 path = cmdutil.findrepo(wd) or ""
425 if not path:
425 if not path:
426 lui = ui
426 lui = ui
427 else:
427 else:
428 try:
428 try:
429 lui = ui.copy()
429 lui = ui.copy()
430 lui.readconfig(os.path.join(path, ".hg", "hgrc"))
430 lui.readconfig(os.path.join(path, ".hg", "hgrc"))
431 except IOError:
431 except IOError:
432 pass
432 pass
433
433
434 # now we can expand paths, even ones in .hg/hgrc
434 # now we can expand paths, even ones in .hg/hgrc
435 rpath = _earlygetopt(["-R", "--repository", "--repo"], args)
435 rpath = _earlygetopt(["-R", "--repository", "--repo"], args)
436 if rpath:
436 if rpath:
437 path = lui.expandpath(rpath[-1])
437 path = lui.expandpath(rpath[-1])
438 lui = ui.copy()
438 lui = ui.copy()
439 lui.readconfig(os.path.join(path, ".hg", "hgrc"))
439 lui.readconfig(os.path.join(path, ".hg", "hgrc"))
440
440
441 # Configure extensions in phases: uisetup, extsetup, cmdtable, and
441 # Configure extensions in phases: uisetup, extsetup, cmdtable, and
442 # reposetup. Programs like TortoiseHg will call _dispatch several
442 # reposetup. Programs like TortoiseHg will call _dispatch several
443 # times so we keep track of configured extensions in _loaded.
443 # times so we keep track of configured extensions in _loaded.
444 extensions.loadall(lui)
444 extensions.loadall(lui)
445 exts = [ext for ext in extensions.extensions() if ext[0] not in _loaded]
445 exts = [ext for ext in extensions.extensions() if ext[0] not in _loaded]
446 # Propagate any changes to lui.__class__ by extensions
446 # Propagate any changes to lui.__class__ by extensions
447 ui.__class__ = lui.__class__
447 ui.__class__ = lui.__class__
448
448
449 # (uisetup and extsetup are handled in extensions.loadall)
449 # (uisetup and extsetup are handled in extensions.loadall)
450
450
451 for name, module in exts:
451 for name, module in exts:
452 cmdtable = getattr(module, 'cmdtable', {})
452 cmdtable = getattr(module, 'cmdtable', {})
453 overrides = [cmd for cmd in cmdtable if cmd in commands.table]
453 overrides = [cmd for cmd in cmdtable if cmd in commands.table]
454 if overrides:
454 if overrides:
455 ui.warn(_("extension '%s' overrides commands: %s\n")
455 ui.warn(_("extension '%s' overrides commands: %s\n")
456 % (name, " ".join(overrides)))
456 % (name, " ".join(overrides)))
457 commands.table.update(cmdtable)
457 commands.table.update(cmdtable)
458 _loaded.add(name)
458 _loaded.add(name)
459
459
460 # (reposetup is handled in hg.repository)
460 # (reposetup is handled in hg.repository)
461
461
462 addaliases(lui, commands.table)
462 addaliases(lui, commands.table)
463
463
464 # check for fallback encoding
464 # check for fallback encoding
465 fallback = lui.config('ui', 'fallbackencoding')
465 fallback = lui.config('ui', 'fallbackencoding')
466 if fallback:
466 if fallback:
467 encoding.fallbackencoding = fallback
467 encoding.fallbackencoding = fallback
468
468
469 fullargs = args
469 fullargs = args
470 cmd, func, args, options, cmdoptions = _parse(lui, args)
470 cmd, func, args, options, cmdoptions = _parse(lui, args)
471
471
472 if options["config"]:
472 if options["config"]:
473 raise util.Abort(_("option --config may not be abbreviated!"))
473 raise util.Abort(_("option --config may not be abbreviated!"))
474 if options["cwd"]:
474 if options["cwd"]:
475 raise util.Abort(_("option --cwd may not be abbreviated!"))
475 raise util.Abort(_("option --cwd may not be abbreviated!"))
476 if options["repository"]:
476 if options["repository"]:
477 raise util.Abort(_(
477 raise util.Abort(_(
478 "Option -R has to be separated from other options (e.g. not -qR) "
478 "Option -R has to be separated from other options (e.g. not -qR) "
479 "and --repository may only be abbreviated as --repo!"))
479 "and --repository may only be abbreviated as --repo!"))
480
480
481 if options["encoding"]:
481 if options["encoding"]:
482 encoding.encoding = options["encoding"]
482 encoding.encoding = options["encoding"]
483 if options["encodingmode"]:
483 if options["encodingmode"]:
484 encoding.encodingmode = options["encodingmode"]
484 encoding.encodingmode = options["encodingmode"]
485 if options["time"]:
485 if options["time"]:
486 def get_times():
486 def get_times():
487 t = os.times()
487 t = os.times()
488 if t[4] == 0.0: # Windows leaves this as zero, so use time.clock()
488 if t[4] == 0.0: # Windows leaves this as zero, so use time.clock()
489 t = (t[0], t[1], t[2], t[3], time.clock())
489 t = (t[0], t[1], t[2], t[3], time.clock())
490 return t
490 return t
491 s = get_times()
491 s = get_times()
492 def print_time():
492 def print_time():
493 t = get_times()
493 t = get_times()
494 ui.warn(_("Time: real %.3f secs (user %.3f+%.3f sys %.3f+%.3f)\n") %
494 ui.warn(_("Time: real %.3f secs (user %.3f+%.3f sys %.3f+%.3f)\n") %
495 (t[4]-s[4], t[0]-s[0], t[2]-s[2], t[1]-s[1], t[3]-s[3]))
495 (t[4]-s[4], t[0]-s[0], t[2]-s[2], t[1]-s[1], t[3]-s[3]))
496 atexit.register(print_time)
496 atexit.register(print_time)
497
497
498 if options['verbose'] or options['debug'] or options['quiet']:
498 if options['verbose'] or options['debug'] or options['quiet']:
499 ui.setconfig('ui', 'verbose', str(bool(options['verbose'])))
499 ui.setconfig('ui', 'verbose', str(bool(options['verbose'])))
500 ui.setconfig('ui', 'debug', str(bool(options['debug'])))
500 ui.setconfig('ui', 'debug', str(bool(options['debug'])))
501 ui.setconfig('ui', 'quiet', str(bool(options['quiet'])))
501 ui.setconfig('ui', 'quiet', str(bool(options['quiet'])))
502 if options['traceback']:
502 if options['traceback']:
503 ui.setconfig('ui', 'traceback', 'on')
503 ui.setconfig('ui', 'traceback', 'on')
504 if options['noninteractive']:
504 if options['noninteractive']:
505 ui.setconfig('ui', 'interactive', 'off')
505 ui.setconfig('ui', 'interactive', 'off')
506
506
507 if options['help']:
507 if options['help']:
508 return commands.help_(ui, cmd, options['version'])
508 return commands.help_(ui, cmd, options['version'])
509 elif options['version']:
509 elif options['version']:
510 return commands.version_(ui)
510 return commands.version_(ui)
511 elif not cmd:
511 elif not cmd:
512 return commands.help_(ui, 'shortlist')
512 return commands.help_(ui, 'shortlist')
513
513
514 repo = None
514 repo = None
515 cmdpats = args[:]
515 cmdpats = args[:]
516 if cmd not in commands.norepo.split():
516 if cmd not in commands.norepo.split():
517 try:
517 try:
518 repo = hg.repository(ui, path=path)
518 repo = hg.repository(ui, path=path)
519 ui = repo.ui
519 ui = repo.ui
520 if not repo.local():
520 if not repo.local():
521 raise util.Abort(_("repository '%s' is not local") % path)
521 raise util.Abort(_("repository '%s' is not local") % path)
522 ui.setconfig("bundle", "mainreporoot", repo.root)
522 ui.setconfig("bundle", "mainreporoot", repo.root)
523 except error.RepoError:
523 except error.RepoError:
524 if cmd not in commands.optionalrepo.split():
524 if cmd not in commands.optionalrepo.split():
525 if args and not path: # try to infer -R from command args
525 if args and not path: # try to infer -R from command args
526 repos = map(cmdutil.findrepo, args)
526 repos = map(cmdutil.findrepo, args)
527 guess = repos[0]
527 guess = repos[0]
528 if guess and repos.count(guess) == len(repos):
528 if guess and repos.count(guess) == len(repos):
529 return _dispatch(ui, ['--repository', guess] + fullargs)
529 return _dispatch(ui, ['--repository', guess] + fullargs)
530 if not path:
530 if not path:
531 raise error.RepoError(_("There is no Mercurial repository"
531 raise error.RepoError(_("There is no Mercurial repository"
532 " here (.hg not found)"))
532 " here (.hg not found)"))
533 raise
533 raise
534 args.insert(0, repo)
534 args.insert(0, repo)
535 elif rpath:
535 elif rpath:
536 ui.warn(_("warning: --repository ignored\n"))
536 ui.warn(_("warning: --repository ignored\n"))
537
537
538 msg = ' '.join(' ' in a and repr(a) or a for a in fullargs)
538 msg = ' '.join(' ' in a and repr(a) or a for a in fullargs)
539 ui.log("command", msg + "\n")
539 ui.log("command", msg + "\n")
540 d = lambda: util.checksignature(func)(ui, *args, **cmdoptions)
540 d = lambda: util.checksignature(func)(ui, *args, **cmdoptions)
541 return runcommand(lui, repo, cmd, fullargs, ui, options, d,
541 return runcommand(lui, repo, cmd, fullargs, ui, options, d,
542 cmdpats, cmdoptions)
542 cmdpats, cmdoptions)
543
543
544 def _runcommand(ui, options, cmd, cmdfunc):
544 def _runcommand(ui, options, cmd, cmdfunc):
545 def checkargs():
545 def checkargs():
546 try:
546 try:
547 return cmdfunc()
547 return cmdfunc()
548 except error.SignatureError:
548 except error.SignatureError:
549 raise error.CommandError(cmd, _("invalid arguments"))
549 raise error.CommandError(cmd, _("invalid arguments"))
550
550
551 if options['profile']:
551 if options['profile']:
552 format = ui.config('profiling', 'format', default='text')
552 format = ui.config('profiling', 'format', default='text')
553
553
554 if not format in ['text', 'kcachegrind']:
554 if not format in ['text', 'kcachegrind']:
555 ui.warn(_("unrecognized profiling format '%s'"
555 ui.warn(_("unrecognized profiling format '%s'"
556 " - Ignored\n") % format)
556 " - Ignored\n") % format)
557 format = 'text'
557 format = 'text'
558
558
559 output = ui.config('profiling', 'output')
559 output = ui.config('profiling', 'output')
560
560
561 if output:
561 if output:
562 path = ui.expandpath(output)
562 path = ui.expandpath(output)
563 ostream = open(path, 'wb')
563 ostream = open(path, 'wb')
564 else:
564 else:
565 ostream = sys.stderr
565 ostream = sys.stderr
566
566
567 try:
567 try:
568 from mercurial import lsprof
568 from mercurial import lsprof
569 except ImportError:
569 except ImportError:
570 raise util.Abort(_(
570 raise util.Abort(_(
571 'lsprof not available - install from '
571 'lsprof not available - install from '
572 'http://codespeak.net/svn/user/arigo/hack/misc/lsprof/'))
572 'http://codespeak.net/svn/user/arigo/hack/misc/lsprof/'))
573 p = lsprof.Profiler()
573 p = lsprof.Profiler()
574 p.enable(subcalls=True)
574 p.enable(subcalls=True)
575 try:
575 try:
576 return checkargs()
576 return checkargs()
577 finally:
577 finally:
578 p.disable()
578 p.disable()
579
579
580 if format == 'kcachegrind':
580 if format == 'kcachegrind':
581 import lsprofcalltree
581 import lsprofcalltree
582 calltree = lsprofcalltree.KCacheGrind(p)
582 calltree = lsprofcalltree.KCacheGrind(p)
583 calltree.output(ostream)
583 calltree.output(ostream)
584 else:
584 else:
585 # format == 'text'
585 # format == 'text'
586 stats = lsprof.Stats(p.getstats())
586 stats = lsprof.Stats(p.getstats())
587 stats.sort()
587 stats.sort()
588 stats.pprint(top=10, file=ostream, climit=5)
588 stats.pprint(top=10, file=ostream, climit=5)
589
589
590 if output:
590 if output:
591 ostream.close()
591 ostream.close()
592 else:
592 else:
593 return checkargs()
593 return checkargs()
General Comments 0
You need to be logged in to leave comments. Login now