Moved be to libbe.ui.command_line and transitioned to Command format.
authorW. Trevor King <wking@drexel.edu>
Sun, 13 Dec 2009 01:57:59 +0000 (20:57 -0500)
committerW. Trevor King <wking@drexel.edu>
Sun, 13 Dec 2009 01:57:59 +0000 (20:57 -0500)
14 files changed:
be
libbe/bug.py
libbe/bugdir.py
libbe/command/__init__.py
libbe/command/base.py
libbe/command/list.py
libbe/command/util.py
libbe/comment.py
libbe/storage/util/settings_object.py
libbe/ui/base.py
libbe/ui/command_line.py [new file with mode: 0755]
libbe/ui/util/cmdutil.py
libbe/util/encoding.py
setup.py

diff --git a/be b/be
index 5e3088e8208b58c95bb85bf34941d02aa742a08d..5f7bd1b15d37046546c97dae84a338a6893a278c 100755 (executable)
--- 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())
index 1f9677971c61f37dba23affc6842e63b819547da..d62de499003becaf214baaaa66f96d5118a57dda 100644 (file)
@@ -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
index 39eface6ba04e73f160d40c5fb09fcc070546d5a..5f76d3c7ded887e97b1de31b7606a80c6953621b 100644 (file)
@@ -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
index 344a8a27bd9c2c556b61486a58148879673fce85..855888203989783fecdc3a11e49a53184bbc2d5b 100644 (file)
 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]
index 0db156b00b9f7e629e5f3ab41b186cbfd1f0cafb..252dd24d433a3aa902a8a72a963ba3aa91dabf38 100644 (file)
@@ -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
index 95277790c6949087a0d003d2ddc4a56cbe61d1e4..c835815959b6456697dee49e132bf48521b1d5d4 100644 (file)
@@ -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',
index a650d3384eaa9dae3b0e590c6909cc622c108cfd..6ce5cc94d692a7d73a3483c17412f22d9c7ca7e2 100644 (file)
@@ -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"):
index ebfde23c091da0bd1eb8006c8407f4d892301768..bf69a698a1cb482d145e18befa4ae83b58d0e965 100644 (file)
@@ -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
index be119dd9ec3e381165a27a29cf32384fc6f21125..760df03ee93cce9eed66239bb0cf3e81b36a3579 100644 (file)
@@ -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)
 
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..b98f1648fbd537dcaaf3dc1283834dea4e906f4b 100644 (file)
@@ -0,0 +1 @@
+# Copyright
diff --git a/libbe/ui/command_line.py b/libbe/ui/command_line.py
new file mode 100755 (executable)
index 0000000..e84d32a
--- /dev/null
@@ -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())
index b2d8a99108dd7a4695e238bc560c73bcfc17856b..86ff9fc757bf7003e64b1bee4e76b30eee5bbf41 100644 (file)
@@ -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):
index 67131bfb1d025e6296117176e9516cc9eb03e371..af312c12c0c51ab3c855c79fed38549074306d30 100644 (file)
@@ -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()
index e770419249ab026fb3bd41457bcbf8871fb8de86..0ce3a2fcc6a0aea8fefd978277641656ccd4d1b6 100755 (executable)
--- 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']),