aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorW. Trevor King <wking@drexel.edu>2009-12-12 20:57:59 -0500
committerW. Trevor King <wking@drexel.edu>2009-12-12 20:57:59 -0500
commitdff6bd9bf89ca80e2265696a478e540476718c9c (patch)
tree230f35262808052839ae2401d99cdf23cc304f20
parent86f886399813d37f3cfcf74a824d352e01eb0d8c (diff)
downloadbugseverywhere-dff6bd9bf89ca80e2265696a478e540476718c9c.tar.gz
Moved be to libbe.ui.command_line and transitioned to Command format.
-rwxr-xr-xbe102
-rw-r--r--libbe/bug.py2
-rw-r--r--libbe/bugdir.py2
-rw-r--r--libbe/command/__init__.py4
-rw-r--r--libbe/command/base.py102
-rw-r--r--libbe/command/list.py1
-rw-r--r--libbe/command/util.py35
-rw-r--r--libbe/comment.py2
-rw-r--r--libbe/storage/util/settings_object.py8
-rw-r--r--libbe/ui/base.py1
-rwxr-xr-xlibbe/ui/command_line.py270
-rw-r--r--libbe/ui/util/cmdutil.py108
-rw-r--r--libbe/util/encoding.py2
-rwxr-xr-xsetup.py4
14 files changed, 375 insertions, 268 deletions
diff --git a/be b/be
index 5e3088e..5f7bd1b 100755
--- a/be
+++ b/be
@@ -1,103 +1,7 @@
#!/usr/bin/env python
-# Copyright (C) 2005-2009 Aaron Bentley and Panometrics, Inc.
-# Chris Ball <cjb@laptop.org>
-# Gianluca Montecchi <gian@grys.it>
-# Oleg Romanyshyn <oromanyshyn@panoramicfeedback.com>
-# W. Trevor King <wking@drexel.edu>
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+# Copyright
-import os
import sys
+import libbe.ui.command_line
-from libbe import cmdutil, version, pager
-
-__doc__ = cmdutil.help()
-
-usage = "be [options] [command] [command_options ...] [command_args ...]"
-
-parser = cmdutil.CmdOptionParser(usage)
-parser.command = "be"
-parser.add_option("--version", action="store_true", dest="version",
- help="Print version string and exit.")
-parser.add_option("--verbose-version", action="store_true", dest="verbose_version",
- help="Print verbose version information and exit.")
-parser.add_option("-d", "--dir", dest="dir", metavar="DIR", default=".",
- help="Run this command on the repository in DIR instead of the current directory.")
-parser.add_option("-p", "--paginate", dest="paginate", default=False,
- action='store_true',
- help="Pipe all output into less (or if set, $PAGER).")
-parser.add_option("--no-pager", dest="no_pager", default=False,
- action='store_true',
- help="Do not pipe git output into a pager.")
-
-# Option(name='repo', short_name='r',
-# help='Select BE repository (see `be help repo`) rather than'
-# 'the current directory.',
-# arg=Argument(name='repo', metavar='REPO', default='.',
-# completion_callback=libbe.ui.util.repo.complete)),
-
-try:
- options,args = parser.parse_args()
- for option,value in cmdutil.option_value_pairs(options, parser):
- if value == "--complete":
- if option == "dir":
- if len(args) == 0:
- args = ["."]
- paths = cmdutil.complete_path(args[0])
- raise cmdutil.GetCompletions(paths)
-except cmdutil.GetHelp:
- print cmdutil.help(parser=parser)
- sys.exit(0)
-except cmdutil.GetCompletions, e:
- print '\n'.join(e.completions)
- sys.exit(0)
-
-if options.version == True or options.verbose_version == True:
- print version.version(verbose=options.verbose_version)
- sys.exit(0)
-
-paginate = 'auto'
-if options.paginate == True:
- paginate = 'always'
-if options.no_pager== True:
- paginate = 'never'
-pager.run_pager(paginate)
-
-try:
- if len(args) == 0:
- raise cmdutil.UsageError, "must supply a command"
- sys.exit(cmdutil.execute(args[0], args=args[1:], dir=options.dir))
-except cmdutil.GetHelp:
- print cmdutil.help(args[0])
- sys.exit(0)
-except cmdutil.GetCompletions, e:
- print '\n'.join(e.completions)
- sys.exit(0)
-except cmdutil.UnknownCommand, e:
- print e
- sys.exit(1)
-except cmdutil.UsageError, e:
- print "Invalid usage:", e
- if len(args) == 0:
- print cmdutil.help(parser=parser)
- else:
- print "\nArgs:", args
- print cmdutil.help(args[0])
- sys.exit(1)
-except cmdutil.UserError, e:
- print "ERROR:"
- print e
- sys.exit(1)
+sys.exit(libbe.ui.command_line.main())
diff --git a/libbe/bug.py b/libbe/bug.py
index 1f96779..d62de49 100644
--- a/libbe/bug.py
+++ b/libbe/bug.py
@@ -37,7 +37,7 @@ import libbe.util.id
from libbe.storage.util.properties import Property, doc_property, \
local_property, defaulting_property, checked_property, cached_property, \
primed_property, change_hook_property, settings_property
-import libbe.storage.settings_object as settings_object
+import libbe.storage.util.settings_object as settings_object
import libbe.storage.util.mapfile as mapfile
import libbe.comment as comment
import libbe.util.utility as utility
diff --git a/libbe/bugdir.py b/libbe/bugdir.py
index 39eface..5f76d3c 100644
--- a/libbe/bugdir.py
+++ b/libbe/bugdir.py
@@ -36,7 +36,7 @@ from libbe.storage.util.properties import Property, doc_property, \
local_property, defaulting_property, checked_property, \
fn_checked_property, cached_property, primed_property, \
change_hook_property, settings_property
-import libbe.storage.settings_object as settings_object
+import libbe.storage.util.settings_object as settings_object
import libbe.storage.util.mapfile as mapfile
import libbe.bug as bug
import libbe.util.utility as utility
diff --git a/libbe/command/__init__.py b/libbe/command/__init__.py
index 344a8a2..8558882 100644
--- a/libbe/command/__init__.py
+++ b/libbe/command/__init__.py
@@ -18,12 +18,12 @@
import base
UserError = base.UserError
-UnkownCommand = base.UnknownCommand
+UnknownCommand = base.UnknownCommand
get_command = base.get_command
commands = base.commands
Option = base.Option
Argument = base.Argument
Command = base.Command
-__all__ = [UserError, UnkownCommand, get_command, commands,
+__all__ = [UserError, UnknownCommand, get_command, commands,
Option, Argument, Command]
diff --git a/libbe/command/base.py b/libbe/command/base.py
index 0db156b..252dd24 100644
--- a/libbe/command/base.py
+++ b/libbe/command/base.py
@@ -36,7 +36,7 @@ def get_command(command_name):
def commands():
for modname in libbe.util.plugin.modnames('libbe.command'):
- if modname != 'base':
+ if modname not in ['base', 'util']:
yield modname
class CommandInput (object):
@@ -44,28 +44,48 @@ class CommandInput (object):
self.name = name
self.help = help
-class Option (CommandInput):
- def __init__(self, option_callback=None, short_name=None, arg=None,
- type=None, *args, **kwargs):
- CommandInput.__init__(self, *args, **kwargs)
- self.option_callback = option_callback
- self.short_name = short_name
- self.arg = arg
- self.type = type
- if self.arg != None:
- assert self.arg.name == self.name, \
- 'Name missmatch: %s != %s' % (self.arg.name, self.name)
-
class Argument (CommandInput):
- def __init__(self, metavar=None, default=None,
+ def __init__(self, metavar=None, default=None, type='string',
optional=False, repeatable=False,
completion_callback=None, *args, **kwargs):
CommandInput.__init__(self, *args, **kwargs)
self.metavar = metavar
self.default = default
+ self.type = type
self.optional = optional
self.repeatable = repeatable
self.completion_callback = completion_callback
+ if self.metavar == None:
+ self.metavar = self.name.upper()
+
+class Option (CommandInput):
+ def __init__(self, callback=None, short_name=None, arg=None,
+ *args, **kwargs):
+ CommandInput.__init__(self, *args, **kwargs)
+ self.callback = callback
+ self.short_name = short_name
+ self.arg = arg
+ if self.arg == None and self.callback == None:
+ # use an implicit boolean argument
+ self.arg = Argument(name=self.name, help=self.help,
+ default=False, type='bool')
+ self.validate()
+
+ def validate(self):
+ if self.arg == None:
+ assert self.callback != None
+ return
+ assert self.callback == None, self.callback
+ assert self.arg.name == self.name, \
+ 'Name missmatch: %s != %s' % (self.arg.name, self.name)
+ assert self.arg.optional == False
+ assert self.arg.repeatable == False
+
+ def __str__(self):
+ return '--%s' % self.name
+
+ def __repr__(self):
+ return '<Option %s>' % self.__str__()
class _DummyParser (object):
def __init__(self, options):
@@ -102,20 +122,18 @@ class OptionFormatter (optparse.IndentedHelpFormatter):
return ''.join(ret[:-1])
class Command (object):
- """
+ """One-line command description.
+
>>> c = Command()
>>> print c.help()
usage: be command [options]
<BLANKLINE>
Options:
- -h HELP, --help=HELP Print a help message
+ -h HELP, --help=HELP Print a help message.
<BLANKLINE>
- --complete=STRING Print a list of possible completions
+ --complete=STRING Print a list of possible completions.
<BLANKLINE>
- -r REPO, --repo=REPO Select BE repository (see `be help repo`) rather
- thanthe current directory.
- <BLANKLINE>
- A detailed help message.
+ A detailed help message.
"""
name = 'command'
@@ -123,15 +141,16 @@ class Command (object):
def __init__(self, input_encoding=None, output_encoding=None):
self.status = None
self.result = None
+ self.requires_bugdir = False
self.input_encoding = None
self.output_encoding = None
self.options = [
Option(name='help', short_name='h',
- help='Print a help message',
- option_callback=self.help),
- Option(name='complete', type='string',
- help='Print a list of possible completions',
- arg=Argument(name='complete', metavar='STRING', optional=True)),
+ help='Print a help message.',
+ callback=self.help),
+ Option(name='complete',
+ help='Print a list of possible completions.',
+ callback=self.complete),
]
self.args = []
@@ -179,28 +198,10 @@ class Command (object):
self.stdout = codecs.getwriter(output_encoding)(sys.stdout)
self.stdout.encoding = output_encoding
- def help(self, *args):
+ def help(self, *args):
return '\n\n'.join([self._usage(),
self._option_help(),
self._long_help()])
-# if cmd != None:
-# return get_command(cmd).help()
-# cmdlist = []
-# for name in commands():
-# module = get_command(name)
-# cmdlist.append((name, module.__desc__))
-# cmdlist.sort()
-# longest_cmd_len = max([len(name) for name,desc in cmdlist])
-# ret = ["Bugs Everywhere - Distributed bug tracking",
-# "", "Supported commands"]
-# for name, desc in cmdlist:
-# numExtraSpaces = longest_cmd_len-len(name)
-# ret.append("be %s%*s %s" % (name, numExtraSpaces, "", desc))
-# ret.extend(["", "Run", " be help [command]", "for more information."])
-# longhelp = "\n".join(ret)
-# if parser == None:
-# return longhelp
-# return parser.help_str() + "\n" + longhelp
def _usage(self):
usage = 'usage: be %s [options]' % self.name
@@ -222,3 +223,14 @@ class Command (object):
def _long_help(self):
return "A detailed help message."
+
+ def complete(self, argument=None, fragment=None):
+ if argument == None:
+ ret = ['--%s' % o.name for o in self.options]
+ if len(self.args) > 0 and self.args[0].completion_callback != None:
+ ret.extend(self.args[0].completion_callback(self, argument))
+ return ret
+ elif argument.completion_callback != None:
+ # finish a particular argument
+ return argument.completion_callback(self, argument, fragment)
+ return [] # the particular argument doesn't supply completion info
diff --git a/libbe/command/list.py b/libbe/command/list.py
index 9527779..c835815 100644
--- a/libbe/command/list.py
+++ b/libbe/command/list.py
@@ -72,6 +72,7 @@ class List (libbe.command.Command):
def __init__(self, *args, **kwargs):
libbe.command.Command.__init__(self, *args, **kwargs)
+ self.requires_bugdir = True
self.options.extend([
libbe.command.Option(name='status',
help='Only show bugs matching the STATUS specifier',
diff --git a/libbe/command/util.py b/libbe/command/util.py
index a650d33..6ce5cc9 100644
--- a/libbe/command/util.py
+++ b/libbe/command/util.py
@@ -1,18 +1,45 @@
# Copyright
+import glob
+import os.path
+
+import libbe
+import libbe.command
+
class Completer (object):
def __init__(self, options):
self.options = options
def __call__(self, bugdir, fragment=None):
return [fragment]
-def complete_status(bugdir, fragment=None):
+def complete_command(command, argument, fragment=None):
+ """
+ List possible command completions for fragment.
+
+ command argument is not used.
+ """
+ return list(libbe.command.commands())
+
+def complete_path(command, argument, fragment=None):
+ """
+ List possible path completions for fragment.
+
+ command argument is not used.
+ """
+ if fragment == None:
+ fragment = '.'
+ comps = glob.glob(fragment+'*') + glob.glob(fragment+'/*')
+ if len(comps) == 1 and os.path.isdir(comps[0]):
+ comps.extend(glob.glob(comps[0]+'/*'))
+ return comps
+
+def complete_status(command, argument, fragment=None):
return [fragment]
-def complete_severity(bugdir, fragment=None):
+def complete_severity(command, argument, fragment=None):
return [fragment]
-def complete_assigned(bugdir, fragment=None):
+def complete_assigned(command, argument, fragment=None):
return [fragment]
-def complete_extra_strings(bugdir, fragment=None):
+def complete_extra_strings(command, argument, fragment=None):
return [fragment]
def select_values(string, possible_values, name="unkown"):
diff --git a/libbe/comment.py b/libbe/comment.py
index ebfde23..bf69a69 100644
--- a/libbe/comment.py
+++ b/libbe/comment.py
@@ -37,7 +37,7 @@ import libbe.util.id
from libbe.storage.util.properties import Property, doc_property, \
local_property, defaulting_property, checked_property, cached_property, \
primed_property, change_hook_property, settings_property
-import libbe.storage.settings_object as settings_object
+import libbe.storage.util.settings_object as settings_object
import libbe.storage.util.mapfile as mapfile
from libbe.util.tree import Tree
import libbe.util.utility as utility
diff --git a/libbe/storage/util/settings_object.py b/libbe/storage/util/settings_object.py
index be119dd..760df03 100644
--- a/libbe/storage/util/settings_object.py
+++ b/libbe/storage/util/settings_object.py
@@ -410,21 +410,21 @@ if libbe.TESTING == True:
self.failUnless(t.settings["List-type"] == [],
t.settings["List-type"])
self.failUnless(SAVES == [
- "'<class 'libbe.storage.settings_object.EMPTY'>' -> '[]'"
+ "'<class 'libbe.storage.util.settings_object.EMPTY'>' -> '[]'"
], SAVES)
t.list_type.append(5)
self.failUnless(SAVES == [
- "'<class 'libbe.storage.settings_object.EMPTY'>' -> '[]'",
+ "'<class 'libbe.storage.util.settings_object.EMPTY'>' -> '[]'",
], SAVES)
self.failUnless(t.settings["List-type"] == [5],
t.settings["List-type"])
self.failUnless(SAVES == [ # the append(5) has not yet been saved
- "'<class 'libbe.storage.settings_object.EMPTY'>' -> '[]'",
+ "'<class 'libbe.storage.util.settings_object.EMPTY'>' -> '[]'",
], SAVES)
self.failUnless(t.list_type == [5], t.list_type)#get triggers saved
self.failUnless(SAVES == [ # now the append(5) has been saved.
- "'<class 'libbe.storage.settings_object.EMPTY'>' -> '[]'",
+ "'<class 'libbe.storage.util.settings_object.EMPTY'>' -> '[]'",
"'[]' -> '[5]'"
], SAVES)
diff --git a/libbe/ui/base.py b/libbe/ui/base.py
index e69de29..b98f164 100644
--- a/libbe/ui/base.py
+++ b/libbe/ui/base.py
@@ -0,0 +1 @@
+# Copyright
diff --git a/libbe/ui/command_line.py b/libbe/ui/command_line.py
new file mode 100755
index 0000000..e84d32a
--- /dev/null
+++ b/libbe/ui/command_line.py
@@ -0,0 +1,270 @@
+# Copyright (C) 2005-2009 Aaron Bentley and Panometrics, Inc.
+# Chris Ball <cjb@laptop.org>
+# Gianluca Montecchi <gian@grys.it>
+# Oleg Romanyshyn <oromanyshyn@panoramicfeedback.com>
+# W. Trevor King <wking@drexel.edu>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+"""
+A command line interface to Bugs Everywhere.
+"""
+
+import optparse
+import os
+import sys
+
+import libbe
+import libbe.command
+import libbe.command.util
+import libbe.version
+import libbe.ui.util.pager
+
+if libbe.TESTING == True:
+ import doctest
+
+class CallbackExit (Exception):
+ pass
+
+class CmdOptionParser(optparse.OptionParser):
+ def __init__(self, command):
+ self.command = command
+ optparse.OptionParser.__init__(self)
+ self.disable_interspersed_args()
+ self.remove_option('-h')
+ self._option_by_name = {}
+ for option in self.command.options:
+ self._add_option(option)
+
+ def _add_option(self, option):
+ option.validate()
+ self._option_by_name[option.name] = option
+ opt_strings = ['--'+option.name]
+ if option.short_name != None:
+ opt_strings.append('-'+option.short_name)
+ if option.arg == None: # a callback option
+ opt = optparse.Option(
+ *opt_strings, action='callback',
+ callback=self.callback, help=option.help)
+ else:
+ kwargs = {}
+ if option.arg.type == 'bool':
+ action = 'store_true'
+ else:
+ kwargs['type'] = option.arg.type
+ action = 'store'
+ opt = optparse.Option(
+ *opt_strings, metavar=option.arg.metavar,
+ default=option.arg.default, action=action,
+ help=option.help, **kwargs)
+ opt._option = option
+ self.add_option(opt)
+
+ def parse_args(self, args=None, values=None):
+ args = self._get_args(args)
+ options,parsed_args = optparse.OptionParser.parse_args(
+ self, args=args, values=values)
+ for name,value in options.__dict__.items():
+ if value == '--complete':
+ argument = None
+ option = self._option_by_name[name]
+ if option.arg != None:
+ argument = option.arg
+ fragment = None
+ indices = [i for i,arg in enumerate(args)
+ if arg == '--complete']
+ for i in indices:
+ assert i > 0 # this --complete is an option value
+ if args[i-1] in ['--%s' % o.name
+ for o in self.command.options]:
+ name = args[i-1][2:]
+ if name == option.name:
+ break
+ elif option.short_name != None \
+ and args[i-1].startswith('-') \
+ and args[i-1].endswith(option.short_name):
+ break
+ if i+1 < len(args):
+ fragment = args[i+1]
+ self.complete(argument, fragment)
+ for i,arg in enumerate(parsed_args):
+ if arg == '--complete':
+ if i < len(self.command.args):
+ argument = self.command.args[i]
+ else:
+ argument = self.command.args[-1]
+ if argument.repeatable == False:
+ raise libbe.command.UserError('Too many arguments')
+ fragment = None
+ if i < len(args) - 1:
+ fragment = args[i+1]
+ self.complete(argument, fragment)
+ if len(parsed_args) > len(self.command.args) \
+ and self.command.args[-1] == False:
+ raise libbe.command.UserError('Too many arguments')
+ for arg in self.command.args[len(parsed_args):]:
+ if arg.optional == False:
+ raise libbe.command.UserError(
+ 'Missing required argument %s' % arg.metavar)
+ return (options, parsed_args)
+
+ def callback(self, option, opt, value, parser):
+ command_option = option._option
+ if command_option.name == 'complete':
+ argument = None
+ fragment = None
+ if len(parser.rargs) > 0:
+ fragment = parser.rargs[0]
+ self.complete(argument, fragment)
+ else:
+ print command_option.callback(
+ self.command, command_option, value)
+ raise CallbackExit
+
+ def complete(self, argument=None, fragment=None):
+ print argument, fragment
+ comps = self.command.complete(argument, fragment)
+ if fragment != None:
+ comps = [c for c in comps if c.startswith(fragment)]
+ print '\n'.join(comps)
+ raise CallbackExit
+
+
+class BE (libbe.command.Command):
+ """Class for parsing the command line arguments for `be`.
+ This class does not contain a useful _run() method. Call this
+ module's main() function instead.
+
+ >>> be = BE()
+ >>> p = CmdOptionParser(be)
+ >>> p.exit_after_callback = False
+ >>> try:
+ ... options,args = p.parse_args(['--help']) # doctest: +ELLIPSIS
+ ... except CallbackExit:
+ ... pass
+ usage: be [options] [COMMAND [command-options] [COMMAND-ARGS ...]]
+ <BLANKLINE>
+ Options:
+ -h HELP, --help=HELP Print a help message.
+ <BLANKLINE>
+ --complete=STRING Print a list of possible completions.
+ <BLANKLINE>
+ --version=VERSION Print version string.
+ ...
+ >>> options,args = p.parse_args(['--complete']) # doctest: +ELLIPSIS
+ """
+ name = 'be'
+
+ def __init__(self, *args, **kwargs):
+ libbe.command.Command.__init__(self, *args, **kwargs)
+ self.options.extend([
+ libbe.command.Option(name='version',
+ help='Print version string.',
+ callback=self.version),
+ libbe.command.Option(name='full-version',
+ help='Print full version information.',
+ callback=self.full_version),
+ libbe.command.Option(name='repo', short_name='r',
+ help='Select BE repository (see `be help repo`) rather '
+ 'than the current directory.',
+ arg=libbe.command.Argument(
+ name='repo', metavar='REPO', default='.',
+ completion_callback=libbe.command.util.complete_path)),
+ libbe.command.Option(name='paginate',
+ help='Pipe all output into less (or if set, $PAGER).'),
+ libbe.command.Option(name='no-pager',
+ help='Do not pipe git output into a pager.'),
+ ])
+ self.args.extend([
+ libbe.command.Argument(
+ name='command', optional=False,
+ completion_callback=libbe.command.util.complete_command),
+ libbe.command.Argument(
+ name='args', optional=True, repeatable=True)
+ ])
+
+ def _usage(self):
+ return 'usage: be [options] [COMMAND [command-options] [COMMAND-ARGS ...]]'
+
+ def _long_help(self):
+ cmdlist = []
+ for name in libbe.command.commands():
+ module = libbe.command.get_command(name)
+ Class = getattr(module, name.capitalize())
+ cmdlist.append((name, Class.__doc__.splitlines()[0]))
+ cmdlist.sort()
+ longest_cmd_len = max([len(name) for name,desc in cmdlist])
+ ret = ['Bugs Everywhere - Distributed bug tracking',
+ '', 'Supported commands']
+ for name, desc in cmdlist:
+ numExtraSpaces = longest_cmd_len-len(name)
+ ret.append('be %s%*s %s' % (name, numExtraSpaces, '', desc))
+ ret.extend(['', 'Run', ' be help [command]', 'for more information.'])
+ return '\n'.join(ret)
+
+ def version(self, *args):
+ return libbe.version.version(verbose=False)
+
+ def full_version(self, *args):
+ return libbe.version.version(verbose=True)
+
+def main():
+ parser = CmdOptionParser(BE())
+ try:
+ options,args = parser.parse_args()
+ except CallbackExit:
+ return 0
+ except libbe.command.UserError, e:
+ print 'ERROR:\n', e
+ return 1
+
+ paginate = 'auto'
+ if options.paginate == True:
+ paginate = 'always'
+ if options.no_pager== True:
+ paginate = 'never'
+ libbe.ui.util.pager.run_pager(paginate)
+
+ command_name = args[0]
+ try:
+ module = libbe.command.get_command(command_name)
+ except libbe.command.UnknownCommand, e:
+ print e
+ return 1
+ Class = getattr(module, command_name.capitalize())
+ command = Class()
+ parser = CmdOptionParser(command)
+ if command.requires_bugdir == True:
+ storage = libbe.storage.get_storage(options['repo'])
+ storage.connect()
+ bugdir = BugDir(storage)
+ else:
+ storage = None
+ bugdir = None
+ try:
+ options,args = parser.parse_args(args[1:])
+ command.run(bugdir, options, args)
+ except CallbackExit:
+ if storage != None: storage.disconnect()
+ return 0
+ except libbe.command.UserError, e:
+ if storage != None: storage.disconnect()
+ print 'ERROR:\n', e
+ return 1
+ if storage != None: storage.disconnect()
+ return 0
+
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/libbe/ui/util/cmdutil.py b/libbe/ui/util/cmdutil.py
index b2d8a99..86ff9fc 100644
--- a/libbe/ui/util/cmdutil.py
+++ b/libbe/ui/util/cmdutil.py
@@ -55,115 +55,7 @@ def execute(cmd, args,
ret = 0
return ret
-class GetHelp(Exception):
- pass
-
-
-class GetCompletions(Exception):
- def __init__(self, completions=[]):
- msg = "Get allowed completions"
- Exception.__init__(self, msg)
- self.completions = completions
-
-def raise_get_help(option, opt, value, parser):
- raise GetHelp
-
-def raise_get_completions(option, opt, value, parser):
- if hasattr(parser, "command") and parser.command == "be":
- comps = []
- for command, module in iter_commands():
- comps.append(command)
- for opt in parser.option_list:
- comps.append(opt.get_opt_string())
- raise GetCompletions(comps)
- raise GetCompletions(completions(sys.argv[1]))
-
-def completions(cmd):
- parser = get_command(cmd).get_parser()
- longopts = []
- for opt in parser.option_list:
- longopts.append(opt.get_opt_string())
- return longopts
-
-
-class CmdOptionParser(optparse.OptionParser):
- def __init__(self, usage):
- optparse.OptionParser.__init__(self, usage)
- self.disable_interspersed_args()
- self.remove_option("-h")
- self.add_option("-h", "--help", action="callback",
- callback=raise_get_help, help="Print a help message")
- self.add_option("--complete", action="callback",
- callback=raise_get_completions,
- help="Print a list of available completions")
-
- def error(self, message):
- raise UsageError(message)
-
- def iter_options(self):
- return iter_combine([self._short_opt.iterkeys(),
- self._long_opt.iterkeys()])
-
- def help_str(self):
- f = StringIO()
- self.print_help(f)
- return f.getvalue()
-
-def option_value_pairs(options, parser):
- """
- Iterate through OptionParser (option, value) pairs.
- """
- for option in [o.dest for o in parser.option_list if o.dest != None]:
- value = getattr(options, option)
- yield (option, value)
-def default_complete(options, args, parser, bugid_args={}):
- """
- A dud complete implementation for becommands so that the
- --complete argument doesn't cause any problems. Use this
- until you've set up a command-specific complete function.
-
- bugid_args is an optional dict where the keys are positional
- arguments taking bug shortnames and the values are functions for
- filtering, since that's a common enough operation.
- e.g. for "be open [options] BUGID"
- bugid_args = {0: lambda bug : bug.active == False}
- A positional argument of -1 specifies all remaining arguments
- (e.g in the case of "be show BUGID BUGID ...").
- """
- for option,value in option_value_pairs(options, parser):
- if value == "--complete":
- raise GetCompletions()
- if len(bugid_args.keys()) > 0:
- max_pos_arg = max(bugid_args.keys())
- else:
- max_pos_arg = -1
- for pos,value in enumerate(args):
- if value == "--complete":
- filter = None
- if pos in bugid_args:
- filter = bugid_args[pos]
- if pos > max_pos_arg and -1 in bugid_args:
- filter = bugid_args[-1]
- if filter != None:
- bugshortnames = []
- try:
- bd = bugdir.BugDir(from_disk=True,
- manipulate_encodings=False)
- bd.load_all_bugs()
- bugs = [bug for bug in bd if filter(bug) == True]
- bugshortnames = [bd.bug_shortname(bug) for bug in bugs]
- except bugdir.NoBugDir:
- pass
- raise GetCompletions(bugshortnames)
- raise GetCompletions()
-
-def complete_path(path):
- """List possible path completions for path."""
- comps = glob.glob(path+"*") + glob.glob(path+"/*")
- if len(comps) == 1 and os.path.isdir(comps[0]):
- comps.extend(glob.glob(comps[0]+"/*"))
- return comps
def restrict_file_access(bugdir, path):
diff --git a/libbe/util/encoding.py b/libbe/util/encoding.py
index 67131bf..af312c1 100644
--- a/libbe/util/encoding.py
+++ b/libbe/util/encoding.py
@@ -47,7 +47,7 @@ def get_input_encoding():
return get_encoding()
def get_output_encoding():
- return get_encoding():
+ return get_encoding()
def get_filesystem_encoding():
return get_encoding()
diff --git a/setup.py b/setup.py
index e770419..0ce3a2f 100755
--- a/setup.py
+++ b/setup.py
@@ -9,9 +9,9 @@ rev_date = rev_id.split("-")[1]
setup(
name='Bugs Everywhere',
version=rev_date,
- description='Bugtracker built on distributed revision control',
+ description='Bugtracker supporting distributed revision control',
url='http://bugseverywhere.org/',
- packages=['becommands', 'libbe'],
+ packages=['libbe'],
scripts=['be'],
data_files=[
('share/man/man1', ['doc/be.1']),