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
 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'm(Z(m)Z) ddl*m+Z+ ddl,m-Z- ddl.m/Z/m0Z0 ddl1m2Z2 ddl3m4Z4 ddl5m6Z6m7Z7 ddl8m9Z9 e :e;¡Z<G dd„ de=ƒZ>dd„ Z?dd„ Z@dd„ ZAdd„ ZBG d d!„ d!eCƒZDe;d"krÎd d#lEmEZE eDejFƒZGeEeG H¡ ƒ eIeG J¡ ƒ dS )$é    )Úabsolute_importÚdivisionÚprint_functionÚunicode_literals)Úliteral_evalN)ÚEACCESÚEPERM)Ú
itemgetter)ÚisdirÚisfileÚjoin)Údedenté   )Ú__version__)Údals)ÚgroupbyÚtake)ÚDEFAULTS_CHANNEL_NAME)Úcontext)Úensure_text_typeÚ	iteritemsÚopenÚ	text_type)Ú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.7/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ÚtimeZstrftimer   ÚsysÚargvr   ÚCONDA_VERSIONÚsplit)Úfor&   r&   r'   Ú
write_head(   s     r5   c             C   s   t dd„ | D ƒƒS )Nc             s   s   | ]}|  d ¡V  qdS ))ú-ú+N)Ú
startswith)r)   r*   r&   r&   r'   r+   /   s    zis_diff.<locals>.<genexpr>)Úany)Úcontentr&   r&   r'   Úis_diff.   s    r;   c       
      c   s
  i }i }xj| D ]b}|dd … }t |ƒ\}}}}|tkrB|d| 7 }| d¡rZ||| ¡ < q| d¡r||| ¡ < qW t|ƒt|ƒ@ }	x(t|	ƒD ]}d||| || f V  qŽW x*tt|ƒ|	 ƒD ]}d||| f V  qÀW x*tt|ƒ|	 ƒD ]}d||| f V  qìW d S )Nr   z (%s)r6   r7   z %s  {%s -> %s}z-%s-%sz+%s-%s)r   r   r8   ÚlowerÚsetÚsorted)
ZdiffÚaddedÚremovedr*   ÚfnÚnameÚversionÚ_ÚchannelÚchangedr&   r&   r'   Úpretty_diff2   s$    


rG   c             C   s    t | ƒrt| ƒS tt| ƒƒS d S )N)r;   rG   Úiterr>   )r:   r&   r&   r'   Úpretty_contentG   s    rI   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)ÚselfrL   r&   r&   r'   Ú__init__T   s    zHistory.__init__c             C   s   |   ¡  | S )N)Úinit_log_file)rO   r&   r&   r'   Ú	__enter__Y   s    zHistory.__enter__c             C   s   |   ¡  d S )N)Úupdate)rO   Úexc_typeÚ	exc_valueÚ	tracebackr&   r&   r'   Ú__exit__]   s    zHistory.__exit__c             C   s   t | jdƒ d S )NT)r   rN   )rO   r&   r&   r'   rQ   `   s    zHistory.init_log_filec             C   s   t  | j¡jdkS )Nr   )ÚosÚstatrN   Úst_size)rO   r&   r&   r'   Úfile_is_emptyc   s    zHistory.file_is_emptyc          
   C   sÂ   yzyt |  ¡ ƒ}W n8 tk
rJ } zt d| j|f t¡ dS d}~X Y nX t| jƒ}t dd„ | 	¡ D ƒƒ}|  
||¡ W nB tk
r¼ } z$|jttfkrªt| j|jƒ‚n‚ W d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 )N)Zdist_str)r)   Z
prefix_recr&   r&   r'   r+   r   s    z!History.update.<locals>.<genexpr>)r=   Ú	get_stater   ÚwarningsÚwarnrN   r"   r   rL   Úiter_recordsÚwrite_changesÚEnvironmentErrorÚerrnor   r   r   )rO   ZlastÚeZpdZcurrr&   r&   r'   rS   f   s    
zHistory.updatec          	   C   sÂ   g }t | jƒs|S t d¡}t| jƒ}| ¡  ¡ }W dQ R X x~|D ]v}| ¡ }|sVqD| |¡}|r~| 	| 
d¡tƒ g f¡ qD| d¡rœ|d d  	|¡ qDt|ƒdkrD|d d  |¡ qDW |S )z„
        parse the history file and return a list of
        tuples(datetime strings, set of distributions/diffs, comments)
        z==>\s*(.+?)\s*<==Nr   ú#éÿÿÿÿé   r   )r   rN   ÚreÚcompiler   ÚreadÚ
