
    @d/                        d dl Z d dlZd dlZd dlZd dlmZ d dlmZ d dlmZ d dlm	Z	 d dl
mZmZmZmZmZmZ d dlmZmZ  e j        d          Z ej        d	          Z ej        d
          Zd Zd Zd ZddZd dZd Zd Zd dZ d Z!d!dZ" G d d          Z#d Z$d Z%d dl&m'Z' d dl(m)Z)m*Z*m+Z+  ej        de+z  ej,                  Z- ej        de+z  ej,                  Z.dS )"    N)datetime)glob)dumps)rmtree)existsgetsizeisdirislinkjoinsplit)PopenPIPEdhpythonz/(.*?)(-py\d\.\d(?:-[^.]*)?)?(\.egg-info|\.pth)$zNEEDED.*libpython(\d\.\d)c                 
   |                      d          }|                     d          }|r,|d         |d         k    r|d= |d= |r|d         |d         k    d                    dgt          |          dz
  z  |z             S )z~Return relative path.

    >>> relpath('/usr/share/python-foo/foo.py', '/usr/bin/foo', )
    '../share/python-foo/foo.py'
    /r   z..   )r   r   len)targetlinktls       &/usr/share/dh-python/dhpython/tools.pyrelpathr   &   s     	SA

3A
 !!aD!A$  !!88TFc!ffqj)A-...    c                 H    t          j        t          | |          |          S )zCreate relative symlink.)ossymlinkr   )r   r   s     r   relative_symlinkr   3   s    :gfd++T222r   c                    t          |           rXt          |           d         }t          j        |           D ].}t	          t          | |          t          ||                     /t          |           r[t          |t          |           d                   }t          t          j        |           |           t          j	        |            dS t          j
        | |           dS )zCMove file to dstdir. Works with symlinks (including relative ones).N)r	   r   r   listdir	move_filer   r
   r   readlinkremoverename)fpathdstdirdnamefndstpaths        r   r"   r"   8   s    U|| <eR *U## 	< 	<Bd5"ootFE':':;;;;e}} !vuU||B/00U++W555
	%
	%     r    c           	      n   t          j        |          j        }|rt          j        |          j        }|pd}t	          j        |           D ]g\  }}}|D ]^}	t          ||	          }
 ||
          rA| |||
          }
t          |t          |
|                     }t	          j        |
|           _hdS )a>  Move files (preserving path) that match given pattern.

    move_matching_files('foo/bar/', 'foo/baz/', 'spam/.*\.so$')
    will move foo/bar/a/b/c/spam/file.so to foo/baz/a/b/c/spam/file.so

    :param sub: regular expression for path part that will be replaced with `repl`
    :param repl: replacement for `sub`
    r+   N)	recompilesearchsubr   walkr   r   renames)srcdstpatternr0   replmatchrootdirs	filenamesr)   spathdpaths               r   move_matching_filesr=   G   s     Jw&E
 joo!zr!# ) )dI 	) 	)BrNNEuU|| )?Ce,,ES'%"5"566
5%(((	)) )r   c                    	 t          j        |           }n4# t          $ r'}t                              d| |           Y d}~dS d}~ww xY w|s|j        dk    rd}|j        r|dz  }n#|s!|j        dk    rd|_        t          |          }|rt                              d|            	 t          | d	          5 }|
                                }ddd           n# 1 swxY w Y   n,# t          $ r t                              d
|            Y dS w xY wt          | d          5 }|                    d|z                      d                     |                    |dd                    ddd           n# 1 swxY w Y   dS )zmNormalize file's shebang.

    :param replacement: new shebang command (path to interpreter and options)
    zfix_shebang (%s): %sN2z/usr/bin/python2z-dbgz	/usr/bin/z/usr/binzreplacing shebang in %srbzcannot open %sFwbz#! %s
