B
    `\              	   @   s`  d Z ddlmZmZmZ eZddlZddlZddl	Z	ddl
Z
ddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlmZmZ ddlmZ yddlmZ W n, ek
r   ddlm Z  e dd	i ZY nX ydd
l!m"Z" W n" ek
r0   ddl"m#Z" Y nX yddl$m%Z& W n" ek
rd   ddl'm%Z& Y nX ddl(m)Z* ddl+m,Z,m-Z-m.Z. ddl/m0Z0m1Z1 ye*2dZ3W n e4k
r   dZ3Y nX i Z5y
ej6Z6W n e4k
r   dZ6Y nX dZ7ej89ej89ej8:e;Z<ej89e<Z=ej89ej8:ej>d Z?ej8@e=dZAdZBej8CeAsej89ej89ej89e<Z=ej8@e=dZ?ej8@e=ddZAe=ZBej8@e<dZDej8@e<dZEejFejGB ejHB ZIeIZJeJejKB ejLB ejMB ZNeJejOB ejPB ejQB ZReIejOB ejKB ejLB ejMB ZSeSejPB ejQB ZTdZUdZVdd ZWd]ddZXd^d!d"ZYd_d#d$ZZd%d& Z[d'd( Z\d)d* Z]d`d,d-Z^d.d/ Z_d0d1 Z`d2d3 Zad4d5 Zbd6d7 Zcd8d9 ZdG d:d; d;ZeG d<d= d=efZgG d>d? d?efZhG d@dA dAegZiG dBdC dCegZjdDdE ZkdFdG ZldHdI ZmdJdK ZndLdM ZodNdO ZpdPdQ ZqdadRdSZrdTdU ZsdVdW ZtejudXdY Zvejudbd[d\Zwee ZxdS )cz,Miscellaneous utility functions and classes.    )absolute_importdivisionprint_functionN)unpackpack)
TIOCGWINSZ)ABC)ABCMetar    )ConfigParser)SafeConfigParser)quote   )types)to_bytesto_optional_bytesto_optional_text)open_binary_fileread_text_fileCZ
coveragercZansiblebinlib_dataconfig)z2.6)z2.6z2.7z3.5z3.6z3.7z3.8z3.9c             C   s   t j| rt |  dS )z
    :type path: str
    N)ospathisfileremove)r   r
   r
   J/home/dcms/DCMS/lib/python3.7/site-packages/ansible_test/_internal/util.pyremove_filez   s    r    Fc             C   sD   |rt j| sg S t|  }dd |D }|r@dd |D }|S )z
    Returns lines from the specified text file with comments removed.
    Comments are any content from a hash symbol to the end of a line.
    Any spaces immediately before a comment are also removed.
    c             S   s   g | ]}t d d|qS )z *#.*$ )resub).0liner
   r
   r   
<listcomp>   s    z/read_lines_without_comments.<locals>.<listcomp>c             S   s   g | ]}|r|qS r
   r
   )r$   r%   r
   r
   r   r&      s    )r   r   existsr   
splitlines)r   Zremove_blank_linesoptionallinesr
   r
   r   read_lines_without_comments   s    r+   Tc             C   s$  d}t  }|s|}t j| rTt j|| }t j|rt |t jt jB r| }n|dkrnt j	
dt jj}|r|t jj}t }xh|D ]`}	|	|krq||	 t j|	|kr|}	t j|	| }
t j|
rt |
t jt jB r|
}P qW |s |r d|  }|dkrt|t| |S )z|
    :type executable: str
    :type cwd: str
    :type path: str
    :type required: bool | str
    :rtype: str | None
    NPATHz Required program "%s" not found.warning)r   getcwdr   dirnamejoinr'   accessF_OKX_OKenvirongetdefpathsplitpathsepsetaddabspathApplicationErrordisplayr-   )
executablecwdr   requiredmatchZreal_cwdtargetZ	path_dirsZ	seen_dirsZpath_dir	candidatemessager
   r
   r   find_executable   s:     

 

rE   c             C   sP   t dd | dD }|s:|tjdt| kr:tj}ntd|  ||d}|S )z`
    :type version: str
    :type path: str | None
    :type required: bool
    :rtype: str
    c             s   s   | ]}t |V  qd S )N)int)r$   nr
   r
   r   	<genexpr>   s    zfind_python.<locals>.<genexpr>.Nzpython%s)r   r@   )tupler7   sysversion_infolenr>   rE   )versionr   r@   rL   Z
