
    c,                     (   d Z dZddlZddlZddlmZ ddlmZ ddlm	Z	m
Z
 ddlmZ  G d d	e      Z G d
 de      Z G d de      Z G d de      Z G d de      Z e       ZdZ ed      d        Z ed      dd       Z ed      dd       Zy)zHelper functions to support command line tools providing more than
one command.

e.g called as "tool command [options] args..." where <options> and <args> are
command'specific
zrestructuredtext en    N)basename)Configuration)init_logget_threshold)callable_deprecatedc                       e Zd ZdZy)BadCommandUsagezRaised when an unknown command is used or when a command is not
    correctly used (bad options, too much / missing arguments...).

    Trigger display of command usage.
    N__name__
__module____qualname____doc__     ;/usr/lib/python3/dist-packages/logilab/common/clcommands.pyr	   r	   %   s    r   r	   c                       e Zd ZdZy)CommandErrorz|Raised when a command can't be processed and we want to display it and
    exit, without traceback nor usage displayed.
    Nr
   r   r   r   r   r   -   s    r   r   c                   d    e Zd ZdZdddddej
                  dfdZddZd ZddZ	ddZ
d	 Zd
 Zy)CommandLineaF  Usage:

    >>> LDI = cli.CommandLine('ldi', doc='Logilab debian installer',
                              version=version, rcfile=RCFILE)
    >>> LDI.register(MyCommandClass)
    >>> LDI.register(MyOtherCommandClass)
    >>> LDI.run(sys.argv[1:])

    Arguments:

    * `pgm`, the program name, default to `basename(sys.argv[0])`

    * `doc`, a short description of the command line tool

    * `copyright`, additional doc string that will be appended to the generated
      doc

    * `version`, version number of string of the tool. If specified, global
      --version option will be available.

    * `rcfile`, path to a configuration file. If specified, global --C/--rc-file
      option will be available?  self.rcfile = rcfile

    * `logger`, logger to propagate to commands, default to
      `logging.getLogger(self.pgm))`
    NTc                     |t        t        j                  d         }|| _        || _        || _        || _        || _        d | _        || _	        || _
        y )Nr   )r   sysargvpgmdoc	copyrightversionrcfileloggerlogthresholdcheck_duplicated_command)selfr   r   r   r   r   r   r    s           r   __init__zCommandLine.__init__R   sU     ;388A;'C"((@%r   c                     | j                   r$|s"|j                  | vsJ d|j                  z         || |j                  <   |S )z,register the given :class:`Command` subclassza command %s is already defined)r    name)r!   clsforces      r   registerzCommandLine.registerg   sE    00ESXXT=Q 	
-8	
Q SXX
r   c                 $   t        d| j                  d       	 |j                  d      }dv r| j	                  d       | j
                  .|dv r*t        | j
                         t        j                  d       | j                  }|'|d	v r#	 |j                  d      }|j                  d      }	 | j                  |      }	 t        j                  j                  ||             y# t        $ r | j	                  d       Y w xY w# t        $ r | j	                  d       Y uw xY w# t        $ r, t        d
|z         t                | j	                  d       Y w xY w# t        $ rQ}t        dd       t        |      rt        d|z  d       t                t        j                  d       Y d}~yd}~wt        $ rN}t        d|       t                t        j!                                t        j                  d       Y d}~yd}~ww xY w)zmain command line access point:
        * init logging
        * handle global options (-h/--help, --version, -C/--rc-file)
        * check command
        * run command

        Terminate by :exc:`SystemExit`
        Tz%(levelname)s: %(message)s)debugr   	logformatr      )z-h--helpNz	--version)z-Cz	--rc-filezERROR: no %s commandInterrupted endz: %s   zERROR:)r   r   pop
IndexErrorusage_and_exitr   printr   exitr   get_commandKeyErrormain_runKeyboardInterruptstrr	   help)r!   argsargr   commandexcerrs          r   runzCommandLine.runo   s    	**2	

	#((1+C """<<#(<$,,HHQK#)<"<'!hhqk	#&&s+G
	HHW%%dF34+  	#"	#  '##A&'  	#(3./G"	# ! 	-S)3xfsl,GHHQKK 	(C G',,.!HHQKK		s[   C( "D 0D( %E  (DDD%$D%(2EE 	H)AF55HAH

Hc                     t        j                  | j                        }|g|_        |t	        | j
                        }|j                  |       |S N)loggingLoggerr   handlersr   r   setLevel)r!   handlerr   r   s       r   create_loggerzCommandLine.create_logger   sD    )")():):;L%r   c                     || j                   }|Jt        j                  | j                        x}| _         |j	                  t        | j                                | |   |      S rD   )r   rE   	getLoggerr   rH   r   r   )r!   cmdr   s      r   r7   zCommandLine.get_command   sX    >[[F>#*#4#4TXX#>>FT[OOM$*;*;<=tCy  r   c                    t        d| j                  d       | j                  rt        dd       t        d       | j                  rt        d| j                  z         t        d| j                  z         t        | D cg c]  }t        |       c}      }d|z  }t        | j                               D ]3  \  }}|j                  rt        d||z   d| |j                                5 | j                  rt        d	| j                  z         t        d
| j                  z         | j                  rt        d| j                  z         | j                  rt        d| j                         yyc c}w )z\display usage for the main program (i.e. when no command supplied)
        and exit
        zusage:r.   r/   z [--rc-file=<configuration file>]z)<command> [options] <command argument>...z