utf-8r   T)Interpreter	from_file	Exceptionlogdebugversionpathreprinfoopen	readlinesIOErrorerrorwriteencode
writelines)r&   replacementinterpretererrfpfcontents         r   fix_shebangrX   ^   s+   
!+E22   		(%555ttttt  (;.#55( 	"6!K ([-<<%;'' (*E222	eT"" *b<<>>* * * * * * * * * * * * * * * 	 	 	II&...55	
 % 	("HHi+-55g>>???MM(122,'''	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 4s]    
AAA(C% 8CC% CC%  C!C% %%DD!A	E66E:=E:c                 F   d| z  }t          |t          d          }t          j                    d         pd}t                              t          |j                                        |                    }|r't          |
                                d                   S dS )	zhReturn libpython version file is linked to or None.

    :rtype: tuple
    :returns: Python version
    zreadelf -Wd '%s'T)stdoutshellr   rB   encodingr   N)r   r   localegetdefaultlocaleSHAREDLIB_REr/   strrZ   readVersiongroups)r&   cmdprocessr]   r7   s        r   so2pyverrg      s     u
$CCD111G&((+6wHGN$7$7$9$9H M M MNNE *u||~~a()))* *r   c                     t                               |           }|r>|                    d          )d                    |                    dd                    S | S )a  Remove Python version and platform name from Egg files/dirs.

    >>> clean_egg_name('python_pipeline-0.1.3_py3k-py3.1.egg-info')
    'python_pipeline-0.1.3_py3k.egg-info'
    >>> clean_egg_name('Foo-1.2-py2.7-linux-x86_64.egg-info')
    'Foo-1.2.egg-info'
       Nr+   r      )
EGGnPTH_REr7   groupr   )namer7   s     r   clean_egg_namern      sS     T""E *Q+wwu{{1a(()))Kr   c                     t          |pg           }| D ][}t          |dd          5 }|D ]+}|r'|                    |                                           ,	 ddd           n# 1 swxY w Y   \|S )z#Parse namespace_packages.txt files.rrB   r\   N)setrL   addstrip)fpathsotherresultr&   rV   lines         r   parse_nsrx      s    "F - -%w/// 	-2 - - -JJtzz||,,,-	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- Ms   /A$$A(	+A(	c                    t          |t                    st          |          }t                      }|D ]}|D ]}t          |                     ||          g|                    d          R  }t          |d          }t          |          sVt          |          dk    r2t                              d|           |	                    |            n||z
  }|D ]}|D ]}t          |                     ||          g|                    d          R  }	t          |	d          }t          |          r<t          j        |           t          j        |	          st          j        |	           t          d|dg|                    d          R  }	t          |	d          }t          |          r<t          j        |           t          j        |	          st          j        |	           |S )z8Remove empty __init__.py files for requested namespaces..z__init__.pyr   z)file not empty, cannot share %s namespacedebianzusr/share/pyshared)
isinstancerq   r   sitedirr   r   r   rF   warningrr   r   r$   r!   rmdir)
rT   package
namespacesversionskeepnsrH   r&   rv   r<   s
             r   	remove_nsr      s   j#&& %__
55D 	 	 	 	G,,Wg>>O#OOOE..E%== u~~""GLLL # $F      	$ 	$G,,Wg>>O#OOOE..Ee}} $	%   z%(( $HUOOOXw(<Mrxx}}MMMUM**%== 	 Ie:e$$  Mr   Tc           	      B   |||d}d}|du rn|"|                     t          t                     n|rt          |t                    rd}t	          |dd          }|                    d	                    t          j                    	                                                     |                    d
                    |                      |
                                 |                     ||           t                              d|            t          | fi |5 }|                                \  }}	|o|                                 t!          |j        |ot          |d          |	ot          |	d                    cddd           S # 1 swxY w Y   dS )a:  Execute external shell command.

    :param cdw: current working directory
    :param env: environment
    :param log_output:
        * opened log file or path to this file, or
        * None if output should be included in the returned dict, or
        * False if output should be redirected to stdout/stderr
    )r[   cwdenvFN)rZ   stderrTarB   r\   z
# command executed on {}z
$ {}
zinvoking: %s)
returncoderZ   r   )updater   r|   ra   rL   rP   formatr   now	isoformatflushrF   rG   r   communicateclosedictr   )
commandr   r   
log_outputr[   argsr   rf   rZ   r   s
             r   executer      s    3s33DEU		4----	 :j#&& 	AEj#@@@J5<<X\^^=U=U=W=WXXYYY**733444:j999IIng&&&	w		$		 <7 ,,..$*""$$w1!:c&'&:&:!:c&'&:&:< < << < < < < < < < < < < < < < < < < <s   #A$FFFc                       e Zd Zd Zd ZdS )memoizec                 "    || _         i | _        d S N)funccache)selfr   s     r   __init__zmemoize.__init__   s    	


r   c                 z    t          ||f          }|| j        vr | j        |i || j        |<   | j        |         S r   )r   r   r   )r   r   kwargskeys       r   __call__zmemoize.__call__   sH    T6N##dj  'di888DJsOz#r   N)__name__
__module____qualname__r   r    r   r   r   r      s2              r   r   c           	      n   d|z  }t          |          sdS | j        }t          ||          }t          |d          D ]}|r|                    d          rt
                              |          }|st          d|z            |                                }|d         r|d         	                    dd	          |d<   |t          ||d
                   z  }|st                              d||           t          |d                   }	|	st          d|d         z            |	D ]}
