U
    ôáêb<  ã                   @   sÎ  d dl mZmZmZmZ d dlmZ d dlZd dlm	Z	m
Z
mZ d dlZd dlmZ d dlZd dlmZmZmZ d dlZd dlZd dlmZ d dlZ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# ddl$m%Z% ddl&m'Z'm(Z( ddl)m*Z* ddl+m,Z, ddl-m.Z.m/Z/ ddl0m1Z1 ddl2m3Z3 ddl4m5Z5m6Z6 ddl7m8Z8 e 9e:¡Z;G dd„ de<ƒZ=dd„ Z>dd„ Z?dd„ Z@dd„ ZAG d d!„ d!eBƒZCe:d"krÊd d#lDmDZD eCejEƒZFeDeF G¡ ƒ eHeF I¡ ƒ dS )$é    )Úabsolute_importÚdivisionÚprint_functionÚunicode_literals)Úliteral_evalN)ÚEACCESÚEPERMÚEROFS)Ú
itemgetter)ÚisdirÚisfileÚjoin)Údedenté   )Ú__version__)Údals)ÚgroupbyÚtake)ÚDEFAULTS_CHANNEL_NAME)Úcontext)Úensure_text_typeÚopen)Úpaths_equal)Ú
PrefixData)ÚCondaHistoryErrorÚNotWritableError)Útouch)Údist_str_to_quad)ÚVersionOrderÚversion_relation_re©Ú	MatchSpecc                   @   s   e Zd ZdS )ÚCondaHistoryWarningN)Ú__name__Ú
__module__Ú__qualname__© r&   r&   ú,lib/python3.8/site-packages/conda/history.pyr"   $   s   r"   c              
   C   sX   |   dt d¡ ¡ |   dd dd„ tjD ƒ¡ ¡ |   dd td	t d¡ƒ¡ ¡ d S )
Nz==> %s <==
z%Y-%m-%d %H:%M:%Sz
# cmd: %s
ú c                 s   s   | ]}t |ƒV  qd S ©N)r   ©Ú.0Úsr&   r&   r'   Ú	<genexpr>*   s     zwrite_head.<locals>.<genexpr>z# conda version: %s
Ú.é   )	ÚwriteÚtimeÚstrftimer   ÚsysÚargvr   ÚCONDA_VERSIONÚsplit)Úfor&   r&   r'   Ú
write_head(   s     r8   c                 C   s   t dd„ | D ƒƒS )Nc                 s   s   | ]}|  d ¡V  qdS ))ú-ú+N)Ú
startswithr*   r&   r&   r'   r-   /   s     zis_diff.<locals>.<genexpr>)Úany©Úcontentr&   r&   r'   Úis_diff.   s    r?   c           
      c   sú   i }i }| D ]b}|dd … }t |ƒ\}}}}|tkr@|d| 7 }| d¡rX||| ¡ < q| d¡r||| ¡ < qt|ƒt|ƒ@ }	t|	ƒD ]}d||| || f V  qˆtt|ƒ|	 ƒD ]}d||| f V  q¶tt|ƒ|	 ƒD ]}d||| f V  qÞd S )Nr   z (%s)r9   r:   z %s  {%s -> %s}z-%s-%sz+%s-%s)r   r   r;   ÚlowerÚsetÚsorted)
ZdiffÚaddedÚremovedr,   ÚfnÚnameÚversionÚ_ÚchannelÚchangedr&   r&   r'   Úpretty_diff2   s$    

