Show More
@@ -0,0 +1,390 b'' | |||||
|
1 | # dispatch.py - command dispatching for mercurial | |||
|
2 | # | |||
|
3 | # Copyright 2005-2007 Matt Mackall <mpm@selenic.com> | |||
|
4 | # | |||
|
5 | # This software may be used and distributed according to the terms | |||
|
6 | # of the GNU General Public License, incorporated herein by reference. | |||
|
7 | ||||
|
8 | from node import * | |||
|
9 | from i18n import _ | |||
|
10 | import os, sys, atexit, signal, pdb, traceback, socket, errno, shlex, time | |||
|
11 | import util, commands, hg, lock, fancyopts, revlog, version, extensions, hook | |||
|
12 | import cmdutil | |||
|
13 | import ui as _ui | |||
|
14 | ||||
|
15 | class ParseError(Exception): | |||
|
16 | """Exception raised on errors in parsing the command line.""" | |||
|
17 | ||||
|
18 | def run(): | |||
|
19 | "run the command in sys.argv" | |||
|
20 | sys.exit(dispatch(sys.argv[1:])) | |||
|
21 | ||||
|
22 | def dispatch(args): | |||
|
23 | "run the command specified in args" | |||
|
24 | try: | |||
|
25 | u = _ui.ui(traceback='--traceback' in args) | |||
|
26 | except util.Abort, inst: | |||
|
27 | sys.stderr.write(_("abort: %s\n") % inst) | |||
|
28 | return -1 | |||
|
29 | return _runcatch(u, args) | |||
|
30 | ||||
|
31 | def _runcatch(ui, args): | |||
|
32 | def catchterm(*args): | |||
|
33 | raise util.SignalInterrupt | |||
|
34 | ||||
|
35 | for name in 'SIGBREAK', 'SIGHUP', 'SIGTERM': | |||
|
36 | num = getattr(signal, name, None) | |||
|
37 | if num: signal.signal(num, catchterm) | |||
|
38 | ||||
|
39 | try: | |||
|
40 | try: | |||
|
41 | # enter the debugger before command execution | |||
|
42 | if '--debugger' in args: | |||
|
43 | pdb.set_trace() | |||
|
44 | try: | |||
|
45 | return _dispatch(ui, args) | |||
|
46 | finally: | |||
|
47 | ui.flush() | |||
|
48 | except: | |||
|
49 | # enter the debugger when we hit an exception | |||
|
50 | if '--debugger' in args: | |||
|
51 | pdb.post_mortem(sys.exc_info()[2]) | |||
|
52 | ui.print_exc() | |||
|
53 | raise | |||
|
54 | ||||
|
55 | except ParseError, inst: | |||
|
56 | if inst.args[0]: | |||
|
57 | ui.warn(_("hg %s: %s\n") % (inst.args[0], inst.args[1])) | |||
|
58 | commands.help_(ui, inst.args[0]) | |||
|
59 | else: | |||
|
60 | ui.warn(_("hg: %s\n") % inst.args[1]) | |||
|
61 | commands.help_(ui, 'shortlist') | |||
|
62 | except cmdutil.AmbiguousCommand, inst: | |||
|
63 | ui.warn(_("hg: command '%s' is ambiguous:\n %s\n") % | |||
|
64 | (inst.args[0], " ".join(inst.args[1]))) | |||
|
65 | except cmdutil.UnknownCommand, inst: | |||
|
66 | ui.warn(_("hg: unknown command '%s'\n") % inst.args[0]) | |||
|
67 | commands.help_(ui, 'shortlist') | |||
|
68 | except hg.RepoError, inst: | |||
|
69 | ui.warn(_("abort: %s!\n") % inst) | |||
|
70 | except lock.LockHeld, inst: | |||
|
71 | if inst.errno == errno.ETIMEDOUT: | |||
|
72 | reason = _('timed out waiting for lock held by %s') % inst.locker | |||
|
73 | else: | |||
|
74 | reason = _('lock held by %s') % inst.locker | |||
|
75 | ui.warn(_("abort: %s: %s\n") % (inst.desc or inst.filename, reason)) | |||
|
76 | except lock.LockUnavailable, inst: | |||
|
77 | ui.warn(_("abort: could not lock %s: %s\n") % | |||
|
78 | (inst.desc or inst.filename, inst.strerror)) | |||
|
79 | except revlog.RevlogError, inst: | |||
|
80 | ui.warn(_("abort: %s!\n") % inst) | |||
|
81 | except util.SignalInterrupt: | |||
|
82 | ui.warn(_("killed!\n")) | |||
|
83 | except KeyboardInterrupt: | |||
|
84 | try: | |||
|
85 | ui.warn(_("interrupted!\n")) | |||
|
86 | except IOError, inst: | |||
|
87 | if inst.errno == errno.EPIPE: | |||
|
88 | if ui.debugflag: | |||
|
89 | ui.warn(_("\nbroken pipe\n")) | |||
|
90 | else: | |||
|
91 | raise | |||
|
92 | except socket.error, inst: | |||
|
93 | ui.warn(_("abort: %s\n") % inst[1]) | |||
|
94 | except IOError, inst: | |||
|
95 | if hasattr(inst, "code"): | |||
|
96 | ui.warn(_("abort: %s\n") % inst) | |||
|
97 | elif hasattr(inst, "reason"): | |||
|
98 | try: # usually it is in the form (errno, strerror) | |||
|
99 | reason = inst.reason.args[1] | |||
|
100 | except: # it might be anything, for example a string | |||
|
101 | reason = inst.reason | |||
|
102 | ui.warn(_("abort: error: %s\n") % reason) | |||
|
103 | elif hasattr(inst, "args") and inst[0] == errno.EPIPE: | |||
|
104 | if ui.debugflag: | |||
|
105 | ui.warn(_("broken pipe\n")) | |||
|
106 | elif getattr(inst, "strerror", None): | |||
|
107 | if getattr(inst, "filename", None): | |||
|
108 | ui.warn(_("abort: %s: %s\n") % (inst.strerror, inst.filename)) | |||
|
109 | else: | |||
|
110 | ui.warn(_("abort: %s\n") % inst.strerror) | |||
|
111 | else: | |||
|
112 | raise | |||
|
113 | except OSError, inst: | |||
|
114 | if getattr(inst, "filename", None): | |||
|
115 | ui.warn(_("abort: %s: %s\n") % (inst.strerror, inst.filename)) | |||
|
116 | else: | |||
|
117 | ui.warn(_("abort: %s\n") % inst.strerror) | |||
|
118 | except util.UnexpectedOutput, inst: | |||
|
119 | ui.warn(_("abort: %s") % inst[0]) | |||
|
120 | if not isinstance(inst[1], basestring): | |||
|
121 | ui.warn(" %r\n" % (inst[1],)) | |||
|
122 | elif not inst[1]: | |||
|
123 | ui.warn(_(" empty string\n")) | |||
|
124 | else: | |||
|
125 | ui.warn("\n%r\n" % util.ellipsis(inst[1])) | |||
|
126 | except ImportError, inst: | |||
|
127 | m = str(inst).split()[-1] | |||
|
128 | ui.warn(_("abort: could not import module %s!\n" % m)) | |||
|
129 | if m in "mpatch bdiff".split(): | |||
|
130 | ui.warn(_("(did you forget to compile extensions?)\n")) | |||
|
131 | elif m in "zlib".split(): | |||
|
132 | ui.warn(_("(is your Python install correct?)\n")) | |||
|
133 | ||||
|
134 | except util.Abort, inst: | |||
|
135 | ui.warn(_("abort: %s\n") % inst) | |||
|
136 | except SystemExit, inst: | |||
|
137 | # Commands shouldn't sys.exit directly, but give a return code. | |||
|
138 | # Just in case catch this and and pass exit code to caller. | |||
|
139 | return inst.code | |||
|
140 | except: | |||
|
141 | ui.warn(_("** unknown exception encountered, details follow\n")) | |||
|
142 | ui.warn(_("** report bug details to " | |||
|
143 | "http://www.selenic.com/mercurial/bts\n")) | |||
|
144 | ui.warn(_("** or mercurial@selenic.com\n")) | |||
|
145 | ui.warn(_("** Mercurial Distributed SCM (version %s)\n") | |||
|
146 | % version.get_version()) | |||
|
147 | raise | |||
|
148 | ||||
|
149 | return -1 | |||
|
150 | ||||
|
151 | def _findrepo(): | |||
|
152 | p = os.getcwd() | |||
|
153 | while not os.path.isdir(os.path.join(p, ".hg")): | |||
|
154 | oldp, p = p, os.path.dirname(p) | |||
|
155 | if p == oldp: | |||
|
156 | return None | |||
|
157 | ||||
|
158 | return p | |||
|
159 | ||||
|
160 | def _parse(ui, args): | |||
|
161 | options = {} | |||
|
162 | cmdoptions = {} | |||
|
163 | ||||
|
164 | try: | |||
|
165 | args = fancyopts.fancyopts(args, commands.globalopts, options) | |||
|
166 | except fancyopts.getopt.GetoptError, inst: | |||
|
167 | raise ParseError(None, inst) | |||
|
168 | ||||
|
169 | if args: | |||
|
170 | cmd, args = args[0], args[1:] | |||
|
171 | aliases, i = cmdutil.findcmd(ui, cmd, commands.table) | |||
|
172 | cmd = aliases[0] | |||
|
173 | defaults = ui.config("defaults", cmd) | |||
|
174 | if defaults: | |||
|
175 | args = shlex.split(defaults) + args | |||
|
176 | c = list(i[1]) | |||
|
177 | else: | |||
|
178 | cmd = None | |||
|
179 | c = [] | |||
|
180 | ||||
|
181 | # combine global options into local | |||
|
182 | for o in commands.globalopts: | |||
|
183 | c.append((o[0], o[1], options[o[1]], o[3])) | |||
|
184 | ||||
|
185 | try: | |||
|
186 | args = fancyopts.fancyopts(args, c, cmdoptions) | |||
|
187 | except fancyopts.getopt.GetoptError, inst: | |||
|
188 | raise ParseError(cmd, inst) | |||
|
189 | ||||
|
190 | # separate global options back out | |||
|
191 | for o in commands.globalopts: | |||
|
192 | n = o[1] | |||
|
193 | options[n] = cmdoptions[n] | |||
|
194 | del cmdoptions[n] | |||
|
195 | ||||
|
196 | return (cmd, cmd and i[0] or None, args, options, cmdoptions) | |||
|
197 | ||||
|
198 | def _parseconfig(config): | |||
|
199 | """parse the --config options from the command line""" | |||
|
200 | parsed = [] | |||
|
201 | for cfg in config: | |||
|
202 | try: | |||
|
203 | name, value = cfg.split('=', 1) | |||
|
204 | section, name = name.split('.', 1) | |||
|
205 | if not section or not name: | |||
|
206 | raise IndexError | |||
|
207 | parsed.append((section, name, value)) | |||
|
208 | except (IndexError, ValueError): | |||
|
209 | raise util.Abort(_('malformed --config option: %s') % cfg) | |||
|
210 | return parsed | |||
|
211 | ||||
|
212 | def _earlygetopt(aliases, args): | |||
|
213 | """Return list of values for an option (or aliases). | |||
|
214 | ||||
|
215 | The values are listed in the order they appear in args. | |||
|
216 | The options and values are removed from args. | |||
|
217 | """ | |||
|
218 | try: | |||
|
219 | argcount = args.index("--") | |||
|
220 | except ValueError: | |||
|
221 | argcount = len(args) | |||
|
222 | shortopts = [opt for opt in aliases if len(opt) == 2] | |||
|
223 | values = [] | |||
|
224 | pos = 0 | |||
|
225 | while pos < argcount: | |||
|
226 | if args[pos] in aliases: | |||
|
227 | if pos + 1 >= argcount: | |||
|
228 | # ignore and let getopt report an error if there is no value | |||
|
229 | break | |||
|
230 | del args[pos] | |||
|
231 | values.append(args.pop(pos)) | |||
|
232 | argcount -= 2 | |||
|
233 | elif args[pos][:2] in shortopts: | |||
|
234 | # short option can have no following space, e.g. hg log -Rfoo | |||
|
235 | values.append(args.pop(pos)[2:]) | |||
|
236 | argcount -= 1 | |||
|
237 | else: | |||
|
238 | pos += 1 | |||
|
239 | return values | |||
|
240 | ||||
|
241 | def _dispatch(ui, args): | |||
|
242 | # read --config before doing anything else | |||
|
243 | # (e.g. to change trust settings for reading .hg/hgrc) | |||
|
244 | config = _earlygetopt(['--config'], args) | |||
|
245 | if config: | |||
|
246 | ui.updateopts(config=_parseconfig(config)) | |||
|
247 | ||||
|
248 | # check for cwd | |||
|
249 | cwd = _earlygetopt(['--cwd'], args) | |||
|
250 | if cwd: | |||
|
251 | os.chdir(cwd[-1]) | |||
|
252 | ||||
|
253 | # read the local repository .hgrc into a local ui object | |||
|
254 | path = _findrepo() or "" | |||
|
255 | if not path: | |||
|
256 | lui = ui | |||
|
257 | if path: | |||
|
258 | try: | |||
|
259 | lui = _ui.ui(parentui=ui) | |||
|
260 | lui.readconfig(os.path.join(path, ".hg", "hgrc")) | |||
|
261 | except IOError: | |||
|
262 | pass | |||
|
263 | ||||
|
264 | # now we can expand paths, even ones in .hg/hgrc | |||
|
265 | rpath = _earlygetopt(["-R", "--repository", "--repo"], args) | |||
|
266 | if rpath: | |||
|
267 | path = lui.expandpath(rpath[-1]) | |||
|
268 | lui = _ui.ui(parentui=ui) | |||
|
269 | lui.readconfig(os.path.join(path, ".hg", "hgrc")) | |||
|
270 | ||||
|
271 | extensions.loadall(lui) | |||
|
272 | # check for fallback encoding | |||
|
273 | fallback = lui.config('ui', 'fallbackencoding') | |||
|
274 | if fallback: | |||
|
275 | util._fallbackencoding = fallback | |||
|
276 | ||||
|
277 | fullargs = args | |||
|
278 | cmd, func, args, options, cmdoptions = _parse(lui, args) | |||
|
279 | ||||
|
280 | if options["config"]: | |||
|
281 | raise util.Abort(_("Option --config may not be abbreviated!")) | |||
|
282 | if options["cwd"]: | |||
|
283 | raise util.Abort(_("Option --cwd may not be abbreviated!")) | |||
|
284 | if options["repository"]: | |||
|
285 | raise util.Abort(_( | |||
|
286 | "Option -R has to be separated from other options (i.e. not -qR) " | |||
|
287 | "and --repository may only be abbreviated as --repo!")) | |||
|
288 | ||||
|
289 | if options["encoding"]: | |||
|
290 | util._encoding = options["encoding"] | |||
|
291 | if options["encodingmode"]: | |||
|
292 | util._encodingmode = options["encodingmode"] | |||
|
293 | if options["time"]: | |||
|
294 | def get_times(): | |||
|
295 | t = os.times() | |||
|
296 | if t[4] == 0.0: # Windows leaves this as zero, so use time.clock() | |||
|
297 | t = (t[0], t[1], t[2], t[3], time.clock()) | |||
|
298 | return t | |||
|
299 | s = get_times() | |||
|
300 | def print_time(): | |||
|
301 | t = get_times() | |||
|
302 | ui.warn(_("Time: real %.3f secs (user %.3f+%.3f sys %.3f+%.3f)\n") % | |||
|
303 | (t[4]-s[4], t[0]-s[0], t[2]-s[2], t[1]-s[1], t[3]-s[3])) | |||
|
304 | atexit.register(print_time) | |||
|
305 | ||||
|
306 | ui.updateopts(options["verbose"], options["debug"], options["quiet"], | |||
|
307 | not options["noninteractive"], options["traceback"]) | |||
|
308 | ||||
|
309 | if options['help']: | |||
|
310 | return commands.help_(ui, cmd, options['version']) | |||
|
311 | elif options['version']: | |||
|
312 | return commands.version_(ui) | |||
|
313 | elif not cmd: | |||
|
314 | return commands.help_(ui, 'shortlist') | |||
|
315 | ||||
|
316 | repo = None | |||
|
317 | if cmd not in commands.norepo.split(): | |||
|
318 | try: | |||
|
319 | repo = hg.repository(ui, path=path) | |||
|
320 | ui = repo.ui | |||
|
321 | if not repo.local(): | |||
|
322 | raise util.Abort(_("repository '%s' is not local") % path) | |||
|
323 | except hg.RepoError: | |||
|
324 | if cmd not in commands.optionalrepo.split(): | |||
|
325 | if not path: | |||
|
326 | raise hg.RepoError(_("There is no Mercurial repository here" | |||
|
327 | " (.hg not found)")) | |||
|
328 | raise | |||
|
329 | d = lambda: func(ui, repo, *args, **cmdoptions) | |||
|
330 | else: | |||
|
331 | d = lambda: func(ui, *args, **cmdoptions) | |||
|
332 | ||||
|
333 | # run pre-hook, and abort if it fails | |||
|
334 | ret = hook.hook(ui, repo, "pre-%s" % cmd, False, args=" ".join(fullargs)) | |||
|
335 | if ret: | |||
|
336 | return ret | |||
|
337 | ret = _runcommand(ui, options, cmd, d) | |||
|
338 | # run post-hook, passing command result | |||
|
339 | hook.hook(ui, repo, "post-%s" % cmd, False, args=" ".join(fullargs), | |||
|
340 | result = ret) | |||
|
341 | return ret | |||
|
342 | ||||
|
343 | def _runcommand(ui, options, cmd, cmdfunc): | |||
|
344 | def checkargs(): | |||
|
345 | try: | |||
|
346 | return cmdfunc() | |||
|
347 | except TypeError, inst: | |||
|
348 | # was this an argument error? | |||
|
349 | tb = traceback.extract_tb(sys.exc_info()[2]) | |||
|
350 | if len(tb) != 2: # no | |||
|
351 | raise | |||
|
352 | raise ParseError(cmd, _("invalid arguments")) | |||
|
353 | ||||
|
354 | if options['profile']: | |||
|
355 | import hotshot, hotshot.stats | |||
|
356 | prof = hotshot.Profile("hg.prof") | |||
|
357 | try: | |||
|
358 | try: | |||
|
359 | return prof.runcall(checkargs) | |||
|
360 | except: | |||
|
361 | try: | |||
|
362 | ui.warn(_('exception raised - generating ' | |||
|
363 | 'profile anyway\n')) | |||
|
364 | except: | |||
|
365 | pass | |||
|
366 | raise | |||
|
367 | finally: | |||
|
368 | prof.close() | |||
|
369 | stats = hotshot.stats.load("hg.prof") | |||
|
370 | stats.strip_dirs() | |||
|
371 | stats.sort_stats('time', 'calls') | |||
|
372 | stats.print_stats(40) | |||
|
373 | elif options['lsprof']: | |||
|
374 | try: | |||
|
375 | from mercurial import lsprof | |||
|
376 | except ImportError: | |||
|
377 | raise util.Abort(_( | |||
|
378 | 'lsprof not available - install from ' | |||
|
379 | 'http://codespeak.net/svn/user/arigo/hack/misc/lsprof/')) | |||
|
380 | p = lsprof.Profiler() | |||
|
381 | p.enable(subcalls=True) | |||
|
382 | try: | |||
|
383 | return checkargs() | |||
|
384 | finally: | |||
|
385 | p.disable() | |||
|
386 | stats = lsprof.Stats(p.getstats()) | |||
|
387 | stats.sort() | |||
|
388 | stats.pprint(top=10, file=sys.stderr, climit=5) | |||
|
389 | else: | |||
|
390 | return checkargs() |
@@ -7,5 +7,5 b'' | |||||
7 | # This software may be used and distributed according to the terms |
|
7 | # This software may be used and distributed according to the terms | |
8 | # of the GNU General Public License, incorporated herein by reference. |
|
8 | # of the GNU General Public License, incorporated herein by reference. | |
9 |
|
9 | |||
10 |
import mercurial. |
|
10 | import mercurial.dispatch | |
11 |
mercurial. |
|
11 | mercurial.dispatch.run() |
@@ -42,7 +42,7 b' class lazycommand(object):' | |||||
42 | return |
|
42 | return | |
43 |
|
43 | |||
44 | try: |
|
44 | try: | |
45 | self._cmd = findcmd(self._ui, self._target)[1] |
|
45 | self._cmd = findcmd(self._ui, self._target, commands.table)[1] | |
46 | if self._cmd == self: |
|
46 | if self._cmd == self: | |
47 | raise RecursiveCommand() |
|
47 | raise RecursiveCommand() | |
48 | if self._target in commands.norepo.split(' '): |
|
48 | if self._target in commands.norepo.split(' '): |
@@ -7,10 +7,8 b'' | |||||
7 |
|
7 | |||
8 | from node import * |
|
8 | from node import * | |
9 | from i18n import _ |
|
9 | from i18n import _ | |
10 | import os, sys, atexit, signal, pdb, traceback, socket, errno, shlex |
|
10 | import os, sys, bisect, stat | |
11 | import bisect, stat |
|
11 | import mdiff, bdiff, util, templater, patch | |
12 | import mdiff, bdiff, util, templater, patch, commands, hg, lock, time |
|
|||
13 | import fancyopts, revlog, version, extensions, hook |
|
|||
14 |
|
12 | |||
15 | revrangesep = ':' |
|
13 | revrangesep = ':' | |
16 |
|
14 | |||
@@ -18,130 +16,8 b' class UnknownCommand(Exception):' | |||||
18 | """Exception raised if command is not in the command table.""" |
|
16 | """Exception raised if command is not in the command table.""" | |
19 | class AmbiguousCommand(Exception): |
|
17 | class AmbiguousCommand(Exception): | |
20 | """Exception raised if command shortcut matches more than one command.""" |
|
18 | """Exception raised if command shortcut matches more than one command.""" | |
21 | class ParseError(Exception): |
|
|||
22 | """Exception raised on errors in parsing the command line.""" |
|
|||
23 |
|
19 | |||
24 | def runcatch(ui, args): |
|
20 | def findpossible(ui, cmd, table): | |
25 | def catchterm(*args): |
|
|||
26 | raise util.SignalInterrupt |
|
|||
27 |
|
||||
28 | for name in 'SIGBREAK', 'SIGHUP', 'SIGTERM': |
|
|||
29 | num = getattr(signal, name, None) |
|
|||
30 | if num: signal.signal(num, catchterm) |
|
|||
31 |
|
||||
32 | try: |
|
|||
33 | try: |
|
|||
34 | # enter the debugger before command execution |
|
|||
35 | if '--debugger' in args: |
|
|||
36 | pdb.set_trace() |
|
|||
37 | try: |
|
|||
38 | return dispatch(ui, args) |
|
|||
39 | finally: |
|
|||
40 | ui.flush() |
|
|||
41 | except: |
|
|||
42 | # enter the debugger when we hit an exception |
|
|||
43 | if '--debugger' in args: |
|
|||
44 | pdb.post_mortem(sys.exc_info()[2]) |
|
|||
45 | ui.print_exc() |
|
|||
46 | raise |
|
|||
47 |
|
||||
48 | except ParseError, inst: |
|
|||
49 | if inst.args[0]: |
|
|||
50 | ui.warn(_("hg %s: %s\n") % (inst.args[0], inst.args[1])) |
|
|||
51 | commands.help_(ui, inst.args[0]) |
|
|||
52 | else: |
|
|||
53 | ui.warn(_("hg: %s\n") % inst.args[1]) |
|
|||
54 | commands.help_(ui, 'shortlist') |
|
|||
55 | except AmbiguousCommand, inst: |
|
|||
56 | ui.warn(_("hg: command '%s' is ambiguous:\n %s\n") % |
|
|||
57 | (inst.args[0], " ".join(inst.args[1]))) |
|
|||
58 | except UnknownCommand, inst: |
|
|||
59 | ui.warn(_("hg: unknown command '%s'\n") % inst.args[0]) |
|
|||
60 | commands.help_(ui, 'shortlist') |
|
|||
61 | except hg.RepoError, inst: |
|
|||
62 | ui.warn(_("abort: %s!\n") % inst) |
|
|||
63 | except lock.LockHeld, inst: |
|
|||
64 | if inst.errno == errno.ETIMEDOUT: |
|
|||
65 | reason = _('timed out waiting for lock held by %s') % inst.locker |
|
|||
66 | else: |
|
|||
67 | reason = _('lock held by %s') % inst.locker |
|
|||
68 | ui.warn(_("abort: %s: %s\n") % (inst.desc or inst.filename, reason)) |
|
|||
69 | except lock.LockUnavailable, inst: |
|
|||
70 | ui.warn(_("abort: could not lock %s: %s\n") % |
|
|||
71 | (inst.desc or inst.filename, inst.strerror)) |
|
|||
72 | except revlog.RevlogError, inst: |
|
|||
73 | ui.warn(_("abort: %s!\n") % inst) |
|
|||
74 | except util.SignalInterrupt: |
|
|||
75 | ui.warn(_("killed!\n")) |
|
|||
76 | except KeyboardInterrupt: |
|
|||
77 | try: |
|
|||
78 | ui.warn(_("interrupted!\n")) |
|
|||
79 | except IOError, inst: |
|
|||
80 | if inst.errno == errno.EPIPE: |
|
|||
81 | if ui.debugflag: |
|
|||
82 | ui.warn(_("\nbroken pipe\n")) |
|
|||
83 | else: |
|
|||
84 | raise |
|
|||
85 | except socket.error, inst: |
|
|||
86 | ui.warn(_("abort: %s\n") % inst[1]) |
|
|||
87 | except IOError, inst: |
|
|||
88 | if hasattr(inst, "code"): |
|
|||
89 | ui.warn(_("abort: %s\n") % inst) |
|
|||
90 | elif hasattr(inst, "reason"): |
|
|||
91 | try: # usually it is in the form (errno, strerror) |
|
|||
92 | reason = inst.reason.args[1] |
|
|||
93 | except: # it might be anything, for example a string |
|
|||
94 | reason = inst.reason |
|
|||
95 | ui.warn(_("abort: error: %s\n") % reason) |
|
|||
96 | elif hasattr(inst, "args") and inst[0] == errno.EPIPE: |
|
|||
97 | if ui.debugflag: |
|
|||
98 | ui.warn(_("broken pipe\n")) |
|
|||
99 | elif getattr(inst, "strerror", None): |
|
|||
100 | if getattr(inst, "filename", None): |
|
|||
101 | ui.warn(_("abort: %s: %s\n") % (inst.strerror, inst.filename)) |
|
|||
102 | else: |
|
|||
103 | ui.warn(_("abort: %s\n") % inst.strerror) |
|
|||
104 | else: |
|
|||
105 | raise |
|
|||
106 | except OSError, inst: |
|
|||
107 | if getattr(inst, "filename", None): |
|
|||
108 | ui.warn(_("abort: %s: %s\n") % (inst.strerror, inst.filename)) |
|
|||
109 | else: |
|
|||
110 | ui.warn(_("abort: %s\n") % inst.strerror) |
|
|||
111 | except util.UnexpectedOutput, inst: |
|
|||
112 | ui.warn(_("abort: %s") % inst[0]) |
|
|||
113 | if not isinstance(inst[1], basestring): |
|
|||
114 | ui.warn(" %r\n" % (inst[1],)) |
|
|||
115 | elif not inst[1]: |
|
|||
116 | ui.warn(_(" empty string\n")) |
|
|||
117 | else: |
|
|||
118 | ui.warn("\n%r\n" % util.ellipsis(inst[1])) |
|
|||
119 | except ImportError, inst: |
|
|||
120 | m = str(inst).split()[-1] |
|
|||
121 | ui.warn(_("abort: could not import module %s!\n" % m)) |
|
|||
122 | if m in "mpatch bdiff".split(): |
|
|||
123 | ui.warn(_("(did you forget to compile extensions?)\n")) |
|
|||
124 | elif m in "zlib".split(): |
|
|||
125 | ui.warn(_("(is your Python install correct?)\n")) |
|
|||
126 |
|
||||
127 | except util.Abort, inst: |
|
|||
128 | ui.warn(_("abort: %s\n") % inst) |
|
|||
129 | except SystemExit, inst: |
|
|||
130 | # Commands shouldn't sys.exit directly, but give a return code. |
|
|||
131 | # Just in case catch this and and pass exit code to caller. |
|
|||
132 | return inst.code |
|
|||
133 | except: |
|
|||
134 | ui.warn(_("** unknown exception encountered, details follow\n")) |
|
|||
135 | ui.warn(_("** report bug details to " |
|
|||
136 | "http://www.selenic.com/mercurial/bts\n")) |
|
|||
137 | ui.warn(_("** or mercurial@selenic.com\n")) |
|
|||
138 | ui.warn(_("** Mercurial Distributed SCM (version %s)\n") |
|
|||
139 | % version.get_version()) |
|
|||
140 | raise |
|
|||
141 |
|
||||
142 | return -1 |
|
|||
143 |
|
||||
144 | def findpossible(ui, cmd): |
|
|||
145 | """ |
|
21 | """ | |
146 | Return cmd -> (aliases, command table entry) |
|
22 | Return cmd -> (aliases, command table entry) | |
147 | for each matching command. |
|
23 | for each matching command. | |
@@ -149,7 +25,7 b' def findpossible(ui, cmd):' | |||||
149 | """ |
|
25 | """ | |
150 | choice = {} |
|
26 | choice = {} | |
151 | debugchoice = {} |
|
27 | debugchoice = {} | |
152 |
for e in |
|
28 | for e in table.keys(): | |
153 | aliases = e.lstrip("^").split("|") |
|
29 | aliases = e.lstrip("^").split("|") | |
154 | found = None |
|
30 | found = None | |
155 | if cmd in aliases: |
|
31 | if cmd in aliases: | |
@@ -161,18 +37,18 b' def findpossible(ui, cmd):' | |||||
161 | break |
|
37 | break | |
162 | if found is not None: |
|
38 | if found is not None: | |
163 | if aliases[0].startswith("debug") or found.startswith("debug"): |
|
39 | if aliases[0].startswith("debug") or found.startswith("debug"): | |
164 |
debugchoice[found] = (aliases, |
|
40 | debugchoice[found] = (aliases, table[e]) | |
165 | else: |
|
41 | else: | |
166 |
choice[found] = (aliases, |
|
42 | choice[found] = (aliases, table[e]) | |
167 |
|
43 | |||
168 | if not choice and debugchoice: |
|
44 | if not choice and debugchoice: | |
169 | choice = debugchoice |
|
45 | choice = debugchoice | |
170 |
|
46 | |||
171 | return choice |
|
47 | return choice | |
172 |
|
48 | |||
173 | def findcmd(ui, cmd): |
|
49 | def findcmd(ui, cmd, table): | |
174 | """Return (aliases, command table entry) for command string.""" |
|
50 | """Return (aliases, command table entry) for command string.""" | |
175 | choice = findpossible(ui, cmd) |
|
51 | choice = findpossible(ui, cmd, table) | |
176 |
|
52 | |||
177 | if choice.has_key(cmd): |
|
53 | if choice.has_key(cmd): | |
178 | return choice[cmd] |
|
54 | return choice[cmd] | |
@@ -187,247 +63,6 b' def findcmd(ui, cmd):' | |||||
187 |
|
63 | |||
188 | raise UnknownCommand(cmd) |
|
64 | raise UnknownCommand(cmd) | |
189 |
|
65 | |||
190 | def findrepo(): |
|
|||
191 | p = os.getcwd() |
|
|||
192 | while not os.path.isdir(os.path.join(p, ".hg")): |
|
|||
193 | oldp, p = p, os.path.dirname(p) |
|
|||
194 | if p == oldp: |
|
|||
195 | return None |
|
|||
196 |
|
||||
197 | return p |
|
|||
198 |
|
||||
199 | def parse(ui, args): |
|
|||
200 | options = {} |
|
|||
201 | cmdoptions = {} |
|
|||
202 |
|
||||
203 | try: |
|
|||
204 | args = fancyopts.fancyopts(args, commands.globalopts, options) |
|
|||
205 | except fancyopts.getopt.GetoptError, inst: |
|
|||
206 | raise ParseError(None, inst) |
|
|||
207 |
|
||||
208 | if args: |
|
|||
209 | cmd, args = args[0], args[1:] |
|
|||
210 | aliases, i = findcmd(ui, cmd) |
|
|||
211 | cmd = aliases[0] |
|
|||
212 | defaults = ui.config("defaults", cmd) |
|
|||
213 | if defaults: |
|
|||
214 | args = shlex.split(defaults) + args |
|
|||
215 | c = list(i[1]) |
|
|||
216 | else: |
|
|||
217 | cmd = None |
|
|||
218 | c = [] |
|
|||
219 |
|
||||
220 | # combine global options into local |
|
|||
221 | for o in commands.globalopts: |
|
|||
222 | c.append((o[0], o[1], options[o[1]], o[3])) |
|
|||
223 |
|
||||
224 | try: |
|
|||
225 | args = fancyopts.fancyopts(args, c, cmdoptions) |
|
|||
226 | except fancyopts.getopt.GetoptError, inst: |
|
|||
227 | raise ParseError(cmd, inst) |
|
|||
228 |
|
||||
229 | # separate global options back out |
|
|||
230 | for o in commands.globalopts: |
|
|||
231 | n = o[1] |
|
|||
232 | options[n] = cmdoptions[n] |
|
|||
233 | del cmdoptions[n] |
|
|||
234 |
|
||||
235 | return (cmd, cmd and i[0] or None, args, options, cmdoptions) |
|
|||
236 |
|
||||
237 | def parseconfig(config): |
|
|||
238 | """parse the --config options from the command line""" |
|
|||
239 | parsed = [] |
|
|||
240 | for cfg in config: |
|
|||
241 | try: |
|
|||
242 | name, value = cfg.split('=', 1) |
|
|||
243 | section, name = name.split('.', 1) |
|
|||
244 | if not section or not name: |
|
|||
245 | raise IndexError |
|
|||
246 | parsed.append((section, name, value)) |
|
|||
247 | except (IndexError, ValueError): |
|
|||
248 | raise util.Abort(_('malformed --config option: %s') % cfg) |
|
|||
249 | return parsed |
|
|||
250 |
|
||||
251 | def earlygetopt(aliases, args): |
|
|||
252 | """Return list of values for an option (or aliases). |
|
|||
253 |
|
||||
254 | The values are listed in the order they appear in args. |
|
|||
255 | The options and values are removed from args. |
|
|||
256 | """ |
|
|||
257 | try: |
|
|||
258 | argcount = args.index("--") |
|
|||
259 | except ValueError: |
|
|||
260 | argcount = len(args) |
|
|||
261 | shortopts = [opt for opt in aliases if len(opt) == 2] |
|
|||
262 | values = [] |
|
|||
263 | pos = 0 |
|
|||
264 | while pos < argcount: |
|
|||
265 | if args[pos] in aliases: |
|
|||
266 | if pos + 1 >= argcount: |
|
|||
267 | # ignore and let getopt report an error if there is no value |
|
|||
268 | break |
|
|||
269 | del args[pos] |
|
|||
270 | values.append(args.pop(pos)) |
|
|||
271 | argcount -= 2 |
|
|||
272 | elif args[pos][:2] in shortopts: |
|
|||
273 | # short option can have no following space, e.g. hg log -Rfoo |
|
|||
274 | values.append(args.pop(pos)[2:]) |
|
|||
275 | argcount -= 1 |
|
|||
276 | else: |
|
|||
277 | pos += 1 |
|
|||
278 | return values |
|
|||
279 |
|
||||
280 | def dispatch(ui, args): |
|
|||
281 | # read --config before doing anything else |
|
|||
282 | # (e.g. to change trust settings for reading .hg/hgrc) |
|
|||
283 | config = earlygetopt(['--config'], args) |
|
|||
284 | if config: |
|
|||
285 | ui.updateopts(config=parseconfig(config)) |
|
|||
286 |
|
||||
287 | # check for cwd |
|
|||
288 | cwd = earlygetopt(['--cwd'], args) |
|
|||
289 | if cwd: |
|
|||
290 | os.chdir(cwd[-1]) |
|
|||
291 |
|
||||
292 | # read the local repository .hgrc into a local ui object |
|
|||
293 | path = findrepo() or "" |
|
|||
294 | if not path: |
|
|||
295 | lui = ui |
|
|||
296 | if path: |
|
|||
297 | try: |
|
|||
298 | lui = commands.ui.ui(parentui=ui) |
|
|||
299 | lui.readconfig(os.path.join(path, ".hg", "hgrc")) |
|
|||
300 | except IOError: |
|
|||
301 | pass |
|
|||
302 |
|
||||
303 | # now we can expand paths, even ones in .hg/hgrc |
|
|||
304 | rpath = earlygetopt(["-R", "--repository", "--repo"], args) |
|
|||
305 | if rpath: |
|
|||
306 | path = lui.expandpath(rpath[-1]) |
|
|||
307 | lui = commands.ui.ui(parentui=ui) |
|
|||
308 | lui.readconfig(os.path.join(path, ".hg", "hgrc")) |
|
|||
309 |
|
||||
310 | extensions.loadall(lui) |
|
|||
311 | # check for fallback encoding |
|
|||
312 | fallback = lui.config('ui', 'fallbackencoding') |
|
|||
313 | if fallback: |
|
|||
314 | util._fallbackencoding = fallback |
|
|||
315 |
|
||||
316 | fullargs = args |
|
|||
317 | cmd, func, args, options, cmdoptions = parse(lui, args) |
|
|||
318 |
|
||||
319 | if options["config"]: |
|
|||
320 | raise util.Abort(_("Option --config may not be abbreviated!")) |
|
|||
321 | if options["cwd"]: |
|
|||
322 | raise util.Abort(_("Option --cwd may not be abbreviated!")) |
|
|||
323 | if options["repository"]: |
|
|||
324 | raise util.Abort(_( |
|
|||
325 | "Option -R has to be separated from other options (i.e. not -qR) " |
|
|||
326 | "and --repository may only be abbreviated as --repo!")) |
|
|||
327 |
|
||||
328 | if options["encoding"]: |
|
|||
329 | util._encoding = options["encoding"] |
|
|||
330 | if options["encodingmode"]: |
|
|||
331 | util._encodingmode = options["encodingmode"] |
|
|||
332 | if options["time"]: |
|
|||
333 | def get_times(): |
|
|||
334 | t = os.times() |
|
|||
335 | if t[4] == 0.0: # Windows leaves this as zero, so use time.clock() |
|
|||
336 | t = (t[0], t[1], t[2], t[3], time.clock()) |
|
|||
337 | return t |
|
|||
338 | s = get_times() |
|
|||
339 | def print_time(): |
|
|||
340 | t = get_times() |
|
|||
341 | ui.warn(_("Time: real %.3f secs (user %.3f+%.3f sys %.3f+%.3f)\n") % |
|
|||
342 | (t[4]-s[4], t[0]-s[0], t[2]-s[2], t[1]-s[1], t[3]-s[3])) |
|
|||
343 | atexit.register(print_time) |
|
|||
344 |
|
||||
345 | ui.updateopts(options["verbose"], options["debug"], options["quiet"], |
|
|||
346 | not options["noninteractive"], options["traceback"]) |
|
|||
347 |
|
||||
348 | if options['help']: |
|
|||
349 | return commands.help_(ui, cmd, options['version']) |
|
|||
350 | elif options['version']: |
|
|||
351 | return commands.version_(ui) |
|
|||
352 | elif not cmd: |
|
|||
353 | return commands.help_(ui, 'shortlist') |
|
|||
354 |
|
||||
355 | repo = None |
|
|||
356 | if cmd not in commands.norepo.split(): |
|
|||
357 | try: |
|
|||
358 | repo = hg.repository(ui, path=path) |
|
|||
359 | ui = repo.ui |
|
|||
360 | if not repo.local(): |
|
|||
361 | raise util.Abort(_("repository '%s' is not local") % path) |
|
|||
362 | except hg.RepoError: |
|
|||
363 | if cmd not in commands.optionalrepo.split(): |
|
|||
364 | if not path: |
|
|||
365 | raise hg.RepoError(_("There is no Mercurial repository here" |
|
|||
366 | " (.hg not found)")) |
|
|||
367 | raise |
|
|||
368 | d = lambda: func(ui, repo, *args, **cmdoptions) |
|
|||
369 | else: |
|
|||
370 | d = lambda: func(ui, *args, **cmdoptions) |
|
|||
371 |
|
||||
372 | # run pre-hook, and abort if it fails |
|
|||
373 | ret = hook.hook(ui, repo, "pre-%s" % cmd, False, args=" ".join(fullargs)) |
|
|||
374 | if ret: |
|
|||
375 | return ret |
|
|||
376 | ret = runcommand(ui, options, cmd, d) |
|
|||
377 | # run post-hook, passing command result |
|
|||
378 | hook.hook(ui, repo, "post-%s" % cmd, False, args=" ".join(fullargs), |
|
|||
379 | result = ret) |
|
|||
380 | return ret |
|
|||
381 |
|
||||
382 | def runcommand(ui, options, cmd, cmdfunc): |
|
|||
383 | def checkargs(): |
|
|||
384 | try: |
|
|||
385 | return cmdfunc() |
|
|||
386 | except TypeError, inst: |
|
|||
387 | # was this an argument error? |
|
|||
388 | tb = traceback.extract_tb(sys.exc_info()[2]) |
|
|||
389 | if len(tb) != 2: # no |
|
|||
390 | raise |
|
|||
391 | raise ParseError(cmd, _("invalid arguments")) |
|
|||
392 |
|
||||
393 | if options['profile']: |
|
|||
394 | import hotshot, hotshot.stats |
|
|||
395 | prof = hotshot.Profile("hg.prof") |
|
|||
396 | try: |
|
|||
397 | try: |
|
|||
398 | return prof.runcall(checkargs) |
|
|||
399 | except: |
|
|||
400 | try: |
|
|||
401 | ui.warn(_('exception raised - generating ' |
|
|||
402 | 'profile anyway\n')) |
|
|||
403 | except: |
|
|||
404 | pass |
|
|||
405 | raise |
|
|||
406 | finally: |
|
|||
407 | prof.close() |
|
|||
408 | stats = hotshot.stats.load("hg.prof") |
|
|||
409 | stats.strip_dirs() |
|
|||
410 | stats.sort_stats('time', 'calls') |
|
|||
411 | stats.print_stats(40) |
|
|||
412 | elif options['lsprof']: |
|
|||
413 | try: |
|
|||
414 | from mercurial import lsprof |
|
|||
415 | except ImportError: |
|
|||
416 | raise util.Abort(_( |
|
|||
417 | 'lsprof not available - install from ' |
|
|||
418 | 'http://codespeak.net/svn/user/arigo/hack/misc/lsprof/')) |
|
|||
419 | p = lsprof.Profiler() |
|
|||
420 | p.enable(subcalls=True) |
|
|||
421 | try: |
|
|||
422 | return checkargs() |
|
|||
423 | finally: |
|
|||
424 | p.disable() |
|
|||
425 | stats = lsprof.Stats(p.getstats()) |
|
|||
426 | stats.sort() |
|
|||
427 | stats.pprint(top=10, file=sys.stderr, climit=5) |
|
|||
428 | else: |
|
|||
429 | return checkargs() |
|
|||
430 |
|
||||
431 | def bail_if_changed(repo): |
|
66 | def bail_if_changed(repo): | |
432 | modified, added, removed, deleted = repo.status()[:4] |
|
67 | modified, added, removed, deleted = repo.status()[:4] | |
433 | if modified or added or removed or deleted: |
|
68 | if modified or added or removed or deleted: |
@@ -9,7 +9,7 b' import demandimport; demandimport.enable' | |||||
9 | from node import * |
|
9 | from node import * | |
10 | from i18n import _ |
|
10 | from i18n import _ | |
11 | import os, re, sys, urllib |
|
11 | import os, re, sys, urllib | |
12 |
import |
|
12 | import hg, util, revlog, bundlerepo, extensions | |
13 | import difflib, patch, time, help, mdiff, tempfile |
|
13 | import difflib, patch, time, help, mdiff, tempfile | |
14 | import errno, version, socket |
|
14 | import errno, version, socket | |
15 | import archival, changegroup, cmdutil, hgweb.server, sshserver |
|
15 | import archival, changegroup, cmdutil, hgweb.server, sshserver | |
@@ -662,7 +662,7 b" def debugcomplete(ui, cmd='', **opts):" | |||||
662 | options = [] |
|
662 | options = [] | |
663 | otables = [globalopts] |
|
663 | otables = [globalopts] | |
664 | if cmd: |
|
664 | if cmd: | |
665 | aliases, entry = cmdutil.findcmd(ui, cmd) |
|
665 | aliases, entry = cmdutil.findcmd(ui, cmd, table) | |
666 | otables.append(entry[1]) |
|
666 | otables.append(entry[1]) | |
667 | for t in otables: |
|
667 | for t in otables: | |
668 | for o in t: |
|
668 | for o in t: | |
@@ -672,7 +672,7 b" def debugcomplete(ui, cmd='', **opts):" | |||||
672 | ui.write("%s\n" % "\n".join(options)) |
|
672 | ui.write("%s\n" % "\n".join(options)) | |
673 | return |
|
673 | return | |
674 |
|
674 | |||
675 | clist = cmdutil.findpossible(ui, cmd).keys() |
|
675 | clist = cmdutil.findpossible(ui, cmd, table).keys() | |
676 | clist.sort() |
|
676 | clist.sort() | |
677 | ui.write("%s\n" % "\n".join(clist)) |
|
677 | ui.write("%s\n" % "\n".join(clist)) | |
678 |
|
678 | |||
@@ -1307,7 +1307,7 b' def help_(ui, name=None, with_version=Fa' | |||||
1307 | if with_version: |
|
1307 | if with_version: | |
1308 | version_(ui) |
|
1308 | version_(ui) | |
1309 | ui.write('\n') |
|
1309 | ui.write('\n') | |
1310 | aliases, i = cmdutil.findcmd(ui, name) |
|
1310 | aliases, i = cmdutil.findcmd(ui, name, table) | |
1311 | # synopsis |
|
1311 | # synopsis | |
1312 | ui.write("%s\n\n" % i[2]) |
|
1312 | ui.write("%s\n\n" % i[2]) | |
1313 |
|
1313 | |||
@@ -3134,14 +3134,3 b' extensions.commandtable = table' | |||||
3134 | norepo = ("clone init version help debugancestor debugcomplete debugdata" |
|
3134 | norepo = ("clone init version help debugancestor debugcomplete debugdata" | |
3135 | " debugindex debugindexdot debugdate debuginstall") |
|
3135 | " debugindex debugindexdot debugdate debuginstall") | |
3136 | optionalrepo = ("paths serve showconfig") |
|
3136 | optionalrepo = ("paths serve showconfig") | |
3137 |
|
||||
3138 | def dispatch(args): |
|
|||
3139 | try: |
|
|||
3140 | u = ui.ui(traceback='--traceback' in args) |
|
|||
3141 | except util.Abort, inst: |
|
|||
3142 | sys.stderr.write(_("abort: %s\n") % inst) |
|
|||
3143 | return -1 |
|
|||
3144 | return cmdutil.runcatch(u, args) |
|
|||
3145 |
|
||||
3146 | def run(): |
|
|||
3147 | sys.exit(dispatch(sys.argv[1:])) |
|
@@ -1,32 +1,32 b'' | |||||
1 | import os |
|
1 | import os | |
2 |
from mercurial import |
|
2 | from mercurial import dispatch | |
3 |
|
3 | |||
4 | def dispatch(cmd): |
|
4 | def testdispatch(cmd): | |
5 |
"""Simple wrapper around |
|
5 | """Simple wrapper around dispatch.dispatch() | |
6 |
|
6 | |||
7 | Prints command and result value, but does not handle quoting. |
|
7 | Prints command and result value, but does not handle quoting. | |
8 | """ |
|
8 | """ | |
9 | print "running: %s" % (cmd,) |
|
9 | print "running: %s" % (cmd,) | |
10 |
result = |
|
10 | result = dispatch.dispatch(cmd.split()) | |
11 | print "result: %r" % (result,) |
|
11 | print "result: %r" % (result,) | |
12 |
|
12 | |||
13 |
|
13 | |||
14 | dispatch("init test1") |
|
14 | testdispatch("init test1") | |
15 | os.chdir('test1') |
|
15 | os.chdir('test1') | |
16 |
|
16 | |||
17 | # create file 'foo', add and commit |
|
17 | # create file 'foo', add and commit | |
18 | f = file('foo', 'wb') |
|
18 | f = file('foo', 'wb') | |
19 | f.write('foo\n') |
|
19 | f.write('foo\n') | |
20 | f.close() |
|
20 | f.close() | |
21 | dispatch("add foo") |
|
21 | testdispatch("add foo") | |
22 | dispatch("commit -m commit1 -d 2000-01-01 foo") |
|
22 | testdispatch("commit -m commit1 -d 2000-01-01 foo") | |
23 |
|
23 | |||
24 | # append to file 'foo' and commit |
|
24 | # append to file 'foo' and commit | |
25 | f = file('foo', 'ab') |
|
25 | f = file('foo', 'ab') | |
26 | f.write('bar\n') |
|
26 | f.write('bar\n') | |
27 | f.close() |
|
27 | f.close() | |
28 | dispatch("commit -m commit2 -d 2000-01-02 foo") |
|
28 | testdispatch("commit -m commit2 -d 2000-01-02 foo") | |
29 |
|
29 | |||
30 | # check 88803a69b24 (fancyopts modified command table) |
|
30 | # check 88803a69b24 (fancyopts modified command table) | |
31 | dispatch("log -r 0") |
|
31 | testdispatch("log -r 0") | |
32 | dispatch("log -r tip") |
|
32 | testdispatch("log -r tip") |
@@ -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, |
|
4 | from mercurial import ui, util, dispatch | |
5 |
|
5 | |||
6 | testui = ui.ui() |
|
6 | testui = ui.ui() | |
7 |
parsed = |
|
7 | parsed = dispatch._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