comparison upmana/mercurial/dispatch.py @ 135:dcf4fbe09b70 beta

Traipse Beta 'OpenRPG' {091010-00} Traipse is a distribution of OpenRPG that is designed to be easy to setup and go. Traipse also makes it easy for developers to work on code without fear of sacrifice. 'Ornery-Orc' continues the trend of 'Grumpy' and adds fixes to the code. 'Ornery-Orc's main goal is to offer more advanced features and enhance the productivity of the user. Update Summary (Beta) Added Bookmarks Fix to Remote Admin Commands Minor fix to text based Server Fix to Pretty Print, from Core Fix to Splitter Nodes not being created Fix to massive amounts of images loading, from Core Added 'boot' command to remote admin Added confirmation window for sent nodes Minor changes to allow for portability to an OpenSUSE linux OS Miniatures Layer pop up box allows users to turn off Mini labels, from FlexiRPG Zoom Mouse plugin added Images added to Plugin UI Switching to Element Tree Map efficiency, from FlexiRPG Added Status Bar to Update Manager default_manifest.xml renamed to default_upmana.xml Cleaner clode for saved repositories New TrueDebug Class in orpg_log (See documentation for usage) Mercurial's hgweb folder is ported to upmana **Pretty important update that can help remove thousands of dead children from your gametree. **Children, <forms />, <group_atts />, <horizontal />, <cols />, <rows />, <height />, etc... are all tags now. Check your gametree and look for dead children!! **New Gamtree Recusion method, mapping, and context sensitivity. !!Alpha - Watch out for infinite loops!!
author sirebral
date Tue, 10 Nov 2009 14:11:28 -0600
parents
children
comparison
equal deleted inserted replaced
101:394ebb3b6a0f 135:dcf4fbe09b70
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 of the
6 # GNU General Public License version 2, incorporated herein by reference.
7
8 from i18n import _
9 import os, sys, atexit, signal, pdb, socket, errno, shlex, time
10 import util, commands, hg, fancyopts, extensions, hook, error
11 import cmdutil, encoding
12 import ui as _ui
13
14 def run():
15 "run the command in sys.argv"
16 sys.exit(dispatch(sys.argv[1:]))
17
18 def dispatch(args):
19 "run the command specified in args"
20 try:
21 u = _ui.ui()
22 if '--traceback' in args:
23 u.setconfig('ui', 'traceback', 'on')
24 except util.Abort, inst:
25 sys.stderr.write(_("abort: %s\n") % inst)
26 return -1
27 return _runcatch(u, args)
28
29 def _runcatch(ui, args):
30 def catchterm(*args):
31 raise error.SignalInterrupt
32
33 for name in 'SIGBREAK', 'SIGHUP', 'SIGTERM':
34 num = getattr(signal, name, None)
35 if num: signal.signal(num, catchterm)
36
37 try:
38 try:
39 # enter the debugger before command execution
40 if '--debugger' in args:
41 pdb.set_trace()
42 try:
43 return _dispatch(ui, args)
44 finally:
45 ui.flush()
46 except:
47 # enter the debugger when we hit an exception
48 if '--debugger' in args:
49 pdb.post_mortem(sys.exc_info()[2])
50 ui.traceback()
51 raise
52
53 # Global exception handling, alphabetically
54 # Mercurial-specific first, followed by built-in and library exceptions
55 except error.AmbiguousCommand, inst:
56 ui.warn(_("hg: command '%s' is ambiguous:\n %s\n") %
57 (inst.args[0], " ".join(inst.args[1])))
58 except error.ConfigError, inst:
59 ui.warn(_("hg: %s\n") % inst.args[0])
60 except error.LockHeld, inst:
61 if inst.errno == errno.ETIMEDOUT:
62 reason = _('timed out waiting for lock held by %s') % inst.locker
63 else:
64 reason = _('lock held by %s') % inst.locker
65 ui.warn(_("abort: %s: %s\n") % (inst.desc or inst.filename, reason))
66 except error.LockUnavailable, inst:
67 ui.warn(_("abort: could not lock %s: %s\n") %
68 (inst.desc or inst.filename, inst.strerror))
69 except error.ParseError, inst:
70 if inst.args[0]:
71 ui.warn(_("hg %s: %s\n") % (inst.args[0], inst.args[1]))
72 commands.help_(ui, inst.args[0])
73 else:
74 ui.warn(_("hg: %s\n") % inst.args[1])
75 commands.help_(ui, 'shortlist')
76 except error.RepoError, inst:
77 ui.warn(_("abort: %s!\n") % inst)
78 except error.ResponseError, inst:
79 ui.warn(_("abort: %s") % inst.args[0])
80 if not isinstance(inst.args[1], basestring):
81 ui.warn(" %r\n" % (inst.args[1],))
82 elif not inst.args[1]:
83 ui.warn(_(" empty string\n"))
84 else:
85 ui.warn("\n%r\n" % util.ellipsis(inst.args[1]))
86 except error.RevlogError, inst:
87 ui.warn(_("abort: %s!\n") % inst)
88 except error.SignalInterrupt:
89 ui.warn(_("killed!\n"))
90 except error.UnknownCommand, inst:
91 ui.warn(_("hg: unknown command '%s'\n") % inst.args[0])
92 commands.help_(ui, 'shortlist')
93 except util.Abort, inst:
94 ui.warn(_("abort: %s\n") % inst)
95 except ImportError, inst:
96 m = str(inst).split()[-1]
97 ui.warn(_("abort: could not import module %s!\n") % m)
98 if m in "mpatch bdiff".split():
99 ui.warn(_("(did you forget to compile extensions?)\n"))
100 elif m in "zlib".split():
101 ui.warn(_("(is your Python install correct?)\n"))
102 except IOError, inst:
103 if hasattr(inst, "code"):
104 ui.warn(_("abort: %s\n") % inst)
105 elif hasattr(inst, "reason"):
106 try: # usually it is in the form (errno, strerror)
107 reason = inst.reason.args[1]
108 except: # it might be anything, for example a string
109 reason = inst.reason
110 ui.warn(_("abort: error: %s\n") % reason)
111 elif hasattr(inst, "args") and inst.args[0] == errno.EPIPE:
112 if ui.debugflag:
113 ui.warn(_("broken pipe\n"))
114 elif getattr(inst, "strerror", None):
115 if getattr(inst, "filename", None):
116 ui.warn(_("abort: %s: %s\n") % (inst.strerror, inst.filename))
117 else:
118 ui.warn(_("abort: %s\n") % inst.strerror)
119 else:
120 raise
121 except OSError, inst:
122 if getattr(inst, "filename", None):
123 ui.warn(_("abort: %s: %s\n") % (inst.strerror, inst.filename))
124 else:
125 ui.warn(_("abort: %s\n") % inst.strerror)
126 except KeyboardInterrupt:
127 try:
128 ui.warn(_("interrupted!\n"))
129 except IOError, inst:
130 if inst.errno == errno.EPIPE:
131 if ui.debugflag:
132 ui.warn(_("\nbroken pipe\n"))
133 else:
134 raise
135 except MemoryError:
136 ui.warn(_("abort: out of memory\n"))
137 except SystemExit, inst:
138 # Commands shouldn't sys.exit directly, but give a return code.
139 # Just in case catch this and and pass exit code to caller.
140 return inst.code
141 except socket.error, inst:
142 ui.warn(_("abort: %s\n") % inst.args[-1])
143 except:
144 ui.warn(_("** unknown exception encountered, details follow\n"))
145 ui.warn(_("** report bug details to "
146 "http://mercurial.selenic.com/bts/\n"))
147 ui.warn(_("** or mercurial@selenic.com\n"))
148 ui.warn(_("** Mercurial Distributed SCM (version %s)\n")
149 % util.version())
150 ui.warn(_("** Extensions loaded: %s\n")
151 % ", ".join([x[0] for x in extensions.extensions()]))
152 raise
153
154 return -1
155
156 def _findrepo(p):
157 while not os.path.isdir(os.path.join(p, ".hg")):
158 oldp, p = p, os.path.dirname(p)
159 if p == oldp:
160 return None
161
162 return p
163
164 def aliasargs(fn):
165 if hasattr(fn, 'args'):
166 return fn.args
167 return []
168
169 class cmdalias(object):
170 def __init__(self, name, definition, cmdtable):
171 self.name = name
172 self.definition = definition
173 self.args = []
174 self.opts = []
175 self.help = ''
176 self.norepo = True
177
178 try:
179 cmdutil.findcmd(self.name, cmdtable, True)
180 self.shadows = True
181 except error.UnknownCommand:
182 self.shadows = False
183
184 if not self.definition:
185 def fn(ui, *args):
186 ui.warn(_("no definition for alias '%s'\n") % self.name)
187 return 1
188 self.fn = fn
189
190 return
191
192 args = shlex.split(self.definition)
193 cmd = args.pop(0)
194 opts = []
195 help = ''
196
197 try:
198 self.fn, self.opts, self.help = cmdutil.findcmd(cmd, cmdtable, False)[1]
199 self.args = aliasargs(self.fn) + args
200 if cmd not in commands.norepo.split(' '):
201 self.norepo = False
202 except error.UnknownCommand:
203 def fn(ui, *args):
204 ui.warn(_("alias '%s' resolves to unknown command '%s'\n") \
205 % (self.name, cmd))
206 return 1
207 self.fn = fn
208 except error.AmbiguousCommand:
209 def fn(ui, *args):
210 ui.warn(_("alias '%s' resolves to ambiguous command '%s'\n") \
211 % (self.name, cmd))
212 return 1
213 self.fn = fn
214
215 def __call__(self, ui, *args, **opts):
216 if self.shadows:
217 ui.debug(_("alias '%s' shadows command\n") % self.name)
218
219 return self.fn(ui, *args, **opts)
220
221 def addaliases(ui, cmdtable):
222 # aliases are processed after extensions have been loaded, so they
223 # may use extension commands. Aliases can also use other alias definitions,
224 # but only if they have been defined prior to the current definition.
225 for alias, definition in ui.configitems('alias'):
226 aliasdef = cmdalias(alias, definition, cmdtable)
227 cmdtable[alias] = (aliasdef, aliasdef.opts, aliasdef.help)
228 if aliasdef.norepo:
229 commands.norepo += ' %s' % alias
230
231 def _parse(ui, args):
232 options = {}
233 cmdoptions = {}
234
235 try:
236 args = fancyopts.fancyopts(args, commands.globalopts, options)
237 except fancyopts.getopt.GetoptError, inst:
238 raise error.ParseError(None, inst)
239
240 if args:
241 cmd, args = args[0], args[1:]
242 aliases, i = cmdutil.findcmd(cmd, commands.table,
243 ui.config("ui", "strict"))
244 cmd = aliases[0]
245 args = aliasargs(i[0]) + args
246 defaults = ui.config("defaults", cmd)
247 if defaults:
248 args = shlex.split(defaults) + args
249 c = list(i[1])
250 else:
251 cmd = None
252 c = []
253
254 # combine global options into local
255 for o in commands.globalopts:
256 c.append((o[0], o[1], options[o[1]], o[3]))
257
258 try:
259 args = fancyopts.fancyopts(args, c, cmdoptions, True)
260 except fancyopts.getopt.GetoptError, inst:
261 raise error.ParseError(cmd, inst)
262
263 # separate global options back out
264 for o in commands.globalopts:
265 n = o[1]
266 options[n] = cmdoptions[n]
267 del cmdoptions[n]
268
269 return (cmd, cmd and i[0] or None, args, options, cmdoptions)
270
271 def _parseconfig(ui, config):
272 """parse the --config options from the command line"""
273 for cfg in config:
274 try:
275 name, value = cfg.split('=', 1)
276 section, name = name.split('.', 1)
277 if not section or not name:
278 raise IndexError
279 ui.setconfig(section, name, value)
280 except (IndexError, ValueError):
281 raise util.Abort(_('malformed --config option: %s') % cfg)
282
283 def _earlygetopt(aliases, args):
284 """Return list of values for an option (or aliases).
285
286 The values are listed in the order they appear in args.
287 The options and values are removed from args.
288 """
289 try:
290 argcount = args.index("--")
291 except ValueError:
292 argcount = len(args)
293 shortopts = [opt for opt in aliases if len(opt) == 2]
294 values = []
295 pos = 0
296 while pos < argcount:
297 if args[pos] in aliases:
298 if pos + 1 >= argcount:
299 # ignore and let getopt report an error if there is no value
300 break
301 del args[pos]
302 values.append(args.pop(pos))
303 argcount -= 2
304 elif args[pos][:2] in shortopts:
305 # short option can have no following space, e.g. hg log -Rfoo
306 values.append(args.pop(pos)[2:])
307 argcount -= 1
308 else:
309 pos += 1
310 return values
311
312 def runcommand(lui, repo, cmd, fullargs, ui, options, d):
313 # run pre-hook, and abort if it fails
314 ret = hook.hook(lui, repo, "pre-%s" % cmd, False, args=" ".join(fullargs))
315 if ret:
316 return ret
317 ret = _runcommand(ui, options, cmd, d)
318 # run post-hook, passing command result
319 hook.hook(lui, repo, "post-%s" % cmd, False, args=" ".join(fullargs),
320 result = ret)
321 return ret
322
323 _loaded = set()
324 def _dispatch(ui, args):
325 # read --config before doing anything else
326 # (e.g. to change trust settings for reading .hg/hgrc)
327 _parseconfig(ui, _earlygetopt(['--config'], args))
328
329 # check for cwd
330 cwd = _earlygetopt(['--cwd'], args)
331 if cwd:
332 os.chdir(cwd[-1])
333
334 # read the local repository .hgrc into a local ui object
335 path = _findrepo(os.getcwd()) or ""
336 if not path:
337 lui = ui
338 if path:
339 try:
340 lui = ui.copy()
341 lui.readconfig(os.path.join(path, ".hg", "hgrc"))
342 except IOError:
343 pass
344
345 # now we can expand paths, even ones in .hg/hgrc
346 rpath = _earlygetopt(["-R", "--repository", "--repo"], args)
347 if rpath:
348 path = lui.expandpath(rpath[-1])
349 lui = ui.copy()
350 lui.readconfig(os.path.join(path, ".hg", "hgrc"))
351
352 extensions.loadall(lui)
353 for name, module in extensions.extensions():
354 if name in _loaded:
355 continue
356
357 # setup extensions
358 # TODO this should be generalized to scheme, where extensions can
359 # redepend on other extensions. then we should toposort them, and
360 # do initialization in correct order
361 extsetup = getattr(module, 'extsetup', None)
362 if extsetup:
363 extsetup()
364
365 cmdtable = getattr(module, 'cmdtable', {})
366 overrides = [cmd for cmd in cmdtable if cmd in commands.table]
367 if overrides:
368 ui.warn(_("extension '%s' overrides commands: %s\n")
369 % (name, " ".join(overrides)))
370 commands.table.update(cmdtable)
371 _loaded.add(name)
372
373 addaliases(lui, commands.table)
374
375 # check for fallback encoding
376 fallback = lui.config('ui', 'fallbackencoding')
377 if fallback:
378 encoding.fallbackencoding = fallback
379
380 fullargs = args
381 cmd, func, args, options, cmdoptions = _parse(lui, args)
382
383 if options["config"]:
384 raise util.Abort(_("Option --config may not be abbreviated!"))
385 if options["cwd"]:
386 raise util.Abort(_("Option --cwd may not be abbreviated!"))
387 if options["repository"]:
388 raise util.Abort(_(
389 "Option -R has to be separated from other options (e.g. not -qR) "
390 "and --repository may only be abbreviated as --repo!"))
391
392 if options["encoding"]:
393 encoding.encoding = options["encoding"]
394 if options["encodingmode"]:
395 encoding.encodingmode = options["encodingmode"]
396 if options["time"]:
397 def get_times():
398 t = os.times()
399 if t[4] == 0.0: # Windows leaves this as zero, so use time.clock()
400 t = (t[0], t[1], t[2], t[3], time.clock())
401 return t
402 s = get_times()
403 def print_time():
404 t = get_times()
405 ui.warn(_("Time: real %.3f secs (user %.3f+%.3f sys %.3f+%.3f)\n") %
406 (t[4]-s[4], t[0]-s[0], t[2]-s[2], t[1]-s[1], t[3]-s[3]))
407 atexit.register(print_time)
408
409 if options['verbose'] or options['debug'] or options['quiet']:
410 ui.setconfig('ui', 'verbose', str(bool(options['verbose'])))
411 ui.setconfig('ui', 'debug', str(bool(options['debug'])))
412 ui.setconfig('ui', 'quiet', str(bool(options['quiet'])))
413 if options['traceback']:
414 ui.setconfig('ui', 'traceback', 'on')
415 if options['noninteractive']:
416 ui.setconfig('ui', 'interactive', 'off')
417
418 if options['help']:
419 return commands.help_(ui, cmd, options['version'])
420 elif options['version']:
421 return commands.version_(ui)
422 elif not cmd:
423 return commands.help_(ui, 'shortlist')
424
425 repo = None
426 if cmd not in commands.norepo.split():
427 try:
428 repo = hg.repository(ui, path=path)
429 ui = repo.ui
430 if not repo.local():
431 raise util.Abort(_("repository '%s' is not local") % path)
432 ui.setconfig("bundle", "mainreporoot", repo.root)
433 except error.RepoError:
434 if cmd not in commands.optionalrepo.split():
435 if args and not path: # try to infer -R from command args
436 repos = map(_findrepo, args)
437 guess = repos[0]
438 if guess and repos.count(guess) == len(repos):
439 return _dispatch(ui, ['--repository', guess] + fullargs)
440 if not path:
441 raise error.RepoError(_("There is no Mercurial repository"
442 " here (.hg not found)"))
443 raise
444 args.insert(0, repo)
445 elif rpath:
446 ui.warn("warning: --repository ignored\n")
447
448 d = lambda: util.checksignature(func)(ui, *args, **cmdoptions)
449 return runcommand(lui, repo, cmd, fullargs, ui, options, d)
450
451 def _runcommand(ui, options, cmd, cmdfunc):
452 def checkargs():
453 try:
454 return cmdfunc()
455 except error.SignatureError:
456 raise error.ParseError(cmd, _("invalid arguments"))
457
458 if options['profile']:
459 format = ui.config('profiling', 'format', default='text')
460
461 if not format in ['text', 'kcachegrind']:
462 ui.warn(_("unrecognized profiling format '%s'"
463 " - Ignored\n") % format)
464 format = 'text'
465
466 output = ui.config('profiling', 'output')
467
468 if output:
469 path = os.path.expanduser(output)
470 path = ui.expandpath(path)
471 ostream = open(path, 'wb')
472 else:
473 ostream = sys.stderr
474
475 try:
476 from mercurial import lsprof
477 except ImportError:
478 raise util.Abort(_(
479 'lsprof not available - install from '
480 'http://codespeak.net/svn/user/arigo/hack/misc/lsprof/'))
481 p = lsprof.Profiler()
482 p.enable(subcalls=True)
483 try:
484 return checkargs()
485 finally:
486 p.disable()
487
488 if format == 'kcachegrind':
489 import lsprofcalltree
490 calltree = lsprofcalltree.KCacheGrind(p)
491 calltree.output(ostream)
492 else:
493 # format == 'text'
494 stats = lsprof.Stats(p.getstats())
495 stats.sort()
496 stats.pprint(top=10, file=ostream, climit=5)
497
498 if output:
499 ostream.close()
500 else:
501 return checkargs()