diff options
author | W. Trevor King <wking@drexel.edu> | 2009-12-12 20:57:59 -0500 |
---|---|---|
committer | W. Trevor King <wking@drexel.edu> | 2009-12-12 20:57:59 -0500 |
commit | dff6bd9bf89ca80e2265696a478e540476718c9c (patch) | |
tree | 230f35262808052839ae2401d99cdf23cc304f20 | |
parent | 86f886399813d37f3cfcf74a824d352e01eb0d8c (diff) | |
download | bugseverywhere-dff6bd9bf89ca80e2265696a478e540476718c9c.tar.gz |
Moved be to libbe.ui.command_line and transitioned to Command format.
-rwxr-xr-x | be | 102 | ||||
-rw-r--r-- | libbe/bug.py | 2 | ||||
-rw-r--r-- | libbe/bugdir.py | 2 | ||||
-rw-r--r-- | libbe/command/__init__.py | 4 | ||||
-rw-r--r-- | libbe/command/base.py | 102 | ||||
-rw-r--r-- | libbe/command/list.py | 1 | ||||
-rw-r--r-- | libbe/command/util.py | 35 | ||||
-rw-r--r-- | libbe/comment.py | 2 | ||||
-rw-r--r-- | libbe/storage/util/settings_object.py | 8 | ||||
-rw-r--r-- | libbe/ui/base.py | 1 | ||||
-rwxr-xr-x | libbe/ui/command_line.py | 270 | ||||
-rw-r--r-- | libbe/ui/util/cmdutil.py | 108 | ||||
-rw-r--r-- | libbe/util/encoding.py | 2 | ||||
-rwxr-xr-x | setup.py | 4 |
14 files changed, 375 insertions, 268 deletions
@@ -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() @@ -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']), |