splitlinesÚstripÚmatchÚappendÚgroupr=   r8   ÚlenÚadd)rO   ÚresZsep_patÚfÚlinesÚlineÚmr&   r&   r'   Úparsez   s$    




zHistory.parsec             C   sL   g }xB|   d¡D ]4}t |¡r:|r:d |d |g¡|d< q| |¡ qW |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"
        ú,re   )r3   r    rl   r   rm   )Ú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< |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)   rz   r&   r&   r'   ú
<listcomp>É   s    z/History._parse_comment_line.<locals>.<listcomp>)rS   ÚinstallZcreateÚupdate_specsry   )ÚremoveZ	uninstallÚremove_specs)Úcom_patrl   rn   r3   r‚   Úconda_v_patÚspec_patÚgroupsr8   r   rJ   r{   )Úclsrt   Úitemru   r1   r   rx   ry   r&   r&   r'   Ú_parse_comment_line¦   s2    


zHistory._parse_comment_linec             C   sB  g }x€|   ¡ D ]t\}}}d|i}x |D ]}|  |¡}| |¡ q&W d|krT| |¡ ttdƒ|ƒ}| dd¡|d< | dd¡|d< qW td	d
„ |D ƒƒ}	|	r>tj	s>t
|	tdd }
d td|
 d¡ƒ¡}d tdt d¡ƒ¡}t|ƒt|ƒk r>tdƒ| jt|dœ }t| jtjƒs2|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   r6   r&   Zunlink_distsr7   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>)Úkeyre   r,   rf   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.
                )rv   rŽ   rS   rm   r   r	   ÚgetÚtupler   Zallow_conda_downgradesr>   r   r   r   r3   r2   r   rL   r   Zroot_prefixr   )rO   rq   ÚdtZunused_contZcommentsr   rt   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 }xl|   ¡ D ]`}dd„ | dd¡D ƒ}x|D ]}| |jd ¡ q.W dd„ | dd¡D ƒ}| dd„ |D ƒ¡ qW tt| jƒ ¡ ƒ‰ t	‡ fdd„t
|ƒD ƒƒS )	Nc             s   s   | ]}t |ƒV  qd S )N)r!   )r)   rz   r&   r&   r'   r+     s    z2History.get_requested_specs_map.<locals>.<genexpr>r‡   r&   c             s   s   | ]}t |ƒV  qd S )N)r!   )r)   rz   r&   r&   r'   r+     s    r…   c             s   s   | ]}|j |fV  qd S )N)rB   )r)   r*   r&   r&   r'   r+     s    c             3   s0   | ](\}‰ t ‡ fd d„ˆD ƒƒr|ˆ fV  qdS )c             3   s   | ]}ˆ   |¡V  qd S )N)rl   )r)   Zdist)rz   r&   r'   r+     s    z<History.get_requested_specs_map.<locals>.<genexpr>.<genexpr>N)r9   )r)   rB   )Úprefix_recs)rz   r'   r+     s    )r˜   r”   ÚpoprB   rS   r•   r   rL   r_   Údictr   )rO   Zspec_mapZrequestr‡   rz   r…   r&   )r™   r'   Úget_requested_specs_map  s    
zHistory.get_requested_specs_mapc             C   sž   g }t g ƒ}xŒ|  ¡ D ]€\}}}t|ƒs.|}nVxT|D ]L}| d¡rV| |dd… ¡ q4| d¡rt| |dd… ¡ q4td| ƒ‚q4W | || ¡ f¡ qW |S )zQ
        return a list of tuples(datetime strings, set of distributions)
        r6   r   Nr7   zDid not expect: %s)	r=   rv   r;   r8   Údiscardrp   r   rm   Úcopy)rO   rq   Zcurr–   ZcontÚ
unused_comr*   r&   r&   r'   Úconstruct_states   s    


zHistory.construct_statesre   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    r=   Úzip)rO   ÚrevZstatesÚtimesZpkgsr&   r&   r'   r\   4  s
    zHistory.get_statec             C   sZ   xTt |  ¡ ƒD ]D\}\}}}td||f ƒ xt|ƒD ]}td| ƒ q6W tdƒ qW d S )Nz%s  (rev %d)z    %sr~   )Ú	enumeraterv   ÚprintrI   )rO   Úir   r:   rŸ   rt   r&   r&   r'   Ú	print_logB  s
    zHistory.print_logc          	   C   sÎ  g }xÂt |  ¡ ƒD ]°\}\}}}||g g g g dœ}i }i }t|ƒršx^|D ]V}	t|	dd … ƒ\}
}}}|	 d¡rˆ|||f||
 ¡ < qN|	 d¡rN|||f||
 ¡ < qNW t|ƒt|ƒ@ }xjt|ƒD ]^}
||
 }||
 }d |
f| ¡d |
f| ¡dœ}||kr|d  	|¡ qÂ|d  	|¡ qÂW x8tt|ƒ| ƒD ]$}
|d  	d |
f||
  ¡¡ q6W x\tt|ƒ| ƒD ]$}
|d	  	d |
f||
  ¡¡ qpW n"x t|ƒD ]}	|d	  	|	¡ q¤W | 	|¡ qW |S )
N)r   r¢   r„   r†   ÚupgradeÚ	downgrader   r7   r6   )ÚoldÚnewr¨   r©   r†   r„   )
r¤   rv   r;   r   r8   r<   r=   r>   r   rm   )rO   Úresultr¦   r   r:   rŸ   Zeventr?   r@   ÚpkgrB   rC   ZbuildrE   rF   rª   r«   Zdetailsr&   r&   r'   Ú
object_logI  sD     




$&zHistory.object_logc          	   C   sˆ   t | jƒst | j¡ tj| jdddV}t|ƒ x"t|| ƒD ]}| 	d| ¡ q@W x"t|| ƒD ]}| 	d| ¡ qdW W d Q R X d S )NÚabzutf-8)ÚmodeÚencodingz-%s
z+%s
)
r
   rM   rX   ÚmakedirsÚcodecsr   rN   r5   r>   r.   )rO   Z
last_stateZcurrent_stater4   rA   r&   r&   r'   r`   y  s    
zHistory.write_changesr&   c          	   C   sj   dd„ |D ƒ}dd„ |D ƒ}|s$|rft j| jddd*}|rJ| d| ¡ |r\| d| ¡ W d Q R X d S )	Nc             S   s   g | ]}t t|ƒƒ‘qS r&   )r   r!   )r)   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&   r'   rƒ   …  s    r¯   zutf-8)r°   r±   z# remove specs: %s
z# update specs: %s
)r³   r   rN   r.   )rO   r‡   r…   Zfhr&   r&   r'   Úwrite_specsƒ  s    zHistory.write_specsN)re   )r&   r&   )r#   r$   r%   rg   rh   rˆ   rŠ   r‰   rP   rR   rW   rQ   r[   rS   rv   Ústaticmethodr{   ÚclassmethodrŽ   r˜   rœ   r    r\   r§   r®   r`   r´   r&   r&   r&   r'   rJ   N   s(   


,=
0
rJ   Ú__main__)Úpprint)KZ
__future__r   r   r   r   Zastr   r³   rb   r   r   ZloggingÚoperatorr	   rX   Úos.pathr
   r   r   rg   r0   Útextwrapr   r/   r]   r~   r   r2   Z_vendor.auxlib.ishr   Z_vendor.toolzr   r   Zbase.constantsr   Zbase.contextr   Zcommon.compatr   r   r   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"   r5   r;   rG   rI   ÚobjectrJ   r¸   rL   Úhr˜   r¥   rœ   r&   r&   r&   r'   Ú<module>   sN   
  B

