##// END OF EJS Templates
dispatch: move dispatching code to cmdutil
Matt Mackall -
r4549:0c61124a default
parent child Browse files
Show More
@@ -7,7 +7,7 b''
7 7
8 8 from mercurial.i18n import _
9 9 from mercurial.node import *
10 from mercurial import commands, hg, node, util
10 from mercurial import commands, cmdutil, hg, node, util
11 11
12 12 def fetch(ui, repo, source='default', **opts):
13 13 '''Pull changes from a remote repository, merge new changes if needed.
@@ -42,7 +42,7 b" def fetch(ui, repo, source='default', **"
42 42 (len(newheads) - 1))
43 43 if not err:
44 44 mod, add, rem = repo.status(wlock=wlock)[:3]
45 message = (commands.logmessage(opts) or
45 message = (cmdutil.logmessage(opts) or
46 46 (_('Automated merge with %s') % other.url()))
47 47 n = repo.commit(mod + add + rem, message,
48 48 opts['user'], opts['date'], lock=lock, wlock=wlock,
@@ -51,7 +51,7 b" def fetch(ui, repo, source='default', **"
51 51 'with local\n') % (repo.changelog.rev(n),
52 52 short(n)))
53 53 def pull():
54 commands.setremoteconfig(ui, opts)
54 cmdutil.setremoteconfig(ui, opts)
55 55
56 56 other = hg.repository(ui, ui.expandpath(source))
57 57 ui.status(_('pulling from %s\n') % ui.expandpath(source))
@@ -1579,7 +1579,7 b' def clone(ui, source, dest=None, **opts)'
1579 1579 Source patch repository is looked for in <src>/.hg/patches by
1580 1580 default. Use -p <url> to change.
1581 1581 '''
1582 commands.setremoteconfig(ui, opts)
1582 cmdutil.setremoteconfig(ui, opts)
1583 1583 if dest is None:
1584 1584 dest = hg.defaultdest(source)
1585 1585 sr = hg.repository(ui, ui.expandpath(source))
@@ -1670,7 +1670,7 b' def new(ui, repo, patch, **opts):'
1670 1670 If none is specified, the patch header is empty and the
1671 1671 commit message is 'New patch: PATCH'"""
1672 1672 q = repo.mq
1673 message = commands.logmessage(opts)
1673 message = cmdutil.logmessage(opts)
1674 1674 if opts['edit']:
1675 1675 message = ui.edit(message, ui.username())
1676 1676 q.new(repo, patch, msg=message, force=opts['force'])
@@ -1688,7 +1688,7 b' def refresh(ui, repo, *pats, **opts):'
1688 1688 git-style patches (--git or [diff] git=1) to track copies and renames.
1689 1689 """
1690 1690 q = repo.mq
1691 message = commands.logmessage(opts)
1691 message = cmdutil.logmessage(opts)
1692 1692 if opts['edit']:
1693 1693 if message:
1694 1694 raise util.Abort(_('option "-e" incompatible with "-m" or "-l"'))
@@ -1724,7 +1724,7 b' def fold(ui, repo, *files, **opts):'
1724 1724 if not q.check_toppatch(repo):
1725 1725 raise util.Abort(_('No patches applied'))
1726 1726
1727 message = commands.logmessage(opts)
1727 message = cmdutil.logmessage(opts)
1728 1728 if opts['edit']:
1729 1729 if message:
1730 1730 raise util.Abort(_('option "-e" incompatible with "-m" or "-l"'))
@@ -1964,7 +1964,7 b' def restore(ui, repo, rev, **opts):'
1964 1964 def save(ui, repo, **opts):
1965 1965 """save current queue state"""
1966 1966 q = repo.mq
1967 message = commands.logmessage(opts)
1967 message = cmdutil.logmessage(opts)
1968 1968 ret = q.save(repo, msg=message)
1969 1969 if ret:
1970 1970 return ret
@@ -7,10 +7,279 b''
7 7
8 8 from node import *
9 9 from i18n import _
10 import os, sys, mdiff, bdiff, util, templater, patch
10 import os, sys, mdiff, bdiff, util, templater, patch, commands
11 import atexit, signal, pdb, hg, lock, fancyopts, traceback
12 import socket, revlog, version, extensions, errno
11 13
12 14 revrangesep = ':'
13 15
16 class UnknownCommand(Exception):
17 """Exception raised if command is not in the command table."""
18 class AmbiguousCommand(Exception):
19 """Exception raised if command shortcut matches more than one command."""
20 class ParseError(Exception):
21 """Exception raised on errors in parsing the command line."""
22
23 def runcatch(u, args):
24 def catchterm(*args):
25 raise util.SignalInterrupt
26
27 for name in 'SIGBREAK', 'SIGHUP', 'SIGTERM':
28 num = getattr(signal, name, None)
29 if num: signal.signal(num, catchterm)
30
31 try:
32 return dispatch(u, args)
33 except ParseError, inst:
34 if inst.args[0]:
35 u.warn(_("hg %s: %s\n") % (inst.args[0], inst.args[1]))
36 commands.help_(u, inst.args[0])
37 else:
38 u.warn(_("hg: %s\n") % inst.args[1])
39 commands.help_(u, 'shortlist')
40 except AmbiguousCommand, inst:
41 u.warn(_("hg: command '%s' is ambiguous:\n %s\n") %
42 (inst.args[0], " ".join(inst.args[1])))
43 except UnknownCommand, inst:
44 u.warn(_("hg: unknown command '%s'\n") % inst.args[0])
45 commands.help_(u, 'shortlist')
46 except hg.RepoError, inst:
47 u.warn(_("abort: %s!\n") % inst)
48 except lock.LockHeld, inst:
49 if inst.errno == errno.ETIMEDOUT:
50 reason = _('timed out waiting for lock held by %s') % inst.locker
51 else:
52 reason = _('lock held by %s') % inst.locker
53 u.warn(_("abort: %s: %s\n") % (inst.desc or inst.filename, reason))
54 except lock.LockUnavailable, inst:
55 u.warn(_("abort: could not lock %s: %s\n") %
56 (inst.desc or inst.filename, inst.strerror))
57 except revlog.RevlogError, inst:
58 u.warn(_("abort: %s!\n") % inst)
59 except util.SignalInterrupt:
60 u.warn(_("killed!\n"))
61 except KeyboardInterrupt:
62 try:
63 u.warn(_("interrupted!\n"))
64 except IOError, inst:
65 if inst.errno == errno.EPIPE:
66 if u.debugflag:
67 u.warn(_("\nbroken pipe\n"))
68 else:
69 raise
70 except socket.error, inst:
71 u.warn(_("abort: %s\n") % inst[1])
72 except IOError, inst:
73 if hasattr(inst, "code"):
74 u.warn(_("abort: %s\n") % inst)
75 elif hasattr(inst, "reason"):
76 try: # usually it is in the form (errno, strerror)
77 reason = inst.reason.args[1]
78 except: # it might be anything, for example a string
79 reason = inst.reason
80 u.warn(_("abort: error: %s\n") % reason)
81 elif hasattr(inst, "args") and inst[0] == errno.EPIPE:
82 if u.debugflag:
83 u.warn(_("broken pipe\n"))
84 elif getattr(inst, "strerror", None):
85 if getattr(inst, "filename", None):
86 u.warn(_("abort: %s: %s\n") % (inst.strerror, inst.filename))
87 else:
88 u.warn(_("abort: %s\n") % inst.strerror)
89 else:
90 raise
91 except OSError, inst:
92 if getattr(inst, "filename", None):
93 u.warn(_("abort: %s: %s\n") % (inst.strerror, inst.filename))
94 else:
95 u.warn(_("abort: %s\n") % inst.strerror)
96 except util.UnexpectedOutput, inst:
97 u.warn(_("abort: %s") % inst[0])
98 if not isinstance(inst[1], basestring):
99 u.warn(" %r\n" % (inst[1],))
100 elif not inst[1]:
101 u.warn(_(" empty string\n"))
102 else:
103 u.warn("\n%r\n" % util.ellipsis(inst[1]))
104 except util.Abort, inst:
105 u.warn(_("abort: %s\n") % inst)
106 except TypeError, inst:
107 # was this an argument error?
108 tb = traceback.extract_tb(sys.exc_info()[2])
109 if len(tb) > 2: # no
110 raise
111 u.debug(inst, "\n")
112 u.warn(_("%s: invalid arguments\n") % cmd)
113 commands.help_(u, cmd)
114 except SystemExit, inst:
115 # Commands shouldn't sys.exit directly, but give a return code.
116 # Just in case catch this and and pass exit code to caller.
117 return inst.code
118 except:
119 u.warn(_("** unknown exception encountered, details follow\n"))
120 u.warn(_("** report bug details to "
121 "http://www.selenic.com/mercurial/bts\n"))
122 u.warn(_("** or mercurial@selenic.com\n"))
123 u.warn(_("** Mercurial Distributed SCM (version %s)\n")
124 % version.get_version())
125 raise
126
127 return -1
128
129 def findpossible(ui, cmd):
130 """
131 Return cmd -> (aliases, command table entry)
132 for each matching command.
133 Return debug commands (or their aliases) only if no normal command matches.
134 """
135 choice = {}
136 debugchoice = {}
137 for e in commands.table.keys():
138 aliases = e.lstrip("^").split("|")
139 found = None
140 if cmd in aliases:
141 found = cmd
142 elif not ui.config("ui", "strict"):
143 for a in aliases:
144 if a.startswith(cmd):
145 found = a
146 break
147 if found is not None:
148 if aliases[0].startswith("debug") or found.startswith("debug"):
149 debugchoice[found] = (aliases, commands.table[e])
150 else:
151 choice[found] = (aliases, commands.table[e])
152
153 if not choice and debugchoice:
154 choice = debugchoice
155
156 return choice
157
158 def findcmd(ui, cmd):
159 """Return (aliases, command table entry) for command string."""
160 choice = findpossible(ui, cmd)
161
162 if choice.has_key(cmd):
163 return choice[cmd]
164
165 if len(choice) > 1:
166 clist = choice.keys()
167 clist.sort()
168 raise AmbiguousCommand(cmd, clist)
169
170 if choice:
171 return choice.values()[0]
172
173 raise UnknownCommand(cmd)
174
175 def parse(ui, args):
176 options = {}
177 cmdoptions = {}
178
179 try:
180 args = fancyopts.fancyopts(args, commands.globalopts, options)
181 except fancyopts.getopt.GetoptError, inst:
182 raise ParseError(None, inst)
183
184 if args:
185 cmd, args = args[0], args[1:]
186 aliases, i = findcmd(ui, cmd)
187 cmd = aliases[0]
188 defaults = ui.config("defaults", cmd)
189 if defaults:
190 args = shlex.split(defaults) + args
191 c = list(i[1])
192 else:
193 cmd = None
194 c = []
195
196 # combine global options into local
197 for o in commands.globalopts:
198 c.append((o[0], o[1], options[o[1]], o[3]))
199
200 try:
201 args = fancyopts.fancyopts(args, c, cmdoptions)
202 except fancyopts.getopt.GetoptError, inst:
203 raise ParseError(cmd, inst)
204
205 # separate global options back out
206 for o in commands.globalopts:
207 n = o[1]
208 options[n] = cmdoptions[n]
209 del cmdoptions[n]
210
211 return (cmd, cmd and i[0] or None, args, options, cmdoptions)
212
213 def parseconfig(config):
214 """parse the --config options from the command line"""
215 parsed = []
216 for cfg in config:
217 try:
218 name, value = cfg.split('=', 1)
219 section, name = name.split('.', 1)
220 if not section or not name:
221 raise IndexError
222 parsed.append((section, name, value))
223 except (IndexError, ValueError):
224 raise util.Abort(_('malformed --config option: %s') % cfg)
225 return parsed
226
227 def dispatch(u, args):
228 extensions.loadall(u)
229 u.addreadhook(extensions.loadall)
230
231 cmd, func, args, options, cmdoptions = parse(u, args)
232
233 if options["encoding"]:
234 util._encoding = options["encoding"]
235 if options["encodingmode"]:
236 util._encodingmode = options["encodingmode"]
237 if options["time"]:
238 def get_times():
239 t = os.times()
240 if t[4] == 0.0: # Windows leaves this as zero, so use time.clock()
241 t = (t[0], t[1], t[2], t[3], time.clock())
242 return t
243 s = get_times()
244 def print_time():
245 t = get_times()
246 u.warn(_("Time: real %.3f secs (user %.3f+%.3f sys %.3f+%.3f)\n") %
247 (t[4]-s[4], t[0]-s[0], t[2]-s[2], t[1]-s[1], t[3]-s[3]))
248 atexit.register(print_time)
249
250 if options['cwd']:
251 os.chdir(options['cwd'])
252
253 u.updateopts(options["verbose"], options["debug"], options["quiet"],
254 not options["noninteractive"], options["traceback"],
255 parseconfig(options["config"]))
256
257 path = u.expandpath(options["repository"]) or ""
258 repo = path and hg.repository(u, path=path) or None
259 if repo and not repo.local():
260 raise util.Abort(_("repository '%s' is not local") % path)
261
262 if options['help']:
263 return commands.help_(u, cmd, options['version'])
264 elif options['version']:
265 return commands.version_(u)
266 elif not cmd:
267 return commands.help_(u, 'shortlist')
268
269 if cmd not in commands.norepo.split():
270 try:
271 if not repo:
272 repo = hg.repository(u, path=path)
273 u = repo.ui
274 except hg.RepoError:
275 if cmd not in commands.optionalrepo.split():
276 raise
277 d = lambda: func(u, repo, *args, **cmdoptions)
278 else:
279 d = lambda: func(u, *args, **cmdoptions)
280
281 return runcommand(u, options, d)
282
14 283 def runcommand(u, options, d):
15 284 # enter the debugger before command execution
16 285 if options['debugger']:
@@ -64,6 +333,37 b' def runcommand(u, options, d):'
64 333 u.print_exc()
65 334 raise
66 335
336 def bail_if_changed(repo):
337 modified, added, removed, deleted = repo.status()[:4]
338 if modified or added or removed or deleted:
339 raise util.Abort(_("outstanding uncommitted changes"))
340
341 def logmessage(opts):
342 """ get the log message according to -m and -l option """
343 message = opts['message']
344 logfile = opts['logfile']
345
346 if message and logfile:
347 raise util.Abort(_('options --message and --logfile are mutually '
348 'exclusive'))
349 if not message and logfile:
350 try:
351 if logfile == '-':
352 message = sys.stdin.read()
353 else:
354 message = open(logfile).read()
355 except IOError, inst:
356 raise util.Abort(_("can't read commit message '%s': %s") %
357 (logfile, inst.strerror))
358 return message
359
360 def setremoteconfig(ui, opts):
361 "copy remote options to ui tree"
362 if opts.get('ssh'):
363 ui.setconfig("ui", "ssh", opts['ssh'])
364 if opts.get('remotecmd'):
365 ui.setconfig("ui", "remotecmd", opts['remotecmd'])
366
67 367 def parseurl(url, revs):
68 368 '''parse url#branch, returning url, branch + revs'''
69 369
@@ -8,48 +8,12 b''
8 8 import demandimport; demandimport.enable()
9 9 from node import *
10 10 from i18n import _
11 import bisect, os, re, sys, signal, urllib, pdb, shlex, stat
12 import fancyopts, ui, hg, util, lock, revlog, bundlerepo, extensions
11 import bisect, os, re, sys, urllib, shlex, stat
12 import ui, hg, util, revlog, bundlerepo, extensions
13 13 import difflib, patch, time, help, mdiff, tempfile
14 import traceback, errno, version, atexit, socket
14 import errno, version, socket
15 15 import archival, changegroup, cmdutil, hgweb.server, sshserver
16 16
17 class UnknownCommand(Exception):
18 """Exception raised if command is not in the command table."""
19 class AmbiguousCommand(Exception):
20 """Exception raised if command shortcut matches more than one command."""
21
22 def bail_if_changed(repo):
23 modified, added, removed, deleted = repo.status()[:4]
24 if modified or added or removed or deleted:
25 raise util.Abort(_("outstanding uncommitted changes"))
26
27 def logmessage(opts):
28 """ get the log message according to -m and -l option """
29 message = opts['message']
30 logfile = opts['logfile']
31
32 if message and logfile:
33 raise util.Abort(_('options --message and --logfile are mutually '
34 'exclusive'))
35 if not message and logfile:
36 try:
37 if logfile == '-':
38 message = sys.stdin.read()
39 else:
40 message = open(logfile).read()
41 except IOError, inst:
42 raise util.Abort(_("can't read commit message '%s': %s") %
43 (logfile, inst.strerror))
44 return message
45
46 def setremoteconfig(ui, opts):
47 "copy remote options to ui tree"
48 if opts.get('ssh'):
49 ui.setconfig("ui", "ssh", opts['ssh'])
50 if opts.get('remotecmd'):
51 ui.setconfig("ui", "remotecmd", opts['remotecmd'])
52
53 17 # Commands start here, listed alphabetically
54 18
55 19 def add(ui, repo, *pats, **opts):
@@ -205,7 +169,7 b' def backout(ui, repo, node=None, rev=Non'
205 169 if not rev:
206 170 rev = node
207 171
208 bail_if_changed(repo)
172 cmdutil.bail_if_changed(repo)
209 173 op1, op2 = repo.dirstate.parents()
210 174 if op2 != nullid:
211 175 raise util.Abort(_('outstanding uncommitted merge'))
@@ -335,7 +299,7 b' def bundle(ui, repo, fname, dest=None, *'
335 299 seen[p] = 1
336 300 visit.append(p)
337 301 else:
338 setremoteconfig(ui, opts)
302 cmdutil.setremoteconfig(ui, opts)
339 303 dest, revs = cmdutil.parseurl(
340 304 ui.expandpath(dest or 'default-push', dest or 'default'), revs)
341 305 other = hg.repository(ui, dest)
@@ -407,7 +371,7 b' def clone(ui, source, dest=None, **opts)'
407 371 Look at the help text for the pull command for important details
408 372 about ssh:// URLs.
409 373 """
410 setremoteconfig(ui, opts)
374 cmdutil.setremoteconfig(ui, opts)
411 375 hg.clone(ui, source, dest,
412 376 pull=opts['pull'],
413 377 stream=opts['uncompressed'],
@@ -425,7 +389,7 b' def commit(ui, repo, *pats, **opts):'
425 389 If no commit message is specified, the editor configured in your hgrc
426 390 or in the EDITOR environment variable is started to enter a message.
427 391 """
428 message = logmessage(opts)
392 message = cmdutil.logmessage(opts)
429 393
430 394 if opts['addremove']:
431 395 cmdutil.addremove(repo, pats, opts)
@@ -685,7 +649,7 b" def debugcomplete(ui, cmd='', **opts):"
685 649 options = []
686 650 otables = [globalopts]
687 651 if cmd:
688 aliases, entry = findcmd(ui, cmd)
652 aliases, entry = cmdutil.findcmd(ui, cmd)
689 653 otables.append(entry[1])
690 654 for t in otables:
691 655 for o in t:
@@ -695,7 +659,7 b" def debugcomplete(ui, cmd='', **opts):"
695 659 ui.write("%s\n" % "\n".join(options))
696 660 return
697 661
698 clist = findpossible(ui, cmd).keys()
662 clist = cmdutil.findpossible(ui, cmd).keys()
699 663 clist.sort()
700 664 ui.write("%s\n" % "\n".join(clist))
701 665
@@ -1295,7 +1259,7 b' def help_(ui, name=None, with_version=Fa'
1295 1259 if with_version:
1296 1260 version_(ui)
1297 1261 ui.write('\n')
1298 aliases, i = findcmd(ui, name)
1262 aliases, i = cmdutil.findcmd(ui, name)
1299 1263 # synopsis
1300 1264 ui.write("%s\n\n" % i[2])
1301 1265
@@ -1357,7 +1321,7 b' def help_(ui, name=None, with_version=Fa'
1357 1321 v = i
1358 1322 header = l[-1]
1359 1323 if not v:
1360 raise UnknownCommand(name)
1324 raise cmdutil.UnknownCommand(name)
1361 1325
1362 1326 # description
1363 1327 doc = help.helptable[v]
@@ -1373,7 +1337,7 b' def help_(ui, name=None, with_version=Fa'
1373 1337 try:
1374 1338 mod = extensions.find(name)
1375 1339 except KeyError:
1376 raise UnknownCommand(name)
1340 raise cmdutil.UnknownCommand(name)
1377 1341
1378 1342 doc = (mod.__doc__ or _('No help text available')).splitlines(0)
1379 1343 ui.write(_('%s extension - %s\n') % (name.split('.')[-1], doc[0]))
@@ -1399,7 +1363,7 b' def help_(ui, name=None, with_version=Fa'
1399 1363 f(name)
1400 1364 i = None
1401 1365 break
1402 except UnknownCommand, inst:
1366 except cmdutil.UnknownCommand, inst:
1403 1367 i = inst
1404 1368 if i:
1405 1369 raise i
@@ -1506,7 +1470,7 b' def import_(ui, repo, patch1, *patches, '
1506 1470 patches = (patch1,) + patches
1507 1471
1508 1472 if opts.get('exact') or not opts['force']:
1509 bail_if_changed(repo)
1473 cmdutil.bail_if_changed(repo)
1510 1474
1511 1475 d = opts["base"]
1512 1476 strip = opts["strip"]
@@ -1528,7 +1492,7 b' def import_(ui, repo, patch1, *patches, '
1528 1492 raise util.Abort(_('no diffs found'))
1529 1493
1530 1494 try:
1531 cmdline_message = logmessage(opts)
1495 cmdline_message = cmdutil.logmessage(opts)
1532 1496 if cmdline_message:
1533 1497 # pickup the cmdline msg
1534 1498 message = cmdline_message
@@ -1587,7 +1551,7 b' def incoming(ui, repo, source="default",'
1587 1551 See pull for valid source format details.
1588 1552 """
1589 1553 source, revs = cmdutil.parseurl(ui.expandpath(source), opts['rev'])
1590 setremoteconfig(ui, opts)
1554 cmdutil.setremoteconfig(ui, opts)
1591 1555
1592 1556 other = hg.repository(ui, source)
1593 1557 ui.status(_('comparing with %s\n') % source)
@@ -1653,7 +1617,7 b' def init(ui, dest=".", **opts):'
1653 1617 Look at the help text for the pull command for important details
1654 1618 about ssh:// URLs.
1655 1619 """
1656 setremoteconfig(ui, opts)
1620 cmdutil.setremoteconfig(ui, opts)
1657 1621 hg.repository(ui, dest, create=1)
1658 1622
1659 1623 def locate(ui, repo, *pats, **opts):
@@ -1890,7 +1854,7 b' def outgoing(ui, repo, dest=None, **opts'
1890 1854 """
1891 1855 dest, revs = cmdutil.parseurl(
1892 1856 ui.expandpath(dest or 'default-push', dest or 'default'), opts['rev'])
1893 setremoteconfig(ui, opts)
1857 cmdutil.setremoteconfig(ui, opts)
1894 1858 if revs:
1895 1859 revs = [repo.lookup(rev) for rev in revs]
1896 1860
@@ -2005,7 +1969,7 b' def pull(ui, repo, source="default", **o'
2005 1969 with the --ssh command line option.
2006 1970 """
2007 1971 source, revs = cmdutil.parseurl(ui.expandpath(source), opts['rev'])
2008 setremoteconfig(ui, opts)
1972 cmdutil.setremoteconfig(ui, opts)
2009 1973
2010 1974 other = hg.repository(ui, source)
2011 1975 ui.status(_('pulling from %s\n') % (source))
@@ -2051,7 +2015,7 b' def push(ui, repo, dest=None, **opts):'
2051 2015 """
2052 2016 dest, revs = cmdutil.parseurl(
2053 2017 ui.expandpath(dest or 'default-push', dest or 'default'), opts['rev'])
2054 setremoteconfig(ui, opts)
2018 cmdutil.setremoteconfig(ui, opts)
2055 2019
2056 2020 other = hg.repository(ui, dest)
2057 2021 ui.status('pushing to %s\n' % (dest))
@@ -2075,7 +2039,7 b' def rawcommit(ui, repo, *pats, **opts):'
2075 2039
2076 2040 ui.warn(_("(the rawcommit command is deprecated)\n"))
2077 2041
2078 message = logmessage(opts)
2042 message = cmdutil.logmessage(opts)
2079 2043
2080 2044 files, match, anypats = cmdutil.matchpats(repo, pats, opts)
2081 2045 if opts['files']:
@@ -3039,272 +3003,5 b' def run():'
3039 3003 except util.Abort, inst:
3040 3004 sys.stderr.write(_("abort: %s\n") % inst)
3041 3005 return -1
3042 sys.exit(runcatch(u, sys.argv[1:]))
3043
3044 def runcatch(u, args):
3045 def catchterm(*args):
3046 raise util.SignalInterrupt
3047
3048 for name in 'SIGBREAK', 'SIGHUP', 'SIGTERM':
3049 num = getattr(signal, name, None)
3050 if num: signal.signal(num, catchterm)
3051
3052 try:
3053 return dispatch(u, args)
3054 except hg.RepoError, inst:
3055 u.warn(_("abort: %s!\n") % inst)
3056 except lock.LockHeld, inst:
3057 if inst.errno == errno.ETIMEDOUT:
3058 reason = _('timed out waiting for lock held by %s') % inst.locker
3059 else:
3060 reason = _('lock held by %s') % inst.locker
3061 u.warn(_("abort: %s: %s\n") % (inst.desc or inst.filename, reason))
3062 except lock.LockUnavailable, inst:
3063 u.warn(_("abort: could not lock %s: %s\n") %
3064 (inst.desc or inst.filename, inst.strerror))
3065 except revlog.RevlogError, inst:
3066 u.warn(_("abort: %s!\n") % inst)
3067 except util.SignalInterrupt:
3068 u.warn(_("killed!\n"))
3069 except KeyboardInterrupt:
3070 try:
3071 u.warn(_("interrupted!\n"))
3072 except IOError, inst:
3073 if inst.errno == errno.EPIPE:
3074 if u.debugflag:
3075 u.warn(_("\nbroken pipe\n"))
3076 else:
3077 raise
3078 except socket.error, inst:
3079 u.warn(_("abort: %s\n") % inst[1])
3080 except IOError, inst:
3081 if hasattr(inst, "code"):
3082 u.warn(_("abort: %s\n") % inst)
3083 elif hasattr(inst, "reason"):
3084 try: # usually it is in the form (errno, strerror)
3085 reason = inst.reason.args[1]
3086 except: # it might be anything, for example a string
3087 reason = inst.reason
3088 u.warn(_("abort: error: %s\n") % reason)
3089 elif hasattr(inst, "args") and inst[0] == errno.EPIPE:
3090 if u.debugflag:
3091 u.warn(_("broken pipe\n"))
3092 elif getattr(inst, "strerror", None):
3093 if getattr(inst, "filename", None):
3094 u.warn(_("abort: %s: %s\n") % (inst.strerror, inst.filename))
3095 else:
3096 u.warn(_("abort: %s\n") % inst.strerror)
3097 else:
3098 raise
3099 except OSError, inst:
3100 if getattr(inst, "filename", None):
3101 u.warn(_("abort: %s: %s\n") % (inst.strerror, inst.filename))
3102 else:
3103 u.warn(_("abort: %s\n") % inst.strerror)
3104 except util.UnexpectedOutput, inst:
3105 u.warn(_("abort: %s") % inst[0])
3106 if not isinstance(inst[1], basestring):
3107 u.warn(" %r\n" % (inst[1],))
3108 elif not inst[1]:
3109 u.warn(_(" empty string\n"))
3110 else:
3111 u.warn("\n%r\n" % util.ellipsis(inst[1]))
3112 except util.Abort, inst:
3113 u.warn(_("abort: %s\n") % inst)
3114 except TypeError, inst:
3115 # was this an argument error?
3116 tb = traceback.extract_tb(sys.exc_info()[2])
3117 if len(tb) > 2: # no
3118 raise
3119 u.debug(inst, "\n")
3120 u.warn(_("%s: invalid arguments\n") % cmd)
3121 help_(u, cmd)
3122 except SystemExit, inst:
3123 # Commands shouldn't sys.exit directly, but give a return code.
3124 # Just in case catch this and and pass exit code to caller.
3125 return inst.code
3126 except:
3127 u.warn(_("** unknown exception encountered, details follow\n"))
3128 u.warn(_("** report bug details to "
3129 "http://www.selenic.com/mercurial/bts\n"))
3130 u.warn(_("** or mercurial@selenic.com\n"))
3131 u.warn(_("** Mercurial Distributed SCM (version %s)\n")
3132 % version.get_version())
3133 raise
3134
3135 return -1
3136
3137 def findpossible(ui, cmd):
3138 """
3139 Return cmd -> (aliases, command table entry)
3140 for each matching command.
3141 Return debug commands (or their aliases) only if no normal command matches.
3142 """
3143 choice = {}
3144 debugchoice = {}
3145 for e in table.keys():
3146 aliases = e.lstrip("^").split("|")
3147 found = None
3148 if cmd in aliases:
3149 found = cmd
3150 elif not ui.config("ui", "strict"):
3151 for a in aliases:
3152 if a.startswith(cmd):
3153 found = a
3154 break
3155 if found is not None:
3156 if aliases[0].startswith("debug") or found.startswith("debug"):
3157 debugchoice[found] = (aliases, table[e])
3158 else:
3159 choice[found] = (aliases, table[e])
3160
3161 if not choice and debugchoice:
3162 choice = debugchoice
3163
3164 return choice
3165
3166 def findcmd(ui, cmd):
3167 """Return (aliases, command table entry) for command string."""
3168 choice = findpossible(ui, cmd)
3169
3170 if choice.has_key(cmd):
3171 return choice[cmd]
3172
3173 if len(choice) > 1:
3174 clist = choice.keys()
3175 clist.sort()
3176 raise AmbiguousCommand(cmd, clist)
3177
3178 if choice:
3179 return choice.values()[0]
3180
3181 raise UnknownCommand(cmd)
3182
3183 class ParseError(Exception):
3184 """Exception raised on errors in parsing the command line."""
3185
3186 def parse(ui, args):
3187 options = {}
3188 cmdoptions = {}
3189
3190 try:
3191 args = fancyopts.fancyopts(args, globalopts, options)
3192 except fancyopts.getopt.GetoptError, inst:
3193 raise ParseError(None, inst)
3194
3195 if args:
3196 cmd, args = args[0], args[1:]
3197 aliases, i = findcmd(ui, cmd)
3198 cmd = aliases[0]
3199 defaults = ui.config("defaults", cmd)
3200 if defaults:
3201 args = shlex.split(defaults) + args
3202 c = list(i[1])
3203 else:
3204 cmd = None
3205 c = []
3206
3207 # combine global options into local
3208 for o in globalopts:
3209 c.append((o[0], o[1], options[o[1]], o[3]))
3210
3211 try:
3212 args = fancyopts.fancyopts(args, c, cmdoptions)
3213 except fancyopts.getopt.GetoptError, inst:
3214 raise ParseError(cmd, inst)
3215
3216 # separate global options back out
3217 for o in globalopts:
3218 n = o[1]
3219 options[n] = cmdoptions[n]
3220 del cmdoptions[n]
3221
3222 return (cmd, cmd and i[0] or None, args, options, cmdoptions)
3223
3224 def parseconfig(config):
3225 """parse the --config options from the command line"""
3226 parsed = []
3227 for cfg in config:
3228 try:
3229 name, value = cfg.split('=', 1)
3230 section, name = name.split('.', 1)
3231 if not section or not name:
3232 raise IndexError
3233 parsed.append((section, name, value))
3234 except (IndexError, ValueError):
3235 raise util.Abort(_('malformed --config option: %s') % cfg)
3236 return parsed
3237
3238 def dispatch(u, args):
3239 extensions.loadall(u)
3240 u.addreadhook(extensions.loadall)
3241
3242 try:
3243 cmd, func, args, options, cmdoptions = parse(u, args)
3244 except ParseError, inst:
3245 if inst.args[0]:
3246 u.warn(_("hg %s: %s\n") % (inst.args[0], inst.args[1]))
3247 help_(u, inst.args[0])
3248 else:
3249 u.warn(_("hg: %s\n") % inst.args[1])
3250 help_(u, 'shortlist')
3251 return -1
3252 except AmbiguousCommand, inst:
3253 u.warn(_("hg: command '%s' is ambiguous:\n %s\n") %
3254 (inst.args[0], " ".join(inst.args[1])))
3255 return -1
3256 except UnknownCommand, inst:
3257 u.warn(_("hg: unknown command '%s'\n") % inst.args[0])
3258 help_(u, 'shortlist')
3259 return -1
3260
3261 if options["encoding"]:
3262 util._encoding = options["encoding"]
3263 if options["encodingmode"]:
3264 util._encodingmode = options["encodingmode"]
3265 if options["time"]:
3266 def get_times():
3267 t = os.times()
3268 if t[4] == 0.0: # Windows leaves this as zero, so use time.clock()
3269 t = (t[0], t[1], t[2], t[3], time.clock())
3270 return t
3271 s = get_times()
3272 def print_time():
3273 t = get_times()
3274 u.warn(_("Time: real %.3f secs (user %.3f+%.3f sys %.3f+%.3f)\n") %
3275 (t[4]-s[4], t[0]-s[0], t[2]-s[2], t[1]-s[1], t[3]-s[3]))
3276 atexit.register(print_time)
3277
3278 if options['cwd']:
3279 os.chdir(options['cwd'])
3280
3281 u.updateopts(options["verbose"], options["debug"], options["quiet"],
3282 not options["noninteractive"], options["traceback"],
3283 parseconfig(options["config"]))
3284
3285 path = u.expandpath(options["repository"]) or ""
3286 repo = path and hg.repository(u, path=path) or None
3287 if repo and not repo.local():
3288 raise util.Abort(_("repository '%s' is not local") % path)
3289
3290 if options['help']:
3291 return help_(u, cmd, options['version'])
3292 elif options['version']:
3293 return version_(u)
3294 elif not cmd:
3295 return help_(u, 'shortlist')
3296
3297 if cmd not in norepo.split():
3298 try:
3299 if not repo:
3300 repo = hg.repository(u, path=path)
3301 u = repo.ui
3302 except hg.RepoError:
3303 if cmd not in optionalrepo.split():
3304 raise
3305 d = lambda: func(u, repo, *args, **cmdoptions)
3306 else:
3307 d = lambda: func(u, *args, **cmdoptions)
3308
3309 return cmdutil.runcommand(u, options, d)
3310
3006 sys.exit(cmdutil.runcatch(u, sys.argv[1:]))
3007
@@ -1,10 +1,10 b''
1 1 #!/usr/bin/env python
2 2
3 3 import ConfigParser
4 from mercurial import ui, util, commands
4 from mercurial import ui, util, cmdutil
5 5
6 6 testui = ui.ui()
7 parsed = commands.parseconfig([
7 parsed = cmdutil.parseconfig([
8 8 'values.string=string value',
9 9 'values.bool1=true',
10 10 'values.bool2=false',
General Comments 0
You need to be logged in to leave comments. Login now