
>gT                 @   s   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	 m
 Z
 d  d l m Z m Z d  d l m Z d  d l m Z y d  d	 l m Z Wn e k
 r d
 d   Z Yn Xe  j d  Z Gd d   d  Z d d   Z d S)    N)wraps)glob1)removewalk)isdirjoin)PopenPIPE)rmtree)execute)quotec             C   s"   |  s
 d Sd |  j  d d  d S)Nz'''z'"'"')replace)s r   +/usr/share/dh-python/dhpython/build/base.pyr   !   s    r   Zdhpythonc               @   s   e  Z d  Z d Z d Z g  Z g  Z i  Z d d d d d d h Z d	 d
   Z	 d d   Z
 e d d    Z d d   Z d d   Z d d   Z d d   Z d d   Z d d   Z d d d  Z d S)Basea  Base class for build system plugins

    :attr REQUIRED_COMMANDS: list of command checked by default in :meth:is_usable,
        if one of them is missing, plugin cannot be used.
    :type REQUIRED_COMMANDS: list of strings
    :attr REQUIRED_FILES: list of files (or glob templates) required by given
        build system
    :attr OPTIONAL_FILES: dictionary of glob templates (key) and score (value)
        used to detect if given plugin is the best one for the job
    :type OPTIONAL_FILES: dict (key is a string, value is an int)
    :attr SUPPORTED_INTERPRETERS: set of interpreter templates (with or without
        {version}) supported by given plugin
     pythonpython3z
python-dbgzpython3-dbgzpython{version}zpython{version}-dbgc             C   s   | |  _  d  S)N)cfg)selfr   r   r   r   __init__>   s    zBase.__init__c             C   s   d |  j  S)NzBuildSystem(%s))NAME)r   r   r   r   __repr__A   s    zBase.__repr__c             C   sj   xc |  j  D]X } t d | g d t d t } | j   \ } } | j d k r
 t d |   q
 q
 Wd  S)NZwhichstdoutstderrr   zmissing command: %s)REQUIRED_COMMANDSr   r	   Zcommunicate
returncode	Exception)clscommandZprocesouterrr   r   r   	is_usableD   s
    zBase.is_usablec       	      C   sF  d } d } i  |  _  x |  j D]w } d } xU | j d  D]D } t | d |  } | r; d } |  j  j | g   j |  q; q; W| r | d 7} q q W|  j r | t | t |  j  d  7} n  i  |  _ x_ |  j	 j
   D]N \ } } t | d |  } | r | | 7} |  j j | g   j |  q q W| d k rBd S| S)	aJ  Return certainty level that this plugin describes the right build system

        This method is using cls.{REQUIRED,OPTIONAL}_FILES only by default,
        please extend it in the plugin if more sofisticated methods can be used
        for given build system.

        :return: 0 <= certainty <= 100
        :rtype: int
        r   F|dirT   2   d   )ZDETECTED_REQUIRED_FILESREQUIRED_FILESsplitr   
setdefaultextendintlenZDETECTED_OPTIONAL_FILESOPTIONAL_FILESitems)	r   contextresultZrequired_files_numZtplfoundZftplresZscorer   r   r   detectL   s.    
	#	$	
#zBase.detectc             C   s  |  j  j rd t | d d  } t |  rd y t |  Wqa t k
 r] t j d |  Yqa Xqd n  xt | d  D]\ } } } x| | D]t } | d k r t | |  } t j d |  y t |  Wn" t k
 r t j d |  Yq X| j	 |  q q Wxr | D]j }	 |	 j
 d	  r
t | |	  }
 t j d |
  y t	 |
  Wqtt k
 rpt j d |
  YqtXq
q
Wqu Wd  S)
Nr&   z.toxzcannot remove %s__pycache__zremoving dir: %s.pyc.pyozremoving: %s)r8   r9   )r   test_toxr   r   r
   r   logdebugr   r   endswith)r   r2   argsZtox_dirrootdirsZ
file_namesnameZdpathfnZfpathr   r   r   cleanq   s2     z
Base.cleanc             C   s   t  d |  j   d  S)Nz&configure method not implemented in %s)NotImplementedErrorr   )r   r2   r>   r   r   r   	configure   s    zBase.configurec             C   s   t  d |  j   d  S)Nz$install method not implemented in %s)rD   r   )r   r2   r>   r   r   r   install   s    zBase.installc             C   s   t  d |  j   d  S)Nz"build method not implemented in %s)rD   r   )r   r2   r>   r   r   r   build   s    z
Base.buildc             C   sf   |  j  j r d S|  j  j r  d S|  j  j r0 d S| d d k s^ | d d ?s^ | d d k rb d	 Sd  S)
Nz;cd {build_dir}; {interpreter} -m nose --with-doctest {args}z.cd {build_dir}; {interpreter} -m pytest {args}zHcd {build_dir}; tox -c {dir}/tox.ini -e py{version.major}{version.minor}versionz2.7z3.1interpreterZpypyz<cd {build_dir}; {interpreter} -m unittest discover -v {args})r   Z	test_noseZtest_pytestr:   )r   r2   r>   r   r   r   test   s    .z	Base.testNc             C   s   | d k r! |  j  j r! d  } n  | j |   } d | k r] t | d  } | d | d <n
 | d } t j |  t | | d | |  S)NF
PYTHONPATHZENVr&   )r   Zreally_quietformatdictr;   infor   )r   r2   r>   r!   log_fileenvr   r   r   r      s    	
zBase.execute)__name__
__module____qualname____doc__ZDESCRIPTIONr   r*   r0   ZSUPPORTED_INTERPRETERSr   r   classmethodr$   r6   rC   rE   rF   rG   rJ   r   r   r   r   r   r   )   s"   %
r   c                s"   t       f d d    } | S)Nc       
         sP  | j  d d   } | sF   |  | | | |  } t | t  rF | Sn  | s t j d |  j   j | j d  | j d   | S|  j j	 r t
 | d d j   j   } n d } t d d	   | j   D  } | j |   } |  j | | | |  } | d
 d k rLd j | d
 |  }	 | r=|	 d j |  7}	 n  t |	   n  d S)Nr!   zBmissing command (plugin=%s, method=%s, interpreter=%s, version=%s)rI   rH   Zhome_dirz
{}_cmd.logFc             s   sN   |  ]D \ } } | d k s* | j  d  r< | t |  f n	 | | f Vq d S)r&   destdirZ_dirN)zdirrV   )r=   r   ).0kvr   r   r   	<genexpr>   s   z6shell_command.<locals>.wrapped_func.<locals>.<genexpr>r   r   zexit code={}: {}z$
full command log is available in {}T)pop
isinstancer.   r;   warnr   rQ   getr   quietr   rL   rM   r1   r   r   )
r   r2   r>   Zoargskwargsr!   rO   Zquoted_argsoutputmsg)funcr   r   wrapped_func   s.    	"z#shell_command.<locals>.wrapped_func)r   )rc   rd   r   )rc   r   shell_command   s     re   )Zlogging	functoolsr   Zglobr   osr   r   os.pathr   r   
subprocessr   r	   Zshutilr
   Zdhpython.toolsr   Zshlexr   ImportErrorZ	getLoggerr;   r   re   r   r   r   r   <module>   s   