##// END OF EJS Templates
merge with stable
merge with stable

File last commit:

r16279:531e69ff merge default
r16291:9952ac7e merge default
Show More
dispatch.py
741 lines | 25.4 KiB | text/x-python | PythonLexer
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 # dispatch.py - command dispatching for mercurial
#
# Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
#
Martin Geisler
updated license to be explicit about GPL version 2
r8225 # This software may be used and distributed according to the terms of the
Matt Mackall
Update license to GPLv2+
r10263 # GNU General Public License version 2 or any later version.
Matt Mackall
dispatch: move command dispatching into its own module...
r5178
from i18n import _
Steve Losh
aliases: provide more flexible ways to work with shell alias arguments...
r11989 import os, sys, atexit, signal, pdb, socket, errno, shlex, time, traceback, re
Peter Arrenbrecht
cleanup: drop unused imports
r7873 import util, commands, hg, fancyopts, extensions, hook, error
Matt Mackall
move encoding bits from util to encoding...
r7948 import cmdutil, encoding
Benoit Boissinot
style: use consistent variable names (*mod) with imports which would shadow
r10651 import ui as uimod
Matt Mackall
dispatch: move command dispatching into its own module...
r5178
Idan Kamara
dispatch: wrap dispatch related information in a request class...
r14438 class request(object):
Idan Kamara
dispatch: add I/O descriptors to the request
r14613 def __init__(self, args, ui=None, repo=None, fin=None, fout=None, ferr=None):
Idan Kamara
dispatch: wrap dispatch related information in a request class...
r14438 self.args = args
Idan Kamara
dispatch: use the request to store the ui object...
r14439 self.ui = ui
Idan Kamara
dispatch: add repo to the request...
r14510 self.repo = repo
Idan Kamara
dispatch: wrap dispatch related information in a request class...
r14438
Idan Kamara
dispatch: add I/O descriptors to the request
r14613 # input/output/error streams
self.fin = fin
self.fout = fout
self.ferr = ferr
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 def run():
"run the command in sys.argv"
Mads Kiilerich
dispatch: exit with 8-bit exit code...
r15439 sys.exit((dispatch(request(sys.argv[1:])) or 0) & 255)
Matt Mackall
dispatch: move command dispatching into its own module...
r5178
Idan Kamara
dispatch: wrap dispatch related information in a request class...
r14438 def dispatch(req):
"run the command specified in req.args"
Idan Kamara
dispatch: assign I/O descriptors from the request to the ui
r14615 if req.ferr:
ferr = req.ferr
elif req.ui:
ferr = req.ui.ferr
else:
ferr = sys.stderr
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 try:
Idan Kamara
dispatch: use the request to store the ui object...
r14439 if not req.ui:
req.ui = uimod.ui()
Idan Kamara
dispatch: wrap dispatch related information in a request class...
r14438 if '--traceback' in req.args:
Idan Kamara
dispatch: use the request to store the ui object...
r14439 req.ui.setconfig('ui', 'traceback', 'on')
Idan Kamara
dispatch: assign I/O descriptors from the request to the ui
r14615
# set ui streams from the request
if req.fin:
req.ui.fin = req.fin
if req.fout:
req.ui.fout = req.fout
if req.ferr:
req.ui.ferr = req.ferr
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 except util.Abort, inst:
Idan Kamara
dispatch: assign I/O descriptors from the request to the ui
r14615 ferr.write(_("abort: %s\n") % inst)
Benoit Boissinot
Abort: add a hint argument, printed in the next line inside parenthesis...
r11574 if inst.hint:
Idan Kamara
dispatch: assign I/O descriptors from the request to the ui
r14615 ferr.write(_("(%s)\n") % inst.hint)
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 return -1
Matt Mackall
error: add new ParseError for various parsing errors
r11288 except error.ParseError, inst:
if len(inst.args) > 1:
Idan Kamara
dispatch: assign I/O descriptors from the request to the ui
r14615 ferr.write(_("hg: parse error at %s: %s\n") %
Matt Mackall
error: add new ParseError for various parsing errors
r11288 (inst.args[1], inst.args[0]))
else:
Idan Kamara
dispatch: assign I/O descriptors from the request to the ui
r14615 ferr.write(_("hg: parse error: %s\n") % inst.args[0])
Martin Geisler
dispatch: catch ConfigError while constructing ui
r9470 return -1
Idan Kamara
dispatch: assign I/O descriptors from the request to the ui
r14615
Idan Kamara
dispatch: use the request to store the ui object...
r14439 return _runcatch(req)
Matt Mackall
dispatch: move command dispatching into its own module...
r5178
Idan Kamara
dispatch: use the request to store the ui object...
r14439 def _runcatch(req):
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 def catchterm(*args):
Matt Mackall
error: move SignalInterrupt...
r7644 raise error.SignalInterrupt
Matt Mackall
dispatch: move command dispatching into its own module...
r5178
Idan Kamara
dispatch: use the request to store the ui object...
r14439 ui = req.ui
Simon Heimberg
dispatch: ignore if signals can not be set...
r10952 try:
for name in 'SIGBREAK', 'SIGHUP', 'SIGTERM':
num = getattr(signal, name, None)
if num:
signal.signal(num, catchterm)
except ValueError:
pass # happens if called in a thread
Matt Mackall
dispatch: move command dispatching into its own module...
r5178
try:
try:
# enter the debugger before command execution
Idan Kamara
dispatch: wrap dispatch related information in a request class...
r14438 if '--debugger' in req.args:
Mads Kiilerich
debugger: give a little intro before entering pdb
r11495 ui.warn(_("entering debugger - "
"type c to continue starting hg or h for help\n"))
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 pdb.set_trace()
try:
Idan Kamara
dispatch: use the request to store the ui object...
r14439 return _dispatch(req)
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 finally:
ui.flush()
except:
# enter the debugger when we hit an exception
Idan Kamara
dispatch: wrap dispatch related information in a request class...
r14438 if '--debugger' in req.args:
Mads Kiilerich
debugger: show traceback before entering pdb post-mortem
r11494 traceback.print_exc()
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 pdb.post_mortem(sys.exc_info()[2])
Matt Mackall
ui: print_exc() -> traceback()
r8206 ui.traceback()
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 raise
Matt Mackall
dispatch: sort exception handlers
r7645 # Global exception handling, alphabetically
# Mercurial-specific first, followed by built-in and library exceptions
Matt Mackall
error: move UnknownCommand and AmbiguousCommand
r7643 except error.AmbiguousCommand, inst:
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 ui.warn(_("hg: command '%s' is ambiguous:\n %s\n") %
(inst.args[0], " ".join(inst.args[1])))
Matt Mackall
error: add new ParseError for various parsing errors
r11288 except error.ParseError, inst:
if len(inst.args) > 1:
ui.warn(_("hg: parse error at %s: %s\n") %
(inst.args[1], inst.args[0]))
else:
ui.warn(_("hg: parse error: %s\n") % inst.args[0])
return -1
Matt Mackall
error: move lock errors...
r7640 except error.LockHeld, inst:
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 if inst.errno == errno.ETIMEDOUT:
reason = _('timed out waiting for lock held by %s') % inst.locker
else:
reason = _('lock held by %s') % inst.locker
ui.warn(_("abort: %s: %s\n") % (inst.desc or inst.filename, reason))
Matt Mackall
error: move lock errors...
r7640 except error.LockUnavailable, inst:
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 ui.warn(_("abort: could not lock %s: %s\n") %
(inst.desc or inst.filename, inst.strerror))
Matt Mackall
error: change ParseError to CommandError
r11287 except error.CommandError, inst:
Matt Mackall
dispatch: sort exception handlers
r7645 if inst.args[0]:
ui.warn(_("hg %s: %s\n") % (inst.args[0], inst.args[1]))
Martin Geisler
help: add -c/--command flag to only show command help (issue2799)
r14286 commands.help_(ui, inst.args[0], full=False, command=True)
Matt Mackall
dispatch: sort exception handlers
r7645 else:
ui.warn(_("hg: %s\n") % inst.args[1])
commands.help_(ui, 'shortlist')
Andrew Pritchard
wireproto: add out-of-band error class to allow remote repo to report errors...
r15017 except error.OutOfBandError, inst:
Mads Kiilerich
add missing localization markup
r15497 ui.warn(_("abort: remote error:\n"))
Andrew Pritchard
wireproto: add out-of-band error class to allow remote repo to report errors...
r15017 ui.warn(''.join(inst.args))
Matt Mackall
dispatch: sort exception handlers
r7645 except error.RepoError, inst:
ui.warn(_("abort: %s!\n") % inst)
Pierre-Yves David
error: Add a hint argument to RepoError...
r14761 if inst.hint:
ui.warn(_("(%s)\n") % inst.hint)
Matt Mackall
dispatch: sort exception handlers
r7645 except error.ResponseError, inst:
ui.warn(_("abort: %s") % inst.args[0])
if not isinstance(inst.args[1], basestring):
ui.warn(" %r\n" % (inst.args[1],))
elif not inst.args[1]:
ui.warn(_(" empty string\n"))
else:
ui.warn("\n%r\n" % util.ellipsis(inst.args[1]))
Matt Mackall
errors: move revlog errors...
r7633 except error.RevlogError, inst:
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 ui.warn(_("abort: %s!\n") % inst)
Matt Mackall
error: move SignalInterrupt...
r7644 except error.SignalInterrupt:
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 ui.warn(_("killed!\n"))
Matt Mackall
dispatch: sort exception handlers
r7645 except error.UnknownCommand, inst:
ui.warn(_("hg: unknown command '%s'\n") % inst.args[0])
Brodie Rao
dispatch: provide help for disabled extensions and commands...
r10364 try:
# check if the command is in a disabled extension
# (but don't check for extensions themselves)
commands.help_(ui, inst.args[0], unknowncmd=True)
except error.UnknownCommand:
commands.help_(ui, 'shortlist')
Matt Mackall
dispatch: sort exception handlers
r7645 except util.Abort, inst:
ui.warn(_("abort: %s\n") % inst)
Benoit Boissinot
Abort: add a hint argument, printed in the next line inside parenthesis...
r11574 if inst.hint:
Patrick Mezard
dispatch: write Abort hint to stderr too
r11683 ui.warn(_("(%s)\n") % inst.hint)
Matt Mackall
dispatch: sort exception handlers
r7645 except ImportError, inst:
Dan Villiom Podlaski Christiansen
dispatch: don't mangle ImportError abort messages...
r11053 ui.warn(_("abort: %s!\n") % inst)
Matt Mackall
dispatch: sort exception handlers
r7645 m = str(inst).split()[-1]
if m in "mpatch bdiff".split():
ui.warn(_("(did you forget to compile extensions?)\n"))
elif m in "zlib".split():
ui.warn(_("(is your Python install correct?)\n"))
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 except IOError, inst:
Augie Fackler
dispatch: use safehasattr instead of hasattr
r14950 if util.safehasattr(inst, "code"):
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 ui.warn(_("abort: %s\n") % inst)
Augie Fackler
dispatch: use safehasattr instead of hasattr
r14950 elif util.safehasattr(inst, "reason"):
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 try: # usually it is in the form (errno, strerror)
reason = inst.reason.args[1]
Dan Villiom Podlaski Christiansen
dispatch: handle IndexErrors
r14096 except (AttributeError, IndexError):
# it might be anything, for example a string
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 reason = inst.reason
ui.warn(_("abort: error: %s\n") % reason)
Augie Fackler
dispatch: use safehasattr instead of hasattr
r14950 elif util.safehasattr(inst, "args") and inst.args[0] == errno.EPIPE:
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 if ui.debugflag:
ui.warn(_("broken pipe\n"))
elif getattr(inst, "strerror", None):
if getattr(inst, "filename", None):
ui.warn(_("abort: %s: %s\n") % (inst.strerror, inst.filename))
else:
ui.warn(_("abort: %s\n") % inst.strerror)
else:
raise
except OSError, inst:
if getattr(inst, "filename", None):
ui.warn(_("abort: %s: %s\n") % (inst.strerror, inst.filename))
else:
ui.warn(_("abort: %s\n") % inst.strerror)
Matt Mackall
dispatch: sort exception handlers
r7645 except KeyboardInterrupt:
try:
ui.warn(_("interrupted!\n"))
except IOError, inst:
if inst.errno == errno.EPIPE:
if ui.debugflag:
ui.warn(_("\nbroken pipe\n"))
else:
raise
Matt Mackall
dispatch: report OOM rather than traceback
r5633 except MemoryError:
ui.warn(_("abort: out of memory\n"))
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 except SystemExit, inst:
# Commands shouldn't sys.exit directly, but give a return code.
# Just in case catch this and and pass exit code to caller.
return inst.code
Matt Mackall
dispatch: sort exception handlers
r7645 except socket.error, inst:
ui.warn(_("abort: %s\n") % inst.args[-1])
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 except:
Matt Mackall
traceback: point to BugTracker on the wiki
r12831 ui.warn(_("** unknown exception encountered,"
" please report by visiting\n"))
ui.warn(_("** http://mercurial.selenic.com/wiki/BugTracker\n"))
Martin Geisler
dispatch: include Python version in traceback
r11206 ui.warn(_("** Python %s\n") % sys.version.replace('\n', ''))
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 ui.warn(_("** Mercurial Distributed SCM (version %s)\n")
Matt Mackall
refactor version code...
r7632 % util.version())
Benoit Boissinot
show extensions loaded on traceback
r6985 ui.warn(_("** Extensions loaded: %s\n")
% ", ".join([x[0] for x in extensions.extensions()]))
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 raise
return -1
Alexander Solovyov
add positional arguments to non-shell aliases
r14265 def aliasargs(fn, givenargs):
args = getattr(fn, 'args', [])
if args and givenargs:
cmd = ' '.join(map(util.shellquote, args))
nums = []
def replacer(m):
num = int(m.group(1)) - 1
nums.append(num)
Matt Mackall
aliases: use empty string for missing position parameters (issue3331)
r16277 if num < len(givenargs):
return givenargs[num]
return ''
Alexander Solovyov
add positional arguments to non-shell aliases
r14265 cmd = re.sub(r'\$(\d+|\$)', replacer, cmd)
givenargs = [x for i, x in enumerate(givenargs)
if i not in nums]
args = shlex.split(cmd)
return args + givenargs
Brendan Cully
Move alias into core
r8655
class cmdalias(object):
def __init__(self, name, definition, cmdtable):
Brodie Rao
alias: make shadowing behavior more consistent (issue2054)...
r12039 self.name = self.cmd = name
Brodie Rao
alias: print what command is being shadowed in debug message
r12092 self.cmdname = ''
Brendan Cully
Move alias into core
r8655 self.definition = definition
self.args = []
self.opts = []
self.help = ''
self.norepo = True
Brodie Rao
help: don't display bogus help messages for invalid aliases
r10021 self.badalias = False
Brendan Cully
Move alias into core
r8655
try:
Brodie Rao
alias: make shadowing behavior more consistent (issue2054)...
r12039 aliases, entry = cmdutil.findcmd(self.name, cmdtable)
for alias, e in cmdtable.iteritems():
if e is entry:
self.cmd = alias
break
Brendan Cully
Move alias into core
r8655 self.shadows = True
except error.UnknownCommand:
self.shadows = False
if not self.definition:
def fn(ui, *args):
ui.warn(_("no definition for alias '%s'\n") % self.name)
return 1
self.fn = fn
Brodie Rao
help: don't display bogus help messages for invalid aliases
r10021 self.badalias = True
Brendan Cully
Move alias into core
r8655 return
Steve Losh
dispatch: add shell aliases...
r11524 if self.definition.startswith('!'):
Steve Losh
alias: only allow global options before a shell alias, pass later ones through...
r12536 self.shell = True
Steve Losh
dispatch: add shell aliases...
r11524 def fn(ui, *args):
Steve Losh
aliases: provide more flexible ways to work with shell alias arguments...
r11989 env = {'HG_ARGS': ' '.join((self.name,) + args)}
def _checkvar(m):
Roman Sokolov
dispatch: support for $ escaping in shell-alias definition...
r13392 if m.groups()[0] == '$':
return m.group()
elif int(m.groups()[0]) <= len(args):
Steve Losh
aliases: provide more flexible ways to work with shell alias arguments...
r11989 return m.group()
else:
David Soria Parra
i18n: remove translation of debug messages
r14708 ui.debug("No argument found for substitution "
"of %i variable in alias '%s' definition."
Roman Sokolov
dispatch: debug message for missing arguments in shell alias...
r13393 % (int(m.groups()[0]), self.name))
Steve Losh
aliases: provide more flexible ways to work with shell alias arguments...
r11989 return ''
Roman Sokolov
dispatch: support for $ escaping in shell-alias definition...
r13392 cmd = re.sub(r'\$(\d+|\$)', _checkvar, self.definition[1:])
Steve Losh
aliases: provide more flexible ways to work with shell alias arguments...
r11989 replace = dict((str(i + 1), arg) for i, arg in enumerate(args))
replace['0'] = self.name
replace['@'] = ' '.join(args)
Roman Sokolov
dispatch: support for $ escaping in shell-alias definition...
r13392 cmd = util.interpolate(r'\$', replace, cmd, escape_prefix=True)
Idan Kamara
dispatch: write shell alias output to ui out descriptor
r14640 return util.system(cmd, environ=env, out=ui.fout)
Steve Losh
dispatch: add shell aliases...
r11524 self.fn = fn
return
Brendan Cully
Move alias into core
r8655 args = shlex.split(self.definition)
Brodie Rao
alias: print what command is being shadowed in debug message
r12092 self.cmdname = cmd = args.pop(0)
Alexander Solovyov
expand paths in aliases
r10793 args = map(util.expandpath, args)
Brendan Cully
Move alias into core
r8655
Dan Villiom Podlaski Christiansen
alias: improved diagnostic when arguments include --cwd, etc....
r11695 for invalidarg in ("--cwd", "-R", "--repository", "--repo"):
if _earlygetopt([invalidarg], args):
def fn(ui, *args):
ui.warn(_("error in definition for alias '%s': %s may only "
"be given on the command line\n")
% (self.name, invalidarg))
return 1
self.fn = fn
self.badalias = True
return
Brendan Cully
Move alias into core
r8655 try:
Nicolas Dumazet
alias: do not crash when aliased command has no usage help text
r9993 tableentry = cmdutil.findcmd(cmd, cmdtable, False)[1]
if len(tableentry) > 2:
self.fn, self.opts, self.help = tableentry
else:
self.fn, self.opts = tableentry
Alexander Solovyov
add positional arguments to non-shell aliases
r14265 self.args = aliasargs(self.fn, args)
Brendan Cully
Move alias into core
r8655 if cmd not in commands.norepo.split(' '):
self.norepo = False
Peter Arrenbrecht
alias: improve help text for command aliases...
r9876 if self.help.startswith("hg " + cmd):
# drop prefix in old-style help lines so hg shows the alias
self.help = self.help[4 + len(cmd):]
Yuya Nishihara
alias: fixes exception when displaying translated help text...
r10564 self.__doc__ = self.fn.__doc__
Peter Arrenbrecht
alias: improve help text for command aliases...
r9876
Brendan Cully
Move alias into core
r8655 except error.UnknownCommand:
def fn(ui, *args):
ui.warn(_("alias '%s' resolves to unknown command '%s'\n") \
% (self.name, cmd))
Brodie Rao
dispatch: provide help for disabled extensions and commands...
r10364 try:
# check if the command is in a disabled extension
commands.help_(ui, cmd, unknowncmd=True)
except error.UnknownCommand:
pass
Brendan Cully
Move alias into core
r8655 return 1
self.fn = fn
Brodie Rao
help: don't display bogus help messages for invalid aliases
r10021 self.badalias = True
Brendan Cully
Move alias into core
r8655 except error.AmbiguousCommand:
def fn(ui, *args):
ui.warn(_("alias '%s' resolves to ambiguous command '%s'\n") \
% (self.name, cmd))
return 1
self.fn = fn
Brodie Rao
help: don't display bogus help messages for invalid aliases
r10021 self.badalias = True
Brendan Cully
Move alias into core
r8655
def __call__(self, ui, *args, **opts):
if self.shadows:
Martin Geisler
Backed out changeset 1ec8bd909ac3...
r14704 ui.debug("alias '%s' shadows command '%s'\n" %
Brodie Rao
alias: print what command is being shadowed in debug message
r12092 (self.name, self.cmdname))
Brendan Cully
Move alias into core
r8655
Augie Fackler
dispatch: use safehasattr instead of hasattr
r14950 if util.safehasattr(self, 'shell'):
Steve Losh
aliases: provide more flexible ways to work with shell alias arguments...
r11989 return self.fn(ui, *args, **opts)
else:
Brodie Rao
alias: on --debug, print expansion when it has invalid arguments
r12093 try:
util.checksignature(self.fn)(ui, *args, **opts)
except error.SignatureError:
args = ' '.join([self.cmdname] + self.args)
Martin Geisler
Backed out changeset 1ec8bd909ac3...
r14704 ui.debug("alias '%s' expands to '%s'\n" % (self.name, args))
Brodie Rao
alias: on --debug, print expansion when it has invalid arguments
r12093 raise
Brendan Cully
Move alias into core
r8655
def addaliases(ui, cmdtable):
# aliases are processed after extensions have been loaded, so they
# may use extension commands. Aliases can also use other alias definitions,
# but only if they have been defined prior to the current definition.
for alias, definition in ui.configitems('alias'):
aliasdef = cmdalias(alias, definition, cmdtable)
Idan Kamara
dispatch: don't rewrap aliases that have the same definition...
r15019
try:
olddef = cmdtable[aliasdef.cmd][0]
if olddef.definition == aliasdef.definition:
continue
except (KeyError, AttributeError):
# definition might not exist or it might not be a cmdalias
pass
Augie Fackler
alias: don't shadow commands that we only partially matched (issue2993) (BC)...
r15233 cmdtable[aliasdef.name] = (aliasdef, aliasdef.opts, aliasdef.help)
Brendan Cully
Move alias into core
r8655 if aliasdef.norepo:
commands.norepo += ' %s' % alias
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 def _parse(ui, args):
options = {}
cmdoptions = {}
try:
args = fancyopts.fancyopts(args, commands.globalopts, options)
except fancyopts.getopt.GetoptError, inst:
Matt Mackall
error: change ParseError to CommandError
r11287 raise error.CommandError(None, inst)
Matt Mackall
dispatch: move command dispatching into its own module...
r5178
if args:
cmd, args = args[0], args[1:]
Henri Wiechers
dispatch: minor refactoring...
r9875 aliases, entry = cmdutil.findcmd(cmd, commands.table,
Thomas Arendsen Hein
Minor cleanup: Add missing space forgotten in recent change.
r7224 ui.config("ui", "strict"))
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 cmd = aliases[0]
Alexander Solovyov
add positional arguments to non-shell aliases
r14265 args = aliasargs(entry[0], args)
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 defaults = ui.config("defaults", cmd)
if defaults:
Alexander Solovyov
make path expanding more consistent...
r9610 args = map(util.expandpath, shlex.split(defaults)) + args
Henri Wiechers
dispatch: minor refactoring...
r9875 c = list(entry[1])
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 else:
cmd = None
c = []
# combine global options into local
for o in commands.globalopts:
c.append((o[0], o[1], options[o[1]], o[3]))
try:
Augie Fackler
fancyopts: Parse options that occur after arguments....
r7772 args = fancyopts.fancyopts(args, c, cmdoptions, True)
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 except fancyopts.getopt.GetoptError, inst:
Matt Mackall
error: change ParseError to CommandError
r11287 raise error.CommandError(cmd, inst)
Matt Mackall
dispatch: move command dispatching into its own module...
r5178
# separate global options back out
for o in commands.globalopts:
n = o[1]
options[n] = cmdoptions[n]
del cmdoptions[n]
Henri Wiechers
dispatch: minor refactoring...
r9875 return (cmd, cmd and entry[0] or None, args, options, cmdoptions)
Matt Mackall
dispatch: move command dispatching into its own module...
r5178
Matt Mackall
ui: kill updateopts...
r8137 def _parseconfig(ui, config):
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 """parse the --config options from the command line"""
Idan Kamara
dispatch: return read config options
r14753 configs = []
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 for cfg in config:
try:
name, value = cfg.split('=', 1)
section, name = name.split('.', 1)
if not section or not name:
raise IndexError
Matt Mackall
ui: kill updateopts...
r8137 ui.setconfig(section, name, value)
Idan Kamara
dispatch: return read config options
r14753 configs.append((section, name, value))
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 except (IndexError, ValueError):
Bill Schroeder
dispatch: better error message for --config option
r9825 raise util.Abort(_('malformed --config option: %r '
'(use --config section.name=value)') % cfg)
Matt Mackall
dispatch: move command dispatching into its own module...
r5178
Idan Kamara
dispatch: return read config options
r14753 return configs
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 def _earlygetopt(aliases, args):
"""Return list of values for an option (or aliases).
The values are listed in the order they appear in args.
The options and values are removed from args.
"""
try:
argcount = args.index("--")
except ValueError:
argcount = len(args)
shortopts = [opt for opt in aliases if len(opt) == 2]
values = []
pos = 0
while pos < argcount:
if args[pos] in aliases:
if pos + 1 >= argcount:
# ignore and let getopt report an error if there is no value
break
del args[pos]
values.append(args.pop(pos))
argcount -= 2
elif args[pos][:2] in shortopts:
# short option can have no following space, e.g. hg log -Rfoo
values.append(args.pop(pos)[2:])
argcount -= 1
else:
pos += 1
return values
Chad Dombrova
provide pre- and post- hooks with parsed command line arguments....
r11330 def runcommand(lui, repo, cmd, fullargs, ui, options, d, cmdpats, cmdoptions):
Bill Barry
dispatch: extract command execution block into method...
r7819 # run pre-hook, and abort if it fails
Chad Dombrova
provide pre- and post- hooks with parsed command line arguments....
r11330 ret = hook.hook(lui, repo, "pre-%s" % cmd, False, args=" ".join(fullargs),
pats=cmdpats, opts=cmdoptions)
Bill Barry
dispatch: extract command execution block into method...
r7819 if ret:
return ret
ret = _runcommand(ui, options, cmd, d)
# run post-hook, passing command result
hook.hook(lui, repo, "post-%s" % cmd, False, args=" ".join(fullargs),
Chad Dombrova
provide pre- and post- hooks with parsed command line arguments....
r11330 result=ret, pats=cmdpats, opts=cmdoptions)
Bill Barry
dispatch: extract command execution block into method...
r7819 return ret
Steve Losh
alias: only allow global options before a shell alias, pass later ones through...
r12536 def _getlocal(ui, rpath):
"""Return (path, local ui object) for the given target path.
Martin Geisler
check-code: find trailing whitespace
r12770
Steve Losh
alias: only allow global options before a shell alias, pass later ones through...
r12536 Takes paths in [cwd]/.hg/hgrc into account."
"""
Mads Kiilerich
dispatch: give better error message when cwd doesn't exist (issue2293)...
r11675 try:
wd = os.getcwd()
except OSError, e:
Nicolas Dumazet
dispatch: trailing whitespace
r11712 raise util.Abort(_("error getting current working directory: %s") %
Mads Kiilerich
dispatch: give better error message when cwd doesn't exist (issue2293)...
r11675 e.strerror)
path = cmdutil.findrepo(wd) or ""
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 if not path:
lui = ui
Andrey Somov
improve code readability
r9436 else:
Brodie Rao
dispatch: remove superfluous try/except when reading local ui config...
r12636 lui = ui.copy()
Brodie Rao
dispatch: properly handle relative path aliases used with -R (issue2376)...
r12637 lui.readconfig(os.path.join(path, ".hg", "hgrc"), path)
Matt Mackall
dispatch: move command dispatching into its own module...
r5178
Matt Mackall
dispatch: fix checking of rpath in _getlocal...
r14860 if rpath and rpath[-1]:
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 path = lui.expandpath(rpath[-1])
Matt Mackall
ui: kill most users of parentui name and arg, replace with .copy()
r8190 lui = ui.copy()
Brodie Rao
dispatch: properly handle relative path aliases used with -R (issue2376)...
r12637 lui.readconfig(os.path.join(path, ".hg", "hgrc"), path)
Matt Mackall
dispatch: move command dispatching into its own module...
r5178
Steve Losh
alias: only allow global options before a shell alias, pass later ones through...
r12536 return path, lui
Matt Mackall
alias: pass local ui to shell alias...
r14888 def _checkshellalias(lui, ui, args):
Steve Losh
alias: back up and restore commands.norepo before checking for shell aliases
r12633 norepo = commands.norepo
Steve Losh
alias: only allow global options before a shell alias, pass later ones through...
r12536 options = {}
Steve Losh
alias: fail gracefully when invalid global options are given (issue2442)...
r12748
try:
args = fancyopts.fancyopts(args, commands.globalopts, options)
except fancyopts.getopt.GetoptError:
return
Steve Losh
alias: only allow global options before a shell alias, pass later ones through...
r12536
if not args:
return
cmdtable = commands.table.copy()
addaliases(lui, cmdtable)
cmd = args[0]
try:
aliases, entry = cmdutil.findcmd(cmd, cmdtable, lui.config("ui", "strict"))
Steve Losh
alias: fall back to normal error handling for ambigious commands (fixes issue2475)
r12932 except (error.AmbiguousCommand, error.UnknownCommand):
Steve Losh
alias: back up and restore commands.norepo before checking for shell aliases
r12633 commands.norepo = norepo
Steve Losh
alias: only allow global options before a shell alias, pass later ones through...
r12536 return
cmd = aliases[0]
fn = entry[0]
Augie Fackler
dispatch: use safehasattr instead of hasattr
r14950 if cmd and util.safehasattr(fn, 'shell'):
Steve Losh
alias: only allow global options before a shell alias, pass later ones through...
r12536 d = lambda: fn(ui, *args[1:])
return lambda: runcommand(lui, None, cmd, args[:1], ui, options, d, [], {})
Steve Losh
alias: back up and restore commands.norepo before checking for shell aliases
r12633 commands.norepo = norepo
Steve Losh
alias: only allow global options before a shell alias, pass later ones through...
r12536
_loaded = set()
Idan Kamara
dispatch: use the request to store the ui object...
r14439 def _dispatch(req):
Idan Kamara
dispatch: wrap dispatch related information in a request class...
r14438 args = req.args
Idan Kamara
dispatch: use the request to store the ui object...
r14439 ui = req.ui
Steve Losh
alias: only allow global options before a shell alias, pass later ones through...
r12536 # read --config before doing anything else
# (e.g. to change trust settings for reading .hg/hgrc)
Idan Kamara
dispatch: set config options on the request repo.ui
r14754 cfgs = _parseconfig(ui, _earlygetopt(['--config'], args))
Steve Losh
alias: only allow global options before a shell alias, pass later ones through...
r12536
# check for cwd
cwd = _earlygetopt(['--cwd'], args)
if cwd:
os.chdir(cwd[-1])
rpath = _earlygetopt(["-R", "--repository", "--repo"], args)
path, lui = _getlocal(ui, rpath)
Matt Mackall
dispatch: move shell alias handling after early arg handling...
r14886 # Now that we're operating in the right directory/repository with
# the right config settings, check for shell aliases
Matt Mackall
alias: pass local ui to shell alias...
r14888 shellaliasfn = _checkshellalias(lui, ui, args)
Matt Mackall
dispatch: move shell alias handling after early arg handling...
r14886 if shellaliasfn:
return shellaliasfn()
Martin Geisler
extensions: load and configure extensions in well-defined phases...
r9410 # Configure extensions in phases: uisetup, extsetup, cmdtable, and
# reposetup. Programs like TortoiseHg will call _dispatch several
# times so we keep track of configured extensions in _loaded.
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 extensions.loadall(lui)
Martin Geisler
extensions: load and configure extensions in well-defined phases...
r9410 exts = [ext for ext in extensions.extensions() if ext[0] not in _loaded]
Brodie Rao
color/progress: subclass ui instead of using wrapfunction (issue2096)...
r11555 # Propagate any changes to lui.__class__ by extensions
ui.__class__ = lui.__class__
Kirill Smelkov
dispatch: allow extensions to provide setup code...
r5828
Yuya Nishihara
extensions: changed to call extsetup() from extensions.loadall()...
r9660 # (uisetup and extsetup are handled in extensions.loadall)
Kirill Smelkov
dispatch: allow extensions to provide setup code...
r5828
Martin Geisler
extensions: load and configure extensions in well-defined phases...
r9410 for name, module in exts:
Alexis S. L. Carvalho
Move cmdtable and reposetup handling out of extensions.py...
r5192 cmdtable = getattr(module, 'cmdtable', {})
overrides = [cmd for cmd in cmdtable if cmd in commands.table]
if overrides:
ui.warn(_("extension '%s' overrides commands: %s\n")
% (name, " ".join(overrides)))
commands.table.update(cmdtable)
Martin Geisler
dispatch: remember loaded extensions in a real set
r8304 _loaded.add(name)
Brendan Cully
Move alias into core
r8655
Martin Geisler
extensions: load and configure extensions in well-defined phases...
r9410 # (reposetup is handled in hg.repository)
Brendan Cully
Move alias into core
r8655 addaliases(lui, commands.table)
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 # check for fallback encoding
fallback = lui.config('ui', 'fallbackencoding')
if fallback:
Matt Mackall
move encoding bits from util to encoding...
r7948 encoding.fallbackencoding = fallback
Matt Mackall
dispatch: move command dispatching into its own module...
r5178
fullargs = args
cmd, func, args, options, cmdoptions = _parse(lui, args)
if options["config"]:
Martin Geisler
Lowercase error messages
r12067 raise util.Abort(_("option --config may not be abbreviated!"))
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 if options["cwd"]:
Martin Geisler
Lowercase error messages
r12067 raise util.Abort(_("option --cwd may not be abbreviated!"))
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 if options["repository"]:
raise util.Abort(_(
Martin Geisler
dispatch: lowercase abort message
r15781 "option -R has to be separated from other options (e.g. not -qR) "
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 "and --repository may only be abbreviated as --repo!"))
if options["encoding"]:
Matt Mackall
move encoding bits from util to encoding...
r7948 encoding.encoding = options["encoding"]
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 if options["encodingmode"]:
Matt Mackall
move encoding bits from util to encoding...
r7948 encoding.encodingmode = options["encodingmode"]
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 if options["time"]:
def get_times():
t = os.times()
if t[4] == 0.0: # Windows leaves this as zero, so use time.clock()
t = (t[0], t[1], t[2], t[3], time.clock())
return t
s = get_times()
def print_time():
t = get_times()
ui.warn(_("Time: real %.3f secs (user %.3f+%.3f sys %.3f+%.3f)\n") %
(t[4]-s[4], t[0]-s[0], t[2]-s[2], t[1]-s[1], t[3]-s[3]))
atexit.register(print_time)
Idan Kamara
dispatch: set global options on the request repo.ui...
r14752 uis = set([ui, lui])
if req.repo:
uis.add(req.repo.ui)
Idan Kamara
dispatch: set config options on the request repo.ui
r14754 # copy configs that were passed on the cmdline (--config) to the repo ui
for cfg in cfgs:
req.repo.ui.setconfig(*cfg)
Idan Kamara
dispatch: make sure global options on the command line take precedence...
r14992 if options['verbose'] or options['debug'] or options['quiet']:
for opt in ('verbose', 'debug', 'quiet'):
val = str(bool(options[opt]))
Idan Kamara
dispatch: set global options on the request repo.ui...
r14752 for ui_ in uis:
Idan Kamara
dispatch: make sure global options on the command line take precedence...
r14992 ui_.setconfig('ui', opt, val)
if options['traceback']:
for ui_ in uis:
ui_.setconfig('ui', 'traceback', 'on')
Idan Kamara
dispatch: make sure unspecified global ui options don't override old values
r14748
Matt Mackall
ui: refactor option setting...
r8136 if options['noninteractive']:
Idan Kamara
dispatch: set global options on the request repo.ui...
r14752 for ui_ in uis:
Idan Kamara
dispatch: fix for-loop variable name
r14618 ui_.setconfig('ui', 'interactive', 'off')
Matt Mackall
dispatch: move command dispatching into its own module...
r5178
Yuya Nishihara
url: add --insecure option to bypass verification of ssl certificates...
r13328 if cmdoptions.get('insecure', False):
Idan Kamara
dispatch: set global options on the request repo.ui...
r14752 for ui_ in uis:
Idan Kamara
dispatch: fix for-loop variable name
r14618 ui_.setconfig('web', 'cacerts', '')
Yuya Nishihara
url: add --insecure option to bypass verification of ssl certificates...
r13328
Matt Mackall
help: drop with_version...
r15020 if options['version']:
return commands.version_(ui)
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 if options['help']:
Matt Mackall
help: drop with_version...
r15020 return commands.help_(ui, cmd)
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 elif not cmd:
return commands.help_(ui, 'shortlist')
repo = None
Chad Dombrova
provide pre- and post- hooks with parsed command line arguments....
r11330 cmdpats = args[:]
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 if cmd not in commands.norepo.split():
Idan Kamara
dispatch: add repo to the request...
r14510 # use the repo from the request only if we don't have -R
Idan Kamara
dispatch: don't use request repo if we have --cwd
r14863 if not rpath and not cwd:
Idan Kamara
dispatch: add repo to the request...
r14510 repo = req.repo
Idan Kamara
dispatch: set descriptors on the request repo.ui
r14744 if repo:
# set the descriptors of the repo ui to those of ui
repo.ui.fin = ui.fin
repo.ui.fout = ui.fout
repo.ui.ferr = ui.ferr
else:
Idan Kamara
dispatch: add repo to the request...
r14510 try:
repo = hg.repository(ui, path=path)
if not repo.local():
raise util.Abort(_("repository '%s' is not local") % path)
Idan Kamara
dispatch: pass the correct ui to runcommand...
r14743 repo.ui.setconfig("bundle", "mainreporoot", repo.root)
Idan Kamara
dispatch: add repo to the request...
r14510 except error.RequirementError:
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 raise
Idan Kamara
dispatch: add repo to the request...
r14510 except error.RepoError:
if cmd not in commands.optionalrepo.split():
if args and not path: # try to infer -R from command args
repos = map(cmdutil.findrepo, args)
guess = repos[0]
if guess and repos.count(guess) == len(repos):
req.args = ['--repository', guess] + fullargs
return _dispatch(req)
if not path:
David Golub
dispatch: avoid double backslashes in error message...
r14914 raise error.RepoError(_("no repository found in '%s'"
Idan Kamara
dispatch: add repo to the request...
r14510 " (.hg not found)") % os.getcwd())
raise
Idan Kamara
dispatch: pass the correct ui to runcommand...
r14743 if repo:
ui = repo.ui
Matt Mackall
dispatch: generalize signature checking for extension command wrapping
r7388 args.insert(0, repo)
Matt Mackall
warn if --repository provided for norepo commands
r7733 elif rpath:
Martin Geisler
mark ui.warn strings for translation
r11600 ui.warn(_("warning: --repository ignored\n"))
Matt Mackall
dispatch: generalize signature checking for extension command wrapping
r7388
Matt Mackall
log: add logging for commands
r11985 msg = ' '.join(' ' in a and repr(a) or a for a in fullargs)
ui.log("command", msg + "\n")
Matt Mackall
dispatch: generalize signature checking for extension command wrapping
r7388 d = lambda: util.checksignature(func)(ui, *args, **cmdoptions)
Adrian Buehlmann
Make sure bundlerepo doesn't leak temp files (issue2491)...
r13382 try:
return runcommand(lui, repo, cmd, fullargs, ui, options, d,
cmdpats, cmdoptions)
finally:
Idan Kamara
dispatch: check for None before closing repo...
r14727 if repo and repo != req.repo:
Adrian Buehlmann
Make sure bundlerepo doesn't leak temp files (issue2491)...
r13382 repo.close()
Matt Mackall
dispatch: move command dispatching into its own module...
r5178
def _runcommand(ui, options, cmd, cmdfunc):
def checkargs():
try:
return cmdfunc()
Matt Mackall
error: move SignatureError
r7646 except error.SignatureError:
Matt Mackall
error: change ParseError to CommandError
r11287 raise error.CommandError(cmd, _("invalid arguments"))
Matt Mackall
dispatch: move command dispatching into its own module...
r5178
Thomas Arendsen Hein
Backed out changeset b913d3aacddc (see issue971/msg5317)
r6141 if options['profile']:
Nicolas Dumazet
profiling: Adding a profiling.format config variable...
r8023 format = ui.config('profiling', 'format', default='text')
Matt Mackall
profile: add undocumented config options for profiler output
r16263 field = ui.config('profiling', 'sort', default='inlinetime')
climit = ui.configint('profiling', 'nested', default=5)
Nicolas Dumazet
profiling: Adding a profiling.format config variable...
r8023
Nicolas Dumazet
profiling: Adding support for kcachegrind output format, using lsprofcalltree
r8024 if not format in ['text', 'kcachegrind']:
Nicolas Dumazet
profiling: Adding a profiling.format config variable...
r8023 ui.warn(_("unrecognized profiling format '%s'"
" - Ignored\n") % format)
format = 'text'
Nicolas Dumazet
profiling: Adding profiling.output config variable...
r8022 output = ui.config('profiling', 'output')
if output:
Alexander Solovyov
make path expanding more consistent...
r9610 path = ui.expandpath(output)
Nicolas Dumazet
profiling: Adding profiling.output config variable...
r8022 ostream = open(path, 'wb')
else:
ostream = sys.stderr
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 try:
from mercurial import lsprof
except ImportError:
raise util.Abort(_(
'lsprof not available - install from '
'http://codespeak.net/svn/user/arigo/hack/misc/lsprof/'))
p = lsprof.Profiler()
p.enable(subcalls=True)
try:
Thomas Arendsen Hein
Backed out changeset b913d3aacddc (see issue971/msg5317)
r6141 return checkargs()
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 finally:
p.disable()
Nicolas Dumazet
profiling: Adding support for kcachegrind output format, using lsprofcalltree
r8024
if format == 'kcachegrind':
import lsprofcalltree
calltree = lsprofcalltree.KCacheGrind(p)
calltree.output(ostream)
else:
# format == 'text'
stats = lsprof.Stats(p.getstats())
Matt Mackall
profile: add undocumented config options for profiler output
r16263 stats.sort(field)
stats.pprint(limit=30, file=ostream, climit=climit)
Nicolas Dumazet
profiling: Adding profiling.output config variable...
r8022
if output:
ostream.close()
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 else:
Thomas Arendsen Hein
Backed out changeset b913d3aacddc (see issue971/msg5317)
r6141 return checkargs()