python_binr
   r
   r   find_python   s
    rO   c              C   sF   yt jS  tk
r   Y nX ttjtdd ddlm	}  | t _| S )zReturn the Ansible version.z
release.pyansible_releaser   )__version__)
get_ansible_versionrN   AttributeErrorload_moduler   r   r0   ANSIBLE_LIB_ROOTrP   rQ   )Zansible_versionr
   r
   r   rR      s    rR   c             C   s@   yt jS  tk
r   Y nX tdd dd | D D t _t jS )zTReturn a dictionary indicating which of the requested Python versions are available.c             s   s   | ]\}}|r||fV  qd S )Nr
   )r$   rN   r   r
   r
   r   rH      s    z0get_available_python_versions.<locals>.<genexpr>c             s   s   | ]}|t |d dfV  qdS )F)r@   N)rO   )r$   rN   r
   r
   r   rH      s    )get_available_python_versionsresultrS   dict)versionsr
   r
   r   rV      s    rV   c             C   s   | t jtdgS )z1
    :type python: str
    :rtype: list[str]
    zquiet_pip.py)r   r   r0   ANSIBLE_TEST_DATA_ROOT)pythonr
   r
   r   generate_pip_command   s    r\   strictc
          
   C   sp  |st  }|st }t| } ddd | D }
tjd|
 |dd tjd| dd	 t| d
 ||d dd}|rtjd| dd	 x.t|	 D ]}tjd||| f dd	 qW |rdS d}|dk	rd}d}n|dk	rt
j}d}|rd}|r
|pt
j}t
j}d}nd}t }d}zy>dd | D }tdd | D }t
j||||||d}W nD tk
r } z$|jtjkrtd| d
   W dd}~X Y nX |rt|}||\}}t||	pd}t||	pd}n|  d\}}W d|r |jdkr |  td td X |j}t | }tjd||f dd	 |d
