# -*- coding: UTF-8 -*- # Copyright 2014 Red Hat, Inc. # Part of clufter project # Licensed under GPLv2+ (a copy included | http://gnu.org/licenses/gpl-2.0.txt) """Machinery entry point""" __author__ = "Jan Pokorný " import logging from optparse import OptionParser, \ OptionGroup, \ IndentedHelpFormatter from os.path import basename from platform import system, linux_distribution from sys import version from . import version_text, description_text from .command_manager import CommandManager from .completion import Completion from .error import EC from .format_manager import FormatManager from .filter_manager import FilterManager from .utils_prog import make_options, set_logging _system = system() _system_extra = linux_distribution(full_distribution_name=0) \ if _system == 'Linux' else () def parser_callback_help(option, opt_str, value, parser): """Makes 'help' option accept 'optional option arguments'""" rargs, val = parser.rargs, '' if rargs and not rargs[0].startswith('-'): val = rargs[0] del rargs[:1] setattr(parser.values, 'help', val) opts_common = ( (('-q', '--quiet', ), dict( action='store_true', help="refrain from unnecesary messages (usually on stderr)" )), (('--loglevel', ), dict( action='store', dest='loglevel', default=logging.getLevelName(logging.WARNING), type="choice", choices=map(logging.getLevelName, xrange(logging.NOTSET, logging.CRITICAL + 1, logging.DEBUG - logging.NOTSET)), help="set loglevel to specified value [%default out of %choices]" )), (('--logfile', ), dict( action='store', dest='logfile', default='', help="log to specified file instead of stderr" )), # TODO other logging related stuff (file, ...) (('-d', '--debug'), dict( action='store_const', dest='loglevel', const='DEBUG', help="shortcut for --loglevel=DEBUG" )), (('--sys', ), dict( action='store', default=_system, help="override autodetected system [%default]" )), (('--dist', ), dict( action='store', default=','.join(_system_extra), help="override autodetected distro if `sys` is `Linux' [%default]" )), ) opts_main = ( (('-h', '--help'), dict( metavar="[CMD]", type='string', nargs=0, # <- we take one if suitable action='callback', callback=parser_callback_help, help="show this help message (global or command-specific) and exit" )), (('-v', '--version'), dict( action='store_true', help="show version details and exit" )), (('-l', '--list'), dict( action='store_true', help="list commands and exit" )), (('--completion-bash', ), dict( action='store_const', dest='completion', const='bash', help="generate bash completion and exit" )), ) opts_nonmain = ( (('-h', '--help'), dict( action='store_true', help="show this help message and exit" )), ) class SharedHelpFormatter(IndentedHelpFormatter): """IndentedHelpFormatter to expand choices along defaults""" choices_tag = "%choices" def expand_default(self, option): ret = IndentedHelpFormatter.expand_default(self, option) return ret.replace(self.choices_tag, ', '.join(option.choices or [])) class SharedOptionParser(OptionParser): """OptionParser with a dynamic on-demand help screen customization.""" # overridden methods def __init__(self, **kwargs): if not 'formatter' in kwargs: kwargs['formatter'] = SharedHelpFormatter() OptionParser.__init__(self, **kwargs) self.description_raw = '' def format_description(self, formatter): # cf. http://bugs.python.org/issue4318 return '\n'.join(formatter.format_description(l) for l in self.get_description().split('\n\n')) \ + (self.description_raw and '\n' + self.description_raw + '\n') # custom methods def format_customized_help(self, **kwargs): for k in ('usage', 'description', 'description_raw', 'epilog'): v = kwargs.pop(k, None) if v: setattr(self, k, v) return self.format_help(**kwargs) def add_option_group_by_args(self, *args, **kwargs): option_list = kwargs.pop('option_list', None) group = OptionGroup(self, *args, **kwargs) if option_list: group.add_options(option_list) self.add_option_group(group) def run(argv=None, *args): """Entry point""" # re option parser: only one instance is used, modified along ec = EC.EXIT_SUCCESS argv = list(argv) + list(args) if argv else list(args) prog, args = (argv[0], argv[1:]) if argv else ('