Changeset 458e997557b9…
Parent 10ad9bbe02a7…
by
Changes to one file · Browse files at 458e997557b9 Showing diff from parent 10ad9bbe02a7 Diff from another changeset...
|
|
@@ -1,8 +1,10 @@ #!/usr/bin/env python
#
# front-end script for TortoiseHg dialogs
+#
# Copyright (C) 2008 Steve Borho <steve@borho.org>
-#
+# Copyright (C) 2008 TK Soh <teekaysoh@gmail.com>
+
# Modify this line to the location of your tortoisehg repository
# or set TORTOISEHG_PATH in your environment
@@ -10,32 +12,100 @@
import os
import sys
+import traceback
+import pygtk
+pygtk.require('2.0')
+import gtk
+import shlex
+from mercurial.i18n import _
+from mercurial import hg, util, fancyopts, commands, cmdutil
+from mercurial.repo import RepoError
+import mercurial.ui as _ui
-dialogs = '''log synch status clone merge update userconfig repoconfig
-serve recovery commit datamine about'''
+class ParseError(Exception):
+ """Exception raised on errors in parsing the command line."""
-nonrepo_commands = 'userconfig clone about'
+nonrepo_commands = 'userconfig clone about help'
-def help():
- print 'TortoiseHg Dialog Wrapper\n'
- print 'hgtk [DIALOG]'
- print ' dialogs:', dialogs
+def dispatch(args):
+ "run the command specified in args"
+ try:
+ u = _ui.ui(traceback='--traceback' in args)
+ except util.Abort, inst:
+ sys.stderr.write(_("abort: %s\n") % inst)
+ return -1
+ return _runcatch(u, args)
-def main(command):
- dlist = dialogs.split()
- l = []
- for d in dlist:
- if d.startswith(command):
- l.append(d)
- if not l:
- print 'dialog', command, 'not recognized'
- help()
- sys.exit(1)
- if len(l) > 1:
- print 'dialog', command, 'is ambiguous'
- print '\tcould be one of', ' '.join(l)
- sys.exit(1)
- command = l[0]
+def _parse(ui, args):
+ options = {}
+ cmdoptions = {}
+
+ try:
+ args = fancyopts.fancyopts(args, globalopts, options)
+ except fancyopts.getopt.GetoptError, inst:
+ raise ParseError(None, inst)
+
+ if args:
+ cmd, args = args[0], args[1:]
+ aliases, i = cmdutil.findcmd(ui, cmd, table)
+ cmd = aliases[0]
+ c = list(i[1])
+ else:
+ cmd = None
+ c = []
+
+ # combine global options into local
+ for o in globalopts:
+ c.append((o[0], o[1], options[o[1]], o[3]))
+
+ try:
+ args = fancyopts.fancyopts(args, c, cmdoptions)
+ except fancyopts.getopt.GetoptError, inst:
+ raise ParseError(cmd, inst)
+
+ # separate global options back out
+ for o in globalopts:
+ n = o[1]
+ options[n] = cmdoptions[n]
+ del cmdoptions[n]
+
+ return (cmd, cmd and i[0] or None, args, options, cmdoptions)
+
+def _runcatch(ui, args):
+ try:
+ try:
+ return runcommand(ui, args)
+ finally:
+ ui.flush()
+ except ParseError, inst:
+ if inst.args[0]:
+ ui.warn(_("hgtk %s: %s\n") % (inst.args[0], inst.args[1]))
+ help_(ui, inst.args[0])
+ else:
+ ui.warn(_("hgtk: %s\n") % inst.args[1])
+ help_('shortlist')
+ except cmdutil.AmbiguousCommand, inst:
+ ui.warn(_("hgtk: command '%s' is ambiguous:\n %s\n") %
+ (inst.args[0], " ".join(inst.args[1])))
+ except cmdutil.UnknownCommand, inst:
+ ui.warn(_("hgtk: unknown command '%s'\n") % inst.args[0])
+ help_(ui, 'shortlist')
+ except RepoError, inst:
+ ui.warn(_("abort: %s!\n") % inst)
+ except util.Abort, inst:
+ ui.warn(_("abort: %s\n") % inst)
+
+ return -1
+
+def runcommand(ui, args):
+ fullargs = args
+ cmd, func, args, options, cmdoptions = _parse(ui, args)
+ ui.updateopts(options["verbose"])
+
+ if options['help']:
+ return help_(ui, cmd)
+ elif not cmd:
+ return help_(ui, 'shortlist')
if hasattr(sys, "frozen"):
# Py2exe environment
@@ -62,58 +132,322 @@ from hggtk import hglib
except ImportError, inst:
m = str(inst).split()[-1]
- print "abort: could not import module %s!\n" % m
if m in "hglib hggtk".split():
# fix "tortoisehg_dir" at the top of this script, or ...
- print 'Please set TORTOISEHG_PATH to location of your ' \
- 'tortoisehg repository'
- sys.exit(1)
+ raise util.Abort(_('Please set TORTOISEHG_PATH to location '
+ 'of your tortoisehg repository'))
+ else:
+ raise util.Abort(_('could not import module %s!\n' % m))
except:
raise
- cwd = os.getcwd()
- root = hglib.rootpath(cwd)
- opts = { 'root' : root, 'cwd' : cwd }
+ if cmd not in nonrepo_commands.split():
+ cmdoptions['root'] = os.path.abspath(options['repository'])
+ try:
+ repo = hg.repository(ui, path=cmdoptions['root'])
+ except RepoError, inst:
+ # try to guess the repo from first of file args
+ root = None
+ if args:
+ from hggtk import hglib
+ root=hglib.rootpath(args[0])
+ if root:
+ cmdoptions['root'] = os.path.abspath(root)
+ repo = hg.repository(ui, path=cmdoptions['root'])
+ else:
+ raise RepoError(_("There is no Mercurial repository here"
+ " (.hg not found)"))
+ try:
+ return func(ui, *args, **cmdoptions)
+ except TypeError, inst:
+ # was this an argument error?
+ tb = traceback.extract_tb(sys.exc_info()[2])
+ if len(tb) != 1: # no
+ raise
+ raise ParseError(cmd, _("invalid arguments"))
- if not root and command not in nonrepo_commands:
- print 'No repository found, and', command, 'requires one.'
- sys.exit(1)
-
- # add aliases to taste (and to commands at top of file)
- if command in ('log'):
- from hggtk.history import run
- opts['files'] = [root]
- elif command in ('datamine'):
- from hggtk.datamine import run
- elif command in ('synch'):
- from hggtk.synch import run
- elif command in ('status'):
- from hggtk.status import run
- elif command in ('clone'):
- from hggtk.clone import run
- elif command in ('merge'):
- from hggtk.merge import run
- elif command in ('update'):
- from hggtk.update import run
- elif command in ('serve'):
- from hggtk.serve import run
- elif command in ('recovery'):
- from hggtk.recovery import run
- elif command in ('commit'):
- from hggtk.commit import run
- elif command in ('repoconfig'):
- from hggtk.thgconfig import run
- opts['files'] = [root]
- elif command in ('userconfig'):
- from hggtk.thgconfig import run
- elif command in ('about'):
- from hggtk.about import run
+def about(ui, **opts):
+ """about TortoiseHg"""
+ from hggtk.about import run
run(**opts)
+def clone(ui, source=None, dest=None, **opts):
+ """clone tool"""
+ from hggtk.clone import run
+ opts['files'] = [os.path.abspath(x) for x in (source, dest) if x]
+ run(**opts)
+
+def commit(ui, *pats, **opts):
+ """commit tool"""
+ from hggtk.commit import run
+ opts['files'] = [os.path.abspath(x) for x in pats]
+ run(**opts)
+
+def userconfig(ui, **opts):
+ """user configuration editor"""
+ from hggtk.thgconfig import run
+ run(**opts)
+
+def repoconfig(ui, *pats, **opts):
+ """repository configuration editor"""
+ from hggtk.thgconfig import run
+ opts['files'] = opts['root']
+ run(**opts)
+
+def datamine(ui, *pats, **opts):
+ """repository search and annotate tool"""
+ from hggtk.datamine import run
+ run(**opts)
+
+def log(ui, *pats, **opts):
+ """changelog viewer"""
+ from hggtk.history import run
+ opts['files'] = [os.path.abspath(x) for x in pats]
+ run(**opts)
+
+def merge(ui, node=None, rev=None, **opts):
+ """merge tool """
+ from hggtk.merge import run
+ run(**opts)
+
+def recovery(ui, *pats, **opts):
+ """recover, rollback & verify"""
+ from hggtk.recovery import run
+ run(**opts)
+
+def serve(ui, **opts):
+ """web server"""
+ from hggtk.serve import run
+ run(**opts)
+
+def status(ui, *pats, **opts):
+ """file status viewer
+
+ Also do add and remove.
+ """
+
+ from hggtk.status import run
+ run(**opts)
+
+def synch(ui, **opts):
+ """repository synchronization tool"""
+ from hggtk.synch import run
+ run(**opts)
+
+def update(ui, **opts):
+ """update/checkout tool"""
+ from hggtk.update import run
+ run(**opts)
+
+### help management, adapted from mercurial.commands.help_()
+def help_(ui, name=None, with_version=False):
+ """show help for a command, extension, or list of commands
+
+ With no arguments, print a list of commands and short help.
+
+ Given a command name, print help for that command.
+
+ Given an extension name, print help for that extension, and the
+ commands it provides."""
+ option_lists = []
+
+ def addglobalopts(aliases):
+ if ui.verbose:
+ option_lists.append((_("global options:"), globalopts))
+ if name == 'shortlist':
+ option_lists.append((_('use "hgtk help" for the full list '
+ 'of commands'), ()))
+ else:
+ if name == 'shortlist':
+ msg = _('use "hgtk help" for the full list of commands '
+ 'or "hgtk -v" for details')
+ elif aliases:
+ msg = _('use "hgtk -v help%s" to show aliases and '
+ 'global options') % (name and " " + name or "")
+ else:
+ msg = _('use "hgtk -v help %s" to show global options') % name
+ option_lists.append((msg, ()))
+
+ def helpcmd(name):
+ if with_version:
+ version_(ui)
+ ui.write('\n')
+ aliases, i = cmdutil.findcmd(ui, name, table)
+ # synopsis
+ ui.write("%s\n" % i[2])
+
+ # aliases
+ if not ui.quiet and len(aliases) > 1:
+ ui.write(_("\naliases: %s\n") % ', '.join(aliases[1:]))
+
+ # description
+ doc = i[0].__doc__
+ if not doc:
+ doc = _("(No help text available)")
+ if ui.quiet:
+ doc = doc.splitlines(0)[0]
+ ui.write("\n%s\n" % doc.rstrip())
+
+ if not ui.quiet:
+ # options
+ if i[1]:
+ option_lists.append((_("options:\n"), i[1]))
+
+ addglobalopts(False)
+
+ def helplist(header, select=None):
+ h = {}
+ cmds = {}
+ for c, e in table.items():
+ f = c.split("|", 1)[0]
+ if select and not select(f):
+ continue
+ if name == "shortlist" and not f.startswith("^"):
+ continue
+ f = f.lstrip("^")
+ if not ui.debugflag and f.startswith("debug"):
+ continue
+ doc = e[0].__doc__
+ if not doc:
+ doc = _("(No help text available)")
+ h[f] = doc.splitlines(0)[0].rstrip()
+ cmds[f] = c.lstrip("^")
+
+ if not h:
+ ui.status(_('no commands defined\n'))
+ return
+
+ ui.status(header)
+ fns = h.keys()
+ fns.sort()
+ m = max(map(len, fns))
+ for f in fns:
+ if ui.verbose:
+ commands = cmds[f].replace("|",", ")
+ ui.write(" %s:\n %s\n"%(commands, h[f]))
+ else:
+ ui.write(' %-*s %s\n' % (m, f, h[f]))
+
+ if not ui.quiet:
+ addglobalopts(True)
+
+ def helptopic(name):
+ v = None
+ for i in help.helptable:
+ l = i.split('|')
+ if name in l:
+ v = i
+ header = l[-1]
+ if not v:
+ raise cmdutil.UnknownCommand(name)
+
+ # description
+ doc = help.helptable[v]
+ if not doc:
+ doc = _("(No help text available)")
+ if callable(doc):
+ doc = doc()
+
+ ui.write("%s\n" % header)
+ ui.write("%s\n" % doc.rstrip())
+
+ def helpext(name):
+ try:
+ mod = extensions.find(name)
+ except KeyError:
+ raise cmdutil.UnknownCommand(name)
+
+ doc = (mod.__doc__ or _('No help text available')).splitlines(0)
+ ui.write(_('%s extension - %s\n') % (name.split('.')[-1], doc[0]))
+ for d in doc[1:]:
+ ui.write(d, '\n')
+
+ ui.status('\n')
+
+ try:
+ ct = mod.cmdtable
+ except AttributeError:
+ ct = {}
+
+ modcmds = dict.fromkeys([c.split('|', 1)[0] for c in ct])
+ helplist(_('list of commands:\n\n'), modcmds.has_key)
+
+ if name and name != 'shortlist':
+ i = None
+ for f in (helpcmd, helptopic, helpext):
+ try:
+ f(name)
+ i = None
+ break
+ except cmdutil.UnknownCommand, inst:
+ i = inst
+ if i:
+ raise i
+
+ else:
+ # program name
+ if ui.verbose or with_version:
+ version_(ui)
+ else:
+ ui.status(_("Hgtk - TortoiseHg's GUI tools for Mercurial SCM (Hg)\n"))
+ ui.status('\n')
+
+ # list of commands
+ if name == "shortlist":
+ header = _('basic commands:\n\n')
+ else:
+ header = _('list of commands:\n\n')
+
+ helplist(header)
+
+ # list all option lists
+ opt_output = []
+ for title, options in option_lists:
+ opt_output.append(("\n%s" % title, None))
+ for shortopt, longopt, default, desc in options:
+ if "DEPRECATED" in desc and not ui.verbose: continue
+ opt_output.append(("%2s%s" % (shortopt and "-%s" % shortopt,
+ longopt and " --%s" % longopt),
+ "%s%s" % (desc,
+ default
+ and _(" (default: %s)") % default
+ or "")))
+
+ if opt_output:
+ opts_len = max([len(line[0]) for line in opt_output if line[1]] or [0])
+ for first, second in opt_output:
+ if second:
+ ui.write(" %-*s %s\n" % (opts_len, first, second))
+ else:
+ ui.write("%s\n" % first)
+
+def version_(ui):
+ """output version and copyright information"""
+ pass
+
+globalopts = [
+ ('R', 'repository', '',
+ _('repository root directory or symbolic path name')),
+ ('v', 'verbose', None, _('enable additional output')),
+ ('h', 'help', None, _('display help and exit')),
+]
+
+table = {
+ "^about": (about, [], _('hgtk about')),
+ "^clone": (clone, [], _('hgtk clone SOURCE [DEST]')),
+ "^commit|ci": (commit, [], _('hgtk commit')),
+ "^datamine": (datamine, [], _('hgtk datamine')),
+ "^log|history": (log, [], _('hgtk log [FILE]')),
+ "^merge": (merge, [], _('hgtk merge')),
+ "^recovery": (recovery, [], _('hgtk recovery')),
+ "^synch": (synch, [], _('hgtk synch')),
+ "^status": (status, [], _('hgtk status')),
+ "^userconfig": (userconfig, [], _('hgtk userconfig')),
+ "^repoconfig": (repoconfig, [], _('hgtk repoconfig')),
+ "^serve": (serve, [], _('hgtk serve')),
+ "^update|checkout|co": (update, [], _('hgtk update')),
+ "help": (help_, [], _('hgtk help [COMMAND]')),
+}
if __name__=='__main__':
- if len(sys.argv) != 2:
- help()
- else:
- main(sys.argv[1])
- sys.exit(0)
+ sys.exit(dispatch(sys.argv[1:]))
|
Loading...