|
                    d          }
|d         r*t          |d         t          |
          d                   }n"|
                    d          r|
dd         }n|
}|D ]}t          |                     ||          |          }t          |          d         }t          |          st#          j        |           t          |          rt#          j        |           t#          j        |
|           dS )zDInstall local files listed in pkg.pyinstall files as public modules.z./debian/%s.pyinstallNrB   r\   #zunrecognized line: %smodulerz   r   vrangez.%s.pyinstall: no matching versions for line %sr5   zmissing file(s): %sz/.r   zdebian/   r   )r   implget_requested_versionsrL   
startswith
INSTALL_REr7   
ValueError	groupdictreplacerF   rG   r   lstripr   r   r}   r   makedirsr$   r   )rT   r   r   srcfpathr   r   rw   detailsmyversfilesr&   dstnamerH   dstfpathr'   s                  r   	pyinstallr      sr   &0H( D%dF33HX000  )  ) 	ts++ 	""4(( 	=4t;<<<##%%8 	D ' 1 9 9#s C CGH249JKKK 	IIFt% % %WY'(( 	I2WY5GGHHH 	) 	)ELL&&Ex   wx0%,,q/BB!!),,  )! ) ) 3 3GW E EwOOx+f~~ (K'''(## (Ih'''x(((()	)# )  )r   c                    d|z  }t          |          sdS | j        }t          ||          }t          |d          D ]3}|r|                    d          rt
                              |          }|st          d|d|          |                                }|t          ||d                   z  }|st          
                    d	||           |D ]}	|                     ||	          }
|
                    |                     ||	                     |
D ]U}t          |d
z   |d         z             }|D ]5}t          |          rt!          |           !t#          j        |           6V5dS )z2Remove public modules listed in pkg.pyremove file.z./debian/%s.pyremoveNrB   r\   r   zunrecognized line: z: r   z-%s.pyremove: no matching versions for line %sr   r5   )r   r   r   rL   r   	REMOVE_REr7   r   r   rF   rG   old_sitedirsappendr}   r   r	   r   r   r$   )rT   r   r   r   r   r   rw   r   r   rH   	site_dirssdirr   r&   s                 r   pyremover   (  s   %/H( D%dF33HX000 ) ) 	ts++ 	//$'' 	L*GGGTTJKKK##%%249JKKK 	%IIEt% % % 		) 		)G#00'BBI[00'BBCCC! ) )TCZ')*<<==" ) )EU|| )u	%((((	))		)) )r   )rC   )rc   r   RANGE_PATTERNz
    (?P<pattern>.+?)  # file pattern
    (?:\s+  # optional Python module name:
    (?P<module>[A-Za-z][A-Za-z0-9_.]*)?
    )?
    \s*  # optional version range:
    (?P<vrange>%s)?$
z^
    (?P<pattern>.+?)  # file pattern
    \s*  # optional version range:
    (?P<vrange>%s)?$
)Nr+   r   )NNNT)/loggingr   r-   r^   r   r   pickler   shutilr   os.pathr   r   r	   r
   r   r   
subprocessr   r   	getLoggerrF   r.   rk   r`   r   r   r"   r=   rX   rg   rn   rx   r   r   r   r   r   dhpython.interpreterrC   dhpython.versionrc   r   r   VERBOSEr   r   r   r   r   <module>r      so  ,  				 				                          ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? " " " " " " " "g
##RZJKK
rz677
/ 
/ 
/3 3 3
! ! !) ) ) ).       F* * *     # # #L< < < <D	 	 	 	 	 	 	 	() () ()V) ) )< - , , , , , K K K K K K K K K KRZ   Z! !
 BJ  	 Z	! !			r   