%szi
Type "%(pgm)s <command> --help" for more information about a specific
command. Available commands are :
Nz
Use --rc-file=<configuration file> / -C <configuration file> before the command
to specify a configuration file. Default to %s.
z?%(pgm)s -h/--help
      display this usage information and exitzA%(pgm)s -v/--version
      display version configuration and exit
)r5   r   r   r   __dict__maxlensorteditemshiddenshort_descriptionr   r   )r!   rM   max_lenpaddingcmdnames        r   usagezCommandLine.usage   sP    	hc*;;4#>9:88&488#$' mm	
 40Cs3x01-"4::<0 	SLGS::cGg-x8#:O:O:QR	S ;; ++	 	1mm	

 <<0-- 
 >>$' 1 1s   E3c                 N    | j                          t        j                  |       y rD   )rZ   r   r6   )r!   statuss     r   r4   zCommandLine.usage_and_exit   s    

r   )FrD   )r   r   r   r   rE   ERRORr"   r'   rB   rJ   r7   rZ   r4   r   r   r   r   r   6   sH    : ]]!%A*0d!)(Vr   r   c                   ^    e Zd ZdZdZdZdZdZdZe	d        Z
e	d        Zd Zd Zdd	Zd
 Zy)Commanda  Base class for command line commands.

    Class attributes:

    * `name`, the name of the command

    * `min_args`, minimum number of arguments, None if unspecified

    * `max_args`, maximum number of arguments, None if unspecified

    * `arguments`, string describing arguments, used in command usage

    * `hidden`, boolean flag telling if the command should be hidden, e.g. does
      not appear in help's commands list

    * `options`, options list, as allowed by :mod:configuration
     FNc                 :    | j                   j                  dd      S )Nz    r`   )r   replacer%   s    r   descriptionzCommand.description   s    {{""62..r   c                 F    | j                         j                  d      d   S )N.r   )rd   splitrc   s    r   rV   zCommand.short_description  s     &&s+A..r   c                     d| j                   d| j                  d| j                         }t        j                  | |       || _        y )Nz%prog r.   z

)rZ   )r$   	argumentsrd   r   r"   r   )r!   r   rZ   s      r   r"   zCommand.__init__  s6    (,		4>>4CSCSCUVt51r   c                     | j                   #t        |      | j                   k  rt        d      | j                  $t        |      | j                  kD  rt        d      yy)z&check command's arguments are providedNzmissing argumenttoo many arguments)min_argsrR   r	   max_argsr!   r=   s     r   
check_argszCommand.check_args  sU    ==$TT]])B!"455==$TT]])B!"677 *C$r   c                     |r| j                  |       | j                  |      }	 | j                  |       | j                  |       y# t        $ r%}| j
                  j                  |       Y d}~yd}~ww xY w)a  Run the command and return status 0 if everything went fine.

        If :exc:`CommandError` is raised by the underlying command, simply log
        the error and return status 2.

        Any other exceptions, including :exc:`BadCommandUsage` will be
        propagated.
        N   r   )load_file_configurationload_command_line_configurationro   rB   r   r   error)r!   r=   r   rA   s       r   r9   zCommand.main_run  sm     ((033D9	OOD!HHTN   	KKc"	s   "A	 		A7A22A7c                     t               )+run the command with its specific arguments)NotImplementedErrorrn   s     r   rB   zCommand.run'  s    !##r   rD   )r   r   r   r   ri   r$   rU   rl   rm   classmethodrd   rV   r"   ro   r9   rB   r   r   r   r_   r_      s\    $ IDFHH/ / / /
8($r   r_   c                   "    e Zd ZdZdZdZdZd Zy)ListCommandsCommandz4list available commands, useful for bash completion.listcommandsz	[command]Tc                     |rG|j                         }t        |   }|j                  D ]  \  }}t        d       t        d|z            yt	        t        j                               }|D ]#  }t        |   }|j                  rt        |       % y)rv   r,   z--N)r2   	_COMMANDSoptionsr5   rS   keysrU   )r!   r=   r?   rM   optnameoptdictcommandss          r   rB   zListCommandsCommand.run3  s    hhjGG$C$'KK & hdWn%& inn./H# #(zz'N#r   N)r   r   r   r   r$   ri   rU   rB   r   r   r   rz   rz   ,  s    >DIF#r   rz   z~Copyright (c) 2004-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
http://www.logilab.fr/ -- mailto:contact@logilab.frzuse cls.register(cli)c                 <    | D ]  }t         j                  |        y)zregister existing commandsN)r}   r'   )r   command_klasss     r   register_commandsr   L  s!     " *=)*r   zuse args.pop(0)c                 p    |t         _        |t         _        |t         _        t         j	                  |        y)zcommand line tool: run command specified by argument list (without the
    program name). Raise SystemExit with status 0 if everything went fine.

    >>> main_run(sys.argv[1:])
    N)r}   r   r   r   rB   )r=   r   r   r   s       r   r9   r9   S  s'     IM#IIMM$r   c                     	 | j                  d      }|t        |       |kD  rt        d      |S # t        $ r t        |      w xY w)z7helper function to get and check command line argumentsr   rk   )r2   r3   r	   rR   )	args_listexpected_size_aftermsgvalues       r   pop_argr   `  sV    #a  &3y><O+O233L	  #c""#s	   0 A)NNN)NzMissing argument)r   __docformat__r   rE   os.pathr   logilab.common.configurationr   logilab.common.logging_extr   r   logilab.common.deprecationr   	Exceptionr	   r   dictr   r_   rz   r}   DEFAULT_COPYRIGHTr   r9   r   r   r   r   <module>r      s   $ & 
   6 > :i 9 h$ h\E$m E$P#' #2 M	7 
 ,-* .* &'	 (	 &' (r   