##// 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 from mercurial.i18n import _
8 from mercurial.i18n import _
9 from mercurial.node import *
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 def fetch(ui, repo, source='default', **opts):
12 def fetch(ui, repo, source='default', **opts):
13 '''Pull changes from a remote repository, merge new changes if needed.
13 '''Pull changes from a remote repository, merge new changes if needed.
@@ -42,7 +42,7 b" def fetch(ui, repo, source='default', **"
42 (len(newheads) - 1))
42 (len(newheads) - 1))
43 if not err:
43 if not err:
44 mod, add, rem = repo.status(wlock=wlock)[:3]
44 mod, add, rem = repo.status(wlock=wlock)[:3]
45 message = (commands.logmessage(opts) or
45 message = (cmdutil.logmessage(opts) or
46 (_('Automated merge with %s') % other.url()))
46 (_('Automated merge with %s') % other.url()))
47 n = repo.commit(mod + add + rem, message,
47 n = repo.commit(mod + add + rem, message,
48 opts['user'], opts['date'], lock=lock, wlock=wlock,
48 opts['user'], opts['date'], lock=lock, wlock=wlock,
@@ -51,7 +51,7 b" def fetch(ui, repo, source='default', **"
51 'with local\n') % (repo.changelog.rev(n),
51 'with local\n') % (repo.changelog.rev(n),
52 short(n)))
52 short(n)))
53 def pull():
53 def pull():
54 commands.setremoteconfig(ui, opts)
54 cmdutil.setremoteconfig(ui, opts)
55
55
56 other = hg.repository(ui, ui.expandpath(source))
56 other = hg.repository(ui, ui.expandpath(source))
57 ui.status(_('pulling from %s\n') % ui.expandpath(source))
57 ui.status(_('pulling from %s\n') % ui.expandpath(source))
@@ -1579,7 +1579,7 b' def clone(ui, source, dest=None, **opts)'
1579 Source patch repository is looked for in <src>/.hg/patches by
1579 Source patch repository is looked for in <src>/.hg/patches by
1580 default. Use -p <url> to change.
1580 default. Use -p <url> to change.
1581 '''
1581 '''
1582 commands.setremoteconfig(ui, opts)
1582 cmdutil.setremoteconfig(ui, opts)
1583 if dest is None:
1583 if dest is None:
1584 dest = hg.defaultdest(source)
1584 dest = hg.defaultdest(source)
1585 sr = hg.repository(ui, ui.expandpath(source))
1585 sr = hg.repository(ui, ui.expandpath(source))
@@ -1670,7 +1670,7 b' def new(ui, repo, patch, **opts):'
1670 If none is specified, the patch header is empty and the
1670 If none is specified, the patch header is empty and the
1671 commit message is 'New patch: PATCH'"""
1671 commit message is 'New patch: PATCH'"""
1672 q = repo.mq
1672 q = repo.mq
1673 message = commands.logmessage(opts)
1673 message = cmdutil.logmessage(opts)
1674 if opts['edit']:
1674 if opts['edit']:
1675 message = ui.edit(message, ui.username())
1675 message = ui.edit(message, ui.username())
1676 q.new(repo, patch, msg=message, force=opts['force'])
1676 q.new(repo, patch, msg=message, force=opts['force'])
@@ -1688,7 +1688,7 b' def refresh(ui, repo, *pats, **opts):'
1688 git-style patches (--git or [diff] git=1) to track copies and renames.
1688 git-style patches (--git or [diff] git=1) to track copies and renames.
1689 """
1689 """
1690 q = repo.mq
1690 q = repo.mq
1691 message = commands.logmessage(opts)
1691 message = cmdutil.logmessage(opts)
1692 if opts['edit']:
1692 if opts['edit']:
1693 if message:
1693 if message:
1694 raise util.Abort(_('option "-e" incompatible with "-m" or "-l"'))
1694 raise util.Abort(_('option "-e" incompatible with "-m" or "-l"'))
@@ -1724,7 +1724,7 b' def fold(ui, repo, *files, **opts):'
1724 if not q.check_toppatch(repo):
1724 if not q.check_toppatch(repo):
1725 raise util.Abort(_('No patches applied'))
1725 raise util.Abort(_('No patches applied'))
1726
1726
1727 message = commands.logmessage(opts)
1727 message = cmdutil.logmessage(opts)
1728 if opts['edit']:
1728 if opts['edit']:
1729 if message:
1729 if message:
1730 raise util.Abort(_('option "-e" incompatible with "-m" or "-l"'))
1730 raise util.Abort(_('option "-e" incompatible with "-m" or "-l"'))
@@ -1964,7 +1964,7 b' def restore(ui, repo, rev, **opts):'
1964 def save(ui, repo, **opts):
1964 def save(ui, repo, **opts):
1965 """save current queue state"""
1965 """save current queue state"""
1966 q = repo.mq
1966 q = repo.mq
1967 message = commands.logmessage(opts)
1967 message = cmdutil.logmessage(opts)
1968 ret = q.save(repo, msg=message)
1968 ret = q.save(repo, msg=message)
1969 if ret:
1969 if ret:
1970 return ret
1970 return ret
@@ -7,10 +7,279 b''
7
7
8 from node import *
8 from node import *
9 from i18n import _
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 revrangesep = ':'
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 def runcommand(u, options, d):
283 def runcommand(u, options, d):
15 # enter the debugger before command execution
284 # enter the debugger before command execution
16 if options['debugger']:
285 if options['debugger']:
@@ -64,6 +333,37 b' def runcommand(u, options, d):'
64 u.print_exc()
333 u.print_exc()
65 raise
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 def parseurl(url, revs):
367 def parseurl(url, revs):
68 '''parse url#branch, returning url, branch + revs'''
368 '''parse url#branch, returning url, branch + revs'''
69
369
@@ -8,48 +8,12 b''
8 import demandimport; demandimport.enable()
8 import demandimport; demandimport.enable()
9 from node import *
9 from node import *
10 from i18n import _
10 from i18n import _
11 import bisect, os, re, sys, signal, urllib, pdb, shlex, stat
11 import bisect, os, re, sys, urllib, shlex, stat
12 import fancyopts, ui, hg, util, lock, revlog, bundlerepo, extensions
12 import ui, hg, util, revlog, bundlerepo, extensions
13 import difflib, patch, time, help, mdiff, tempfile
13 import difflib, patch, time, help, mdiff, tempfile
14 import traceback, errno, version, atexit, socket
14 import errno, version, socket
15 import archival, changegroup, cmdutil, hgweb.server, sshserver
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 # Commands start here, listed alphabetically
17 # Commands start here, listed alphabetically
54
18
55 def add(ui, repo, *pats, **opts):
19 def add(ui, repo, *pats, **opts):
@@ -205,7 +169,7 b' def backout(ui, repo, node=None, rev=Non'
205 if not rev:
169 if not rev:
206 rev = node
170 rev = node
207
171
208 bail_if_changed(repo)
172 cmdutil.bail_if_changed(repo)
209 op1, op2 = repo.dirstate.parents()
173 op1, op2 = repo.dirstate.parents()
210 if op2 != nullid:
174 if op2 != nullid:
211 raise util.Abort(_('outstanding uncommitted merge'))
175 raise util.Abort(_('outstanding uncommitted merge'))
@@ -335,7 +299,7 b' def bundle(ui, repo, fname, dest=None, *'
335 seen[p] = 1
299 seen[p] = 1
336 visit.append(p)
300 visit.append(p)
337 else:
301 else:
338 setremoteconfig(ui, opts)
302 cmdutil.setremoteconfig(ui, opts)
339 dest, revs = cmdutil.parseurl(
303 dest, revs = cmdutil.parseurl(
340 ui.expandpath(dest or 'default-push', dest or 'default'), revs)
304 ui.expandpath(dest or 'default-push', dest or 'default'), revs)
341 other = hg.repository(ui, dest)
305 other = hg.repository(ui, dest)
@@ -407,7 +371,7 b' def clone(ui, source, dest=None, **opts)'
407 Look at the help text for the pull command for important details
371 Look at the help text for the pull command for important details
408 about ssh:// URLs.
372 about ssh:// URLs.
409 """
373 """
410 setremoteconfig(ui, opts)
374 cmdutil.setremoteconfig(ui, opts)
411 hg.clone(ui, source, dest,
375 hg.clone(ui, source, dest,
412 pull=opts['pull'],
376 pull=opts['pull'],
413 stream=opts['uncompressed'],
377 stream=opts['uncompressed'],
@@ -425,7 +389,7 b' def commit(ui, repo, *pats, **opts):'
425 If no commit message is specified, the editor configured in your hgrc
389 If no commit message is specified, the editor configured in your hgrc
426 or in the EDITOR environment variable is started to enter a message.
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 if opts['addremove']:
394 if opts['addremove']:
431 cmdutil.addremove(repo, pats, opts)
395 cmdutil.addremove(repo, pats, opts)
@@ -685,7 +649,7 b" def debugcomplete(ui, cmd='', **opts):"
685 options = []
649 options = []
686 otables = [globalopts]
650 otables = [globalopts]
687 if cmd:
651 if cmd:
688 aliases, entry = findcmd(ui, cmd)
652 aliases, entry = cmdutil.findcmd(ui, cmd)
689 otables.append(entry[1])
653 otables.append(entry[1])
690 for t in otables:
654 for t in otables:
691 for o in t:
655 for o in t:
@@ -695,7 +659,7 b" def debugcomplete(ui, cmd='', **opts):"
695 ui.write("%s\n" % "\n".join(options))
659 ui.write("%s\n" % "\n".join(options))
696 return
660 return
697
661
698 clist = findpossible(ui, cmd).keys()
662 clist = cmdutil.findpossible(ui, cmd).keys()
699 clist.sort()
663 clist.sort()
700 ui.write("%s\n" % "\n".join(clist))
664 ui.write("%s\n" % "\n".join(clist))
701
665
@@ -1295,7 +1259,7 b' def help_(ui, name=None, with_version=Fa'
1295 if with_version:
1259 if with_version:
1296 version_(ui)
1260 version_(ui)
1297 ui.write('\n')
1261 ui.write('\n')
1298 aliases, i = findcmd(ui, name)
1262 aliases, i = cmdutil.findcmd(ui, name)
1299 # synopsis
1263 # synopsis
1300 ui.write("%s\n\n" % i[2])
1264 ui.write("%s\n\n" % i[2])
1301
1265
@@ -1357,7 +1321,7 b' def help_(ui, name=None, with_version=Fa'
1357 v = i
1321 v = i
1358 header = l[-1]
1322 header = l[-1]
1359 if not v:
1323 if not v:
1360 raise UnknownCommand(name)
1324 raise cmdutil.UnknownCommand(name)
1361
1325
1362 # description
1326 # description
1363 doc = help.helptable[v]
1327 doc = help.helptable[v]
@@ -1373,7 +1337,7 b' def help_(ui, name=None, with_version=Fa'
1373 try:
1337 try:
1374 mod = extensions.find(name)
1338 mod = extensions.find(name)
1375 except KeyError:
1339 except KeyError:
1376 raise UnknownCommand(name)
1340 raise cmdutil.UnknownCommand(name)
1377
1341
1378 doc = (mod.__doc__ or _('No help text available')).splitlines(0)
1342 doc = (mod.__doc__ or _('No help text available')).splitlines(0)
1379 ui.write(_('%s extension - %s\n') % (name.split('.')[-1], doc[0]))
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 f(name)
1363 f(name)
1400 i = None
1364 i = None
1401 break
1365 break
1402 except UnknownCommand, inst:
1366 except cmdutil.UnknownCommand, inst:
1403 i = inst
1367 i = inst
1404 if i:
1368 if i:
1405 raise i
1369 raise i
@@ -1506,7 +1470,7 b' def import_(ui, repo, patch1, *patches, '
1506 patches = (patch1,) + patches
1470 patches = (patch1,) + patches
1507
1471
1508 if opts.get('exact') or not opts['force']:
1472 if opts.get('exact') or not opts['force']:
1509 bail_if_changed(repo)
1473 cmdutil.bail_if_changed(repo)
1510
1474
1511 d = opts["base"]
1475 d = opts["base"]
1512 strip = opts["strip"]
1476 strip = opts["strip"]
@@ -1528,7 +1492,7 b' def import_(ui, repo, patch1, *patches, '
1528 raise util.Abort(_('no diffs found'))
1492 raise util.Abort(_('no diffs found'))
1529
1493
1530 try:
1494 try:
1531 cmdline_message = logmessage(opts)
1495 cmdline_message = cmdutil.logmessage(opts)
1532 if cmdline_message:
1496 if cmdline_message:
1533 # pickup the cmdline msg
1497 # pickup the cmdline msg
1534 message = cmdline_message
1498 message = cmdline_message
@@ -1587,7 +1551,7 b' def incoming(ui, repo, source="default",'
1587 See pull for valid source format details.
1551 See pull for valid source format details.
1588 """
1552 """
1589 source, revs = cmdutil.parseurl(ui.expandpath(source), opts['rev'])
1553 source, revs = cmdutil.parseurl(ui.expandpath(source), opts['rev'])
1590 setremoteconfig(ui, opts)
1554 cmdutil.setremoteconfig(ui, opts)
1591
1555
1592 other = hg.repository(ui, source)
1556 other = hg.repository(ui, source)
1593 ui.status(_('comparing with %s\n') % source)
1557 ui.status(_('comparing with %s\n') % source)
@@ -1653,7 +1617,7 b' def init(ui, dest=".", **opts):'
1653 Look at the help text for the pull command for important details
1617 Look at the help text for the pull command for important details
1654 about ssh:// URLs.
1618 about ssh:// URLs.
1655 """
1619 """
1656 setremoteconfig(ui, opts)
1620 cmdutil.setremoteconfig(ui, opts)
1657 hg.repository(ui, dest, create=1)
1621 hg.repository(ui, dest, create=1)
1658
1622
1659 def locate(ui, repo, *pats, **opts):
1623 def locate(ui, repo, *pats, **opts):
@@ -1890,7 +1854,7 b' def outgoing(ui, repo, dest=None, **opts'
1890 """
1854 """
1891 dest, revs = cmdutil.parseurl(
1855 dest, revs = cmdutil.parseurl(
1892 ui.expandpath(dest or 'default-push', dest or 'default'), opts['rev'])
1856 ui.expandpath(dest or 'default-push', dest or 'default'), opts['rev'])
1893 setremoteconfig(ui, opts)
1857 cmdutil.setremoteconfig(ui, opts)
1894 if revs:
1858 if revs:
1895 revs = [repo.lookup(rev) for rev in revs]
1859 revs = [repo.lookup(rev) for rev in revs]
1896
1860
@@ -2005,7 +1969,7 b' def pull(ui, repo, source="default", **o'
2005 with the --ssh command line option.
1969 with the --ssh command line option.
2006 """
1970 """
2007 source, revs = cmdutil.parseurl(ui.expandpath(source), opts['rev'])
1971 source, revs = cmdutil.parseurl(ui.expandpath(source), opts['rev'])
2008 setremoteconfig(ui, opts)
1972 cmdutil.setremoteconfig(ui, opts)
2009
1973
2010 other = hg.repository(ui, source)
1974 other = hg.repository(ui, source)
2011 ui.status(_('pulling from %s\n') % (source))
1975 ui.status(_('pulling from %s\n') % (source))
@@ -2051,7 +2015,7 b' def push(ui, repo, dest=None, **opts):'
2051 """
2015 """
2052 dest, revs = cmdutil.parseurl(
2016 dest, revs = cmdutil.parseurl(
2053 ui.expandpath(dest or 'default-push', dest or 'default'), opts['rev'])
2017 ui.expandpath(dest or 'default-push', dest or 'default'), opts['rev'])
2054 setremoteconfig(ui, opts)
2018 cmdutil.setremoteconfig(ui, opts)
2055
2019
2056 other = hg.repository(ui, dest)
2020 other = hg.repository(ui, dest)
2057 ui.status('pushing to %s\n' % (dest))
2021 ui.status('pushing to %s\n' % (dest))
@@ -2075,7 +2039,7 b' def rawcommit(ui, repo, *pats, **opts):'
2075
2039
2076 ui.warn(_("(the rawcommit command is deprecated)\n"))
2040 ui.warn(_("(the rawcommit command is deprecated)\n"))
2077
2041
2078 message = logmessage(opts)
2042 message = cmdutil.logmessage(opts)
2079
2043
2080 files, match, anypats = cmdutil.matchpats(repo, pats, opts)
2044 files, match, anypats = cmdutil.matchpats(repo, pats, opts)
2081 if opts['files']:
2045 if opts['files']:
@@ -3039,272 +3003,5 b' def run():'
3039 except util.Abort, inst:
3003 except util.Abort, inst:
3040 sys.stderr.write(_("abort: %s\n") % inst)
3004 sys.stderr.write(_("abort: %s\n") % inst)
3041 return -1
3005 return -1
3042 sys.exit(runcatch(u, sys.argv[1:]))
3006 sys.exit(cmdutil.runcatch(u, sys.argv[1:]))
3043
3007
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
@@ -1,10 +1,10 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2
2
3 import ConfigParser
3 import ConfigParser
4 from mercurial import ui, util, commands
4 from mercurial import ui, util, cmdutil
5
5
6 testui = ui.ui()
6 testui = ui.ui()
7 parsed = commands.parseconfig([
7 parsed = cmdutil.parseconfig([
8 'values.string=string value',
8 'values.string=string value',
9 'values.bool1=true',
9 'values.bool1=true',
10 'values.bool2=false',
10 'values.bool2=false',
General Comments 0
You need to be logged in to leave comments. Login now