Mercurial > traipse_dev
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() |