rK   c                 C   s    t | ƒrt| ƒS tt| ƒƒS d S r)   )r?   rK   ÚiterrB   r=   r&   r&   r'   Úpretty_contentG   s    rM   c                   @   s¾   e Zd Ze d¡Ze d¡Ze d¡Zdd„ Zdd„ Z	dd	„ Z
d
d„ Zdd„ Zdd„ Zdd„ Zedd„ ƒZedd„ ƒZdd„ Zdd„ Zdd„ Zd)dd„Zdd „ Zd!d"„ Zd#d$„ Zd*d&d'„Zd(S )+ÚHistoryz#\s*cmd:\s*(.+)z#\s*(\w+)\s*specs:\s*(.+)?z#\s*conda version:\s*(.+)c                 C   s$   || _ t|dƒ| _t| jdƒ| _d S )Nz
conda-metaÚhistory)Úprefixr   Úmeta_dirÚpath)ÚselfrP   r&   r&   r'   Ú__init__T   s    zHistory.__init__c                 C   s   |   ¡  | S r)   )Úinit_log_file©rS   r&   r&   r'   Ú	__enter__Y   s    zHistory.__enter__c                 C   s   |   ¡  d S r)   )Úupdate)rS   Úexc_typeÚ	exc_valueÚ	tracebackr&   r&   r'   Ú__exit__]   s    zHistory.__exit__c                 C   s   t | jdƒ d S )NT)r   rR   rV   r&   r&   r'   rU   `   s    zHistory.init_log_filec                 C   s   t  | j¡jdkS )Nr   )ÚosÚstatrR   Úst_sizerV   r&   r&   r'   Úfile_is_emptyc   s    zHistory.file_is_emptyc              
   C   sÌ   z‚zt |  ¡ ƒ}W n@ tk
rR } z"t d| j|f t¡ W Y ¢W dS d}~X Y nX t| jƒ}t dd„ | 	¡ D ƒƒ}|  
||¡ W nD tk
rÆ } z&|jtttfkr´t| j|jƒ‚n‚ W 5 d}~X Y nX dS )zK
        update the history file (creating a new one if necessary)
        zError in %s: %sNc                 s   s   | ]}|  ¡ V  qd S r)   )Zdist_str)r+   Z
prefix_recr&   r&   r'   r-   r   s     z!History.update.<locals>.<genexpr>)rA   Ú	get_stater   ÚwarningsÚwarnrR   r"   r   rP   Úiter_recordsÚwrite_changesÚEnvironmentErrorÚerrnor   r   r	   r   )rS   ZlastÚeZpdZcurrr&   r&   r'   rX   f   s    ÿ
zHistory.updatec              	   C   s¾   g }t | jƒs|S t d¡}t| jƒ}| ¡  ¡ }W 5 Q R X |D ]v}| ¡ }|sTqB| |¡}|r|| 	| 
d¡tƒ g f¡ qB| d¡rš|d d  	|¡ qBt|ƒdkrB|d d  |¡ qB|S )z„
        parse the history file and return a list of
        tuples(datetime strings, set of distributions/diffs, comments)
        z==>\s*(.+?)\s*<==r   ú#éÿÿÿÿé   r   )r   rR   ÚreÚcompiler   ÚreadÚ
splitlinesÚstripÚmatchÚappendÚgrouprA   r;   ÚlenÚadd)rS   ÚresZsep_patÚfÚlinesÚlineÚmr&   r&   r'   Úparsez   s$    



zHistory.parsec                 C   sH   g }|   d¡D ]4}t |¡r8|r8d |d |g¡|d< q| |¡ q|S )zÖ
        Parse specifications string that use conda<4.5 syntax.

        Examples
        --------
          - "param >=1.5.1,<2.0'"
          - "python>=3.5.1,jupyter >=1.0.0,<2.0,matplotlib >=1.5.1,<2.0"
        ú,rj   )r6   r   rq   r   rr   )Úspecs_stringÚspecsÚspecr&   r&   r'   Ú_parse_old_format_specs_string’   s    
z&History._parse_old_format_specs_stringc                 C   s   i }| j  |¡}|r@| d¡ ¡ }|d  d¡r8d|d< ||d< | j |¡}|r^| d¡|d< | j |¡}|r| ¡ \}}|p‚d}||d< | d¡r t	|ƒ}nd|kr²t
 |¡}d	d
„ |D ƒ}|rÞ|dkrÞ| |d< |d< n>|rü|dkrü| |d< |d< n |r|dkr| |d< |d< |S )aH  
        Parse comment lines in the history file.

        These lines can be of command type or action type.

        Examples
        --------
          - "# cmd: /scratch/mc3/bin/conda install -c conda-forge param>=1.5.1,<2.0"
          - "# install specs: python>=3.5.1,jupyter >=1.0.0,<2.0,matplotlib >=1.5.1,<2.0"
        r   r   ZcondaÚcmdÚconda_versionÚ Úactionú[c                 S   s   g | ]}|r|  d ¡s|‘qS )ú@)Úendswith©r+   r   r&   r&   r'   Ú
<listcomp>É   s      
 z/History._parse_comment_line.<locals>.<listcomp>)rX   ÚinstallZcreateÚupdate_specsr~   )ÚremoveZ	uninstallÚremove_specs)ZneuteredÚneutered_specs)Úcom_patrq   rs   r6   r‡   Úconda_v_patÚspec_patÚgroupsr;   r   rN   r€   )Úclsry   Úitemrz   r4   r„   r}   r~   r&   r&   r'   Ú_parse_comment_line¦   s6    


zHistory._parse_comment_linec                 C   s:  g }|   ¡ D ]p\}}}d|i}|D ]}|  |¡}| |¡ q"d|krN| |¡ ttdƒ|ƒ}| dd¡|d< | dd¡|d< qtd	d
„ |D ƒƒ}	|	r6tj	s6t
|	tdd }
d td|
 d¡ƒ¡}d tdt d¡ƒ¡}t|ƒt|ƒk r6tdƒ| jt|dœ }t| jtjƒs*|tdƒtj|dœ 7 }|tdƒ7 }|S )a4  
        return a list of user requested items.  Each item is a dict with the
        following keys:
        'date': the date and time running the command
        'cmd': a list of argv of the actual command which was run
        'action': install/remove/update
        'specs': the specs being used
        Údater   r   r9   r&   Zunlink_distsr:   Z
link_distsc                 s   s   | ]}d |kr|d  V  qdS )r‚   Nr&   )r+   Úxr&   r&   r'   r-   ë   s    ÿz,History.get_user_requests.<locals>.<genexpr>)Úkeyrj   r.   rk   a†  
                This environment has previously been operated on by a conda version that's newer
                than the conda currently being used. A newer version of conda is required.
                  target environment location: %(target_prefix)s
                  current conda version: %(conda_version)s
                  minimum conda version: %(minimum_version)s
                )Ztarget_prefixr‚   Úminimum_versionzŸ
                    Update conda and try again.
                        $ conda install -p "%(base_prefix)s" "conda>=%(minimum_version)s"
                    )Úbase_prefixr™   z­
                To work around this restriction, one can also set the config parameter
                'allow_conda_downgrades' to False at their own risk.
                )r{   r•   rX   rr   r   r
   ÚgetÚtupler   Zallow_conda_downgradesrB   r   r   r   r6   r5   r   rP   r   Zroot_prefixr   )rS   rv   ÚdtZunused_contZcommentsr”   ry   Zcomment_itemsZdistsZconda_versions_from_historyZminimum_conda_versionZminimum_major_minorZcurrent_major_minorÚmessager&   r&   r'   Úget_user_requestsÔ   s>    	

ýúþý
zHistory.get_user_requestsc                    sÊ   i }|   ¡ D ]†}dd„ | dd¡D ƒ}|D ]}| |jd ¡ q*dd„ | dd¡D ƒ}| dd„ |D ƒ¡ dd„ | d	d¡D ƒ}| d
d„ |D ƒ¡ qtdd„ t| jƒ ¡ D ƒƒ‰ t	‡ fdd„| 
¡ D ƒƒS )Nc                 s   s   | ]}t |ƒV  qd S r)   r    rˆ   r&   r&   r'   r-     s     z2History.get_requested_specs_map.<locals>.<genexpr>r   r&   c                 s   s   | ]}t |ƒV  qd S r)   r    rˆ   r&   r&   r'   r-     s     r‹   c                 s   s   | ]}|j |fV  qd S r)   ©rF   r*   r&   r&   r'   r-     s     c                 s   s   | ]}t |ƒV  qd S r)   r    rˆ   r&   r&   r'   r-     s     rŽ   c                 s   s   | ]}|j |fV  qd S r)   r    r*   r&   r&   r'   r-     s     c                 s   s   | ]}|j V  qd S r)   r    )r+   rH   r&   r&   r'   r-   !  s     c                 3   s"   | ]\}}|ˆ kr||fV  qd S r)   r&   )r+   rF   r   ©Zprefix_recsr&   r'   r-   "  s      )rŸ   r›   ÚpoprF   rX   rA   r   rP   rd   ÚdictÚitems)rS   Zspec_mapZrequestr   r   r‹   rŽ   r&   r¡   r'   Úget_requested_specs_map  s    zHistory.get_requested_specs_mapc                 C   s–   g }t g ƒ}|  ¡ D ]|\}}}t|ƒs,|}nR|D ]L}| d¡rR| |dd… ¡ q0| d¡rp| |dd… ¡ q0td| ƒ‚q0| || ¡ f¡ q|S )zQ
        return a list of tuples(datetime strings, set of distributions)
        r9   r   Nr:   zDid not expect: %s)	rA   r{   r?   r;   Údiscardru   r   rr   Úcopy)rS   rv   Zcurr   ZcontÚ
unused_comr,   r&   r&   r'   Úconstruct_states$  s    

zHistory.construct_statesrj   c                 C   s(   |   ¡ }|stg ƒS t|Ž \}}|| S )zé
        return the state, i.e. the set of distributions, for a given revision,
        defaults to latest (which is the same as the current state when
        the log file is up-to-date)

        Returns a list of dist_strs
        )r©   rA   Úzip)rS   ÚrevZstatesÚtimesZpkgsr&   r&   r'   ra   8  s
    zHistory.get_statec                 C   sR   t |  ¡ ƒD ]@\}\}}}td||f ƒ t|ƒD ]}td| ƒ q2tdƒ qd S )Nz%s  (rev %d)z    %srƒ   )Ú	enumerater{   ÚprintrM   )rS   Úir–   r>   r¨   ry   r&   r&   r'   Ú	print_logF  s
    zHistory.print_logc              	   C   s´  g }t |  ¡ ƒD ]œ\}\}}}||g g g g dœ}i }i }t|ƒr†|D ]V}	t|	dd … ƒ\}
}}}|	 d¡r‚|||f||
 ¡ < qH|	 d¡rH|||f||
 ¡ < qHt|ƒt|ƒ@ }t|ƒD ]^}
||
 }||
 }d |
f| ¡d |
f| ¡dœ}||kr|d  	|¡ q¸|d  	|¡ q¸tt|ƒ| ƒD ]$}
|d  	d |
f||
  ¡¡ q(tt|ƒ| ƒD ]$}
|d	  	d |
f||
  ¡¡ q^nt|ƒD ]}	|d	  	|	¡ qŽ| 	|¡ q|S )
N)r–   r«   rŠ   rŒ   ÚupgradeÚ	downgrader   r:   r9   )ÚoldÚnewr±   r²   rŒ   rŠ   )
r­   r{   r?   r   r;   r@   rA   rB   r   rr   )rS   Úresultr¯   r–   r>   r¨   ZeventrC   rD   ÚpkgrF   rG   ZbuildrI   rJ   r³   r´   Zdetailsr&   r&   r'   Ú
object_logM  sH    ú


þ
"$zHistory.object_logc              	   C   s€   t | jƒst | j¡ tj| jdddN}t|ƒ t|| ƒD ]}| 	d| ¡ q>t|| ƒD ]}| 	d| ¡ q^W 5 Q R X d S )NÚabúutf-8©ÚmodeÚencodingz-%s
z+%s
)
r   rQ   r]   ÚmakedirsÚcodecsr   rR   r8   rB   r0   )rS   Z
last_stateZcurrent_stater7   rE   r&   r&   r'   re   }  s    
zHistory.write_changesr&   c              	   C   s   dd„ |D ƒ}dd„ |D ƒ}dd„ |D ƒ}t |||fƒrŒtj| jddd<}|r^| d| ¡ |rp| d	| ¡ |r‚| d
| ¡ W 5 Q R X d S )Nc                 S   s   g | ]}t t|ƒƒ‘qS r&   ©Ústrr!   r*   r&   r&   r'   r‰   ˆ  s     z'History.write_specs.<locals>.<listcomp>c                 S   s   g | ]}t t|ƒƒ‘qS r&   r¿   r*   r&   r&   r'   r‰   ‰  s     c                 S   s   g | ]}t t|ƒƒ‘qS r&   r¿   r*   r&   r&   r'   r‰   Š  s     r¸   r¹   rº   z# remove specs: %s
z# update specs: %s
z# neutered specs: %s
)r<   r¾   r   rR   r0   )rS   r   r‹   rŽ   Zfhr&   r&   r'   Úwrite_specs‡  s    zHistory.write_specsN)rj   )r&   r&   r&   )r#   r$   r%   rl   rm   r   r‘   r   rT   rW   r\   rU   r`   rX   r{   Ústaticmethodr€   Úclassmethodr•   rŸ   r¥   r©   ra   r°   r·   re   rÁ   r&   r&   r&   r'   rN   N   s,   




-=
0
rN   Ú__main__)Úpprint)JZ
__future__r   r   r   r   Zastr   r¾   rg   r   r   r	   ZloggingÚoperatorr
   r]   Úos.pathr   r   r   rl   r3   Útextwrapr   r1   rb   rƒ   r   r5   Z
auxlib.ishr   Z_vendor.toolzr   r   Zbase.constantsr   Zbase.contextr   Zcommon.compatr   r   Zcommon.pathr   Zcore.prefix_datar   Ú
exceptionsr   r   Zgateways.disk.updater   Zmodels.distr   Zmodels.versionr   r   Zmodels.match_specr!   Z	getLoggerr#   ÚlogÚWarningr"   r8   r?   rK   rM   ÚobjectrN   rÅ   rP   ÚhrŸ   r®   r¥   r&   r&   r&   r'   Ú<module>   sN   
  I

