U
    R^*                     @   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mZ d dlmZ zd d	lmZ W n ek
r   d
d ZY nX e dZdddZG dd dZdd ZdS )    Nwraps)glob1)removewalk)existsisdirjoin)PopenPIPE)rmtreecopyfilecopytree)execute)quotec                 C   s   | sdS d|  dd d S )Nz'''z'"'"')replace)s r   +/usr/share/dh-python/dhpython/build/base.pyr   !   s    r   Zdhpython{build_dir}){home_dir}/testfiles_to_rm_before_installtesttestsc                    s    fdd}|S )Nc                    s   t   fdd}|S )Nc              
      s|  ddh}dD ]x}|j |d j|d |d jd}t|d d |}t|rt|d	d
&}dd | D }W 5 Q R   qW 5 Q R X qt }	|D ]}
t|d |
}tj f ||
ddd }t|rt|st	|rt
|| n
t|| |	|d  |d sd|d kr| jjs"| jjr|
 kr|
|d< q|	rhrhtj f |d}||	 W 5 Q R X | ||f||S )Nr   r   )z_{i}{v}z_{i}{m} interpreterversion)ivmdirzdebian/pybuild{}.testfileszutf-8)encodingc                 S   s   g | ]}| d s| qS )#)
startswithstrip).0liner   r   r   
<listcomp>;   s    
zXcopy_test_files.<locals>._copy_test_files.<locals>.__copy_test_files.<locals>.<listcomp>/   
argsZPYBUILD_TEST_ARGSENVa)formatnamemajorr	   r   open	readlinessetrsplitr   r   r   addcfgtest_pytest	test_nose
writelines)selfcontextr-   oargskwargsZfiles_to_copytplfpathfpZfiles_to_remover1   Z	src_dpathZ	dst_dpath)add_to_argsdestfilelistfuncr   r   __copy_test_files/   sB    

zDcopy_test_files.<locals>._copy_test_files.<locals>.__copy_test_filesr   )rF   rG   rC   rD   rE   rF   r   _copy_test_files-   s    #z)copy_test_files.<locals>._copy_test_filesr   )rD   rE   rC   rJ   r   rH   r   copy_test_files)   s    'rK   c                   @   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e dd Zd ddZ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
    r   pythonpython3z
python-dbgzpython3-dbgzpython{version}zpython{version}-dbgc                 C   s
   || _ d S )N)r8   )r<   r8   r   r   r   __init__l   s    zBase.__init__c                 C   s
   d| j  S )NzBuildSystem(%s))NAME)r<   r   r   r   __repr__o   s    zBase.__repr__c                 C   sD   | j D ]8}td|gttd}| \}}|jdkrtd| qd S )NZwhich)stdoutstderrr   zmissing command: %s)REQUIRED_COMMANDSr
   r   Zcommunicate
returncode	Exception)clscommandZprocesouterrr   r   r   	is_usabler   s
    

zBase.is_usablec           	      C   s   d}d}i | _ | jD ]N}d}|dD ].}t|d |}|r&d}| j |g | q&|r|d7 }q| jr|t|t| j d 7 }i | _| j	
 D ]6\}}t|d |}|r||7 }| j|g | q|dkrd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|r!   Tr*   2   d   )ZDETECTED_REQUIRED_FILESREQUIRED_FILESsplitr   
setdefaultextendintlenZDETECTED_OPTIONAL_FILESOPTIONAL_FILESitems)	r<   r=   resultZrequired_files_numr@   foundZftplresZscorer   r   r   detectz   s.    


zBase.detectc              
   C   s"  | j jrLt|d d}t|rLzt| W n  tk
rJ   td| Y nX t|d D ]\}}}|D ]Z}|dkrft||}td| zt| W n  tk
r   td| Y qfX |	| qf|D ]T}	|	
drt||	}
td|
 zt	|
 W q tk
r   td|
 Y qX qqXd S )Nr!   z.toxzcannot remove %s__pycache__zremoving dir: %s)z.pycz.pyozremoving: %s)r8   test_toxr	   r   r   rV   logdebugr   r   endswith)r<   r=   r-   Ztox_dirrootdirsZ
file_namesr1   ZdpathfnrA   r   r   r   clean   s2    


z
Base.cleanc                 C   s   t d| j d S )Nz&configure method not implemented in %sNotImplementedErrorrP   r<   r=   r-   r   r   r   	configure   s    zBase.configurec                 C   s   t d| j d S )Nz$install method not implemented in %srt   rv   r   r   r   install   s    zBase.installc                 C   s   t d| j d S )Nz"build method not implemented in %srt   rv   r   r   r   build   s    z
Base.buildc                 C   sP   | j jrdS | j jrdS | j jr$dS |d dksH|d d? sH|d dkrLd	S d S )
Nz/cd {build_dir}; {interpreter} -m nose -v {args}z.cd {build_dir}; {interpreter} -m pytest {args}zHcd {build_dir}; tox -c {dir}/tox.ini -e py{version.major}{version.minor}r   z2.7z3.1r   Zpypyz<cd {build_dir}; {interpreter} -m unittest discover -v {args})r8   r:   r9   rl   rv   r   r   r   r      s    $z	Base.testNc                 C   sf   |dkr| j jrd }|jf |}d|krBt|d }|d |d< n|d }t| t||d ||S )NF
PYTHONPATHr.   r!   )r8   Zreally_quietr0   dictrm   infor   )r<   r=   r-   rX   log_fileenvr   r   r   r      s    
zBase.executec              
   C   s   | j }t|jdkrft|jdkrfd|jd krf|jd }d|krTt|jf | qt||d nD|jD ]<}d|krt|jf | qltd|d |||d qld S )Nr*   z	{version}r   {r   z	{} {}: {}r   )r8   rd   
print_argsr   printr0   get)r<   r=   r-   r8   r   r   r   r   r      s    *

zBase.print_args)N)__name__
__module____qualname____doc__ZDESCRIPTIONrT   r_   re   ZSUPPORTED_INTERPRETERSrO   rQ   classmethodr[   rj   rs   rw   rx   ry   rK   r   r   r   r   r   r   r   rL   W   s,    
%


rL   c                    s   t   fdd}|S )Nc           
   	      s   | dd }|s2 | ||f||}t|tr2|S |s\td| j j|d|d |S | jj	r|t
|d d j}nd}tdd	 | D }|jf |}| ||||}|d
 dkrd|d
 |}	|r|	d|7 }	t|	dS )NrX   zBmissing command (plugin=%s, method=%s, interpreter=%s, version=%s)r   r   Zhome_dirz
{}_cmd.logFc                 s   s8   | ]0\}}|d ks| dr(|t|fn||fV  qdS ))r!   ZdestdirZ_dirN)ro   r   )r&   kr   r   r   r   	<genexpr>  s
   z6shell_command.<locals>.wrapped_func.<locals>.<genexpr>rU   r   zexit code={}: {}z$
full command log is available in {}T)pop
isinstancerc   rm   warnrP   r   r   r8   quietr	   r0   r{   rf   r   rV   )
r<   r=   r-   r>   r?   rX   r}   Zquoted_argsoutputmsgrI   r   r   wrapped_func   s6    
  z#shell_command.<locals>.wrapped_funcr   )rF   r   r   rI   r   shell_command   s    r   )r   r   r   )Zlogging	functoolsr   globr   osr   r   os.pathr   r   r	   
subprocessr
   r   Zshutilr   r   r   Zdhpython.toolsr   Zshlexr   ImportErrorZ	getLoggerrm   rK   rL   r   r   r   r   r   <module>   s&   
   
. 