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