kr\||fS t| ||||dS )aM  
    :type cmd: collections.Iterable[str]
    :type capture: bool
    :type env: dict[str, str] | None
    :type data: str | None
    :type cwd: str | None
    :type explain: bool
    :type stdin: file | None
    :type stdout: file | None
    :type cmd_verbosity: int
    :type str_errors: str
    :rtype: str | None, str | None
     c             s   s   | ]}t |V  qd S )N)	cmd_quote)r$   cr
   r
   r   rH     s    zraw_command.<locals>.<genexpr>zRun command: %sT)	verbositytruncatezWorking directory: %s   )ra   r   r,   r-   )r?   r   r@   zProgram found: %sz%s=%s)NNFNc             S   s   g | ]}t |qS r
   )r   )r$   r`   r
   r
   r   r&   A  s    zraw_command.<locals>.<listcomp>c             s   s"   | ]\}}t |t |fV  qd S )N)r   )r$   kvr
   r
   r   rH   B  s    )envstdinstdoutstderrr?   z Required program "%s" not found.r!   z]Killed command to avoid an orphaned child process during handling of an unexpected exception.z/Command exited with status %s after %s seconds.   )r   r.   common_environmentlistr0   r=   inforE   sortedkeys
subprocessPIPEtimerX   itemsPopenOSErrorerrnoENOENTr<   r   communicater   wait
returncodekillnoticeSubprocessError)cmdcapturerf   datar?   explainrg   rh   Zcmd_verbosityZ
str_errorsZescaped_cmdprogramkeyrx   ri   startprocessZ	cmd_bytesZ	env_bytesexZ
data_bytesZstdout_bytesZstderr_bytesZstdout_textZstderr_textstatusruntimer
   r
   r   raw_command  sr    


r   c              C   s8   t dtjdtjjd} d}d}| t||d | S )z3Common environment used for executing all programs.zen_US.UTF-8r,   )LC_ALLr,   )HOME)Z
HTTPTESTERZLD_LIBRARY_PATHZSSH_AUTH_SOCKZ#OBJC_DISABLE_INITIALIZE_FORK_SAFETYZANSIBLE_KEEP_REMOTE_FILESLDFLAGSCFLAGS)r@   r)   )rX   r   r4   r5   r   r6   update	pass_vars)rf   r@   r)   r
   r
   r   rk   b  s    rk   c             C   s^   i }x,| D ]$}|t jkr t|t j| ||< q
W x&|D ]}|t jkrHq8t j| ||< q8W |S )z|
    :type required: collections.Iterable[str]
    :type optional: collections.Iterable[str]
    :rtype: dict[str, str]
    )r   r4   MissingEnvironmentVariable)r@   r)   rf   namer
   r
   r   r     s    



r   c             C   s@   | dkrd} |dkrd}|  |r*| p(dS | | r<|p:dS dS )zReturn the deepest of two paths, or None if the paths are unrelated.
    :type path_a: str
    :type path_b: str
    :rtype: str | None
    rI   r!   N)
startswith)Zpath_aZpath_br
   r
   r   deepest_path  s    

r   c          
   C   sH   yt t|  W n0 tk
rB } z|jtjkr2 W dd}~X Y nX dS )z
    :type path: str
    N)shutilrmtreer   ru   rv   rw   )r   r   r
   r
   r   remove_tree  s
    r   c             C   s   t ddddddddd	d
dddddddddddg}t ddddddddddd d!d"d#d$g}tj| d% }||krtd&S ||krd'S t| }d(|d)kS Q R X d*S )+z*
    :type path: str
    :rtype: bool
    z.cfgz.confz.crtz.csz.cssz.htmlz.iniz.j2z.jsz.jsonz.mdz.pemz.ps1z.psm1z.pyz.rstz.shz.txtz.xmlz.yamlz.ymlz.binz.eotz.gzz.icoz.isoz.jpgz.otfz.p12z.pngz.pycz.rpmz.ttfz.woffz.woff2z.zipr   FT    i   N)r9   r   r   splitextr   read)r   Zassume_textZassume_binaryextZpath_fdr
   r
   r   is_binary_file  sZ    
r   c              C   sF   t jt jt jt jdgd } ddd | dd D }tj| |S )z0Generate a random password.
    :rtype: str
    -rj   r!   c             S   s   g | ]}t |qS r
   )randomchoice)r$   charr
   r
   r   r&     s    z%generate_password.<locals>.<listcomp>Nr   )stringascii_lettersdigitsr0   r=   	sensitiver:   )charspasswordr
   r
   r   generate_password  s    r   c               @   s   e Zd ZdZdZdZdZdZdZdZ	dZ
d	eee
d
Zdd Zdd Zdd ZdddZdd Zdd ZdddZd	ejdfddZd	S )DisplayzManages color console output.z[0mz[31mz[32mz[33mz[34mz[35mz[36mN)r   r   rc      c             C   s   d| _ tj | _g | _t | _d| _d| _	d| _
d| _d| _t | _tdrtdtdttdddddd d \| _	| _
d S )Nr   FTZHHHHrc   )ra   rK   rh   isattycolorwarningsr9   warnings_uniqueinfo_stderrrowscolumnsrb   redactr   r   r   fcntlZioctlr   r   )selfr
   r
   r   __init__  s    
zDisplay.__init__c             C   s   | j d| | jtjd dS )z$
        :type message: str
        zWARNING: %s)r   fdN)print_messagepurplerK   ri   )r   rD   r
   r
   r   Z	__warning-  s    zDisplay.__warningc             C   s<   | j s
dS | dt| j   x| j D ]}| | q&W dS )z.Review all warnings which previously occurred.Nz!Reviewing previous %d warning(s):)r   _Display__warningrM   )r   r-   r
   r
   r   review_warnings3  s
    zDisplay.review_warningsFr   c             C   sF   || j krdS |r,|| jkr dS | j| | | | j| dS )z\
        :type message: str
        :type unique: bool
        :type verbosity: int
        N)ra   r   r:   r   r   append)r   rD   uniquera   r
   r
   r   r-   =  s    


zDisplay.warningc             C   s   | j d| | jtjd dS )z$
        :type message: str
        z
NOTICE: %s)r   r   N)r   r   rK   ri   )r   rD   r
   r
   r   r|   O  s    zDisplay.noticec             C   s   | j d| | jtjd dS )z$
        :type message: str
        z	ERROR: %s)r   r   N)r   redrK   ri   )r   rD   r
   r
   r   errorU  s    zDisplay.errorc             C   s>   | j |kr:| j|| j}| j||| jr.tjntj|d dS )z^
        :type message: str
        :type verbosity: int
        :type truncate: bool
        )r   r   rb   N)	ra   verbosity_colorsr5   yellowr   r   rK   ri   rh   )r   rD   ra   rb   r   r
   r
   r   rm   [  s    
zDisplay.infoc             C   s   | j r6| jr6x(| jD ]}|sq||dt| }qW |rnt|| j  krTdkrnn n|d| jd  d }|r| jr|| j|}d||| jf }tjd dkrt	|}t
||d |  dS )	zx
        :type message: str
        :type color: str | None
        :type fd: file
        :type truncate: bool
        *   Nz ...z%s%s%sr   rc   )file)r   r   replacerM   rb   r   clearrK   rL   r   printflush)r   rD   r   r   rb   itemr
   r
   r   r   e  s    
zDisplay.print_message)Fr   )r   F)__name__
__module____qualname____doc__r   r   Zgreenr   Zbluer   Zcyanr   r   r   r   r-   r|   r   rm   rK   rh   r   r
   r
   r
   r   r     s(   



r   c               @   s   e Zd ZdZdS )r<   zGeneral application error.N)r   r   r   r   r
   r
   r
   r   r<     s   r<   c               @   s   e Zd ZdZdS )ApplicationWarningzAGeneral application warning which interrupts normal program flow.N)r   r   r   r   r
   r
   r
   r   r     s   r   c                   s"   e Zd ZdZd fdd	Z  ZS )r}   z1Error resulting from failed subprocess execution.r   Nc                s   dd dd |D |f }|r>|d7 }|d| tjf 7 }|r`|d7 }|d| tjf 7 }| }tt| | || _|| _|| _	|| _
