B
    ›³ëbh+  ã               @   sÆ   d 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ZdZdZdZdZe ¡ jZdd„ Zdd„ Zej ee¡Zej ed¡Zd	d
„ Zej ed¡ZG dd„ dƒZdS )zCacheDir support
é    NTFc       	      C   sü   | d }|j }| ¡ }| jd7  _| |¡\}}| |¡sN| d||¡ dS | jd7  _| d||¡ tjj	rø| 
|¡r”| | |¡| ¡ ¡ n8| ||| ¡ ¡ yt |d ¡ W n tk
rÊ   Y nX | |¡}| | ¡ t |tj ¡tjB ¡ dS )Nr   é   z$CacheRetrieve(%s):  %s not in cache
z'CacheRetrieve(%s):  retrieving from %s
)ÚfsÚget_CacheDirÚrequestsÚ	cachepathÚexistsÚ
CacheDebugÚhitsÚSConsÚActionZexecute_actionsÚislinkÚsymlinkÚreadlinkÚget_internal_pathÚcopy_from_cacheÚosÚutimeÚOSErrorÚstatÚchmodÚS_IMODEÚST_MODEÚS_IWRITE)	ÚtargetÚsourceÚenvÚtr   ÚcdÚcachedirÚ	cachefileÚst© r!   ú-lib/python3.7/site-packages/SCons/CacheDir.pyÚCacheRetrieveFunc.   s*    


"r#   c             C   s@   | d }|j }| ¡ }| |¡\}}|j  |¡r<d| ¡  S d S )Nr   zRetrieved `%s' from cache)r   r   r   r   r   )r   r   r   r   r   r   r   r   r!   r!   r"   ÚCacheRetrieveStringF   s    r$   c             C   sP  t rd S | d }|jrd S |j}| ¡ }| |¡\}}| |¡rR| d||¡ d S | d||¡ d|tf }d}	y|j|dd W n0 t	k
r²   |	t
| ƒ|f }
tj |
¡‚Y nX yH| | ¡ ¡rÜ| | | ¡ ¡|¡ n| || ¡ |¡ | ||¡ W nN tk
rJ   |	t
|ƒ|f }
| |	d t
|ƒ|¡ tj tjj|
¡ Y nX d S )	Nr   z+CachePush(%s):  %s already exists in cache
zCachePush(%s):  pushing to %s
z%s.tmp%sz,Unable to copy %s to cache. Cache file is %sT)Úexist_okÚ
)Úcache_readonlyZnocacher   r   r   r   r   Úcache_tmp_uuidÚmakedirsr   Ústrr
   ÚErrorsÚSConsEnvironmentErrorr   r   r   r   Úcopy_to_cacheÚrenameÚEnvironmentErrorZWarningsÚwarnZCacheWriteErrorWarning)r   r   r   r   r   r   r   r   ZtempfileZerrfmtÚmsgr!   r!   r"   ÚCachePushFuncS   s8    
r2   c               @   sŒ   e Zd Zdd„ Zdd„ Zdd„ Zedd„ ƒZed	d
„ ƒZe	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„ ZdS )ÚCacheDirc             C   s@   d| _ d| _|| _d| _d| _tƒ | _|dkr2dS |  |¡ dS )a+  
        Initialize a CacheDir object.

        The cache configuration is stored in the object. It
        is read from the config file in the supplied path if
        one exists,  if not the config file is created and
        the default config is written, as well as saved in the object.
        r   N)r   r	   ÚpathÚcurrent_cache_debugÚdebugFPÚdictÚconfigÚ_readconfig)Úselfr4   r!   r!   r"   Ú__init__ˆ   s    	zCacheDir.__init__c             C   s(  t j |d¡}yt j|dd W n: tk
