<s> """<STR_LIT>""" <EOL> import re <EOL> import sys <EOL> import inspect <EOL> class Option ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , name , description = None , action = None , resolve = None ) : <EOL> self . name = name <EOL> self . description = description <EOL> self . action = action <EOL> self . resolve = resolve <EOL> self . parse ( name , description ) <EOL> def __str__ ( self ) : <EOL> return self . key <EOL> def __repr__ ( self ) : <EOL> return '<STR_LIT>' % str ( self ) <EOL> def parse ( self , name , description ) : <EOL> """<STR_LIT>""" <EOL> name = name . strip ( ) <EOL> if '<STR_LIT:<>' in name : <EOL> self . required = True <EOL> self . boolean = False <EOL> name = name [ : name . index ( '<STR_LIT:<>' ) ] . strip ( ) <EOL> elif '<STR_LIT:[>' in name : <EOL> self . required = False <EOL> self . boolean = False <EOL> name = name [ : name . index ( '<STR_LIT:[>' ) ] . strip ( ) <EOL> else : <EOL> self . required = False <EOL> self . boolean = True <EOL> regex = re . compile ( r'<STR_LIT>' ) <EOL> m = regex . findall ( name ) <EOL> if not m : <EOL> raise ValueError ( '<STR_LIT>' , name ) <EOL> shortname , longname = m [ <NUM_LIT:0> ] <EOL> if not shortname and not longname : <EOL> raise ValueError ( '<STR_LIT>' , name ) <EOL> self . shortname = shortname <EOL> self . longname = longname <EOL> if longname and longname . startswith ( '<STR_LIT>' ) : <EOL> self . key = longname [ <NUM_LIT:5> : ] <EOL> elif longname : <EOL> self . key = longname [ <NUM_LIT:2> : ] <EOL> else : <EOL> self . key = shortname <EOL> if self . boolean : <EOL> if longname and longname . startswith ( '<STR_LIT>' ) : <EOL> self . default = True <EOL> else : <EOL> self . default = False <EOL> return self <EOL> if not description : <EOL> self . default = None <EOL> return self <EOL> regex = re . compile ( r'<STR_LIT>' ) <EOL> m = regex . findall ( description ) <EOL> if not m : <EOL> self . default = None <EOL> return self <EOL> self . required = False <EOL> value = m [ <NUM_LIT:0> ] . strip ( ) <EOL> if value . startswith ( '<STR_LIT:<>' ) and value . endswith ( '<STR_LIT:>>' ) : <EOL> value = value [ <NUM_LIT:1> : - <NUM_LIT:1> ] <EOL> elif value . startswith ( '<STR_LIT:[>' ) and value . endswith ( '<STR_LIT:]>' ) : <EOL> value = value [ <NUM_LIT:1> : - <NUM_LIT:1> ] <EOL> self . default = value . strip ( ) <EOL> return self <EOL> def to_python ( self , value = None ) : <EOL> """<STR_LIT>""" <EOL> if value is None : <EOL> return self . default <EOL> if self . resolve : <EOL> return self . resolve ( value ) <EOL> return value <EOL> class Command ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , name , description = None , version = None , usage = None , <EOL> title = None , func = None , help_footer = None , arguments = None ) : <EOL> self . _name = name <EOL> self . _description = description <EOL> self . _version = version <EOL> self . _usage = usage <EOL> self . _title = title <EOL> self . _command_func = func <EOL> self . _help_footer = help_footer <EOL> self . _positional_list = arguments or [ ] <EOL> self . _parent = None <EOL> self . _option_list = [ ] <EOL> self . _command_list = [ ] <EOL> self . _results = { } <EOL> self . _args_results = [ ] <EOL> self . _add_default_options ( ) <EOL> def __getitem__ ( self , key ) : <EOL> return self . get ( key ) <EOL> def __getattr__ ( self , key ) : <EOL> try : <EOL> return object . __getattribute__ ( self , key ) <EOL> except AttributeError : <EOL> try : <EOL> return self . get ( key ) <EOL> except ValueError : <EOL> raise AttributeError ( '<STR_LIT>' % key ) <EOL> def __call__ ( self , func ) : <EOL> return self . action ( func ) <EOL> @ property <EOL> def args ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . _args_results <EOL> def keys ( self ) : <EOL> return self . _results . keys ( ) <EOL> def get ( self , key ) : <EOL> """<STR_LIT>""" <EOL> value = self . _results . get ( key ) <EOL> if value is not None : <EOL> return value <EOL> option = list ( filter ( lambda o : o . key == key , self . _option_list ) ) <EOL> if not option : <EOL> raise ValueError ( '<STR_LIT>' % key ) <EOL> option = option [ <NUM_LIT:0> ] <EOL> return option . default <EOL> def option ( self , name , description = None , action = None , resolve = None ) : <EOL> """<STR_LIT>""" <EOL> if isinstance ( name , Option ) : <EOL> option = name <EOL> else : <EOL> name = name . strip ( ) <EOL> option = Option ( <EOL> name = name , description = description , <EOL> action = action , resolve = resolve , <EOL> ) <EOL> self . _option_list . append ( option ) <EOL> return self <EOL> def _add_default_options ( self ) : <EOL> def print_help ( ) : <EOL> self . print_help ( ) <EOL> return sys . exit ( <NUM_LIT:0> ) <EOL> self . option ( <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> print_help <EOL> ) <EOL> if self . _version : <EOL> def print_version ( ) : <EOL> self . print_version ( ) <EOL> return sys . exit ( <NUM_LIT:0> ) <EOL> self . option ( <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> print_version <EOL> ) <EOL> return self <EOL> def parse_options ( self , arg ) : <EOL> """<STR_LIT>""" <EOL> if not arg . startswith ( '<STR_LIT:->' ) : <EOL> return False <EOL> value = None <EOL> if '<STR_LIT:=>' in arg : <EOL> arg , value = arg . split ( '<STR_LIT:=>' ) <EOL> for option in self . _option_list : <EOL> if arg not in ( option . shortname , option . longname ) : <EOL> continue <EOL> action = option . action <EOL> if action : <EOL> action ( ) <EOL> if option . key == option . shortname : <EOL> self . _results [ option . key ] = True <EOL> return True <EOL> if option . boolean and option . default : <EOL> self . _results [ option . key ] = False <EOL> return True <EOL> if option . boolean : <EOL> self . _results [ option . key ] = True <EOL> return True <EOL> if not value : <EOL> if self . _argv : <EOL> value = self . _argv [ <NUM_LIT:0> ] <EOL> self . _argv = self . _argv [ <NUM_LIT:1> : ] <EOL> if not value : <EOL> raise RuntimeError ( '<STR_LIT>' % option . name ) <EOL> self . _results [ option . key ] = option . to_python ( value ) <EOL> return True <EOL> return False <EOL> def validate_options ( self ) : <EOL> """<STR_LIT>""" <EOL> for option in self . _option_list : <EOL> if option . required and option . key not in self . _results : <EOL> raise RuntimeError ( '<STR_LIT>' % option . name ) <EOL> def action ( self , command ) : <EOL> """<STR_LIT>""" <EOL> if isinstance ( command , Command ) : <EOL> self . _command_list . append ( command ) <EOL> return command <EOL> func = command <EOL> args , varargs , keywords , defaults = inspect . getargspec ( func ) <EOL> if func . __doc__ : <EOL> doclines = func . __doc__ . splitlines ( ) <EOL> else : <EOL> doclines = [ ] <EOL> doclines = filter ( lambda o : o . strip ( ) , doclines ) <EOL> doclines = list ( map ( lambda o : o . strip ( ) , doclines ) ) <EOL> params = { } <EOL> options = { } <EOL> usage = None <EOL> for line in doclines : <EOL> if line . startswith ( '<STR_LIT>' ) : <EOL> usage = line [ <NUM_LIT:6> : ] . strip ( ) <EOL> elif line . startswith ( '<STR_LIT>' ) : <EOL> name , desc = line [ <NUM_LIT:7> : ] . split ( '<STR_LIT::>' , <NUM_LIT:1> ) <EOL> params [ name . strip ( ) ] = desc . strip ( ) <EOL> elif line . startswith ( '<STR_LIT>' ) : <EOL> name , desc = line [ <NUM_LIT:8> : ] . split ( '<STR_LIT::>' , <NUM_LIT:1> ) <EOL> options [ name . strip ( ) ] = desc . strip ( ) <EOL> desc = None <EOL> if doclines : <EOL> desc = doclines [ <NUM_LIT:0> ] <EOL> cmd = self . __class__ ( func . __name__ , desc , usage = usage ) <EOL> defaults = defaults or [ ] <EOL> kwargs = dict ( zip ( * [ reversed ( i ) for i in ( args , defaults ) ] ) ) <EOL> for arg in args : <EOL> desc = params . get ( arg , None ) <EOL> name = options . get ( arg , None ) <EOL> if arg in kwargs : <EOL> value = kwargs [ arg ] <EOL> if value is True : <EOL> name = name or '<STR_LIT>' % arg <EOL> option = Option ( name , desc ) <EOL> elif value is False : <EOL> name = name or '<STR_LIT>' % ( arg [ <NUM_LIT:0> ] , arg ) <EOL> option = Option ( name , desc ) <EOL> else : <EOL> name = name or '<STR_LIT>' % ( arg [ <NUM_LIT:0> ] , arg , arg ) <EOL> option = Option ( name , desc ) <EOL> option . default = value <EOL> cmd . option ( option ) <EOL> elif desc : <EOL> name = name or '<STR_LIT>' % ( arg [ <NUM_LIT:0> ] , arg , arg ) <EOL> cmd . option ( name , desc ) <EOL> else : <EOL> cmd . _positional_list . append ( arg ) <EOL> cmd . _command_func = func <EOL> self . _command_list . append ( cmd ) <EOL> return command <EOL> def subcommand ( self , command ) : <EOL> """<STR_LIT>""" <EOL> return self . action ( command ) <EOL> def parse ( self , argv = None ) : <EOL> """<STR_LIT>""" <EOL> if not argv : <EOL> argv = sys . argv <EOL> elif isinstance ( argv , str ) : <EOL> argv = argv . split ( ) <EOL> self . _argv = argv [ <NUM_LIT:1> : ] <EOL> if not self . _argv : <EOL> self . validate_options ( ) <EOL> if self . _command_func : <EOL> self . _command_func ( ** self . _results ) <EOL> return True <EOL> return False <EOL> cmd = self . _argv [ <NUM_LIT:0> ] <EOL> if not cmd . startswith ( '<STR_LIT:->' ) : <EOL> for command in self . _command_list : <EOL> if isinstance ( command , Command ) and command . _name == cmd : <EOL> command . _parent = self <EOL> return command . parse ( self . _argv ) <EOL> _positional_index = <NUM_LIT:0> <EOL> while self . _argv : <EOL> arg = self . _argv [ <NUM_LIT:0> ] <EOL> self . _argv = self . _argv [ <NUM_LIT:1> : ] <EOL> if not self . parse_options ( arg ) : <EOL> self . _args_results . append ( arg ) <EOL> if len ( self . _positional_list ) > _positional_index : <EOL> key = self . _positional_list [ _positional_index ] <EOL> self . _results [ key ] = arg <EOL> _positional_index += <NUM_LIT:1> <EOL> self . validate_options ( ) <EOL> if self . _parent and isinstance ( self . _parent , Command ) : <EOL> self . _parent . _args_results = self . _args_results <EOL> if self . _command_func : <EOL> self . _command_func ( ** self . _results ) <EOL> return True <EOL> return False <EOL> def print_version ( self ) : <EOL> """<STR_LIT>""" <EOL> if not self . _version : <EOL> return self <EOL> if not self . _title : <EOL> print ( '<STR_LIT>' % ( self . _name , self . _version ) ) <EOL> return self <EOL> print ( '<STR_LIT>' % ( self . _title , self . _name , self . _version ) ) <EOL> return self <EOL> def print_title ( self , title ) : <EOL> """<STR_LIT>""" <EOL> print ( title ) <EOL> return self <EOL> def print_help ( self ) : <EOL> """<STR_LIT>""" <EOL> print ( '<STR_LIT>' % ( self . _title or self . _name , self . _version or '<STR_LIT>' ) ) <EOL> if self . _usage : <EOL> print ( '<STR_LIT>' % self . _usage ) <EOL> else : <EOL> cmd = self . _name <EOL> if hasattr ( self , '<STR_LIT>' ) and isinstance ( self . _parent , Command ) : <EOL> cmd = '<STR_LIT>' % ( self . _parent . _name , cmd ) <EOL> if self . _command_list : <EOL> usage = '<STR_LIT>' % cmd <EOL> else : <EOL> usage = '<STR_LIT>' % cmd <EOL> pos = '<STR_LIT:U+0020>' . join ( [ '<STR_LIT>' % name for name in self . _positional_list ] ) <EOL> print ( '<STR_LIT>' % ( usage , pos ) ) <EOL> arglen = max ( len ( o . name ) for o in self . _option_list ) <EOL> arglen += <NUM_LIT:2> <EOL> self . print_title ( '<STR_LIT>' ) <EOL> for o in self . _option_list : <EOL> print ( '<STR_LIT>' % ( _pad ( o . name , arglen ) , o . description or '<STR_LIT>' ) ) <EOL> print ( '<STR_LIT>' ) <EOL> if self . _command_list : <EOL> self . print_title ( '<STR_LIT>' ) <EOL> for cmd in self . _command_list : <EOL> if isinstance ( cmd , Command ) : <EOL> name = _pad ( cmd . _name , arglen ) <EOL> desc = cmd . _description or '<STR_LIT>' <EOL> print ( '<STR_LIT>' % ( _pad ( name , arglen ) , desc ) ) <EOL> print ( '<STR_LIT>' ) <EOL> if self . _help_footer : <EOL> print ( self . _help_footer ) <EOL> print ( '<STR_LIT>' ) <EOL> return self <EOL> def _pad ( msg , length ) : <EOL> return '<STR_LIT>' % ( msg , '<STR_LIT:U+0020>' * ( length - len ( msg ) ) ) </s>