|| _|| _dS )	z
        :type cmd: list[str]
        :type status: int
        :type stdout: str | None
        :type stderr: str | None
        :type runtime: float | None
        z&Command "%s" returned exit status %s.
r^   c             s   s   | ]}t |V  qd S )N)r_   )r$   r`   r
   r
   r   rH     s    z+SubprocessError.__init__.<locals>.<genexpr>z>>> Standard Error
z%s%s
z>>> Standard Output
N)r0   stripr   r   superr}   r   r~   rD   r   rh   ri   r   )r   r~   r   rh   ri   r   rD   )	__class__r
   r   r     s    zSubprocessError.__init__)r   NNN)r   r   r   r   r   __classcell__r
   r
   )r   r   r}     s   r}   c                   s    e Zd ZdZ fddZ  ZS )r   z-Error caused by missing environment variable.c                s   t t| d|  || _dS )z!
        :type name: str
        z Missing environment variable: %sN)r   r   r   r   )r   r   )r   r
   r   r     s    z#MissingEnvironmentVariable.__init__)r   r   r   r   r   r   r
   r
   )r   r   r     s   r   c             C   sb   g }g }x:|  D ].}t| |}|r6||  q|| qW |r^td| d|f |S )zS
    :type pattern: str
    :type value: str
    :return: list[dict[str, str]]
    z%Pattern "%s" did not match values:
%s
)r(   r"   searchr   	groupdict	Exceptionr0   )patternvaluematched	unmatchedr%   rA   r
   r
   r   parse_to_list_of_dict  s    r   c           	   C   s<   t  t jt j} t|  | d |  d S Q R X dS )z
    :rtype: int
    )r!   r   r   N)socketAF_INETSOCK_STREAM
contextlibclosingbindgetsockname)Z	socket_fdr
   r
   r   get_available_port  s    
r   c             C   sZ   t  }| g}xH|rT| }x6| D ]*}||kr$t|sD|| || q$W qW |S )zHReturns the set of types that are concrete subclasses of the given type.)r9   pop__subclasses__inspect
isabstractr:   r   )Z
class_typeZ
subclassesqueueparentchildr
   r
   r   get_subclasses  s    

r   c             C   s>   | tjjs|tjj7 }|  tjjs4| tjj7 } | |S )zAReturns true if candidate_path is path or a subdirectory of path.)endswithr   r   sepr   )Zcandidate_pathr   r
   r
   r   	is_subdir  s
    r   c             C   sR   t  }xB| D ]:}x4tj|}|r.|tjjkr0P ||tjj  qW qW t|S )zEReturns a list of directories extracted from the given list of paths.)r9   r   r   r/   r   r:   rn   )pathsZ	dir_namesr   r
   r
   r   paths_to_dirs  s    
r   c             C   s   t dd | dD S )z-Return a version tuple from a version string.c             s   s   | ]}t |V  qd S )N)rF   )r$   rG   r
   r
   r   rH     s    z!str_to_version.<locals>.<genexpr>rI   )rJ   r7   )rN   r
   r
   r   str_to_version  s    r   c             C   s   d dd | D S )z-Return a version string from a version tuple.rI   c             s   s   | ]}t |V  qd S )N)str)r$   rG   r
   r
   r   rH     s    z!version_to_str.<locals>.<genexpr>)r0   )rN   r
   r
   r   version_to_str
  s    r   c       	      C   s   |dkrt jt}t j|| }tddd }d|| t jjdf }xVt	j
|g|dD ]B\}}}t j||t|d d dt jjd }t|| q\W dS )z
    Import plugins from the given directory relative to the given root.
    If the root is not provided, the 'lib' directory for the test runner will be used.
    NrI   r   r   z%s.%s.)prefixz.py)r   r   r/   __file__r0   r   rsplitr   r   pkgutiliter_modulesrM   rT   )		directoryrootr   packager   Z_module_loaderr   Z_ispkgmodule_pathr
   r
   r   import_plugins  s    .r   c             C   s4   t dd t| D }x|D ]}|| ||< qW dS )z
    Load plugins of the specified type and track them in the specified database.
    Only plugins which have already been imported will be loaded.
    c             s   s$   | ]}|j d dd |fV  qdS )rI   r   N)r   r   )r$   Zscr
   r
   r   rH   %  s    zload_plugins.<locals>.<genexpr>N)rX   r   )Z	base_typeZdatabaseZpluginsZpluginr
   r
   r   load_plugins   s    
r   c          	   C   s   |t jkrdS t jdkrRddl}|j|| }|j|}|j| |t j|< n8ddl	}t
t| }|||| dd|jf W dQ R X dS )z3Load a Python module using the given name and path.N)r   rj   r   z.pyr)rK   modulesrL   Zimportlib.utilutilspec_from_file_locationmodule_from_specloaderexec_moduleimpopenr   rT   	PY_SOURCE)r   r   	importlibspecmoduler  Zmodule_filer
   r
   r   rT   +  s    

rT   c              c   s   t  } | V  t|  dS )zHCreates a temporary directory that is deleted outside the context scope.N)tempfilemkdtempr   r   )Z	temp_pathr
   r
   r   tempdirE  s    r  r   c             c   s    t j| |d}|V  |  dS )z3Opens a zip file and closes the file automatically.)modeN)zipfileZipFileclose)r   r  Zzib_objr
   r
   r   open_zipfileM  s    r  )FF)NNT)NT)	FNNNFNNr   r]   )N)r   )yr   
__future__r   r   r   type__metaclass__r   rv   r   r   r   r   r   r"   r   r   statr   rp   rK   r	  rr   r  structr   r   termiosr   abcr   ImportErrorr	   configparserr   r   shlexr   r_   Zpipesr!   r   tencodingr   r   r   ior   r   TypeVarr   rS   ZPYTHON_PATHSZMAXFDZCOVERAGE_CONFIG_NAMEr   r/   r;   r   ZANSIBLE_TEST_ROOTZANSIBLE_ROOTargvZANSIBLE_BIN_PATHr0   rU   ZANSIBLE_SOURCE_ROOTr'   rZ   ZANSIBLE_TEST_CONFIG_ROOTS_IRUSRS_IRGRPS_IROTHZ	MODE_READZ	MODE_FILES_IXUSRS_IXGRPS_IXOTHZMODE_FILE_EXECUTES_IWUSRS_IWGRPS_IWOTHZMODE_FILE_WRITEZMODE_DIRECTORYZMODE_DIRECTORY_WRITEZREMOTE_ONLY_PYTHON_VERSIONSZSUPPORTED_PYTHON_VERSIONSr    r+   rE   rO   rR   rV   r\   r   rk   r   r   r   r   r   r   r   r<   r   r}   r   r   r   r   r   r   r   r   r   r   rT   contextmanagerr  r  r=   r
   r
   r
   r   <module>   s   





4
 
_'<v 