r4   Y n( tk
rZ   d| }tj |¡‚Y nX y`t	|dƒL}d| j
d< yt | j
|¡ W n( tk
r®   d| }tj |¡‚Y nX W d	Q R X W nf tk
r"   y$t	|ƒ}t |¡| _
W d	Q R X W n* tk
r   d
| }tj |¡‚Y nX Y nX d	S )a¥  
        Read the cache config.

        If directory or config file do not exist, create.  Take advantage
        of Py3 capability in os.makedirs() and in file open(): just try
        the operation and handle failure appropriately.

        Omit the check for old cache format, assume that's old enough
        there will be none of those left to worry about.

        :param path: path to the cache directory
        r8   T)r%   z!Failed to create cache directory Úxé   Ú
prefix_lenz(Failed to write cache configuration for Nz'Failed to read cache configuration for )r   r4   Újoinr)   ÚFileExistsErrorr   r
   r+   r,   Úopenr8   ÚjsonÚdumpÚ	ExceptionÚloadÚ
ValueError)r:   r4   Zconfig_filer1   r8   r!   r!   r"   r9      s.    
 
zCacheDir._readconfigc             C   sš   t | jkrPt dkrtj| _n.t rDdd„ }tt dƒ| _t || j¡ nd | _t | _| jr–| j ||t	j
 |¡d f ¡ | j d| j| j| j| jf ¡ d S )Nú-c             S   s   |   ¡  d S )N)Úclose)r6   r!   r!   r"   Údebug_cleanupÈ   s    z*CacheDir.CacheDebug.<locals>.debug_cleanupÚwr   z5requests: %d, hits: %d, misses: %d, hit rate: %.2f%%
)Úcache_debugr5   ÚsysÚstdoutr6   rA   ÚatexitÚregisterÚwriter   r4   Úsplitr   r	   ÚmissesÚ	hit_ratio)r:   Zfmtr   r   rI   r!   r!   r"   r   Ã   s    

 zCacheDir.CacheDebugc             C   s&   |j r|j ||¡S |j ||¡S d S )N)Zcache_timestamp_newerr   ÚcopyÚcopy2)Úclsr   ÚsrcÚdstr!   r!   r"   r   Õ   s    zCacheDir.copy_from_cachec          
   C   st   yF|j  ||¡}| |¡j }| |¡}| |t |tj ¡tjB ¡ |S  tk
rn } z
t	|‚W d d }~X Y nX d S )N)
r   rU   ÚFiler   r   r   r   r   ÚAttributeErrorr/   )rV   r   rW   rX   Úresultr   r    Úexr!   r!   r"   r-   Ü   s    
zCacheDir.copy_to_cachec             C   s   | j dkrd| j | j  S dS )Nr   g      Y@éd   )r   r	   )r:   r!   r!   r"   rS   ç   s    zCacheDir.hit_ratioc             C   s   | j | j S )N)r   r	   )r:   r!   r!   r"   rR   ë   s    zCacheDir.missesc             C   s   t o| jd k	S )N)Úcache_enabledr4   )r:   r!   r!   r"   Ú
is_enabledï   s    zCacheDir.is_enabledc             C   s   t S )N)r'   )r:   r!   r!   r"   Úis_readonlyò   s    zCacheDir.is_readonlyc             C   s8   |   |¡\}}|r4tj |¡r4tj |tjjj	j
¡S d S )N)r   r   r4   r   r
   ZUtilZhash_file_signatureZNodeZFSrY   Zhash_chunksize)r:   Únoder   r   r!   r!   r"   Úget_cachedir_csigõ   s    zCacheDir.get_cachedir_csigc             C   sL   |   ¡ sdS | ¡ }|d| jd …  ¡ }tj | j|¡}|tj ||¡fS )z	
        )NNNr>   )r_   Zget_cachedir_bsigr8   Úupperr   r4   r?   )r:   ra   ZsigZsubdirÚdirr!   r!   r"   r   ú   s    zCacheDir.cachepathc             C   s\   |   ¡ sdS | ¡ }tr@t|g |dddkrX|jddd dS nt|g |dddkrXdS dS )aS  
        This method is called from multiple threads in a parallel build,
        so only do thread safe stuff here. Do thread unsafe stuff in
        built().

        Note that there's a special trick here with the execute flag
        (one that's not normally done for other actions).  Basically
        if the user requested a no_exec (-n) build, then
        SCons.Action.execute_actions is set to 0 and when any action
        is called, it does its showing but then just returns zero
        instead of actually calling the action execution operation.
        The problem for caching is that if the file does NOT exist in
        cache then the CacheRetrieveString won't return anything to
        show for the task, but the Action.__call__ won't call
        CacheRetrieveFunc; instead it just returns zero, which makes
        the code below think that the file *was* successfully
        retrieved from the cache, therefore it doesn't do any
        subsequent building.  However, the CacheRetrieveString didn't
        print anything because it didn't actually exist in the cache,
        and no more build actions will be performed, so the user just
        sees nothing.  The fix is to tell Action.__call__ to always
        execute the CacheRetrieveFunc and then have the latter
        explicitly check SCons.Action.execute_actions itself.
        Fr   )Úexecuter   )Zpresubre   T)r_   Úget_build_envÚ
cache_showÚCacheRetrieveSilentZbuildÚCacheRetrieve)r:   ra   r   r!   r!   r"   Úretrieve  s    zCacheDir.retrievec             C   s$   |   ¡ s|  ¡ sd S t|g | ¡ ƒS )N)r`   r_   Ú	CachePushrf   )r:   ra   r!   r!   r"   Úpush.  s    zCacheDir.pushc             C   s   t r|  |¡S d S )N)Úcache_forcerl   )r:   ra   r!   r!   r"   Úpush_if_forced3  s    zCacheDir.push_if_forcedN)Ú__name__Ú
__module__Ú__qualname__r;   r9   r   Úclassmethodr   r-   ÚpropertyrS   rR   r_   r`   rb   r   rj   rl   rn   r!   r!   r!   r"   r3   †   s   &'r3   )Ú__doc__rN   rB   r   r   rL   ZuuidZSCons.Actionr
   ZSCons.ErrorsZSCons.Warningsr^   rK   rm   rg   r'   Zuuid4Úhexr(   r#   r$   r   ri   rh   r2   rk   r3   r!   r!   r!   r"   Ú<module>   s.   
	0