
U]"                 @   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
 m Z d  d l m Z m Z d  d l m Z 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)existsisdirjoin)PopenPIPE)rmtreecopytree)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   sg   x` |  j  D]U } t d | g d t d t } | j   \ } } | j d k r
 t d |   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   s:  d } d } i  |  _  x| |  j D]q } d } xR | j d  D]A } t | d |  } | r; d } |  j  j | g   j |  q; W| r | d 7} q W|  j r | t | t |  j  d  7} i  |  _ x\ |  j	 j
   D]K \ } } t | d |  } | r | | 7} |  j j | g   j |  q W| d k r6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   st  |  j  j r^ t | d d  } t |  r^ y t |  Wn" t k
 r] t j d |  Yn Xxt | d  D] \ } } } xy | D]q } | d k r t | |  } t j d |  y t |  Wn" t k
 r t j d |  Yq X| j	 |  q Wxo | D]g }	 |	 j
 d	  rt | |	  }
 t j d |
  y t	 |
  Wqt k
 rgt j d |
  YqXqWqo Wd  S)
Nr(   z.toxzcannot remove %s__pycache__zremoving dir: %s.pyc.pyozremoving: %s)r:   r;   )r   test_toxr   r   r   r!   logdebugr   r   endswith)r   r4   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   r4   r@   r   r   r   	configure   s    zBase.configurec             C   s   t  d |  j   d  S)Nz$install method not implemented in %s)rF   r   )r   r4   r@   r   r   r   install   s    zBase.installc             C   s   t  d |  j   d  S)Nz"build method not implemented in %s)rF   r   )r   r4   r@   r   r   r   build   s    z
Base.buildc          	   C   sR  t    } x d D] } t | d |  } t | d |  } t |  r t |  sr t | |  | j | d  | d r d | d k r |  j j s |  j j r | | d <q W| r t	 t | d	 d
  d   } | j
 |  Wd  QRX|  j j r d S|  j j rd S|  j j rd S| d d k sJ| d d ?sJ| d d k rNd Sd  S)Ntesttestsr(   Z	build_dir
r@   ZPYBUILD_TEST_ARGSENVhome_dirZbuild_dirs_to_rm_before_installwz,cd {build_dir}; {interpreter} -m nose {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})ztestrK   )setr   r   r   r   addr   Ztest_pytestZ	test_noseopen
writelinesr<   )r   r4   r@   Zdirs_to_removeZdnameZ	src_dpathZ	dst_dpathfpr   r   r   rJ      s,    	.z	Base.testNc             C   s   | d k r |  j  j r d  } | j |   } d | k rZ t | d  } | d | d <n
 | d } t j |  t | | d | |  S)NF
PYTHONPATHrM   r(   )r   Zreally_quietformatdictr=   infor   )r   r4   r@   r#   log_fileenvr   r   r   r      s    
zBase.execute)__name__
__module____qualname____doc__ZDESCRIPTIONr   r,   r2   ZSUPPORTED_INTERPRETERSr   r   classmethodr&   r8   rE   rG   rH   rI   rJ   r   r   r   r   r   r   )   s"   %r   c                s"   t       f d d    } | S)Nc       
         sG  | j  d d   } | sC   |  | | | |  } t | t  rC | S| 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 rCd j | d
 |  }	 | r7|	 d j |  7}	 t |	   d S)Nr#   zBmissing command (plugin=%s, method=%s, interpreter=%s, version=%s)rQ   rP   rN   z
{}_cmd.logFc             s   sN   |  ]D \ } } | d k s* | j  d  r< | t |  f n	 | | f Vq d S)r(   destdirZ_dirN)zdirrb   )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
isinstancer0   r=   warnr   r]   getr   quietr   rX   rY   r3   r   r!   )
r   r4   r@   Zoargskwargsr#   r[   Zquoted_argsoutputmsg)funcr   r   wrapped_func   s.    	"z#shell_command.<locals>.wrapped_func)r   )ro   rp   r   )ro   r   shell_command   s     rq   )Zlogging	functoolsr   globr   osr   r   os.pathr   r   r   
subprocessr	   r
   Zshutilr   r   Zdhpython.toolsr   Zshlexr   ImportErrorZ	getLoggerr=   r   rq   r   r   r   r   <module>   s   